Błędy braku pamięci metadanych bazy danych tempdb zoptymalizowane pod kątem pamięci (HkTempDB)

Ten artykuł zawiera rozwiązania problemów z brakiem pamięci związanych z funkcją metadanych zoptymalizowanych tempdb pod kątem pamięci.

Symptomy

Po włączeniu funkcji metadanych zoptymalizowanych tempdb pod kątem pamięci (HkTempDB) może zostać wyświetlony błąd 701 wskazujący wyjątki braku pamięci dla tempdb alokacji i awarii usługi SQL Server. Ponadto może się okazać, że urzędnik MEMORYCLERK_XTP pamięci dla In-Memory OLTP (Hekaton) rośnie stopniowo lub szybko i nie zmniejsza się z powrotem. Gdy pamięć XTP rośnie bez górnego limitu, w SQL Server zostanie wyświetlony następujący komunikat o błędzie:

Nie zezwalaj na alokacje stron dla bazy danych "tempdb" z powodu niewystarczającej ilości pamięci w puli zasobów "domyślne". Aby uzyskać więcej informacji, zobacz "http://go.microsoft.com/fwlink/?LinkId=510837".

Po uruchomieniu zapytania na dm_os_memory_clerksDMV widać, że przydzielona pamięć stron jest duża dla urzędnika dsMEMORYCLERK_XTP. pamięci. Przykład:

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

Wynik:

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

Diagnozowanie problemu

Aby zebrać dane w celu zdiagnozowania problemu, wykonaj następujące kroki:

  1. Zbierz uproszczony ślad lub zdarzenie rozszerzone (XEvent), aby zrozumieć tempdb obciążenie i dowiedzieć się, czy obciążenie ma jakiekolwiek długotrwałe jawne transakcje z instrukcjami DDL w tabelach tymczasowych.

  2. Zbierz dane wyjściowe następujących widoków DMV, aby przeprowadzić dalszą analizę.

    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
    

Przyczyna i rozwiązanie

Za pomocą widoków DMV w celu zweryfikowania przyczyny mogą wystąpić różne scenariusze problemu. Te scenariusze można podzielić na dwie następujące kategorie. Aby rozwiązać ten problem, możesz użyć odpowiedniego rozwiązania dla każdego scenariusza. Aby uzyskać więcej informacji na temat sposobu złagodzenia problemu, zobacz Kroki ograniczania ryzyka, aby zachować pamięć metadanych bazy danych tempdb zoptymalizowaną pod kątem pamięci.

Stopniowe zwiększanie zużycia pamięci XTP

  • Scenariusz 1

    Plik DMV tempdb.sys.dm_xtp_system_memory_consumers lub tempdb.sys.dm_db_xtp_memory_consumers pokazuje dużą różnicę między przydzielonym bajtem a używanymi bajtami.

    Rozwiązanie: Aby rozwiązać ten problem, można uruchomić następujące polecenia w SQL Server 2019 CU13, SQL Server 2022 CU1 lub nowszej wersji, która ma nową procedurę sys.sp_xtp_force_gc zwalniania przydzielonych, ale nieużywanych bajtów.

    Uwaga

    Począwszy od SQL Server 2022 CU1, należy wykonać procedurę składowaną tylko raz.

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

    Widok DMV tempdb.sys.dm_xtp_system_memory_consumers pokazuje wysokie wartości dla przydzielonych i używanych bajtów dla typów VARHEAP odbiorców pamięci i LOOKASIDE.

    Rozwiązanie: sprawdź długotrwałe jawne transakcje obejmujące instrukcje DDL w tabelach tymczasowych i rozwiąż je po stronie aplikacji, utrzymując krótkie transakcje.

    Uwaga

    Aby odtworzyć ten problem w środowisku testowym, możesz utworzyć jawną transakcję przy użyciu instrukcji języka data definition language (DDL) w tabelach tymczasowych i pozostawić ją otwartą przez długi czas, gdy odbywa się inne działanie.

  • Scenariusz 3

    Widok DMV tempdb.sys.dm_db_xtp_memory_consumers pokazuje wysokie wartości przydzielonych i używanych bajtów w alokatorze dużych obiektów (LOB) lub stercie tabeli, gdzie Object_ID, XTP_Object_IDi Index_IDNULL.

    Rozwiązanie: zastosuj SQL Server 2019 CU16 do 14535149 problemu.

  • Scenariusz 4

    Stale rosnący użytkownik pamięci bazy danych XTP "VARHEAP\Storage internal heap" prowadzi do błędu 41805 braku pamięci.

    Rozwiązanie: Problem 14087445 już zidentyfikowany i rozwiązany w wersji SQL Server 17 CU25 i nowszych wersjach, który ma zostać przekierowany do SQL Server 2019 r.

Nagły wzrost lub szybki wzrost zużycia pamięci XTP

  • Scenariusz 5

    Widok DMV tempdb.sys.dm_db_xtp_memory_consumers pokazuje wysokie wartości dla przydzielonych lub używanych bajtów w stercie tabeli, gdzie Object_ID nie NULLjest . Najczęstszą przyczyną tego problemu jest długotrwała, jawnie otwarta transakcja z instrukcjami DDL w tabelach tymczasowych. Przykład:

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

    Jawnie otwarta transakcja z instrukcjami DDL w tabelach tymczasowych nie zezwala na zwalnianie sterty tabeli i sterty lookaside dla kolejnych transakcji przy użyciu tempdb metadanych.

    Rozwiązanie: sprawdź długotrwałe jawne transakcje obejmujące instrukcje DDL w tabelach tymczasowych i rozwiąż je po stronie aplikacji, utrzymując krótkie transakcje.

