Risoluzione dei problemi SOS_SCHEDULER_YIELD aspetta


14

Gestendo il nostro ERP aziendale (Dynamics AX 2012), ho notato che il nostro ambiente di produzione sembrava molto più lento dei nostri sistemi di sviluppo.

Dopo aver eseguito le stesse attività negli ambienti di sviluppo e produzione durante l'esecuzione di una traccia, ho confermato che le query SQL venivano eseguite molto lentamente nel nostro ambiente di produzione rispetto allo sviluppo (in media 10-50 volte più lento).

Inizialmente l'ho attribuito al caricamento e ho eseguito nuovamente le stesse attività sull'ambiente di produzione durante le ore di inattività e ho trovato gli stessi risultati nella traccia.

Ho cancellato le mie statistiche di attesa in SQL Server, quindi ho lasciato il server sotto il suo normale carico di produzione per un po ', quindi ho eseguito questa query:

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

I miei risultati sono i seguenti:

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

Quindi apparentemente il più grande Wait è SOS_Scheduler_Yield di gran lunga, e ho cercato su Google e ho scoperto che in genere si riferisce alla CPU che non è in grado di tenere il passo.

Ho quindi eseguito questa query più volte in successione.

SELECT *
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255

So che dovrei cercare programmatori con runnable_tasks_count diverso da zero o pending_disk_io_count, ma è praticamente zero quasi sempre.

Devo anche menzionare che Max Degree of Parallelism era impostato su 1, poiché il carico di lavoro di Dynamics AX è in genere di tipo OLTP, e cambiarlo 8 non ha fatto molta differenza nelle statistiche di attesa sopra, sono diventate quasi identiche con lo stesso problemi di prestazioni.

Sono quasi a corto di dove andare da qui, fondamentalmente ho un SQL Server che è apparentemente legato alla CPU ma non aspetta runnable_tasks o IO.

So che il sottosistema IO di questo SQL Server non è molto buono, perché l'esecuzione di SQLIO sull'unità contenente i database effettivi può portare a numeri piuttosto bassi (si pensi a 10 MB al secondo per alcuni tipi di letture / scritture), che diceva: non sembra che SQL lo stia aspettando a causa della quantità di memoria sul server che memorizza nella cache la maggior parte dei database.

Ecco alcune informazioni sull'ambiente per aiutare:

Ambiente di produzione:

  • server SQL
  • HP ProLian DL360p Gen8
  • Intel Xeon E5-2650 0 a 2,00 GHz x 2 con hyperthreading (32 core logici)
  • 184 GB di memoria
  • Windows Server 2012
  • 2 istanze di SQL Server 2012 Standard (RTM, senza patch)
  • Raid 1 unità da 279 GB (15k) C: unità, contiene database e sistema operativo
  • File di paging e TempDB su unità distinte e separate (stato solido)

Il mio DEV:

  • Hyper-V ha ospitato SQL Server e Dynamics AX 2012 AOS server
  • Core i7 3.4ghz con hyperthreading (8 core logici)
  • 8 GB di memoria
  • Windows Server 2008 R2
  • SSD per l'intera macchina virtuale.

Gradirei qualsiasi input su altre cose da cercare.

Risposte:


16

Quindi l'ho risolto, ho scoperto che sul nostro server SQL erano abilitate le funzioni di risparmio energetico che scalavano la frequenza della CPU su e giù, ma non abbastanza velocemente da tenere il passo con la piccola domanda e introdotto l'attesa SOS_Scheduler_Yield. Dopo averlo modificato per funzionare sempre ad alte prestazioni, il problema è scomparso e ora le attese sono più normali (roba di tipo LatchIO).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.