O que acontece quando não há memória física disponível para o SQL Server?

16

Enquanto pesquisava, encontrei algumas informações conflitantes.

Alguns sites afirmam que, quando não há memória física para os dados, o SQL Server move os dados já existentes para o TEMPDB (consulte: SQL Server: Desmistificando o TempDb e recomendações ).

Mas outros sites afirmam que, quando não há memória física suficiente, o sistema operacional pode usar o PAGE FILE e mover os dados da memória física para ele (consulte Arquivo de Página do SQL Server ).

Gostaria de saber onde o SQL Server grava dados quando fica sem memória física? Para tempdb ou para o arquivo de página do SO? Ou talvez os dois?

RaufDBA
fonte

Respostas:

28

quando não há memória física para os dados, o SQL Server move os dados já existentes para o TEMPDB

O artigo ao qual você vinculou é enganoso, na melhor das hipóteses, e incorreto em alguns lugares. Acho que o autor estava tentando simplificar demais algumas coisas complicadas e, ao fazê-lo, foi um pouco longe demais.

O SQL Server não move os dados da memória (o buffer pool) para o tempdb dessa maneira. Ele usa uma estratégia de cache "menos usada recentemente" (em geral); portanto, se houver pressão de memória e novos dados precisarem ser puxados para a memória, o SQL Server lançará os dados LRU do buffer pool para acomodar os novos dados. Esse comportamento geralmente é monitorado por um contador perfmon chamado "Expectativa de vida da página" (PLE) :

A definição de PLE é o tempo esperado, em segundos, que uma página de arquivo de dados lida no buffer pool (o cache na memória das páginas de arquivos de dados) permanecerá na memória antes de ser empurrada para fora da memória para liberar espaço para dados diferentes página do arquivo. Outra maneira de pensar no PLE é uma medida instantânea da pressão no buffer pool para liberar espaço para as páginas lidas no disco. Para ambas as definições, um número maior é melhor.

Durante a execução da consulta, o SQL Server pode usar o tempdb para determinadas operações. Isso geralmente é feito se as estimativas forem ruins, mas a pouca memória disponível pode influenciar esse comportamento.

Algumas das operações que podem "derramar" para o tempdb dessa maneira são hash de linhas (para junções ou agregados, etc), classificação de linhas na memória e buffer de linhas durante a execução de consultas paralelas.

As consultas do usuário também podem usar explicitamente o tempdb (com tabelas temporárias globais ou locais) e implicitamente usar o tempdb (com captura instantânea ou níveis de isolamento de captura instantânea confirmada por leitura).

Nenhuma dessas situações parece realmente se encaixar na afirmação que você citou.

quando não há memória física suficiente, o sistema operacional pode usar o PAGE FILE e mover os dados da memória física para ele

Definitivamente, isso pode acontecer e está fora do controle do SQL Server na maior parte. Há um botão que você pode ativar para tentar impedir alguns tipos de paginação no nível do SO, como ativar "Bloquear páginas na memória" (LPIM) :

Esta política do Windows determina quais contas podem usar um processo para manter os dados na memória física, impedindo que o sistema pagine os dados para a memória virtual no disco.

Então, o que podemos impedir de ser paginado em disco?

Antes do SQL Server 2012, as páginas alocadas por meio de um componente chamado "Alocador de página única" eram bloqueadas na memória (não podiam ser paginadas). Isso inclui o pool de buffers (páginas do banco de dados), o cache do procedimento e algumas outras áreas da memória.

Consulte Diversão com páginas bloqueadas, AWE, Gerenciador de tarefas e o conjunto de trabalho ... para obter detalhes, especialmente a seção "4. Agora eu sei que o SQL Server no x64 pode usar" Páginas bloqueadas ", o que exatamente está bloqueado?" Outras leituras relacionadas podem ser encontradas aqui: Ótimos debates sobre o SQL Server: Bloquear páginas na memória

No SQL Server 2012 e posterior, não existe um "Alocador de página única" (os alocadores de página única e de várias páginas foram mesclados, de acordo com uma análise detalhada da memória - SQL Server 2012/2014 ). Os detalhes do que exatamente podem e não podem ser paginados não estão documentados em detalhes em nenhum lugar que eu tenha visto. Você pode usar uma consulta como esta para ver o que está bloqueado:

select osn.node_id, osn.memory_node_id, osn.node_state_desc, omn.locked_page_allocations_kb
from sys.dm_os_memory_nodes omn
inner join sys.dm_os_nodes osn on (omn.memory_node_id = osn.memory_node_id)
where osn.node_state_desc <> 'ONLINE DAC'

Pelo mesmo artigo de suporte da MS, você também pode usar DBCC MEMORYSTATUSpara ver quanta memória está "bloqueada".

Como uma observação lateral, você pode ver evidências de que o conjunto de trabalho do SQL Server está sendo paginado pelo sistema operacional no log de erros. Haverá mensagens parecidas com esta:

2019-09-02 10: 19: 27.29 spid11s Uma parte significativa da memória do processo do servidor sql foi paginada. Isso pode resultar em uma degradação do desempenho. Duração: 329 segundos. Conjunto de trabalho (KB): 68780, confirmado (KB): 244052, utilização de memória: 28%.

Josh Darnell
fonte
0

As versões modernas do SQL server têm uma chance muito pequena de desligar completamente. O SQL Server carrega o .NET Framework em seu espaço de endereço e o usa em operação normal. Se a memória física e o arquivo de paginação acabarem, o Windows tentará aumentar o arquivo de paginação; no entanto, mesmo que possa aumentar o arquivo de paginação, essa não é uma operação instantânea e as alocações de memória falham enquanto o arquivo de paginação está crescendo. Há um erro no manipulador de E / S assíncrona do .NET em que ele aloca memória em resposta a uma notificação da APC. Se a chamada newfalhar, será lançadaOutOfMemoryException. Essa exceção é capturada no código nativo dentro do planejador de tarefas; no entanto, a E / S assíncrona parecerá nunca terminar. O encadeamento do finalizador do FileStream bloqueará a espera pelo término da E / S para que possa desafixar o buffer, desligando o encadeamento do finalizador para sempre. Isso faz com que o .NET Framework use gradualmente mais e mais memória até que nenhuma memória possa ser alocada. Nesse momento, o SQL Server não responderá porque o winsock não pode alocar mais buffers, portanto, mesmo a conexão de acesso de administrador é inútil.

Na verdade, eu atingi um agendador total de tarefas em um aplicativo .NET devido à falta de memória. Felizmente, o processo finalmente morreu devido ao lançamento OutOfMemoryExceptionde algum encadeamento que não o pegou após várias falhas, para que pudéssemos descobrir o que estava realmente desligando o servidor.

Depois que soube o que estava procurando, foi fácil encontrar o bug na análise estática.

Joshua
fonte