Partilhar via


Resolver erros de falta de memória com Azure SQL Database e Fabric SQL Database

Aplica-se a:Azure SQL Databasebase de dados SQL em Fabric

Você pode ver mensagens de erro quando o mecanismo de banco de dados SQL não conseguiu alocar memória suficiente para executar a consulta. Isso pode ser causado por vários motivos, incluindo os limites do objetivo de serviço selecionado, demandas de memória de carga de trabalho agregadas e demandas de memória pela consulta.

Para mais informações sobre o limite de recursos de memória para Azure SQL Database, veja Gestão de recursos em Azure SQL Database. A base de dados Fabric SQL partilha muitas funcionalidades com a Azure SQL Database; para mais informações sobre monitorização de desempenho, consulte Fabric SQL monitorização do desempenho da base de dados.

Para mais informações sobre a resolução de problemas de memória em SQL Server, veja MSSQLSERVER_701.

Tente as seguintes vias de investigação em resposta a:

  • Código de erro 701 com a mensagem de erro "Há memória insuficiente do sistema no pool de recursos '%ls' para executar esta consulta."
  • Código de erro 802 com mensagem de erro "Há memória insuficiente disponível no pool de buffers."

Exibir eventos sem memória

Se encontrar erros de memória esgotada, revise sys.dm_os_out_of_memory_events. Esta visão inclui informações sobre a causa prevista de falta de memória, determinada por um algoritmo heurístico e é fornecida com um grau finito de confiança.

SELECT * FROM sys.dm_os_out_of_memory_events ORDER BY event_time DESC;  

Investigar a alocação de memória

Se persistirem erros de falta de memória no Azure SQL Database, considere aumentar pelo menos temporariamente o objetivo de nível de serviço da base de dados no portal Azure.

Se os erros de falta de memória persistirem, use as consultas a seguir para procurar concessões de memória de consulta excepcionalmente altas que possam contribuir para uma condição de memória insuficiente. Execute as seguintes consultas de exemplo na base de dados que experienciaram o erro (não na base de dados master do servidor lógico Azure SQL).

Usar o Detran para exibir eventos sem memória

O sys.dm_os_out_of_memory_events permite visibilidade dos eventos e das causas de eventos de falta de memória (OOM) no Azure SQL Database. O summarized_oom_snapshot evento ampliado faz parte da sessão de eventos existente system_health para simplificar a deteção. Para obter mais informações, consulte sys.dm_os_out_of_memory_events e blog: uma nova maneira de solucionar erros de falta de memória no mecanismo de banco de dados.

Usar DMVs para ver os gestores de memória

Comece com uma investigação ampla, se o erro de falta de memória ocorreu recentemente, visualizando a alocação de memória para os coordenadores de memória. Os gestores de memória são internos ao motor de base de dados do Azure SQL Database. Os principais alocadores de memória, em termos de páginas alocadas, podem ser úteis para identificar que tipo de consulta ou funcionalidade do SQL Server está a consumir mais memória.

SELECT [type], [name], pages_kb, virtual_memory_committed_kb
FROM sys.dm_os_memory_clerks
WHERE memory_node_id <> 64 -- ignore Dedicated Admin Connection (DAC) node
ORDER BY pages_kb DESC;
GO
SELECT [type], [name], pages_kb, virtual_memory_committed_kb
FROM sys.dm_os_memory_clerks
WHERE memory_node_id <> 64 -- ignore Dedicated Admin Connection (DAC) node
ORDER BY virtual_memory_committed_kb DESC;
  • Alguns despachantes de memória comuns, como MEMORYCLERK_SQLQERESERVATIONS, são solucionados de forma mais eficaz identificando consultas com grandes alocações de memória e otimizando o seu desempenho com melhor indexação e ajuste de índice.
  • Embora o OBJECTSTORE_LOCK_MANAGER não esteja relacionado a concessões de memória, espera-se que o seu valor seja elevado quando as consultas solicitam muitos bloqueios, por exemplo, devido a escalonamento de bloqueio desativado ou transações muito grandes.
  • Espera-se que alguns gestores sejam os de maior utilização: MEMORYCLERK_SQLBUFFERPOOL é quase sempre o gestor principal, enquanto CACHESTORE_COLUMNSTOREOBJECTPOOL terá uma utilização elevada quando os índices columnstore forem usados. Espera-se uma maior utilização por parte destes funcionários.

