Поделиться через


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

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

Симптомы

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

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

При выполнении запроса на DMVdm_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

    DMV 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 CU16 для проблемы 14535149.

  • Сценарий 4

    Непрерывно растущий потребитель памяти базы данных XTP "VARHEAP\Storage внутренних куч" приводит к ошибке нехватки памяти 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, оптимизированную для памяти tempdb, в проверке

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

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

  3. Периодически выполняйте.sys.sp_xtp_force_gc

  4. Чтобы защитить сервер от потенциальных проблем нехватки памяти, можно привязать tempdb к пулу ресурсов Диспетчера Ресурсов. Например, создайте пул ресурсов с помощью 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 в In-Memory OLTP — это потоковый распределитель памяти, помогающий обеспечить быструю обработку транзакций. Каждый объект потока содержит коллекцию средств выделения памяти lookaside. Каждый lookaside-буфер, связанный с каждым потоком, имеет предварительно определенное верхнее ограничение на объем памяти, который может выделять. Когда ограничение достигнуто, поток выделяет память из переполненного общего пула памяти (VARHEAP). DMV sys.dm_xtp_system_memory_consumers агрегирует данные для каждого типа lookaside (memory_consumer_type_desc = 'LOOKASIDE') и общего пула памяти (memory_consumer_type_desc = 'VARHEAP' и memory_consumer_desc = 'Lookaside heap').

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

Верхний предел составляет примерно 25 типов потребителей памяти lookaside. Когда потокам требуется больше памяти из этих lookaside, память переходит в и удовлетворяется lookaside-кучей. Высокие значения для используемых байтов могут быть индикатором постоянной тяжелой 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-распределитель используется для системных таблиц LOB/данные вне строки.

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

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