Behandeln von Problemen mit der automatischen Sauber up-Überwachung von Änderungen

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed Instance

Dieser Artikel bietet Möglichkeiten, häufige Probleme zu behandeln, die bei der automatischen sauber up der Änderungsnachverfolgung beobachtet werden.

Problembeschreibung

Wenn die automatische sauber up im Allgemeinen nicht wie erwartet funktioniert, können Sie eines oder mehrere der folgenden Symptome sehen:

  • Hoher Speicherverbrauch durch eine oder mehrere Änderungsnachverfolgungsseitentabellen oder die syscommittab Systemtabelle.
  • Seitliche Tabellen (interne Tabellen, deren Name mit dem Präfix change_trackingbeginnt , z change_tracking_12345. B. ) oder syscommittab beides, zeigen eine signifikante Anzahl von Zeilen an, die sich außerhalb des konfigurierten Aufbewahrungszeitraums befinden.
  • dbo.MSChange_tracking_historyDie Tabelle enthält Einträge mit bestimmten sauber Up-Fehlern.
  • CHANGETABLE Die Leistung hat sich im Laufe der Zeit verschlechtert.
  • Die automatische sauber up oder manuelle sauber up meldet eine hohe CPU-Auslastung.

Debuggen und Entschärfung

Um die Ursache eines Problems mit der automatischen sauber up der Änderungsnachverfolgung zu identifizieren, führen Sie die folgenden Schritte aus, um das Problem zu debuggen und zu beheben.

Status der automatischen sauber up

Überprüfen Sie, ob die automatische sauber up ausgeführt wurde. Um dies zu überprüfen, fragen Sie die sauber Upverlaufstabelle in derselben Datenbank ab. Wenn die sauber up ausgeführt wurde, enthält die Tabelle Einträge mit den Anfangs- und Endzeiten der sauber up. Wenn die sauber up nicht ausgeführt wurde, ist die Tabelle leer oder enthält veraltete Einträge. Wenn die Verlaufstabelle Einträge mit dem Tag cleanup errors in der Spalte commentsenthält, tritt aufgrund von Fehlern auf Tabellenebene sauber up ein Fehler beim sauber up auf.

SELECT TOP 1000 * FROM dbo.MSChange_tracking_history ORDER BY start_time DESC;

Die automatische sauber up wird regelmäßig mit einem Standardintervall von 30 Minuten ausgeführt. Wenn die Verlaufstabelle nicht vorhanden ist, wird die automatische sauber up wahrscheinlich nie ausgeführt. Überprüfen Sie andernfalls die Werte und start_timeend_time Spaltenwerte. Wenn die neuesten Einträge nicht aktuell sind, d. h. Stunden oder Tage alt, wird die automatische sauber up möglicherweise nicht ausgeführt. Wenn dies der Fall ist, führen Sie die folgenden Schritte aus, um probleme zu beheben.

1. Die Bereinigung ist deaktiviert.

Sehen Sie nach, ob für die Datenbank die automatische Bereinigung aktiviert ist. Wenn dies nicht der Fall ist, aktivieren Sie sie und warten Sie mindestens 30 Minuten, bis Sie in der Verlaufstabelle nach neuen Einträgen suchen. Überwachen Sie anschließend den Fortschritt in der Verlaufstabelle.

SELECT * FROM sys.change_tracking_databases WHERE database_id=DB_ID('<database_name>')

Ein Wert ungleich Null in is_auto_cleanup_on gibt an, dass die automatische sauber up aktiviert ist. Der Aufbewahrungszeitraumswert steuert die Dauer, für die Änderungsnachverfolgungsmetadaten im System aufbewahrt werden. Der Standardwert für den Aufbewahrungszeitraum für die Änderungsnachverfolgung beträgt 2 Tage.

Informationen zum Aktivieren oder Deaktivieren der Änderungsnachverfolgung finden Sie unter Aktivieren und Deaktivieren von Änderungsnachverfolgung (SQL Server).To enable or disable change tracking see Enable and Disable Änderungsnachverfolgung (SQL Server)