Para obter mais informações sobre tipos de servidor de memória, consulte sys.dm_os_memory_clerks.

Utilize DMVs para investigar consultas ativas

Na maioria dos casos, a consulta que falhou não é a causa desse erro.

A seguinte consulta de exemplo para o Azure SQL Database retorna informações importantes sobre transações que estão atualmente em espera ou em espera de concessões de memória. Direcione as principais consultas identificadas para exame e ajuste de desempenho e avalie se elas estão ou não sendo executadas conforme pretendido. Considere o tempo de consultas de relatórios com uso intensivo de memória ou operações de manutenção.

--Active requests with memory grants
SELECT
--Session data 
  s.[session_id], s.open_transaction_count
--Memory usage
, r.granted_query_memory, mg.grant_time, mg.requested_memory_kb, mg.granted_memory_kb
, mg.required_memory_kb, mg.used_memory_kb, mg.max_used_memory_kb     
--Query 
, query_text = t.text, input_buffer = ib.event_info, query_plan_xml = qp.query_plan
, request_row_count = r.row_count, session_row_count = s.row_count
--Session history and status
, s.last_request_start_time, s.last_request_end_time, s.reads, s.writes, s.logical_reads
, session_status = s.[status], request_status = r.status
--Session connection information
, s.host_name, s.program_name, s.login_name, s.client_interface_name, s.is_user_process
FROM sys.dm_exec_sessions s 
LEFT OUTER JOIN sys.dm_exec_requests AS r 
    ON r.[session_id] = s.[session_id]
LEFT OUTER JOIN sys.dm_exec_query_memory_grants AS mg 
    ON mg.[session_id] = s.[session_id]
OUTER APPLY sys.dm_exec_sql_text (r.[sql_handle]) AS t
OUTER APPLY sys.dm_exec_input_buffer(s.[session_id], NULL) AS ib 
OUTER APPLY sys.dm_exec_query_plan (r.[plan_handle]) AS qp 
WHERE mg.granted_memory_kb > 0
ORDER BY mg.granted_memory_kb desc, mg.requested_memory_kb desc;

Você pode decidir usar a instrução KILL para interromper uma consulta em execução que está retendo ou aguardando uma grande concessão de memória. Use esta instrução com cuidado, especialmente quando processos críticos estão em execução. Para mais informações, consulte KILL (Transact-SQL).

Use o Query Store para investigar o uso passado da memória de consultas

Enquanto a consulta de exemplo anterior reporta apenas resultados em tempo real, a consulta seguinte utiliza o Query Store para devolver informação sobre execuções anteriores de consultas. Isso pode ser útil na investigação de um erro de falta de memória que ocorreu no passado.

O seguinte exemplo de consulta para o Azure SQL Database devolve informações importantes sobre execuções de consulta registadas pela Query Store. Direcione as principais consultas identificadas para exame e ajuste de desempenho e avalie se elas estão ou não sendo executadas conforme pretendido. Observe o filtro de tempo ativado qsp.last_execution_time para restringir os resultados ao histórico recente. Você pode ajustar a cláusula TOP para produzir mais ou menos resultados, dependendo do seu ambiente.

SELECT TOP 10 PERCENT --limit results
  a.plan_id, query_id, plan_group_id, query_sql_text
