Оптимизированные для памяти метаданные tempdb (HkTempDB) — ошибки нехватки памяти

В этой статье приводятся способы устранения проблем с нехваткой памяти, связанными с функцией метаданных, оптимизированной tempdb для памяти.

Симптомы

После включения функции оптимизированных для памяти tempdb метаданных (HkTempDB) вы можете увидеть ошибку 701, указывающую на исключение нехватки памяти при tempdb выделении и сбое службы SQL Server. Кроме того, вы можете увидеть, что клерок MEMORYCLERK_XTP памяти для In-Memory OLTP (Hekaton) растет постепенно или быстро и не сокращается. По мере увеличения объема памяти XTP без верхнего предела в SQL Server отображается следующее сообщение об ошибке:

Запрет выделения страниц для базы данных tempdb из-за нехватки памяти в пуле ресурсов по умолчанию. Дополнительные сведения см. в разделе "http://go.microsoft.com/fwlink/?LinkId=510837".

При выполнении запроса к dm_os_memory_clerksдинамического административного представления вы увидите, что выделенная на страницах память является высокой для клерка MEMORYCLERK_XTPпамяти . Например:

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

Результат:

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

Диагностика проблемы

Чтобы собрать данные для диагностики проблемы, выполните следующие действия.

  1. Соберите упрощенную трассировку или расширенное событие (XEvent), чтобы понять tempdb рабочую нагрузку и выяснить, есть ли в рабочей нагрузке какие-либо длительные явные транзакции с инструкциями DDL во временных таблицах.

  2. Соберите выходные данные следующих динамических административных представлений для дальнейшего анализа.

    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
    

Причина и разрешение

Используя динамические административные представления для проверки причины, вы можете увидеть различные сценарии проблемы. Эти сценарии можно разделить на следующие две категории. Чтобы устранить эту проблему, можно использовать соответствующее решение для каждого сценария. Дополнительные сведения о том, как устранить эту проблему, см. в статье Действия по устранению рисков для хранения памяти метаданных tempdb, оптимизированной для памяти, в проверка.