2. Bereinigung ist aktiviert, aber nicht ausgeführt

Wenn die automatische sauber up aktiviert ist, wird der automatische sauber upthread wahrscheinlich aufgrund unerwarteter Fehler beendet. Derzeit ist ein Neustart des automatischen sauber up-Threads nicht möglich. Sie müssen ein Failover auf einen sekundären Server initiieren (oder den Server ohne sekundäre Server neu starten), und vergewissern Sie sich, dass die Einstellung für die automatische sauber up für die Datenbank aktiviert ist.

Die automatische sauber up wird ausgeführt, macht jedoch keinen Fortschritt

Wenn eine oder mehrere Seitentabellen einen erheblichen Speicherverbrauch aufweisen oder eine große Anzahl von Datensätzen enthalten, die über die konfigurierte Aufbewahrung hinausgehen, führen Sie die Schritte in diesem Abschnitt aus, die Abhilfemaßnahmen für eine einzelne seitliche Tabelle beschreiben. Bei Bedarf können dieselben Schritte für weitere Tabellen wiederholt werden.

1. Bewerten des automatischen sauber up-Backlogs

Identifizieren Sie seitenseitige Tabellen mit einem großen Backlog abgelaufener Datensätze, für die eine Entschärfung erforderlich ist. Führen Sie die folgenden Abfragen aus, um die seitlichen Tabellen mit großen Anzahl abgelaufener Datensätze zu identifizieren. Denken Sie daran, die Werte in den Beispielskripts wie dargestellt zu ersetzen.

  1. Ruft die ungültige sauber up-Version ab:

    SELECT * FROM sys.change_tracking_tables;
    

    Der cleanup_version Wert aus den zurückgegebenen Zeilen stellt die ungültige sauber up-Version dar.

  2. Führen Sie die folgende dynamische Transact-SQL -Abfrage (T-SQL) aus, die die Abfrage generiert, um die Anzahl der abgelaufenen Zeilen von Seitentabellen abzurufen. Ersetzen Sie den Wert <invalid_version> in der Abfrage durch den Wert, der im vorherigen Schritt abgerufen wurde.

    SELECT 'SELECT ''' + QUOTENAME(name) + ''', count(*) FROM [sys].' + QUOTENAME(name)
        + ' WHERE sys_change_xdes_id IN (SELECT xdes_id FROM sys.syscommittab ssct WHERE ssct.commit_ts <= <invalid_version>) UNION'
    FROM sys.internal_tables
    WHERE internal_type = 209;
    
  3. Kopieren Sie das Resultset aus der vorherigen Abfrage, und entfernen Sie den Schlüsselwort (keyword) aus der UNION letzten Zeile. Wenn Sie die generierte T-SQL-Abfrage über eine dedizierte Administratorverbindung (DAC) ausführen, gibt die Abfrage die Anzahl der abgelaufenen Zeilen aller Seitentabellen an. Abhängig von der Größe der sys.syscommittab Tabelle und der Anzahl der seitlichen Tabellen kann die Ausführung dieser Abfrage sehr lange dauern.

    Wichtig

    Dieser Schritt ist erforderlich, um mit den Entschärfungsschritten fortzufahren. Wenn die vorherige Abfrage nicht ausgeführt werden kann, identifizieren Sie die Anzahl der abgelaufenen Zeilen für die einzelnen Seitentabellen mithilfe der folgenden Abfragen.

Führen Sie die folgenden Entschärfungsschritte für die seitlichen Tabellen aus, wobei die absteigende Reihenfolge der Anzahl abgelaufener Zeilen bis zu einem verwaltbaren Zustand für die automatische sauber, um nachholen zu können.

Nachdem Sie die Seitentabellen mit einer großen Anzahl abgelaufener Datensätze identifiziert haben, sammeln Sie Informationen über die Latenz der Löschanweisungen der Seittabelle und die Löschrate pro Sekunde in den letzten Stunden. Schätzen Sie als Nächstes die Zeit, die zum sauber der Seittabelle erforderlich ist, indem Sie sowohl die veraltete Zeilenanzahl als auch die Löschlatenz berücksichtigen.

Verwenden Sie den folgenden T-SQL-Codeausschnitt, indem Sie Parametervorlagen durch entsprechende Werte ersetzen.

  • Abfrage der Rate von sauber up pro Sekunde:

    SELECT
        table_name,
        rows_cleaned_up / ISNULL(NULLIF(DATEDIFF(second, start_time, end_time), 0), 1),
        cleanup_version
    FROM dbo.MSChange_tracking_history
    WHERE table_name = '<table_name>'
    ORDER BY end_time DESC;
    

    Sie können auch die Granularität von Minuten oder Stunden für die DATEDIFF Funktion verwenden.

  • Suchen Sie die Anzahl der veralteten Zeilen in der Seitentabelle. Mit dieser Abfrage können Sie die Anzahl der Zeilen ermitteln, die noch bereinigt werden müssen.

    Die <internal_table_name> und <cleanup_version> für die Benutzertabelle befinden sich in der Ausgabe, die im vorherigen Abschnitt zurückgegeben wird. Führen Sie mithilfe dieser Informationen den folgenden T-SQL-Code über eine dedizierte Administratorverbindung (DAC) aus:

    SELECT '<internal_table_name>',
        COUNT(*)
    FROM sys.<internal_table_name>
    WHERE sys_change_xdes_id IN (
            SELECT xdes_id
            FROM sys.syscommittab ssct
            WHERE ssct.commit_ts <= <cleanup_version>
    );
    

    Diese Abfrage kann einige Zeit in Anspruch nehmen. In Fällen, in denen die Abfrage eine Zeitüberschreitung aufweist, berechnen Sie veraltete Zeilen, indem Sie die Differenz zwischen den Gesamtzeilen und den aktiven Zeilen ermitteln, die nach oben sauber werden.

  • Suchen Sie die Gesamtzahl der Zeilen in der seitlichen Tabelle, indem Sie die folgende Abfrage ausführen:

    SELECT sum(row_count) FROM sys.dm_db_partition_stats
    WHERE object_id = OBJECT_ID('sys.<internal_table_name>')
    GROUP BY partition_id;
    
  • Suchen Sie die Anzahl der aktiven Zeilen in der Seitentabelle, indem Sie die folgende Abfrage ausführen:

    SELECT '<internal_table_name>', COUNT(*) FROM sys.<internal_table_name> WHERE sys_change_xdes_id
    IN (SELECT xdes_id FROM sys.syscommittab ssct WHERE ssct.commit_ts > <cleanup_version>);
    

    Sie können die geschätzte Zeit berechnen, um die Tabelle mithilfe der Rate der Anzahl der sauber up- und veralteten Zeilen zu sauber. Betrachten Sie die folgende Formel:

    Zeit bis sauber in Minuten nach oben = (veraltete Zeilenanzahl) / (Rate der sauber up in Minuten)

    Wenn die Zeit zum Abschließen der Tabelle sauber up akzeptabel ist, überwachen Sie den Fortschritt, und lassen Sie die automatische sauber up ihre Arbeit fortsetzen. Wenn nicht, fahren Sie mit den nächsten Schritten fort, um einen weiteren Drilldown auszuführen.

2. Überprüfen von Tabellensperrkonflikten

Ermitteln Sie, ob sauber up aufgrund von Eskalationskonflikten bei Tabellensperren nicht voranschreitet, wodurch sauber immer wieder Sperren in der Seittabelle abgerufen werden, um Zeilen zu löschen.

Führen Sie den folgenden T-SQL-Code aus, um einen Sperrkonflikt zu bestätigen. Diese Abfrage ruft Datensätze für die problematische Tabelle ab, um festzustellen, ob mehrere Einträge vorhanden sind, die Sperrkonflikte angeben. Einige sporadische Konflikte, die über einen Zeitraum verteilt sind, sollten sich nicht für die fortschreitenden Entschärfungsschritte qualifizieren. Die Konflikte sollten immer wieder auftreten.

SELECT TOP 1000 *
FROM dbo.MSChange_tracking_history
WHERE table_name = '<user_table_name>'
ORDER BY start_time DESC;

Wenn die Verlaufstabelle mehrere Einträge in den comments Spalten mit dem Wert Cleanup error: Lock request time out period exceededenthält, ist es eindeutig, dass mehrere sauber upversuche aufgrund von Sperrkonflikten oder Sperrtimeouts nacheinander fehlgeschlagen sind. Berücksichtigen Sie die folgenden Abhilfemaßnahmen:

  • Deaktivieren und aktivieren Sie die Änderungsnachverfolgung für die Tabelle, in der das Problem auftritt. Dadurch werden alle Nachverfolgungsmetadaten, die für die Tabelle aufbewahrt werden, bereinigt. Die Daten der Tabelle bleiben intakt. Dies ist der schnellste Lösungsweg.

  • Wenn die vorherige Option nicht möglich ist, fahren Sie mit der Ausführung manueller sauber up für die Tabelle fort, indem Sie die Ablaufverfolgungskennzeichnung 8284 wie folgt aktivieren:

    DBCC TRACEON (8284, -1);
    GO
    EXEC [sys].[sp_flush_CT_internal_table_on_demand] @TableToClean = '<table_name>';
    

3. Überprüfen anderer Ursachen

Eine weitere mögliche Ursache für sauber upverzögerung ist die Langsamkeit der Löschanweisungen. Um festzustellen, ob dies der Derart ist, überprüfen Sie den Wert von hardened_cleanup_version. Dieser Wert kann über eine dedizierte Administratorverbindung (DAC) mit der zu berücksichtigenden Datenbank abgerufen werden.

Suchen Sie die gehärtete sauber up-Version, indem Sie die folgende Abfrage ausführen:

SELECT * FROM sys.sysobjvalues WHERE valclass = 7 AND objid = 1004;

Suchen Sie die sauber up-Version, indem Sie die folgende Abfrage ausführen:

SELECT * FROM sys.sysobjvalues WHERE valclass = 7 AND objid = 1003;

Wenn hardened_cleanup_version und cleanup_version Werte gleich sind, überspringen Sie diesen Abschnitt, und fahren Sie mit dem nächsten Abschnitt fort.

Wenn beide Werte unterschiedlich sind, bedeutet dies, dass mindestens eine Nebentabelle Fehler aufgetreten ist. Die schnellste Entschärfung besteht darin, die Änderungsnachverfolgung in der problematischen Tabelle zu deaktivieren und zu aktivieren. Dadurch werden alle Nachverfolgungsmetadaten, die für die Tabelle aufbewahrt werden, bereinigt. Die Daten in der Tabelle sind intakt Standard.

Wenn die vorherige Option nicht möglich ist, führen Sie manuelle sauber up für die Tabelle aus.

Beheben von Syscommittab-Problemen

In diesem Abschnitt werden Die Schritte zum Debuggen und Beheben von Problemen mit der syscommittab Systemtabelle behandelt, wenn sie viel Speicherplatz verwendet oder wenn ein großer Backlog veralteter Zeilen vorhanden ist.

Die syscommittab Systemtabelle sauber up hängt von seitenseitiger sauber up ab. Erst nachdem alle Seitentabellen sauber werden, syscommittab können gelöscht werden. Stellen Sie sicher, dass alle Schritte in der automatischen sauber up ausgeführt werden, aber keinen Fortschrittsabschnitt ausführen.

Um die syscommittab sauber up explizit aufzurufen, verwenden Sie die sys.sp_flush_commit_table_on_demand gespeicherte Prozedur.

Hinweis

Die sys.sp_flush_commit_table_on_demand gespeicherte Prozedur kann Zeit in Anspruch nehmen, wenn ein großer Backlog von Zeilen gelöscht wird.

Wie im Beispielabschnitt aus dem artikel sys.sp_flush_commit_table_on_demand gezeigt, gibt diese gespeicherte Prozedur den Wert von safe_cleanup_version()und die Anzahl der gelöschten Zeilen zurück. Wenn der zurückgegebene Wert angezeigt wird 0und Momentaufnahme Isolation aktiviert ist, löscht die sauber up möglicherweise nichts aus syscommittab.

Wenn der Aufbewahrungszeitraum größer als ein Tag ist, sollte es sicher sein, die sys.sp_flush_commit_table_on_demand gespeicherte Prozedur erneut durchzuführen, nachdem die Ablaufverfolgungskennzeichnung 8239 global aktiviert wurde. Die Verwendung dieses Ablaufverfolgungskennzeichnungs, wenn Momentaufnahme Isolation deaktiviert ist, ist immer sicher, aber in einigen Fällen ist dies möglicherweise nicht erforderlich.

Hohe CPU-Auslastung während sauber up

Das in diesem Abschnitt beschriebene Problem kann in älteren Versionen von SQL Server auftreten. Wenn es eine große Anzahl von Änderungsnachverfolgungstabellen in einer Datenbank gibt, und die automatische sauber up oder manuelle sauber up verursacht eine hohe CPU-Auslastung. Dieses Problem kann auch aufgrund der Verlaufstabelle verursacht werden, die in früheren Abschnitten kurz Erwähnung wurde.

Verwenden Sie den folgenden T-SQL-Code, um die Anzahl der Zeilen in der Verlaufstabelle zu überprüfen:

SELECT COUNT(*) from dbo.MSChange_tracking_history;

Wenn die Anzahl der Zeilen ausreichend groß ist, versuchen Sie, den folgenden Index hinzuzufügen, wenn er nicht vorhanden ist. Verwenden Sie den folgenden T-SQL-Code, um den Index hinzuzufügen:

IF NOT EXISTS (
    SELECT *
    FROM sys.indexes
    WHERE name = 'IX_MSchange_tracking_history_start_time'
        AND object_id = OBJECT_ID('dbo.MSchange_tracking_history')
)
BEGIN
    CREATE NONCLUSTERED INDEX IX_MSchange_tracking_history_start_time
    ON dbo.MSchange_tracking_history (start_time)
END

Ausführen von sauber häufiger als 30 Minuten

Bestimmte Tabellen können eine hohe Änderungsrate aufweisen, und Sie stellen möglicherweise fest, dass der Auto sauber Upauftrag die Seitentabellen und syscommittab innerhalb des 30-Minuten-Intervalls nicht sauber kann. In diesem Fall können Sie einen manuellen sauber Upauftrag mit erhöhter Häufigkeit ausführen, um den Prozess zu erleichtern.

Erstellen Sie für SQL Server und Azure SQL verwaltete Instanz einen Hintergrundauftrag mit sp_flush_CT_internal_table_on_demand einem kürzeren internen Hintergrundauftrag als die standard 30 Minuten. Für Azure SQL-Datenbank können Azure Logic Apps verwendet werden, um diese Aufträge zu planen.

Der folgende T-SQL-Code kann verwendet werden, um einen Auftrag zu erstellen, um die seitenseitigen Tabellen für die Änderungsnachverfolgung zu sauber:

-- Loop to invoke manual cleanup procedure for cleaning up change tracking tables in a database
-- Fetch the tables enabled for change tracking
SELECT IDENTITY(INT, 1, 1) AS TableID,
    (SCHEMA_NAME(tbl.Schema_ID) + '.' + OBJECT_NAME(ctt.object_id)) AS TableName
INTO #CT_Tables
FROM sys.change_tracking_tables ctt
INNER JOIN sys.tables tbl
    ON tbl.object_id = ctt.object_id;

-- Set up the variables
DECLARE @start INT = 1,
    @end INT = (
        SELECT COUNT(*)
        FROM #CT_Tables
        ),
    @tablename VARCHAR(255);

WHILE (@start <= @end)
BEGIN
    -- Fetch the table to be cleaned up
    SELECT @tablename = TableName
    FROM #CT_Tables
    WHERE TableID = @start

    -- Execute the manual cleanup stored procedure
    EXEC sp_flush_CT_internal_table_on_demand @tablename

    -- Increment the counter
    SET @start = @start + 1;
END

DROP TABLE #CT_Tables;