Metadados de tempdb com otimização de memória (HkTempDB) fora dos erros de memória

Este artigo fornece resoluções para solucionar problemas de memória relacionados ao recurso de metadados com tempdb otimização de memória.

Sintomas

Depois de habilitar o recurso de metadados com tempdb otimização de memória (HkTempDB), você poderá ver o erro 701 indicando exceções de memória para tempdb alocações e falhas do Serviço SQL Server. Além disso, você pode ver que o funcionário MEMORYCLERK_XTP de memória do In-Memory OLTP (Hekaton) está crescendo gradualmente ou rapidamente e não recua. À medida que a memória XTP cresce sem um limite superior, você vê a seguinte mensagem de erro no SQL Server:

Não permitir alocações de página para o banco de dados 'tempdb' devido à memória insuficiente no pool de recursos 'default'. Consulte 'http://go.microsoft.com/fwlink/?LinkId=510837' para obter mais informações.

Ao executar uma consulta no dm_os_memory_clerks de DMV, você pode ver que a memória de páginas alocadas é alta para o assistente de MEMORYCLERK_XTPmemória . Por exemplo:

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

Diagnosticar o problema

Para coletar dados para diagnosticar o problema, siga estas etapas:

  1. Colete um XEvent (rastreamento leve ou evento estendido) para entender tempdb a carga de trabalho e descubra se a carga de trabalho tem transações explícitas de longa execução com instruções DDL em tabelas temporárias.

  2. Colete a saída dos DMVs a seguir para analisar mais.

    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 e resolução

Usando os DMVs para verificar a causa, você pode ver diferentes cenários do problema. Esses cenários podem ser divididos nas duas categorias a seguir. Para resolve o problema, você pode usar a resolução correspondente para cada cenário. Para obter mais informações sobre como aliviar o problema, consulte Etapas de mitigação para manter a memória de metadados tempdb com otimização de memória em marcar.

Aumento gradual no consumo de memória XTP

  • Cenário 1

    O DMV tempdb.sys.dm_xtp_system_memory_consumers ou tempdb.sys.dm_db_xtp_memory_consumers mostra uma grande diferença entre bytes alocados e bytes usados.

    Resolução: para resolve o problema, você pode executar os seguintes comandos no CU13 SQL Server 2019, SQL Server 2022 CU1 ou uma versão posterior que tenha um novo procedimento sys.sp_xtp_force_gc para liberar bytes alocados, mas não utilizados.

    Observação

    Começando com SQL Server CU1 2022, você precisa executar o procedimento armazenado apenas uma 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
    
  • Cenário 2

    O DMV tempdb.sys.dm_xtp_system_memory_consumers mostra valores elevados para bytes alocados e usados para tipos VARHEAP de consumidor de memória e LOOKASIDE.

    Resolução: verifique se há transações explícitas de longa execução envolvendo instruções DDL em tabelas temporárias e resolve do lado do aplicativo, mantendo as transações curtas.

    Observação

    Para reproduzir esse problema em um ambiente de teste, você pode criar uma transação explícita usando instruções DDL (Linguagem de Definição de Dados) em tabelas temporárias e deixá-la aberta por muito tempo quando outra atividade ocorrer.

  • Cenário 3

    O DMV tempdb.sys.dm_db_xtp_memory_consumers mostra valores elevados para bytes alocados e usados em um alocador de lob (objeto grande) ou heap de tabela em que Object_ID, XTP_Object_IDe Index_ID são NULL.

    Resolução: aplique SQL Server CU16 2019 para o problema 14535149.

  • Cenário 4

    O consumidor de memória de banco de dados XTP "VARHEAP\Storage internal heap" em crescimento contínuo leva ao erro de memória 41805.

    Resolução: o problema 14087445 já identificado e resolvido em SQL Server 17 versões CU25 e posteriores estão em análise para serem portadas para SQL Server 2019.

Pico repentino ou aumento rápido no consumo de memória XTP

  • Cenário 5

    O DMV tempdb.sys.dm_db_xtp_memory_consumers mostra valores elevados para bytes alocados ou usados em um heap de tabelas em que Object_ID não NULLé . A causa mais comum desse problema é uma transação longa e aberta explicitamente com instruções DDL em tabelas temporárias. Por exemplo:

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

    Uma transação aberta explicitamente com instruções DDL em tabelas temporárias não permitirá que o heap de tabela e o heap lookaside sejam liberados para transações subsequentes usando tempdb metadados.

    Resolução: verifique se há transações explícitas de longa execução envolvendo instruções DDL em tabelas temporárias e resolve do lado do aplicativo, mantendo as transações curtas.

