Condividi tramite


Risolvere gli errori di memoria insufficiente con Azure SQL Database e Fabric SQL Database

Applies to:Azure SQL DatabaseSQL database in Fabric

È possibile che vengano visualizzati messaggi di errore quando il motore di database SQL non è riuscito ad assegnare memoria sufficiente per eseguire la query. Ciò può essere causato da vari motivi, tra cui i limiti dell'obiettivo di servizio selezionato, le richieste di memoria del carico di lavoro aggregate e le richieste di memoria da parte della query.

Per altre informazioni sul limite di risorse di memoria per Azure SQL Database, vedere Gestione delle risorse in Azure SQL Database. Il database SQL Fabric condivide molte funzionalità con Azure SQL Database. Per ulteriori informazioni sul monitoraggio delle prestazioni, consultare il monitoraggio delle prestazioni del database SQL Fabric.

Per altre informazioni sulla risoluzione dei problemi di memoria insufficiente in SQL Server, vedere MSSQLSERVER_701.

Provare le vie di indagine seguenti in risposta a:

  • Codice errore 701 con messaggio di errore “Memoria di sistema insufficiente nel pool di risorse '%Is' per l'esecuzione della query”.
  • Codice di errore 802 con messaggio di errore "Memoria insufficiente disponibile nel pool di buffer".

Visualizzazione eventi di memoria insufficiente

Se si verificano errori di memoria insufficiente, esaminare sys.dm_os_out_of_memory_events. Questa vista include informazioni sulla causa stimata di memoria insufficiente, determinata da un algoritmo euristico e fornita con un grado di attendibilità finito.

SELECT * FROM sys.dm_os_out_of_memory_events ORDER BY event_time DESC;  

Analizzare l'allocazione di memoria

Se gli errori di memoria insufficiente persistono in Azure SQL Database, valutare almeno l'aumento temporaneamente dell'obiettivo del livello di servizio del database nel portale di Azure.

Se gli errori di memoria insufficiente persistono, usare le seguenti query per cercare assegnazioni di memoria per query insolitamente elevate che potrebbero contribuire a una condizione di memoria insufficiente. Eseguire le query di esempio seguenti nel database che ha riscontrato l'errore (non nel database master del server logico Azure SQL).

Usare DMV per visualizzare gli eventi di esaurimento memoria

Il sys.dm_os_out_of_memory_events consente la visibilità agli eventi e alle cause di eventi di esaurimento della memoria (OOM) in Azure SQL Database. L'evento summarized_oom_snapshot esteso fa parte della sessione eventi esistente system_health per semplificare il rilevamento. Per altre informazioni, vedere sys.dm_os_out_of_memory_events e Blog: un nuovo modo per risolvere gli errori di memoria insufficiente nel motore di database.

Usare le DMV per visualizzare i gestori di memoria

Iniziare con un'indagine approfondita, se l'errore di memoria insufficiente si è verificato di recente, visualizzando l'allocazione della memoria ai gestori di memoria. I clerk di memoria sono interni al motore di database di questo Azure SQL Database. I principali gestori di memoria in termini di pagine allocate potrebbero indicare quale tipo di query o funzionalità di SQL Server sta consumando la maggior parte della memoria.

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;
  • Alcuni gestori di memoria comuni, ad esempio MEMORYCLERK_SQLQERESERVATIONS, vengono gestiti in modo più efficace identificando le query con doti di memoria elevate e migliorando le prestazioni con una migliore indicizzazione e ottimizzazione degli indici.
  • Sebbene OBJECTSTORE_LOCK_MANAGER non sia correlato alle concessioni di memoria, ci si aspetta che sia elevato quando le query richiedono molti blocchi, ad esempio a causa dell'escalation dei blocchi disabilitata o di transazioni di grandi dimensioni.
  • Si prevede che alcuni clerk siano l'utilizzo più elevato: MEMORYCLERK_SQLBUFFERPOOL è quasi sempre il clerk principale, mentre CACHESTORE_COLUMNSTOREOBJECTPOOL sarà elevato quando vengono usati indici columnstore. È previsto l'utilizzo più elevato di questi clerk.

Per ulteriori dettagli sui tipi di memory clerk, vedere sys.dm_os_memory_clerks.

