Consumo di memoria di SQL Server 2012 all'esterno del pool di buffer


10

Ho un'istanza di SQL Server 2012 SP2 Enterprise Edition che consuma ~ 20 GB di memoria in più rispetto al limite massimo. limite di memoria. L'istanza è limitata a 65 GB, ma la memoria fisica in uso dalla query seguente mostra 86 GB

SELECT (physical_memory_in_use_kb/1024)/1024 AS [PhysicalMemInUseGB]
FROM sys.dm_os_process_memory;
GO

Il server è fisico con 2 nodi NUMA. C'è un modo per scoprire cosa sta consumando la memoria al di fuori del pool di buffer (suppongo che sia ciò che sta accadendo)?

Ecco l'output di DBCC MEMORYSTATUS: -

uscita di DBCC MEMORYSTATUS

Ed ecco il limite di memoria impostato: -

schermata del limite di memoria

Grazie in anticipo.

AGGIORNAMENTO: - Ho eseguito la query suggerita da Aaron

SELECT TOP (20) * FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESC

Ecco l'output: -

MemoryClerkOutput

La SOMMA di pages_kb arriva a ~ 60 GB

AGGIORNAMENTO 2: - L'output completo di DBCC MEMORYSTATUS è qui: - http://pastebin.com/nGn6kXEc

AGGIORNAMENTO 3: - Output degli script di Shanky nel file Excel qui: - http://jmp.sh/LKRlH4K

AGGIORNAMENTO 4: - Schermata dell'output di: -

SELECT (physical_memory_in_use_kb/1024)/1024 AS [PhysicalMemInUseGB]
FROM sys.dm_os_process_memory;
GO

Schermata PhysMemInUse

Quindi questo sembra indicare che SQL Server sta usando più del set da 65 GB.


Cosa produce questo? SELECT TOP (20) * FROM sys.dm_os_memory_clerks ORDER BY pages_kb DESC;?
Aaron Bertrand

Ciao Aaron, grazie per la risposta. Aggiornerò la domanda con l'output ora
dbafromthecold

Risposte:


11

La memoria massima del server controlla il pool di buffer e tutte le allocazioni delle dimensioni della pagina, ma non controlla ancora cose come allocazioni dirette di Windows (server collegati, sp_OA, XP), memoria necessaria per thread / stack di thread, ecc .

Probabilmente puoi aspettarti che questo sia più alto su NUMA (anche se non sono sicuro che 20 GB sia normale); il punto è che non ci si può aspettare che la memoria massima del server controlli completamente la memoria utilizzata da un'istanza di SQL Server. Se si desidera che l'intera istanza (non solo pool di buffer, cache di piano e CLR) non utilizzi più di 64 GB, è necessario impostare la memoria massima del server su un valore inferiore.

Alcune idee potenziali per rintracciarlo (normalizzerò tutto in MB):

  • contatori delle prestazioni

    Vedi se qualcosa salta qui come eccessivamente grande:

    SELECT counter_name, instance_name, mb = cntr_value/1024.0
      FROM sys.dm_os_performance_counters 
      WHERE (counter_name = N'Cursor memory usage' and instance_name <> N'_Total')
      OR (instance_name = N'' AND counter_name IN 
           (N'Connection Memory (KB)', N'Granted Workspace Memory (KB)', 
            N'Lock Memory (KB)', N'Optimizer Memory (KB)', N'Stolen Server Memory (KB)', 
            N'Log Pool Memory (KB)', N'Free Memory (KB)')
      ) ORDER BY mb DESC;
  • primi 20 impiegati

    Lo hai già fatto, ma per completezza:

    SELECT TOP (21) [type] = COALESCE([type],'Total'), 
      mb = SUM(pages_kb/1024.0)
    FROM sys.dm_os_memory_clerks
    GROUP BY GROUPING SETS((type),())
    ORDER BY mb DESC;
  • dimensione della pila del filo

    Innanzitutto, assicurati che sia zero e non un numero personalizzato (se non è 0, scopri perché e correggilo):

    SELECT value_in_use
      FROM sys.configurations 
      WHERE name = N'max worker threads';

    Ma puoi anche vedere quanta memoria viene occupata dagli stack di thread usando:

    SELECT stack_size_in_bytes/1024.0/1024 
      FROM sys.dm_os_sys_info;
  • Moduli di terze parti caricati

    SELECT base_address, description, name
      FROM sys.dm_os_loaded_modules 
      WHERE company NOT LIKE N'Microsoft%';
    
    -- you can probably trace down memory usage using the base_address
  • DMV relativi alla memoria

    Potresti anche essere in grado di individuare qualcosa di straordinario guardando questi DMV:

    SELECT * FROM sys.dm_os_sys_memory;
    SELECT * FROM sys.dm_os_memory_nodes WHERE memory_node_id <> 64;

Questo articolo è stato scritto prima di SQL Server 2012, pertanto potrebbe essere necessario modificare alcuni nomi di colonna e calcoli, ma potrebbe essere utile provare anche altri percorsi:

Qualche buona base anche in un altro articolo su quel sito:

