Errores de memoria insuficiente de metadatos de tempdb optimizados para memoria (HkTempDB)

En este artículo se proporcionan soluciones para solucionar problemas de memoria insuficiente relacionados con la característica de metadatos optimizados para tempdb memoria.

Síntomas

Después de habilitar la característica de metadatos optimizados tempdb para memoria (HkTempDB), es posible que vea el error 701 que indica excepciones de memoria insuficiente para tempdb las asignaciones y SQL Server bloqueos del servicio. Además, es posible que vea que el empleado MEMORYCLERK_XTP de memoria para In-Memory OLTP (Hekaton) está creciendo gradual o rápidamente y no se reduce. A medida que la memoria XTP crece sin un límite superior, verá el siguiente mensaje de error en SQL Server:

No permitir asignaciones de páginas para la base de datos "tempdb" debido a la memoria insuficiente en el grupo de recursos "default". Consulte 'http://go.microsoft.com/fwlink/?LinkId=510837' para obtener más información.

Al ejecutar una consulta en la dmvdm_os_memory_clerks, puede ver que la memoria asignada a páginas es alta para el empleado MEMORYCLERK_XTPde memoria . Por ejemplo:

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

Resultado:

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

Diagnóstico del problema

Para recopilar datos para diagnosticar el problema, siga estos pasos:

  1. Recopile un seguimiento ligero o un evento extendido (XEvent) para comprender tempdb la carga de trabajo y averigüe si la carga de trabajo tiene transacciones explícitas de ejecución prolongada con instrucciones DDL en tablas temporales.

  2. Recopile la salida de las siguientes DMV para analizar más.

    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
    

Causa y resolución

Al usar las DMV para comprobar la causa, es posible que vea diferentes escenarios del problema. Estos escenarios se pueden dividir en las dos categorías siguientes. Para resolver el problema, puede usar la resolución correspondiente para cada escenario. Para obtener más información sobre cómo mitigar el problema, vea Pasos de mitigación para mantener la memoria de metadatos tempdb optimizada para memoria activada.

Aumento gradual del consumo de memoria XTP

  • Escenario 1

    DmV tempdb.sys.dm_xtp_system_memory_consumers o tempdb.sys.dm_db_xtp_memory_consumers muestra una gran diferencia entre los bytes asignados y los bytes usados.

    Solución: para resolver el problema, puede ejecutar los siguientes comandos en SQL Server 2019 CU13, SQL Server 2022 CU1 o en una versión posterior que tenga un nuevo procedimiento sys.sp_xtp_force_gc para liberar bytes asignados pero sin usar.

    Nota:

    A partir de SQL Server 2022 CU1, debe ejecutar el procedimiento almacenado solo una vez.

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

    La DMV tempdb.sys.dm_xtp_system_memory_consumers muestra valores altos para bytes asignados y usados para los tipos VARHEAP de consumidor de memoria y LOOKASIDE.

    Resolución: compruebe si hay transacciones explícitas de ejecución prolongada que impliquen instrucciones DDL en tablas temporales y resuelva desde la aplicación manteniendo las transacciones cortas.

    Nota:

    Para reproducir este problema en un entorno de prueba, puede crear una transacción explícita mediante instrucciones de Lenguaje de definición de datos (DDL) en tablas temporales y dejarla abierta durante mucho tiempo cuando se produzca otra actividad.

  • Escenario 3

    La DMV tempdb.sys.dm_db_xtp_memory_consumers muestra valores altos para bytes asignados y usados en un asignador de objetos grandes (LOB) o un montón de tablas donde Object_ID, XTP_Object_IDy Index_ID son NULL.

    Resolución: aplique SQL Server 2019 CU16 para el 14535149 de problemas.

  • Escenario 4

    El crecimiento continuo del consumidor de memoria de base de datos XTP "VARHEAP\Storage internal heap" provoca el error de memoria insuficiente 41805.

    Solución: el problema 14087445 ya identificado y resuelto en SQL Server 17 CU25 y versiones posteriores se está examinando para pasar a SQL Server 2019.

Aumento repentino o aumento rápido del consumo de memoria XTP

  • Escenario 5

    La DMV tempdb.sys.dm_db_xtp_memory_consumers muestra valores altos para bytes asignados o usados en un montón de tablas donde Object_ID no NULLes . La causa más común de este problema es una transacción abierta explícitamente de larga duración con instrucciones DDL en tablas temporales. Por ejemplo:

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

    Una transacción abierta explícitamente con instrucciones DDL en tablas temporales no permitirá que el montón de tablas y el montón de lookaside se liberen para las transacciones posteriores mediante tempdb metadatos.

    Resolución: compruebe si hay transacciones explícitas de ejecución prolongada que impliquen instrucciones DDL en tablas temporales y resuelva desde la aplicación manteniendo las transacciones cortas.

