SOS_SCHEDULER_YIELD bekleme sorunlarını giderme


14

Kurumsal ERP (Dynamics AX 2012) çalıştırarak, üretim ortamımızın geliştirme sistemlerimizden çok daha yavaş göründüğünü fark ettim.

Bir izleme çalıştırırken hem geliştirme hem de üretim ortamlarında aynı faaliyetleri gerçekleştirdikten sonra, SQL sorgularının geliştirme ortamımıza göre (ortalama 10-50x daha yavaş) üretim ortamımızda çok yavaş çalıştığını doğruladım.

İlk başta bunu yüklemeye bağladım ve çalışma saatleri dışında aynı faaliyetleri üretim ortamında yeniden çalıştırdım ve aynı sonuçları izde buldum.

SQL Server'daki bekleme istatistiklerimi temizledim, sonra sunucunun normal üretim yükü altında bir süre çalışmasına izin verdim ve sonra bu sorguyu çalıştırdım:

WITH [Waits] AS
    (SELECT
        [wait_type],
        [wait_time_ms] / 1000.0 AS [WaitS],
        ([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
        [signal_wait_time_ms] / 1000.0 AS [SignalS],
        [waiting_tasks_count] AS [WaitCount],
        100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
        ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
    FROM sys.dm_os_wait_stats
    WHERE [wait_type] NOT IN (
        N'CLR_SEMAPHORE',    N'LAZYWRITER_SLEEP',
        N'RESOURCE_QUEUE',   N'SQLTRACE_BUFFER_FLUSH',
        N'SLEEP_TASK',       N'SLEEP_SYSTEMTASK',
        N'WAITFOR',          N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
        N'CHECKPOINT_QUEUE', N'REQUEST_FOR_DEADLOCK_SEARCH',
        N'XE_TIMER_EVENT',   N'XE_DISPATCHER_JOIN',
        N'LOGMGR_QUEUE',     N'FT_IFTS_SCHEDULER_IDLE_WAIT',
        N'BROKER_TASK_STOP', N'CLR_MANUAL_EVENT',
        N'CLR_AUTO_EVENT',   N'DISPATCHER_QUEUE_SEMAPHORE',
        N'TRACEWRITE',       N'XE_DISPATCHER_WAIT',
        N'BROKER_TO_FLUSH',  N'BROKER_EVENTHANDLER',
        N'FT_IFTSHC_MUTEX',  N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
        N'DIRTY_PAGE_POLL',  N'SP_SERVER_DIAGNOSTICS_SLEEP')
    )
SELECT
    [W1].[wait_type] AS [WaitType],
    CAST ([W1].[WaitS] AS DECIMAL(14, 2)) AS [Wait_S],
    CAST ([W1].[ResourceS] AS DECIMAL(14, 2)) AS [Resource_S],
    CAST ([W1].[SignalS] AS DECIMAL(14, 2)) AS [Signal_S],
    [W1].[WaitCount] AS [WaitCount],
    CAST ([W1].[Percentage] AS DECIMAL(4, 2)) AS [Percentage],
    CAST (([W1].[WaitS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgWait_S],
    CAST (([W1].[ResourceS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgRes_S],
    CAST (([W1].[SignalS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgSig_S]
FROM [Waits] AS [W1] INNER JOIN [Waits] AS [W2] ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum], [W1].[wait_type], [W1].[WaitS],
    [W1].[ResourceS], [W1].[SignalS], [W1].[WaitCount], [W1].[Percentage]
HAVING SUM ([W2].[Percentage]) - [W1].[Percentage] < 95; -- percentage threshold

Sonuçlarım aşağıdaki gibidir:

WaitType               Wait_S  Resource_S  Signal_S  WaitCount  Percentage  AvgWait_S  AvgRes_S  AvgSig_S
SOS_SCHEDULER_YIELD   4162.52        3.64   4158.88    4450085       77.33     0.0009    0.0000    0.0009
ASYNC_NETWORK_IO       457.98      331.59    126.39     351113        8.51     0.0013    0.0009    0.0004
PAGELATCH_EX           252.94        5.14    247.80     796348        4.70     0.0003    0.0000    0.0003
WRITELOG               166.01       48.01    118.00     302209        3.08     0.0005    0.0002    0.0004
LCK_M_U                145.47      145.45      0.02        123        2.70     1.1827    1.1825    0.0002

Görünüşe göre en büyük Bekleme SOS_Scheduler_Yield çok uzak, ve ben googled ve genellikle CPU yetişmek mümkün değil ilgili olduğunu bulundu.

Daha sonra bu sorguyu art arda birkaç kez çalıştırdım.

SELECT *
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255

Sıfır olmayan runnable_tasks_count veya pending_disk_io_count ile zamanlayıcılar arıyorum gerekiyordu, ama temelde neredeyse her zaman sıfır.

Ayrıca, Dynamics AX iş yükü tipik olarak doğada OLTP olduğundan ve 8'i yukarıdaki bekleme istatistiklerinde çok fazla fark yaratmadığından, Maksimum Paralellik Derecesi 1 olarak ayarlandığından bahsetmeliyim. performans sorunları.

Ben buradan nereye kaybı, tür temelde görünüşte CPU sarılı ama runnable_tasks veya IO bekleyen değil bir SQL Server var.

Bu SQL Server'ın IO alt sisteminin çok iyi olmadığını biliyorum, çünkü gerçek veritabanlarını içeren sürücüde SQLIO'yu çalıştırmak oldukça düşük sayılara yol açabilir (bazı okuma / yazma türleri için 10MB saniye düşünün), Veritabanlarının çoğunu önbelleğe alan sunucudaki bellek miktarı nedeniyle SQL bunu beklemiyor gibi görünüyor.

İşte size yardımcı olacak bazı çevre bilgileri:

Üretim ortamı:

  • SQL Server
  • HP ProLian DL360p Gen8
  • Hiper iş parçacıklı Intel Xeon E5-2650 0 @ 2.00GHz x 2 (32 mantıksal çekirdek)
  • 184 GB bellek
  • Windows Server 2012
  • SQL Server 2012 Standard'ın 2 örneği (RTM, işlenmemiş)
  • Raid 1 279GB sürücüler (15k) C: sürücü, veritabanları ve işletim sistemi içerir
  • Farklı, ayrı sürücülerde Sayfa Dosyası ve TempDB (yarıiletken)

DEV'm:

  • Hyper-V tarafından barındırılan SQL Server ve Dynamics AX 2012 AOS sunucusu
  • Core i7 3.4ghz, hiper iş parçacıklı (8 mantıksal çekirdek)
  • 8GB bellek
  • Windows Server 2008 R2
  • Tüm VM için SSD.

Aramak için başka şeyler hakkında herhangi bir girdi hoş geldiniz.

Yanıtlar:


16

Bunu çözdüm, SQL sunucumuzda CPU frekansını yukarı ve aşağı ölçeklendiren, ancak küçük talebe ayak uyduracak kadar hızlı olmayan ve SOS_Scheduler_Yield beklemesini sağlayan güç yönetimi özelliklerinin etkinleştirildiği ortaya çıktı. Her zaman yüksek performansta çalışacak şekilde değiştirdikten sonra sorun ortadan kalktı ve şimdi beklemeler daha normal (LatchIO tipi şeyler).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.