Постепенное увеличение потребления памяти XTP

  • Сценарий 1

    Динамическое административное представление tempdb.sys.dm_xtp_system_memory_consumers или tempdb.sys.dm_db_xtp_memory_consumers показывает большую разницу между выделенными и используемыми байтами.

    Решение. Чтобы устранить проблему, можно выполнить следующие команды в SQL Server 2019 CU13, SQL Server 2022 CU1 или более поздней версии с новой процедурой sys.sp_xtp_force_gc освобождения выделенных, но неиспользуемых байтов.

    Примечание.

    Начиная с SQL Server 2022 CU1 необходимо выполнить хранимую процедуру только один раз.

    /* 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
    
  • Сценарий 2

    Динамическое административное представление tempdb.sys.dm_xtp_system_memory_consumers показывает высокие значения для выделенных и используемых байтов для типов VARHEAP потребителей памяти и LOOKASIDE.

    Решение. Проверьте наличие длительных явных транзакций с использованием инструкций DDL во временных таблицах и разрешения из приложения, сохраняя транзакции короткими.

    Примечание.

    Чтобы воспроизвести эту проблему в тестовой среде, можно создать явную транзакцию с помощью инструкций языка определения данных (DDL) во временных таблицах и оставить ее открытой в течение длительного времени при выполнении других действий.

  • Сценарий 3

    Динамическое административное представление tempdb.sys.dm_db_xtp_memory_consumers показывает высокие значения для выделенных и используемых байтов в распределителье больших объектов (LOB) или табличной куче, где Object_ID, XTP_Object_IDи Index_ID являются NULL.

    Решение. Примените SQL Server 2019 с накопительным пакетом обновления 16 (CU16) для 14535149 проблемы.

  • Сценарий 4

    Непрерывно увеличивающееся число потребителей памяти базы данных XTP "VARHEAP\Storage internal heap" приводит к ошибке нехватки памяти 41805.

    Решение. Проблема, 14087445 уже обнаружена и решена в SQL Server 17 CU25 и более поздних версиях, рассматривается для переноса на SQL Server 2019 г.

Внезапный пик или быстрое увеличение потребления памяти XTP

  • Сценарий 5

    Динамическое административное представление tempdb.sys.dm_db_xtp_memory_consumers показывает высокие значения для выделенных или используемых байтов в куче таблицы, где Object_ID не NULLимеет значения . Наиболее распространенной причиной этой проблемы является длительная, явно открытая транзакция с инструкциями DDL во временных таблицах. Например:

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

    Явно открытая транзакция с операторами DDL во временных таблицах не позволяет освободить кучу таблицы и кучу lookaside для последующих транзакций с помощью tempdb метаданных.

    Решение. Проверьте наличие длительных явных транзакций с использованием инструкций DDL во временных таблицах и разрешения из приложения, сохраняя транзакции короткими.

Действия по устранению рисков, чтобы сохранить оптимизированную для памяти память метаданных tempdb в проверка

  1. Чтобы избежать или разрешить длительные транзакции, использующие инструкции DDL во временных таблицах, общее руководство заключается в сохранении коротких транзакций.

  2. Увеличьте максимальное количество памяти сервера , чтобы обеспечить достаточный объем памяти для работы при наличии рабочих нагрузок с большим объемом tempdb.

  3. Периодически запускайте sys.sp_xtp_force_gc .

  4. Чтобы защитить сервер от потенциального нехватки памяти, можно привязать базу данных tempdb к пулу ресурсов Resource Governor. Например, создайте пул ресурсов с помощью MAX_MEMORY_PERCENT = 30. Затем используйте следующую команду ALTER SERVER CONFIGURATION , чтобы привязать пул ресурсов к метаданным tempdb, оптимизированным для памяти.

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

    Это изменение требует перезапуска, даже если метаданные, оптимизированные для tempdb памяти, уже включены. Дополнительные сведения см. в разделе:

    Предупреждение

    После привязки HktempDB к пулу пул может достичь максимального значения, а все используемые tempdb запросы могут завершиться ошибкой с ошибками нехватки памяти. Например:

    Запрет выделения страниц для базы данных tempdb из-за нехватки памяти в пуле ресурсов HkTempDB. Дополнительные сведения см. в разделе "http://go.microsoft.com/fwlink/?LinkId=510837". Не удалось выделить страницу XTP из-за нехватки памяти: FAIL_PAGE_ALLOCATION 8

    При определенных обстоятельствах служба SQL Server может остановиться в случае ошибки нехватки памяти. Чтобы снизить вероятность этого, задайте для пула MAX_MEMORY_PERCENT памяти большое значение.

  5. Функция метаданных, оптимизированная tempdb для памяти, поддерживает не все рабочие нагрузки. Например, использование явных транзакций с операторами DDL во временных таблицах, которые выполняются в течение длительного времени, приведет к описанным сценариям. Если у вас есть такие транзакции в рабочей нагрузке и вы не можете контролировать их длительность, возможно, эта функция не подходит для вашей среды. Перед использованием HkTempDBследует тщательно протестировать .

Дополнительная информация

В этих разделах содержатся дополнительные сведения о некоторых компонентах памяти, участвующих в оптимизированных tempdb для памяти метаданных.

Распределитель памяти Lookaside

Lookaside в In-Memory OLTP — это локальный распределитель памяти потока, помогающий обеспечить быструю обработку транзакций. Каждый объект потока содержит коллекцию распределительных модулей памяти. Каждый внешний вид, связанный с каждым потоком, имеет предварительно определенный верхний предел на объем памяти, который он может выделить. При достижении ограничения поток выделяет память из пула общей памяти (VARHEAP). Динамическое административное представление sys.dm_xtp_system_memory_consumers объединяет данные для каждого типа сайда (memory_consumer_type_desc = 'LOOKASIDE') и пула общей памяти (memory_consumer_type_desc = 'VARHEAP' и memory_consumer_desc = 'Lookaside heap').

Потребители на уровне системы: tempdb.sys.dm_xtp_system_memory_consumers

Около 25 типов потребителей сайд-памяти являются верхним пределом. Когда потоки нуждаются в большем объеме памяти от этих внешних элементов, память перетекает в и удовлетворяется смотровой кучей. Высокие значения для использованных байтов могут быть индикатором постоянной большой tempdb рабочей нагрузки и (или) длительной открытой транзакции, использующей временные объекты.

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

Потребители уровня базы данных: tempdb.sys.dm_db_xtp_memory_consumers

  • Распределитель бизнес-объектов используется для системных таблиц с данными lob/off-row.

  • Куча таблиц используется для строк системных таблиц.

Высокие значения для использованных байтов могут быть индикатором постоянной интенсивной tempdb рабочей нагрузки и (или) длительной открытой транзакции, использующей временные объекты.