Pasos de mitigación para mantener la memoria de metadatos tempdb optimizada para memoria en estado de protección

  1. Para evitar o resolver transacciones de ejecución prolongada que usan instrucciones DDL en tablas temporales, la guía general es mantener las transacciones cortas.

  2. Aumente la memoria máxima del servidor para permitir que la memoria suficiente funcione en presencia de cargas de trabajo pesadas en tempdb.

  3. Ejecute sys.sp_xtp_force_gc periódicamente.

  4. Para proteger el servidor de posibles condiciones de memoria insuficiente, puede enlazar tempdb a un grupo de recursos de Resource Governor. Por ejemplo, cree un grupo de recursos mediante MAX_MEMORY_PERCENT = 30. A continuación, use el siguiente comando ALTER SERVER CONFIGURATION para enlazar el grupo de recursos a metadatos tempdb optimizados para memoria.

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

    Este cambio requiere que el reinicio surta efecto, incluso si los metadatos optimizados para tempdb memoria ya están habilitados. Para obtener más información, consulte:

    Advertencia

    Después de enlazar HktempDB a un grupo, el grupo puede alcanzar su configuración máxima y cualquier consulta que use tempdb puede producir errores de memoria insuficiente. Por ejemplo:

    No permitir asignaciones de páginas para la base de datos "tempdb" debido a la memoria insuficiente en el grupo de recursos "HkTempDB". Consulte 'http://go.microsoft.com/fwlink/?LinkId=510837' para obtener más información. Error de asignación de página de XTP debido a la presión de memoria: FAIL_PAGE_ALLOCATION 8

    En determinadas circunstancias, el servicio de SQL Server podría detenerse si se produce un error de memoria insuficiente. Para reducir la posibilidad de que esto ocurra, establezca el grupo de MAX_MEMORY_PERCENT memoria en un valor alto.

  5. La característica de metadatos optimizados para tempdb memoria no admite todas las cargas de trabajo. Por ejemplo, el uso de transacciones explícitas con instrucciones DDL en tablas temporales que se ejecutan durante mucho tiempo dará lugar a los escenarios descritos. Si tiene tales transacciones en la carga de trabajo y no puede controlar su duración, quizás esta característica no sea adecuada para su entorno. Debe realizar una prueba exhaustiva antes de usar HkTempDB.

Más información

En estas secciones se proporcionan más detalles sobre algunos de los componentes de memoria implicados en los metadatos optimizados para tempdb memoria.

Asignador de memoria de Lookaside

Lookaside en In-Memory OLTP es un asignador de memoria local de subproceso para ayudar a lograr un procesamiento rápido de transacciones. Cada objeto de subproceso contiene una colección de asignadores de memoria lookaside. Cada lookaside asociado a cada subproceso tiene un límite superior predefinido sobre la cantidad de memoria que puede asignar. Cuando se alcanza el límite, el subproceso asigna memoria de un grupo de memoria compartida de desbordamiento (VARHEAP). La DMV sys.dm_xtp_system_memory_consumers agrega datos para cada tipo de lookaside (memory_consumer_type_desc = 'LOOKASIDE') y el grupo de memoria compartida (memory_consumer_type_desc = 'VARHEAP' y memory_consumer_desc = 'Lookaside heap').

Consumidores de nivel de sistema: tempdb.sys.dm_xtp_system_memory_consumers

Alrededor de 25 tipos de consumidores de memoria lookaside son el límite superior. Cuando los subprocesos necesitan más memoria de esas apariencias, la memoria se derrama en y se satisface con el montón de lookaside. Los valores altos de los bytes usados podrían ser un indicador de carga de trabajo pesada tempdb constante o de transacciones abiertas de ejecución prolongada que usan objetos temporales.

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

Consumidores de nivel de base de datos: tempdb.sys.dm_db_xtp_memory_consumers

  • El asignador de LOB se usa para los datos lob/off-row de las tablas del sistema.

  • El montón de tablas se usa para las filas de tablas del sistema.

Los valores altos de los bytes usados podrían ser el indicador de una carga de trabajo pesada tempdb constante o de una transacción abierta de larga duración que usa objetos temporales.