Speicheroptimierte tempdb-Metadaten (HkTempDB): Nicht genügend Speicher-Fehler

Dieser Artikel bietet Lösungsansätze zur Fehlerbehebung von Arbeitsspeicherproblemen im Zusammenhang mit dem Feature für speicheroptimierte tempdb Metadaten.

Symptome

Nachdem Sie das Feature für speicheroptimierte tempdb Metadaten (HkTempDB) aktiviert haben, wird möglicherweise der Fehler 701 angezeigt, der darauf hinweist, dass Ausnahmen wegen unzureichendem Arbeitsspeicher bei tempdb-Zuordnungen und Abstürze des SQL Server-Diensts auftreten können. Darüber hinaus können Sie sehen, dass der Memory Clerk MEMORYCLERK_XTP für In-Memory OLTP (Hekaton) allmählich oder schnell wächst und nicht wieder schrumpft. Da der XTP-Speicher ohne obere Grenze wächst, wird in SQL Server die folgende Fehlermeldung angezeigt:

Die Zuordnung von Seiten für die Datenbank "tempdb" werden aufgrund unzureichenden Arbeitsspeichers im Ressourcenpool "default" nicht zugelassen. Weitere Informationen finden Sie unter „http://go.microsoft.com/fwlink/?LinkId=510837“.

Wenn Sie eine Abfrage für die DMVdm_os_memory_clerks ausführen, können Sie sehen, dass der zugewiesene Seitenspeicher für den Speicherclerk MEMORYCLERK_XTP hoch ist. Beispiele:

SELECT type, memory_node_id, pages_kb 
FROM sys.dm_os_memory_clerks
WHERE type = 'MEMORYCLERK_XTP'

Ergebnis:

type                    memory_node_id                     pages_kb
------------------------------------------------------------ -------------- --------------------
MEMORYCLERK_XTP         0                                  60104496
MEMORYCLERK_XTP         64                                 0

Diagnostizieren des Problems

Führen Sie die folgenden Schritte aus, um Daten zum Diagnostizieren des Problems zu sammeln:

  1. Sammeln Sie eine leichtgewichtige Ablaufverfolgung oder ein erweitertes Ereignis (XEvent), um die Workload zu verstehen tempdb, und ermitteln Sie, ob die Workload über lang laufende explizite Transaktionen mit DDL-Anweisungen für temporäre Tabellen verfügt.

  2. Erfassen Sie die Ausgabe der folgenden DMVs zur weiteren Analyse.

    SELECT * FROM sys.dm_os_memory_clerks
    SELECT * FROM sys.dm_exec_requests
    SELECT * FROM sys.dm_exec_sessions
    
    -- from tempdb
    SELECT * FROM tempdb.sys.dm_xtp_system_memory_consumers 
    SELECT * FROM tempdb.sys.dm_db_xtp_memory_consumers
    
    SELECT * FROM tempdb.sys.dm_xtp_transaction_stats
    SELECT * FROM tempdb.sys.dm_xtp_gc_queue_stats
    SELECT * FROM tempdb.sys.dm_db_xtp_object_stats
    
    SELECT * FROM tempdb.sys.dm_db_xtp_transactions
    SELECT * FROM tempdb.sys.dm_tran_session_transactions
    SELECT * FROM tempdb.sys.dm_tran_database_transactions
    SELECT * FROM tempdb.sys.dm_tran_active_transactions
    

Ursache und Auflösung

Wenn Sie die DMVs verwenden, um die Ursache des Problems zu ermitteln, werden möglicherweise verschiedene Szenarien des Problems angezeigt. Diese Szenarien können in die folgenden beiden Kategorien unterteilt werden. Um das Problem zu beheben, können Sie die entsprechende Lösung für jedes Szenario verwenden. Weitere Informationen dazu, wie das Problem behoben werden kann, finden Sie unter Schritte zur Problembehebung, um den speicheroptimierten tempdb-Metadatenspeicher unter Kontrolle zu halten.