Alcune buone informazioni sui tipi di cose che usano la memoria al di fuori max server memory(ma non ci sono buoni dati su come raccogliere l'utilizzo effettivo):


Grazie Aaron, il server ha molta memoria disponibile Volevo solo vedere se potevo scoprire cosa stava usando quel 20GB. Esiste un modo per identificare il consumo di memoria delle allocazioni dirette di Windows o degli stack di thread?
dbafromthecold

Ho gli script di esecuzione e il contatore Stolen Server Memory (KB) è a 14 GB. Andando a scavare per vedere se posso ottenere ulteriori informazioni
dbafromthecold

La memoria del server rubato non sembra essere il problema. Ancora alla ricerca
dbafromthecold

Anche se non è questo il problema, vale la pena ricordare che il pool di oggetti Columnstore (tipo di impiegato della memoria CACHESTORE_COLUMNSTOREOBJECTPOOL) è esterno al pool di buffer. Vedi questo post sul blog di Niko Neugebauer
Blaž Dakskobler,

@ BlažDakskobler sì, grazie, anche in memoria. Aggiornerò il post quando ne avrò la possibilità
Aaron Bertrand

3

Ho ricevuto una definizione al di sotto di Bob Dorr su ciò che controlla la memoria del server Max in SQL Server 2012. Puoi anche leggere libri online per maggiori dettagli

La memoria massima del server controlla l'allocazione della memoria di SQL Server, inclusi pool di buffer, memoria di compilazione, tutte le cache, richieste di memoria qe, memoria di gestione blocchi e memoria CLR (praticamente qualsiasi "impiegato" come si trova in dm_os_memory_clerks). La memoria per stack di thread, heap di memoria, provider di server collegati diversi da SQL Server o qualsiasi memoria allocata da una DLL "non SQL Server" non è controllata dalla memoria massima del server.

Memoria allocata per stack di thread, DLL di terze parti, provider di server collegati diverso da quello di Microsoft (come MySQL.PostgreSQL ecc.) O qualsiasi DLL caricata nello spazio degli indirizzi di SQL Server che non è SQL Server viene allocata al di fuori della memoria massima del server. Anche l'operazione di backup IIRC in SQL Server 2012 è ancora allocata memoria al di fuori del pool di buffer.

Stai utilizzando un server collegato per eseguire query su altri RDBMS? Qualsiasi altro software installato sullo stesso computer Windows. Puoi pubblicare su una posizione condivisa l'output delle seguenti query

select type,
sum(pages_kb)/1024 as [Memory utilized in MB],
sum(awe_allocated_kb)/1024 as [Memory allocated though Windows API]
 from sys.dm_os_memory_clerks
 group by type
 order by [Memory utilized in MB] desc
 Go
-------

 select (virtual_address_space_committed_kb/1024) as virtual_address_space_committed_MB,
 (locked_page_allocations_kb/1024) locked_page_allocations_MB,
 (pages_kb/1024) [memory allocated MB]
  from sys.dm_os_memory_nodes
  Go
-------
SELECT SUM (pages_in_bytes)/1024 as 'KB Used', type 
FROM sys.dm_os_memory_objects
GROUP BY type 
ORDER BY 'KB Used' DESC;
GO
--------
select name,
type,
sum(pages_kb)/1024 as [Mem MB],
sum(entries_count) as [Total Entry count] from sys.dm_os_memory_cache_counters
group by
type, name
order by [Mem MB] desc
Go
-----
select * from sys.dm_os_loaded_modules where company <> 'Microsoft Corporation'
go

Puoi anche caricare l' DBCC MMEMORYSTATUSoutput completo su una posizione condivisa e pubblicare il link qui. Ciò aiuterebbe a capire quale componente sta prendendo memoria

Modifica: secondo l'output di dbcc memorystatus posso vedere 2 nodi NUMA e la memoria utilizzata da ciascun nodo è di ca.

Node 1 : VM Committed 33554380

Node 2: VM Committed  33554420

Total is approx 64 G. 

Ancora una volta, se vedi Memory Manager in memorystatus ne viene visualizzato l'output

Memory Manager                           KB
---------------------------------------- -----------
VM Reserved                              260726964
VM Committed                             **67108820**

Il commit della VM è in realtà memoria virtuale impegnata da SQL Server e poiché questa memoria è impegnata ha physical memory backing it. Questo di nuovo, il che mi fa pensare che SQL Server stia usando 65 G come impostato nella memoria massima del server

Questa è la memoria massima del server. Quindi la memoria è ben distribuita tra i due nodi, è possibile anche aggiungere l'output dello jut di query sottostante per verificare. Aggiungi screenshot

SELECT (physical_memory_in_use_kb/1024)/1024 AS [PhysicalMemInUseGB]
FROM sys.dm_os_process_memory;
GO

@DBAFromTheCold: È tardi ma stai ancora cercando una risposta, se sì voglio fare un altro tentativo :) Puoi pubblicare un output completo diselect * from sys.dm_so_process_memory
Shanky,

Ciao Shanky, grazie per la risposta ma il problema si è risolto da solo. Nulla da parte mia, SQL ha rilasciato la memoria da solo. Sto monitorando il server e, se si verifica nuovamente, invierò un aggiornamento. Voglio davvero arrivare al fondo di questo.
dbafromthecold
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.