Fehlerbehebung bei SOS_SCHEDULER_YIELD Warten

14

Als wir unser Unternehmens-ERP (Dynamics AX 2012) ausführten, stellte ich fest, dass unsere Produktionsumgebung viel langsamer schien als unsere Entwicklungssysteme.

Nachdem ich die gleichen Aktivitäten sowohl in der Entwicklungs- als auch in der Produktionsumgebung ausgeführt habe, während ein Trace ausgeführt wurde, bestätigte ich, dass SQL-Abfragen in unserer Produktionsumgebung im Vergleich zur Entwicklung sehr langsam ausgeführt wurden (durchschnittlich 10-50x langsamer).

Zuerst schrieb ich dies dem Laden zu und führte die gleichen Aktivitäten in der Produktionsumgebung außerhalb der Geschäftszeiten erneut aus und fand die gleichen Ergebnisse in der Ablaufverfolgung.

Ich habe meine Wartestatistiken in SQL Server gelöscht und den Server eine Weile unter normaler Produktionslast laufen lassen und dann die folgende Abfrage ausgeführt:

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

Meine Ergebnisse sind wie folgt:

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

Die mit Abstand größte Wartezeit scheint also SOS_Scheduler_Yield zu sein, und ich habe herumgegoogelt und festgestellt, dass dies in der Regel damit zusammenhängt, dass die CPU nicht mithalten kann.

Ich habe diese Abfrage dann mehrmals hintereinander ausgeführt.

SELECT *
FROM sys.dm_os_schedulers
WHERE scheduler_id < 255

Ich weiß, dass ich nach Schedulern suchen soll, die nicht null sind. Runnable_tasks_count oder pending_disk_io_count, aber im Grunde ist es fast die ganze Zeit null.

Ich sollte auch erwähnen, dass Max. Grad der Parallelität auf 1 gesetzt wurde, da die Dynamics AX-Arbeitslast normalerweise OLTP ist und die Änderung von 8 keinen großen Unterschied in den obigen Wartestatistiken machte Leistungsprobleme.

Ich bin irgendwie ratlos, wo ich von hier aus hingehen soll. Ich habe im Grunde einen SQL Server, der anscheinend überlastet ist, aber nicht auf runnable_tasks oder IO wartet.

Ich weiß, dass das E / A-Subsystem dieses SQL Servers nicht sehr gut ist, da das Ausführen von SQLIO auf dem Laufwerk, das die tatsächlichen Datenbanken enthält, zu ziemlich niedrigen Zahlen führen kann (denken Sie an 10 MB pro Sekunde für bestimmte Arten von Lese- / Schreibvorgängen). SQL scheint nicht darauf zu warten, da auf dem Server die meisten Datenbanken zwischengespeichert sind.

Hier sind einige Umgebungsinformationen, die helfen sollen:

Produktionsumgebung:

  • SQL Server
  • HP ProLian DL360p Gen8
  • Intel Xeon E5-2650 0 bei 2,00 GHz x 2 mit Hyperthreading (32 logische Kerne)
  • 184 GB Speicher
  • Windows Server 2012
  • 2 Instanzen von SQL Server 2012 Standard (RTM, nicht gepatcht)
  • RAID 1 279 GB-Laufwerke (15 KB) C: Laufwerk, enthält Datenbanken und Betriebssystem
  • Auslagerungsdatei und TempDB auf getrennten Laufwerken (Solid State)

Mein DEV:

  • Von Hyper-V gehosteter SQL Server- und Dynamics AX 2012-AOS-Server
  • Core i7 3.4 GHz mit Hyperthreading (8 logische Kerne)
  • 8 GB Speicher
  • Windows Server 2008 R2
  • SSD für die gesamte VM.

Ich würde mich über jede Eingabe zu anderen Themen freuen.

Nicholas Peterson
quelle

Antworten:

16

Ich habe dieses Problem behoben und festgestellt, dass auf unserem SQL-Server Energieverwaltungsfunktionen aktiviert waren, die die CPU-Frequenz hoch und runter skalierten, aber nicht schnell genug waren, um mit der geringen Nachfrage Schritt zu halten, und die Wartezeit für SOS_Scheduler_Yield eingeführt haben. Nachdem es so geändert wurde, dass es immer mit hoher Leistung läuft, wurde das Problem behoben und die Wartezeiten sind normaler (LatchIO-Typ Zeug).

Nicholas Peterson
quelle