Schrittweise Erhöhung der XTP-Speicherauslastung

  • Szenario 1

    Der DMV tempdb.sys.dm_xtp_system_memory_consumers oder tempdb.sys.dm_db_xtp_memory_consumers zeigt einen großen Unterschied zwischen zugeordneten Bytes und verwendeten Bytes an.

    Lösung: Um das Problem zu beheben, können Sie die folgenden Befehle in SQL Server 2019 CU13, SQL Server 2022 CU1 oder einer höheren Version ausführen, die über eine neue Prozedur sys.sp_xtp_force_gc verfügt, um zugewiesene, aber nicht verwendete Bytes freizugeben.

    Note

    Ab SQL Server 2022 CU1 müssen Sie die gespeicherte Prozedur nur einmal ausführen.

    /* Yes, 2 times for both*/
    EXEC sys.sp_xtp_force_gc 'tempdb'
    GO
    EXEC sys.sp_xtp_force_gc 'tempdb'
    GO
    EXEC sys.sp_xtp_force_gc
    GO
    EXEC sys.sp_xtp_force_gc
    
  • Szenario 2

    Die DMV tempdb.sys.dm_xtp_system_memory_consumers zeigt hohe Werte für zugewiesene und verwendete Bytes für Speicherverbrauchertypen VARHEAP und LOOKASIDE.

    Lösung: Prüfen Sie, ob es lang laufende explizite Transaktionen gibt, die DDL-Anweisungen für temporäre Tabellen umfassen, und beheben Sie sie anwendungsseitig, indem Sie Transaktionen kurz halten.

    Note

    Um dieses Problem in einer Testumgebung zu reproduzieren, können Sie eine explizite Transaktion erstellen, indem Sie DDL-Anweisungen (Data Definition Language) für temporäre Tabellen verwenden und diese lange geöffnet lassen, wenn andere Aktivitäten stattfinden.

  • Szenario 3

    Der DMV tempdb.sys.dm_db_xtp_memory_consumers zeigt hohe Werte für zugeordnete und verwendete Bytes in einem LOB-Allocator oder Tabellen-Heap an, wobei Object_ID, XTP_Object_ID und Index_IDNULL sind.

    Lösung: Installieren Sie SQL Server 2019 CU16 zur Behebung des Problems 14535149.

  • Szenario 4

    Der ständig wachsende XTP-Datenbankspeicher-Speicherverbraucher "VARHEAP\Storage internal heap" führt zu Fehler 41805 wegen unzureichendem Speicher.

    Lösung: Das Problem 14087445, das bereits in SQL Server 17 CU25 und späteren Versionen identifiziert und behoben wurde, wird untersucht, um auf SQL Server 2019 portiert zu werden.

Plötzliche Spitzen- oder schnelle Zunahme der XTP-Speicherauslastung

  • Szenario 5

    Der DMV tempdb.sys.dm_db_xtp_memory_consumers zeigt hohe Werte für zugeordnete oder verwendete Bytes in einem Tabellen-Heap an, wobei Object_ID nicht NULL ist. Die häufigste Ursache für dieses Problem ist eine lang andauernde, explizit geöffnete Transaktion mit DDL-Anweisungen für temporäre Tabellen. Beispiele:

    BEGIN TRAN
        CREATE TABLE #T(sn int)
        …
        …
    COMMIT
    

    Eine explizit geöffnete Transaktion mit DDL-Anweisungen für temporäre Tabellen lässt nicht zu, dass der Tabellenhap und der Lookaside-Heap für nachfolgende Transaktionen mithilfe von tempdb-Metadaten freigegeben werden.

    Lösung: Prüfen Sie, ob es lang andauernde explizite Transaktionen gibt, die DDL-Anweisungen für temporäre Tabellen umfassen, und beheben Sie diese anwendungsseitig, indem Sie Transaktionen kurz halten.

Entschärfungsschritte, um den speicheroptimierten tempdb-Metadatenspeicher unter Kontrolle zu halten

  1. Um lange ausgeführte Transaktionen zu vermeiden oder aufzulösen, die DDL-Anweisungen für temporäre Tabellen verwenden, besteht die allgemeine Anleitung darin, Transaktionen kurz zu halten.

  2. Erhöhen Sie den maximalen Serverspeicher, um genügend Arbeitsspeicher bereitzustellen, damit bei tempdb-intensiven Workloads gearbeitet werden kann.

  3. Führen Sie sys.sp_xtp_force_gc regelmäßig aus.

  4. Um den Server vor potenzieller Speicherknappheit zu schützen, können Sie tempdb an einen Resource Governor-Ressourcenpool binden. Erstellen Sie beispielsweise einen Ressourcenpool mithilfe von MAX_MEMORY_PERCENT = 30. Verwenden Sie dann den folgenden ALTER SERVER CONFIGURATION-Befehl, um den Ressourcenpool an speicheroptimierte tempdb-Metadaten zu binden.

    ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON (RESOURCE_POOL = '<PoolName>');
    

    Diese Änderung erfordert einen Neustart, damit sie wirksam wird, auch wenn speicheroptimierte tempdb Metadaten bereits aktiviert sind. Weitere Informationen findest du unter:

    Warnung

    Nach dem Binden von HktempDB an einen Pool kann der Pool seine maximale Einstellung erreichen, und alle Abfragen, die tempdb verwenden, können mit Fehlern aufgrund von unzureichendem Arbeitsspeicher fehlschlagen. Beispiele:

    Die Zuweisung von Seiten für die Datenbank "tempdb" wird aufgrund unzureichenden Arbeitsspeichers im Ressourcenpool "HkTempDB" nicht zugelassen. Weitere Informationen finden Sie unter „http://go.microsoft.com/fwlink/?LinkId=510837“. XTP-Fehler bei der Seitenallokation aufgrund von Speicherknappheit: FAIL_PAGE_ALLOCATION 8

    Unter bestimmten Umständen kann der SQL Server-Dienst möglicherweise beendet werden, wenn ein Speichermangelfehler auftritt. Um die Wahrscheinlichkeit dafür zu verringern, legen Sie den Wert MAX_MEMORY_PERCENT des Speicherpools auf einen hohen Wert fest.

  5. Das feature für arbeitsspeicheroptimierte tempdb Metadaten unterstützt nicht jede Workload. Beispielsweise führt die Verwendung expliziter Transaktionen mit DDL-Anweisungen für temporäre Tabellen, die lange ausgeführt werden, zu den beschriebenen Szenarien. Wenn Sie solche Transaktionen in Ihrer Workload haben und ihre Dauer nicht steuern können, ist dieses Feature möglicherweise nicht für Ihre Umgebung geeignet. Sie sollten vor der Verwendung HkTempDBumfassend testen.