Etapas de mitigação para manter a memória de metadados tempdb com otimização de memória em marcar

  1. Para evitar ou resolve transações de longa execução que usam instruções DDL em tabelas temporárias, a orientação geral é manter as transações curtas.

  2. Aumente a memória máxima do servidor para permitir que a memória suficiente opere na presença de cargas de trabalho tempdb pesadas.

  3. Execute sys.sp_xtp_force_gc periodicamente.

  4. Para proteger o servidor contra possíveis condições fora da memória, você pode associar o tempdb a um pool de recursos Resource Governor. Por exemplo, crie um pool de recursos usando MAX_MEMORY_PERCENT = 30. Em seguida, use o seguinte comando ALTER SERVER CONFIGURATION para associar o pool de recursos a metadados tempdb com otimização de memória.

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

    Essa alteração requer uma reinicialização para entrar em vigor, mesmo que os metadados com tempdb otimização de memória já estejam habilitados. Para saber mais, veja:

    Aviso

    Depois de associar o HktempDB a um pool, o pool pode atingir sua configuração máxima e todas as consultas que usam tempdb podem falhar com erros fora da memória. Por exemplo:

    Não permite alocações de página para o banco de dados 'tempdb' devido à memória insuficiente no pool de recursos 'HkTempDB'. Consulte 'http://go.microsoft.com/fwlink/?LinkId=510837' para obter mais informações. Falha na alocação de página do XTP devido à pressão de memória: FAIL_PAGE_ALLOCATION 8

    Em determinadas circunstâncias, o serviço de SQL Server pode potencialmente parar se ocorrer um erro fora de memória. Para reduzir a chance de isso acontecer, defina o pool de MAX_MEMORY_PERCENT memória como um valor alto.

  5. O recurso de metadados com tempdb otimização de memória não dá suporte a todas as cargas de trabalho. Por exemplo, o uso de transações explícitas com instruções DDL em tabelas temporárias que são executadas por muito tempo levará aos cenários descritos. Se você tiver essas transações em sua carga de trabalho e não puder controlar a duração delas, talvez esse recurso não seja apropriado para seu ambiente. Você deve testar extensivamente antes de usar HkTempDB.

Mais informações

Essas seções fornecem mais detalhes sobre alguns dos componentes de memória envolvidos em metadados com tempdb otimização de memória.

Alocador de memória lookaside

Lookaside no In-Memory OLTP é um alocador de memória local de thread para ajudar a alcançar o processamento rápido de transações. Cada objeto thread contém uma coleção de alocadores de memória lookaside. Cada lookaside associado a cada thread tem um limite superior pré-definido sobre a quantidade de memória que ele pode alocar. Quando o limite é atingido, o thread aloca memória de um pool de memória compartilhada de derramamento (VARHEAP). O DMV sys.dm_xtp_system_memory_consumers agrega dados para cada tipo lookaside (memory_consumer_type_desc = 'LOOKASIDE') e o pool de memória compartilhado (memory_consumer_type_desc = 'VARHEAP' e memory_consumer_desc = 'Lookaside heap').

Consumidores no nível do sistema: tempdb.sys.dm_xtp_system_memory_consumers

Cerca de 25 tipos de consumidor de memória visual são o limite superior. Quando os threads precisam de mais memória desses lookasides, a memória é respingada e é satisfeita com o heap lookaside. Valores altos para bytes usados podem ser um indicador de carga de trabalho pesada tempdb constante e/ou transação aberta de longa execução que usa objetos temporários.

-- 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 no nível do banco de dados: tempdb.sys.dm_db_xtp_memory_consumers

  • O alocador LOB é usado para tabelas de sistema dados LOB/Off-row.

  • O heap de tabelas é usado para linhas de tabelas do sistema.

Valores altos para bytes usados podem ser o indicador de carga de trabalho pesada tempdb constante e/ou transação aberta de longa execução que usa objetos temporários.