Kroki ograniczania ryzyka w celu zachowania pamięci metadanych bazy danych tempdb zoptymalizowanej pod kątem pamięci w ryzach

  1. Aby uniknąć lub rozwiązać długotrwałe transakcje korzystające z instrukcji DDL w tabelach tymczasowych, ogólne wskazówki to utrzymywanie krótkich transakcji.

  2. Zwiększ maksymalną ilość pamięci serwera , aby umożliwić obsługę wystarczającej ilości pamięci w obecności obciążeń z dużą liczbą baz danych tempdb.

  3. Uruchamiane sys.sp_xtp_force_gc okresowo.

  4. Aby chronić serwer przed potencjalnymi warunkami braku pamięci, możesz powiązać bazę danych tempdb z pulą zasobów zarządcy zasobów. Na przykład utwórz pulę zasobów przy użyciu polecenia MAX_MEMORY_PERCENT = 30. Następnie użyj następującego polecenia ALTER SERVER CONFIGURATION , aby powiązać pulę zasobów z metadanymi bazy danych tempdb zoptymalizowanymi pod kątem pamięci.

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

    Ta zmiana wymaga ponownego uruchomienia, nawet jeśli metadane zoptymalizowane tempdb pod kątem pamięci są już włączone. Więcej informacji można znaleźć w następujących artykułach:

    Ostrzeżenie

    Po powiązaniu bazy danych HktempDB z pulą pula może osiągnąć maksymalne ustawienie, a wszystkie zapytania, które używają tempdb , mogą zakończyć się niepowodzeniem z powodu błędów braku pamięci. Przykład:

    Wyłączenie alokacji stron dla bazy danych "tempdb" z powodu niewystarczającej ilości pamięci w puli zasobów "HkTempDB". Aby uzyskać więcej informacji, zobacz "http://go.microsoft.com/fwlink/?LinkId=510837". Alokacja strony XTP nie powiodła się z powodu obciążenia pamięcią: FAIL_PAGE_ALLOCATION 8

    W pewnych okolicznościach usługa SQL Server może przeprowadzić zatrzymanie w przypadku wystąpienia błędu braku pamięci. Aby zmniejszyć prawdopodobieństwo wystąpienia tego zdarzenia, ustaw wartość puli MAX_MEMORY_PERCENT pamięci na wysoką wartość.

  5. Funkcja metadanych zoptymalizowanych tempdb pod kątem pamięci nie obsługuje każdego obciążenia. Na przykład użycie jawnych transakcji z instrukcjami DDL w tabelach tymczasowych, które działają przez długi czas, doprowadzi do opisanych scenariuszy. Jeśli masz takie transakcje w obciążeniu i nie możesz kontrolować ich czasu trwania, być może ta funkcja nie jest odpowiednia dla twojego środowiska. Przed użyciem programu HkTempDBnależy przeprowadzić obszerne testy.

Więcej informacji

Te sekcje zawierają więcej szczegółów na temat niektórych składników pamięci zaangażowanych w metadane zoptymalizowane tempdb pod kątem pamięci.

Alokator pamięci lookaside

Lookaside w In-Memory OLTP jest alokatorem pamięci wątkowo-lokalnej, który ułatwia szybkie przetwarzanie transakcji. Każdy obiekt wątku zawiera kolekcję alokatorów pamięci lookaside. Każdy wygląd skojarzony z każdym wątkiem ma wstępnie zdefiniowany górny limit ilości pamięci, jaką może przydzielić. Po osiągnięciu limitu wątek przydziela pamięć z rozlanej puli pamięci udostępnionej (VARHEAP). DMV sys.dm_xtp_system_memory_consumers agreguje dane dla każdego typu lookaside (memory_consumer_type_desc = 'LOOKASIDE') i udostępnionej puli pamięci (memory_consumer_type_desc = 'VARHEAP' i memory_consumer_desc = 'Lookaside heap').

Użytkownicy na poziomie systemu: tempdb.sys.dm_xtp_system_memory_consumers

Około 25 typów odbiorców pamięci lookaside to górny limit. Gdy wątki potrzebują więcej pamięci z tych lookasides, pamięć rozla się do i jest zadowolony ze sterty lookaside. Wysokie wartości dla używanych bajtów mogą być wskaźnikiem stałego dużego tempdb obciążenia i/lub długotrwałej otwartej transakcji korzystającej z obiektów tymczasowych.

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

Użytkownicy na poziomie bazy danych: tempdb.sys.dm_db_xtp_memory_consumers

  • Alokator LOB jest używany w przypadku danych lob/off-row tabel systemowych.

  • Sterta tabeli jest używana dla wierszy tabel systemowych.

Wysokie wartości dla używanych bajtów mogą być wskaźnikiem stałego dużego tempdb obciążenia i/lub długotrwałej otwartej transakcji korzystającej z obiektów tymczasowych.