Udostępnij za pomocą


Błędy dotyczące braku pamięci w przypadku metadanych bazy danych tempdb zoptymalizowanych pod kątem pamięci (HkTempDB)

Ten artykuł zawiera rozwiązania problemów związanych z brakiem pamięci dotyczących funkcji metadanych zoptymalizowanych dla pamięci tempdb.

Symptomy

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

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

Po uruchomieniu zapytania na DMVdm_os_memory_clerks, widać, że przydzielona pamięć stron jest wysoka dla zarządcy pamięci MEMORYCLERK_XTP. Na 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 lekkie śledzenie lub rozszerzone zdarzenie (XEvent), aby zrozumieć obciążenie tempdb, i sprawdź, czy obciążenie ma długotrwałe jawne transakcje z instrukcjami typu DDL w tabelach tymczasowych.

  2. Zbierz dane wyjściowe następujących DMV, aby je dalej analizować.

    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

Korzystając z widoków DMV w celu zweryfikowania przyczyny, mogą pojawić się różne scenariusze problemu. Te scenariusze można podzielić na następujące dwie 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 łagodzenia problemu, zobacz Kroki zaradcze w celu kontrolowania pamięci metadanych tempdb zoptymalizowanej pod kątem pamięci.

Stopniowy wzrost zużycia pamięci XTP

  • Scenariusz 1

    Widok DMV tempdb.sys.dm_xtp_system_memory_consumers lub tempdb.sys.dm_db_xtp_memory_consumers pokazuje dużą różnicę między przydzielone bajty i używane bajty.

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

    Uwaga

    Począwszy od programu 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 przedstawia wysokie wartości przydzielonych i używanych bajtów dla typów odbiorców pamięci VARHEAP i LOOKASIDE.

    Rozwiązanie: Sprawdź długotrwałe jawne transakcje zawierają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żna utworzyć jawną transakcję przy użyciu instrukcji języka DDL (Data Definition Language) w tabelach tymczasowych i pozostawić je otwarte przez długi czas, gdy odbywa się inne działanie.

  • Scenariusz 3

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

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

  • Scenariusz 4

    Stale rosnący konsument pamięci bazy danych XTP "VARHEAP\Storage wewnętrzny sterta" prowadzi do błędu braku pamięci 41805.

    Rozwiązanie: problem 14087445 już zidentyfikowany i rozwiązany w programie SQL Server 17 CU25 i nowszych wersjach jest rozważany do przeniesienia do programu SQL Server 2019.

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

  • Scenariusz 5

    Dynamiczny widok zarządzania (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 jest NULL. Najczęstszą przyczyną tego problemu jest długotrwała transakcja z wyraźnie otwartą treścią zawierającą instrukcje DDL w tabelach tymczasowych. Na przykład:

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

    Jawnie otwarta transakcja z instrukcjami DDL w tabelach tymczasowych nie pozwoli na zwolnienie sterty tabeli i bufora tymczasowego dla kolejnych transakcji przy użyciu metadanych tempdb.

    Rozwiązanie: Sprawdź długotrwałe jawne transakcje obejmujące instrukcje DDL w tabelach tymczasowych i rozwiązuj je po stronie aplikacji, dbając o to, aby transakcje były krótkie.

Kroki zaradcze w celu utrzymania pamięci metadanych tempdb zoptymalizowanej pod kątem pamięci pod kontrolą.

  1. Aby uniknąć długotrwałych transakcji korzystających z instrukcji DDL w tabelach tymczasowych lub rozwiązać je, ogólne wskazówki dotyczą utrzymywania krótkich transakcji.

  2. Zwiększ maksymalną ilość pamięci serwera, aby zapewnić wystarczającą ilość pamięci do działania w przypadku obciążeń o dużym obciążeniu bazy danych tempdb.

  3. Uruchamiaj sys.sp_xtp_force_gc okresowo.

  4. Aby chronić serwer przed potencjalnymi warunkami braku pamięci, można 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 pod kątem tempdb pamięci są już włączone. Aby uzyskać więcej informacji, zobacz:

    Ostrzeżenie

    Po powiązaniu bazy danych HktempDB z pulą, ta może osiągnąć swoje maksymalne ustawienie, a wszystkie zapytania używające tempdb mogą zakończyć się niepowodzeniem z powodu błędów związanych z brakiem pamięci. Na przykład:

    Brak zezwalania na alokacje 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 użycia pamięci: FAIL_PAGE_ALLOCATION 8

    W pewnych okolicznościach usługa SQL Server może potencjalnie zatrzymać się, jeśli wystąpi błąd braku pamięci. Aby zmniejszyć prawdopodobieństwo wystąpienia takiej sytuacji, ustaw pulę MAX_MEMORY_PERCENT pamięci na wartość wysoką.

  5. Funkcja metadanych zoptymalizowanych tempdb pod kątem pamięci nie obsługuje każdego obciążenia. Na przykład użycie transakcji jawnych z instrukcjami DDL na 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. Należy przeprowadzić obszerne testy przed użyciem HkTempDB.

Więcej informacji

Te części zawierają więcej szczegółów na temat niektórych składników pamięci związanych z zoptymalizowanymi pod kątem pamięci tempdb metadanymi.

Alokator pamięci typu lookaside

Lookaside in In-Memory OLTP to alokator pamięci przypisanej do lokalnego wątku, który pomaga w szybkim przetwarzaniu transakcji. Każdy obiekt wątku zawiera zbiór alokatorów pamięci typu lookaside. Każdy bufor powiązany 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 nadmiarowej, udostępnionej puli pamięci (VARHEAP). DMV sys.dm_xtp_system_memory_consumers agreguje dane dla każdego typu buforu nadmiarowego (memory_consumer_type_desc = 'LOOKASIDE') i puli pamięci udostępnionej (memory_consumer_type_desc = 'VARHEAP' i memory_consumer_desc = 'Lookaside heap').

Odbiorcy na poziomie systemu: tempdb.sys.dm_xtp_system_memory_consumers

Około 25 typów odbiorców pamięci podręcznej to górna granica. Gdy wątki potrzebują więcej pamięci z tych rezerw pamięci, pamięć przenosi się do i jest obsługiwana przez stertę lookaside. Wysokie wartości używanych bajtów mogą być wskaźnikiem ciągł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

Odbiorcy na poziomie bazy danych: tempdb.sys.dm_db_xtp_memory_consumers

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

  • Sterta tabeli jest używana w przypadku wierszy tabel systemowych.

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