Mehr erfahren

Diese Abschnitte enthalten weitere Details zu einigen der Speicherkomponenten, die an speicheroptimierten tempdb Metadaten beteiligt sind.

Lookaside-Speicherzuweiser

Lookaside in In-Memory OLTP ist ein threadlokaler Speicher-Allocator, um eine schnelle Transaktionsverarbeitung zu erzielen. Jedes Threadobjekt enthält eine Auflistung von Lookaside-Speicherzuweisern. Jeder Lookaside, der jedem Thread zugeordnet ist, verfügt über einen vordefinierten oberen Grenzwert dafür, wie viel Speicher er zuweisen kann. Wenn das Limit erreicht ist, reserviert der Thread Speicher aus einem gemeinsamen Überlauf-Speicherpool (VARHEAP). Die DMV sys.dm_xtp_system_memory_consumers aggregiert Daten für jeden Lookaside-Typ (memory_consumer_type_desc = 'LOOKASIDE') und den freigegebenen Speicherpool (memory_consumer_type_desc = 'VARHEAP' und memory_consumer_desc = 'Lookaside heap').

Verbraucher auf Systemebene: tempdb.sys.dm_xtp_system_memory_consumers

Ungefähr 25 Typen von Lookaside-Speicherverbrauchern bilden die Obergrenze. Wenn Threads mehr Arbeitsspeicher von diesen Lookasides benötigen, wird der Speicher in den Lookaside-Heap ausgelagert und daraus bedient. Hohe Werte für verwendete Bytes können ein Indikator für konstante schwere tempdb Arbeitsauslastung und/oder lange laufende geöffnete Transaktion sein, die temporäre Objekte verwendet.

-- system memory consumers @ instance  
SELECT memory_consumer_type_desc, memory_consumer_desc, allocated_bytes, used_bytes
FROM sys.dm_xtp_system_memory_consumers 
memory_consumer_type_desc     memory_consumer_desc                   allocated_bytes      used_bytes
------------------------- ------------------------------------------ -------------------- --------------------
VARHEAP                       Lookaside heap                             0                    0
PGPOOL                        256K page pool                             0                    0
PGPOOL                        4K page pool                               0                    0
VARHEAP                       System heap                                458752               448000
LOOKASIDE                     Transaction list element                   0                    0
LOOKASIDE                     Delta tracker cursor                       0                    0
LOOKASIDE                     Transaction delta tracker                  0                    0
LOOKASIDE                     Creation Statement Id Map Entry            0                    0
LOOKASIDE                     Creation Statement Id Map                  0                    0
LOOKASIDE                     Log IO proxy                               0                    0
LOOKASIDE                     Log IO completion                          0                    0
LOOKASIDE                     Sequence object insert row                 0                    0
LOOKASIDE                     Sequence object map entry                  0                    0
LOOKASIDE                     Sequence object values map                 0                    0
LOOKASIDE                     Redo transaction map entry                 0                    0
LOOKASIDE                     Transaction recent rows                    0                    0
LOOKASIDE                     Heap cursor                                0                    0
LOOKASIDE                     Range cursor                               0                    0
LOOKASIDE                     Hash cursor                                0                    0
LOOKASIDE                     Transaction dependent ring buffer          0                    0
LOOKASIDE                     Transaction save-point set entry           0                    0
LOOKASIDE                     Transaction FK validation sets             0                    0
LOOKASIDE                     Transaction partially-inserted rows set    0                    0
LOOKASIDE                     Transaction constraint set                 0                    0
LOOKASIDE                     Transaction save-point set                 0                    0
LOOKASIDE                     Transaction write set                      0                    0
LOOKASIDE                     Transaction scan set                       0                    0
LOOKASIDE                     Transaction read set                       0                    0
LOOKASIDE                     Transaction                                0                    0

Speicherverbraucher auf Datenbankebene: tempdb.sys.dm_db_xtp_memory_consumers

  • Der LOB-Allocator wird für LOB-/Off-Row-Daten in Systemtabellen verwendet.

  • Der Tabellen-Heap wird für Zeilen von Systemtabellen verwendet.

Hohe Werte für verwendete Bytes können ein Hinweis auf konstant hohe tempdb Arbeitsauslastung und/oder eine lange offene Transaktion sein, die temporäre Objekte verwendet.