Dela via


Minnesoptimerade tempdb-metadata (HkTempDB) slut på minnesfel

Den här artikeln innehåller lösningar för att felsöka minnesproblem relaterade till den minnesoptimerade tempdb metadatafunktionen.

Symptom

När du har aktiverat funktionen minnesoptimerade tempdb metadata (HkTempDB) kan du se felet 701 som anger undantag från minne för tempdb allokeringar och SQL Server Service-krascher. Dessutom kan du se att minnestjänstemannen MEMORYCLERK_XTP för Minnesintern OLTP (Hekaton) växer gradvis eller snabbt och inte krymper tillbaka. När XTP-minnet växer utan en övre gräns visas följande felmeddelande i SQL Server:

Tillåt inte sidallokeringar för databasen "tempdb" på grund av otillräckligt minne i resurspoolens "standard". Mer information finns i "http://go.microsoft.com/fwlink/?LinkId=510837".

När du kör en fråga på DMV-dm_os_memory_clerks kan du se att det allokerade sidminnet är högt för minnestjänstemannen .MEMORYCLERK_XTP Till exempel:

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

Resultat:

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

Diagnostisera problemet

Följ dessa steg för att samla in data för att diagnostisera problemet:

  1. Samla in en enkel spårning eller utökad händelse (XEvent) för att förstå tempdb arbetsbelastningen och ta reda på om arbetsbelastningen har några långvariga explicita transaktioner med DDL-instruktioner i tillfälliga tabeller.

  2. Samla in utdata från följande DMV:er för att analysera ytterligare.

    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
    

Orsak och lösning

Genom att använda DMV:erna för att verifiera orsaken kan du se olika scenarier med problemet. Dessa scenarier kan delas in i följande två kategorier. För att lösa problemet kan du använda motsvarande lösning för varje scenario. Mer information om hur du åtgärdar problemet finns i Åtgärdssteg för att hålla minnesoptimerad tempdb-metadataminne i schack.