, query_plan = TRY_CAST(query_plan as XML)
, avg_query_max_used_memory
, min_query_max_used_memory
, max_query_max_used_memory
, last_query_max_used_memory 
, last_execution_time  
, query_count_executions
    FROM (
    SELECT 
      qsp.plan_id, qsp.query_id, qsp.plan_group_id, qsp.query_plan, qsqt.query_sql_text
    , last_execution_time = MAX(qsp.last_execution_time)
    , query_count_executions = SUM(qsrs.count_executions) 
    , avg_query_max_used_memory = AVG(qsrs.avg_query_max_used_memory)
    , min_query_max_used_memory = MIN(qsrs.min_query_max_used_memory)
    , max_query_max_used_memory = MAX(qsrs.max_query_max_used_memory)
    , last_query_max_used_memory = MAX(qsrs_latest.last_query_max_used_memory) --only from latest result
    FROM sys.query_store_plan AS qsp 
    INNER JOIN sys.query_store_query AS qsq
        ON qsp.query_id = qsq.query_id
    INNER JOIN sys.query_store_query_text AS qsqt
        ON qsq.query_text_id = qsqt.query_text_id 
    INNER JOIN sys.query_store_runtime_stats AS qsrs
        ON qsp.plan_id = qsrs.plan_id 
    INNER JOIN (SELECT plan_id
            , last_query_max_used_memory 
            , rownum = ROW_NUMBER() OVER (PARTITION BY plan_id ORDER BY last_execution_time DESC)
            FROM sys.query_store_runtime_stats qsrs) AS qsrs_latest
        ON qsrs_latest.plan_id = qsp.plan_id
        AND qsrs_latest.rownum = 1 --use latest last_query_max_used_memory per plan_id
    WHERE DATEADD(hour, -24, sysdatetime()) < qsp.last_execution_time --past 24 hours only
    AND qsrs_latest.last_query_max_used_memory > 0
    GROUP BY qsp.plan_id, qsp.query_id, qsp.plan_group_id, qsp.query_plan, qsqt.query_sql_text
    ) AS a
ORDER BY max_query_max_used_memory DESC, avg_query_max_used_memory DESC;

Eventos prolongados

Para além da informação anterior, pode ser útil captar um rasto das atividades no servidor para investigar minuciosamente um problema de falta de memória no Azure SQL Database.

Existem duas formas de capturar rastreios no SQL Server: Eventos Estendidos (XEvents) e Rastreios do Perfilador. No entanto, SQL Server Profiler é uma tecnologia de traço obsoleta que não é suportada para Azure SQL Database. Extended Events é a tecnologia de rastreio mais recente que permite maior versatilidade e menor impacto no sistema observado, e a sua interface está integrada no SQL Server Management Studio (SSMS). Para mais informações sobre a consulta a eventos estendidos em Azure SQL Database, consulte Eventos estendidos em Azure SQL Database.

Consulte o documento que explica como usar o Assistente para Nova Sessão de Eventos Estendidos no SSMS. No entanto, para bases de dados Azure SQL, o SSMS fornece uma subpasta de Eventos Estendidos sob cada base de dados em Object Explorer. Use uma sessão de Eventos Estendidos para capturar esses eventos úteis e identificar as consultas que os geram:

  • Erros de categoria:

    • error_reported
    • exchange_spill
    • hash_spill_details
  • Execução da categoria:

    • excessive_non_grant_memory_used
  • Categoria Memória:

    • query_memory_grant_blocking
    • query_memory_grant_usage
  • summarized_oom_snapshot

    A captura de blocos de concessão de memória, derrames de concessão de memória ou concessões de memória excessivas pode ser uma pista para explicar o motivo de uma consulta começar repentinamente a usar mais memória do que usava anteriormente, e uma potencial explicação para a emergência de um erro de falta de memória numa carga de trabalho já existente. O summarized_oom_snapshot evento ampliado faz parte da sessão de eventos existente system_health para simplificar a deteção. Para obter mais informações, consulte Blog: Uma nova maneira de solucionar erros de falta de memória no mecanismo de banco de dados.

OLTP na memória sem memória suficiente

Você pode encontrar Error code 41805: There is insufficient memory in the resource pool '%ls' to run this operation se estiver usando In-Memory OLTP. Reduza a quantidade de dados em tabelas com otimização de memória e parâmetros com valor de tabela otimizados para memória ou aumente a escala do banco de dados para um objetivo de serviço mais alto para ter mais memória. Para mais informações sobre problemas de falta de memória com SQL Server In-Memory OLTP, veja Resolver problemas de Falta de Memória.

Obtenha suporte ao Azure SQL Database

Se persistirem erros de falta de memória em Azure SQL Database, faça um pedido de Azure support selecionando Get Support no site Azure Support.