Usare DMV per analizzare le query attive

Nella maggior parte dei casi, la query non riuscita non è la causa dell'errore.

La query di esempio seguente per Azure SQL Database restituisce informazioni importanti sulle transazioni che attualmente stanno trattenendo o sono in attesa di allocazioni di memoria. Puntare alle query principali individuate per l'analisi e il tuning delle prestazioni e valutare se vengono eseguite come previsto. Prendere in considerazione la tempistica delle query di report a elevato utilizzo di memoria o delle operazioni di manutenzione.

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

Potresti decidere di usare l'istruzione KILL per arrestare una query attualmente in esecuzione che contiene o attende un’ampia concessione di memoria. Usare questa istruzione con cautela, soprattutto quando sono in esecuzione processi critici. Per altre informazioni, vedere KILL (Transact-SQL).

Usare Query Store per analizzare l'utilizzo della memoria delle query precedenti

Mentre la query di esempio precedente segnala solo i risultati delle query in tempo reale, la query seguente usa il Query Store per restituire informazioni sull'esecuzione della query precedente. Ciò può essere utile per analizzare un errore di memoria insufficiente che si è verificato in passato.

La query di esempio seguente per Azure SQL Database restituisce informazioni importanti sulle esecuzioni di query registrate dal Query Store. Puntare alle query principali individuate per l'analisi e il tuning delle prestazioni e valutare se vengono eseguite come previsto. Si noti il filtro temporale su qsp.last_execution_time per limitare i risultati alla cronologia recente. È possibile modificare la clausola TOP per produrre più o meno risultati a seconda dell'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;

Eventi estesi

Oltre alle informazioni precedenti, può essere utile acquisire una traccia delle attività nel server per analizzare accuratamente un problema di memoria insufficiente in Azure SQL Database.

Esistono due modi per acquisire tracce in SQL Server; Eventi estesi (XEvent) e tracce profiler. Tuttavia, SQL Server Profiler è una tecnologia di traccia deprecata non supportata per Azure SQL Database. Extended Events è la tecnologia di traccia più recente che consente maggiore versatilità e minore impatto sul sistema osservato e la sua interfaccia è integrata in SQL Server Management Studio (SSMS). Per ulteriori informazioni sull'interrogazione degli eventi estesi in Azure SQL Database, vedere Extended events in Azure SQL Database.

Consultare il documento che illustra come usare la Creazione guidata per una nuova sessione di Eventi Estesi in SSMS. Per Azure SQL database, tuttavia, SSMS fornisce una sottocartella Eventi estesi in ogni database in Object Explorer. Usare una sessione di Eventi Estesi per acquisire questi eventi importanti e identificare le query che li generano.

  • Errori di categoria

    • error_reported
    • exchange_spill
    • hash_spill_details
  • Categoria esecuzione:

    • excessive_non_grant_memory_used
  • Categoria di memoria

    • query_memory_grant_blocking
    • query_memory_grant_usage
  • summarized_oom_snapshot

    L'acquisizione di blocchi di concessioni di memoria, la perdita di concessioni di memoria o un numero eccessivo di concessioni di memoria potrebbero essere un potenziale indizio di una query che assume improvvisamente più memoria rispetto al passato e una potenziale spiegazione per un emergente errore di esaurimento della memoria in un carico di lavoro esistente. L'evento summarized_oom_snapshot esteso fa parte della sessione eventi esistente system_health per semplificare il rilevamento. Per altre informazioni, vedere Blog: Un nuovo modo per risolvere gli errori di memoria insufficiente nel motore di database.

OLTP in-memory senza memoria

Si potrebbe incontrare Error code 41805: There is insufficient memory in the resource pool '%ls' to run this operation se si usa OLTP in memoria. Ridurre la quantità di dati nelle tabelle ottimizzate per la memoria e nei parametri con valori di tabella ottimizzati per la memoria o aumentare le prestazioni del database a un obiettivo di servizio superiore per avere più memoria. Per altre informazioni sui problemi di memoria insufficiente con OLTP SQL Server In-Memory, vedere Resolve out of memory issues.

Ottenere supporto Azure SQL Database

Se gli errori di memoria insufficiente persistono in Azure SQL Database, inviare una richiesta di Azure support selezionando Get Support nel sito Azure Support.