Gradvis ökning av XTP-minnesförbrukning

  • Scenario 1

    DMV-tempdb.sys.dm _xtp_system_memory_consumers eller tempdb.sys.dm_db_xtp_memory_consumers visar en stor skillnad mellan allokerade byte och använda byte.

    Lösning: För att lösa problemet kan du köra följande kommandon i SQL Server 2019 CU13, SQL Server 2022 CU1 eller en senare version som har en ny procedur sys.sp_xtp_force_gc för att frigöra allokerade men oanvända byte.

    Kommentar

    Från och med SQL Server 2022 CU1 behöver du bara köra den lagrade proceduren en gång.

    /* 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
    
  • Scenario 2

    DMV tempdb.sys.dm_xtp_system_memory_consumers visar höga värden för allokerade och använda byte för minneskonsumenttyper VARHEAP och LOOKASIDE.

    Lösning: Sök efter långvariga explicita transaktioner som involverar DDL-instruktioner i tillfälliga tabeller och lös från programsidan genom att hålla transaktionerna korta.

    Kommentar

    Om du vill återskapa det här problemet i en testmiljö kan du skapa en explicit transaktion med hjälp av DDL-instruktioner (Data Definition Language) på tillfälliga tabeller och låta den vara öppen under en längre tid när annan aktivitet äger rum.

  • Scenario 3

    DMV tempdb.sys.dm_db_xtp_memory_consumers visar höga värden för allokerade och använda byte i en stor objektallokerare (LOB) eller tabell heap där Object_ID, XTP_Object_IDoch Index_ID är NULL.

    Lösning: Använd SQL Server 2019 CU16 för problemet 14535149.

  • Scenario 4

    Kontinuerlig växande "VARHEAP\Storage internal heap" XTP-databasminneskonsument leder till minnesfel 41805.

    Lösning: Problemet 14087445 som redan har identifierats och lösts i SQL Server 17 CU25 och senare versioner granskas för att portas över till SQL Server 2019.

Plötslig topp eller snabb ökning av XTP-minnesförbrukning

  • Scenario 5

    DMV tempdb.sys.dm_db_xtp_memory_consumers visar höga värden för allokerade eller använda byte i en tabell heap där Object_ID inte NULLär . Den vanligaste orsaken till det här problemet är en tidskrävande, explicit öppen transaktion med DDL-instruktioner på tillfälliga tabeller. Till exempel:

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

    En explicit öppen transaktion med DDL-instruktioner i tillfälliga tabeller tillåter inte att tabellhanten och lookaside-heapen frigörs för efterföljande transaktioner med hjälp tempdb av metadata.

    Lösning: Sök efter långvariga explicita transaktioner som involverar DDL-instruktioner i tillfälliga tabeller och lös från programsidan genom att hålla transaktionerna korta.

Åtgärdssteg för att hålla minnesoptimerad tempdb-metadataminne i schack

  1. För att undvika eller lösa långvariga transaktioner som använder DDL-instruktioner i tillfälliga tabeller är den allmänna vägledningen att hålla transaktionerna korta.

  2. Öka det maximala serverminnet så att tillräckligt med minne kan användas i närvaro av tempdb-tunga arbetsbelastningar.

  3. Kör sys.sp_xtp_force_gc med jämna mellanrum.

  4. För att skydda servern från potentiella minnesbrister kan du binda tempdb till en resurspool för Resource Governor. Skapa till exempel en resurspool med hjälp MAX_MEMORY_PERCENT = 30av . Använd sedan följande ALTER SERVER CONFIGURATION-kommando för att binda resurspoolen till minnesoptimerade tempdb-metadata.

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

    Den här ändringen kräver att en omstart börjar gälla, även om minnesoptimerade metadata redan är aktiverade tempdb . Mer information finns i:

    Varning

    När HktempDB har bindts till en pool kan poolen nå sin högsta inställning och eventuella frågor som används tempdb kan misslyckas med fel som inte är minnesfria. Till exempel:

    Neka sidallokeringar för databasen "tempdb" på grund av otillräckligt minne i resurspoolen "HkTempDB". Mer information finns i "http://go.microsoft.com/fwlink/?LinkId=510837". XTP-sidallokering misslyckades på grund av minnestryck: FAIL_PAGE_ALLOCATION 8

    Under vissa omständigheter kan SQL Server-tjänsten eventuellt stoppas om ett minnesfel inträffar. Om du vill minska risken för detta ställer du in minnespoolens MAX_MEMORY_PERCENT till ett högt värde.

  5. Den minnesoptimerade tempdb metadatafunktionen stöder inte alla arbetsbelastningar. Om du till exempel använder explicita transaktioner med DDL-instruktioner i temporära tabeller som körs under lång tid leder det till de scenarier som beskrivs. Om du har sådana transaktioner i din arbetsbelastning och du inte kan styra deras varaktighet kanske den här funktionen inte är lämplig för din miljö. Du bör testa mycket innan du använder HkTempDB.

Mer information

De här avsnitten innehåller mer information om några av de minneskomponenter som ingår i minnesoptimerade tempdb metadata.

Lookaside-minnesallokering

Lookaside i Minnesintern OLTP är en trådlokal minnesallokering för att uppnå snabb transaktionsbearbetning. Varje trådobjekt innehåller en samling minnesallokerare för lookaside. Varje lookaside som är associerad med varje tråd har en fördefinierad övre gräns för hur mycket minne den kan allokera. När gränsen har nåtts allokerar tråden minne från en spill-over delad minnespool (VARHEAP). DMV sys.dm_xtp_system_memory_consumers aggregerar data för varje typ av lookaside (memory_consumer_type_desc = 'LOOKASIDE') och den delade minnespoolen (memory_consumer_type_desc = 'VARHEAP' och memory_consumer_desc = 'Lookaside heap').

Konsumenter på systemnivå: tempdb.sys.dm_xtp_system_memory_consumers

Cirka 25 minneskonsumenttyper för lookaside är den övre gränsen. När trådar behöver mer minne från dessa lookasides, spiller minnet över till och är nöjd med lookaside heap. Höga värden för använda byte kan vara en indikator på konstant hög tempdb arbetsbelastning och/eller långvariga öppna transaktioner som använder tillfälliga objekt.

-- 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

Konsumenter på databasnivå: tempdb.sys.dm_db_xtp_memory_consumers

  • LOB-allokeraren används för systemtabeller med LOB-/off-row-data.

  • Tabell heap används för systemtabellrader.

Höga värden för använda byte kan vara indikatorn för konstant hög tempdb arbetsbelastning och/eller långvariga öppna transaktioner som använder tillfälliga objekt.