Ich werde von Anfang an sagen , dass meine Frage / Problem ähnlich sieht diesen vorherigen, aber da ich bin nicht sicher , ob die Ursache oder die Start-Informationen die gleiche ist, habe ich beschlossen , meine Frage mit einem paar mehr Details zu veröffentlichen.
Problem zur Hand:
- Zu einer seltsamen Stunde (gegen Ende des Geschäftstages) beginnt sich eine Produktionsinstanz unregelmäßig zu verhalten:
- hohe CPU für die Instanz (von einer Grundlinie von ~ 30% ging es auf etwa das Doppelte und wuchs immer noch)
- erhöhte Anzahl von Transaktionen / Sek. (obwohl sich beim Laden der App nichts geändert hat)
- erhöhte Anzahl von Leerlaufsitzungen
- seltsame Blockierungsereignisse zwischen Sitzungen, die dieses Verhalten nie zeigten (selbst das Lesen nicht festgeschriebener Sitzungen verursachte Blockierungen)
- Die obersten Wartezeiten für das Intervall waren keine Seitenverriegelung auf dem 1. Platz, wobei Sperren den 2. Platz einnahmen
Erste Untersuchung:
- Mit sp_whoIsActive haben wir gesehen, dass eine von unserem Überwachungstool ausgeführte Abfrage extrem langsam ausgeführt wird und viel CPU beansprucht, was vorher nicht geschehen ist.
- seine Isolationsstufe wurde unverbindlich gelesen;
- Wir haben uns den Plan angesehen, bei dem wir verrückte Zahlen gesehen haben: StatementEstRows = "3.86846e + 010" mit etwa 150 TB geschätzten Daten, die zurückgegeben werden sollen
- Wir hatten den Verdacht, dass eine Abfrageüberwachungsfunktion des Überwachungstools die Ursache war, und haben diese Funktion deaktiviert (wir haben auch ein Ticket bei unserem Anbieter geöffnet, um zu überprüfen, ob ihm ein Problem bekannt ist).
- Von diesem ersten Ereignis an passierte es noch einige Male. Jedes Mal, wenn wir die Sitzung beenden, wird alles wieder normal.
- Wir stellen fest, dass die Abfrage einer der von MS in BOL für die Überwachung von Abfragespeichern verwendeten Abfragen sehr ähnlich ist - Abfragen, deren Leistung kürzlich zurückgegangen ist (Vergleich verschiedener Zeitpunkte)
- Wir führen dieselbe Abfrage manuell aus und sehen dasselbe Verhalten (die verwendete CPU nimmt ständig zu, die Wartezeiten zwischen den Latches steigen, unerwartete Sperren usw.).
Schuldige Abfrage:
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS q
ON qt.query_text_id = q.query_text_id
Inner Join sys.query_store_plan AS p1
ON q.query_id = p1.query_id
Inner Join sys.query_store_runtime_stats AS rs1
ON p1.plan_id = rs1.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi1
ON rsi1.runtime_stats_interval_id = rs1.runtime_stats_interval_id
Inner Join sys.query_store_plan AS p2
ON q.query_id = p2.query_id
Inner Join sys.query_store_runtime_stats AS rs2
ON p2.plan_id = rs2.plan_id
Inner Join sys.query_store_runtime_stats_interval AS rsi2
ON rsi2.runtime_stats_interval_id = rs2.runtime_stats_interval_id
Where rsi1.start_time > DATEADD(hour, -48, GETUTCDATE())
AND rsi2.start_time > rsi1.start_time
AND p1.plan_id <> p2.plan_id
AND rs2.avg_duration > rs1.avg_duration * 2
Order By q.query_id, rsi1.start_time, rsi2.start_time
Einstellungen und Infos:
- SQL Server 2016 SP1 CU4 Enterprise auf einem Windows Server 2012R2-Cluster
- Abfragespeicher aktiviert und standardmäßig konfiguriert (keine Einstellung geändert)
- Datenbank aus einer SQL 2005-Instanz importiert (und immer noch auf Kompatibilitätsstufe 100)
Empirische Beobachtung:
- Aufgrund extrem verrückter Statistiken haben wir alle * plan_persist ** -Objekte verwendet, die im fehlerhaften geschätzten Plan verwendet wurden (noch kein tatsächlicher Plan, da die Abfrage nie abgeschlossen wurde) und Statistiken überprüft. Einige der im Plan verwendeten Indizes hatten keine Statistiken (DBCC SHOWSTATISTICS hat nichts zurückgegeben. Wählen Sie aus sys.stats die Funktion NULL stats_date () für einige Indizes aus
Schnelle und schmutzige Lösung:
- Erstellen Sie manuell fehlende Statistiken zu Systemobjekten, die sich auf Query Store oder beziehen
- Erzwingen Sie, dass die Abfrage mit dem neuen CE (Traceflag) ausgeführt wird. Dadurch werden auch die erforderlichen Statistiken erstellt oder aktualisiert
- Ändern Sie die Kompatibilitätsstufe der Datenbank auf 130 (daher wird standardmäßig das neue CE verwendet).
Meine eigentliche Frage wäre also:
Warum würde eine Abfrage im Abfragespeicher Leistungsprobleme für die gesamte Instanz verursachen? Befinden wir uns mit Query Store in einem Fehlergebiet?
PS: Ich werde in Kürze einige Dateien (Druckbildschirme, E / A-Statistiken und Pläne) hochladen.
Auf Dropbox hinzugefügte Dateien .
Plan 1 - anfänglicher verrückter geschätzter Plan in der Produktion
Plan 2 - tatsächlicher Plan, altes CE, in einer Testumgebung (gleiches Verhalten, gleiche verrückte Statistiken)
Plan 3 - aktueller Plan, neues CE, in einer Testumgebung