SQL Server não está usando toda a memória

10

Eu tenho o SQL Server 2014 com memória máxima definida como 6 GB (a memória física é 8 GB).

A memória do servidor alvo é, por vezes, 6GB e depois cai de volta ao Servidor Memória Total (aproximadamente 5.3GB, nunca atinge 6GB). Eu costumava committed_kb em sys.dm_os_sys_info para verificar a memória usada pelo SQL Server.

Ao monitorar sys.dm_os_buffer_descriptors , vejo que as páginas são descartadas do cache - mas ainda resta 700 MB de memória. Se nada precisasse da memória, como você explicaria o fato de as páginas serem removidas do cache? Eu esperaria que o SQL Server apenas remova as páginas quando precisar de memória.

Tabelas temporárias desalocadas não são um problema neste servidor. Meu PLE é 3632. O cache do procedimento é 2182 MB.

Eu esperava que as páginas fossem descartadas apenas quando não restasse memória, mas tenho 700 MB livres ou estou entendendo isso errado?

Alguém por favor pode tentar explicar esse comportamento?

O SQL Server também está lendo do disco, então acho que posso concluir que nem todas as páginas necessárias estão na memória.

Pesquisei um pouco mais e li uma quantidade enorme de páginas do disco na memória e notei algo no gerenciador de tarefas durante as leituras:

  • A memória em uso passou de 7,0 GB -> 7,2 GB -> 7,0 GB -> 7,2 GB -> ...
  • Sqlservr.exe passou de 5,3 GB -> 5,5 GB -> 5,3 GB -> 5,5 GB -> ...

É como se o Windows não permitisse que o sqlservr.exe aumentasse para 6 GB.

Eu executei a consulta fornecida por Shanky:

select
(physical_memory_in_use_kb/1024) Physical_Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024 )Locked_pages_used_Sqlserver_MB,
(Virtual_address_committed_kb/1024 )Total_Memory_in_MB,--RAM+ Pagefile
process_physical_memory_low,
process_virtual_memory_low
from sys. dm_os_process_memory

Isso deu o seguinte resultado:

Physical_Memory_usedby_Sqlserver_MB: 5247
Locked_pages_used_Sqlserver_MB: 0
Total_Memory_in_MB: 5625
process_physical_memory_low: 0
process_virtual_memory_low: 0

O que eu não entendo é por que Total_Memory_in_MB não é igual a 6144 (memória máxima)?

Em sys.dm_os_ring_buffers que encontrei RESOURCE_MEMPHYSICAL_LOW, acho que o Windows está com pouca memória e o SQL Server deve retornar alguns. Mas há aproximadamente 1 GB de memória disponível => por que o Windows está dizendo que está com pouca memória?

<Record id="13861" type="RING_BUFFER_RESOURCE_MONITOR" time="20635079241">   
   <ResourceMonitor>
        <Notification>RESOURCE_MEMPHYSICAL_LOW</Notification>
        <IndicatorsProcess>0</IndicatorsProcess>
        <IndicatorsSystem>2</IndicatorsSystem>
        <NodeId>0</NodeId>
        <Effect type="APPLY_LOWPM" state="EFFECT_OFF" reversed="0">0</Effect>
        <Effect type="APPLY_HIGHPM" state="EFFECT_IGNORE" reversed="0">85827186</Effect>
        <Effect type="REVERT_HIGHPM" state="EFFECT_OFF" reversed="0">0</Effect>   
   </ResourceMonitor>   
   <MemoryNode id="0">
        <TargetMemory>6050080</TargetMemory>
        <ReservedMemory>67208656</ReservedMemory>
        <CommittedMemory>5423548</CommittedMemory>
        <SharedMemory>0</SharedMemory>
        <AWEMemory>0</AWEMemory>
        <PagesMemory>4975656</PagesMemory>   
   </MemoryNode>   
   <MemoryRecord>
        <MemoryUtilization>100</MemoryUtilization>
        <TotalPhysicalMemory>8387608</TotalPhysicalMemory>
        <AvailablePhysicalMemory>1048452</AvailablePhysicalMemory>
        <TotalPageFile>11142348</TotalPageFile>
        <AvailablePageFile>2887916</AvailablePageFile>
        <TotalVirtualAddressSpace>137438953344</TotalVirtualAddressSpace>
        <AvailableVirtualAddressSpace>137371168056</AvailableVirtualAddressSpace>
        <AvailableExtendedVirtualAddressSpace>0</AvailableExtendedVirtualAddressSpace
   </MemoryRecord> 
</Record>

Atualização
Depois de mais algumas pesquisas sobre por que sempre havia 1 GB de memória disponível, acho que encontrei algo.
É possível que o SQL Server possa alocar apenas memória livre e que a memória disponível seja ignorada? Ao executar o Process Explorer (Sysinternals), vi que a memória livre era 0.

Frederik Vanderhaegen
fonte

Respostas:

3

Para começar, devo dizer que você configurou o máximo de memória do servidor para 6 GB e a memória total é de 8 GB, então você deixou apenas 2 GB para o sistema operacional, o que em muitos casos, mesmo que nada esteja instalado além do SQL Server em uma máquina Windows , há pouca memória fornecida ao sistema operacional. Para funcionar corretamente, em um sistema com antivírus instalado, o sistema operacional deve receber pelo menos 4 GB. Deixo 2 GB para o SO imediatamente e 1,5 G para o AV.

Às vezes, a memória do servidor de destino tem 6 GB e volta à Memória total do servidor (aproximadamente 5,3 GB, nunca atinge 6 GB).

A memória do servidor de destino significa quanta memória é necessária pelo SQL Server para funcionar corretamente no caso ideal. A memória do servidor de destino está tentando ter 6 GB, porque você definiu o valor máximo da memória do servidor para 6 GB. Ele está tentando consumir toda a memória que é permitido.

Memória total do servidor é o que o SQL Server realmente pode consumir no momento. Isso é memória comprometida e suportada por RAM física. Este é um máximo de 5,5 GB no seu caso.

O SQL Server está tentando aumentar o consumo de memória, mas após atingir 5,3 ou 5,5 GB, o sistema operacional está solicitando ao SQL Server que não aumente ainda mais o consumo de memória e pode estar sinalizando uma notificação de pouca memória. Isso está acontecendo porque o sistema operacional pode estar com pouca memória, como já foi dito acima. O SQLOS responde se o sistema operacional Windows enfrentar pressão de memória solicitando que seus caches reduzam seu consumo. Você pode consultar o buffer de anel para verificar se houve uma notificação de pouca memória sinalizada. Devo adicionar o DMV sys.dm_os_ring_buffer não está documentado, mas é seguro.

Vejo que as páginas são descartadas do cache - mas ainda resta 700 MB de memória. Se nada precisasse da memória, como você explicaria o fato de as páginas serem removidas do cache? Eu esperaria que o SQL Server remova apenas as páginas quando precisar de memória.

Se você está procurando memória livre, eu não sugeriria que você olhe os DMV sys.dm_os_buffer_descriptors . O contador do SO Available Mbytes informará a quantidade de memória física, em bytes, disponível para os processos em execução no computador. Sugiro que você também veja O que é um método determinístico para avaliar um tamanho sensível do buffer pool? e leia também O SQL Server precisa de mais RAM para descobrir quanta RAM o SQL Server precisa e se o SQL Server está enfrentando pressão de memória. Pelo que você mencionou, se tiver certeza de que as páginas estão sendo removidas do pool de buffers, sim, o SQL Server considera que as páginas precisam ser movidas porque precisam de espaço para acomodar novas páginas. Não sei como você calculou os 700 MB gratuitos.

Outra coisa, não consulte o Gerenciador de Tarefas para o consumo de memória do SQL Server. Nem sempre ele fornece o valor correto, especialmente quando a conta de serviço do SQL Server possui privilégios de bloqueio de páginas na memória . No seu caso, mesmo se o SQL Server tiver uma memória máxima de 6 GB, o sistema operacional receberá apenas 2 GB, o que está forçando o SQL Server a não aumentar seu consumo, porque 2 GB é baixo para o SQL Server. Existe algo além do SQL Server em execução no sistema?

Se você deseja calcular o consumo de memória do SQL Server, use:

select
(physical_memory_in_use_kb/1024) Physical_Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024 ) Locked_pages_used_Sqlserver_MB,
(virtual_address_space_committed_kb/1024 ) Total_Memory_in_MB,--RAM+ Pagefile
process_physical_memory_low,
process_virtual_memory_low
from sys.dm_os_process_memory

O que eu não entendo é porque o Total_Memory_in_MB não é igual a 6144 (memória máxima).

A coluna Total_Memory_in_MB significa memória total usada pelo SQL Server (RAM + arquivo de paginação). A RAM é realmente memória física usada ou confirmada. Alguma parte do processo do SQL Server também é paginada em disco e isso constitui como memória virtual ou arquivo de paginação e, portanto, se você deseja ver TOTAL da memória consumida pelo SQL Server, seria a soma da memória física e do arquivo de paginação.

Enquanto a coluna Physical_Memory_usedby_Sqlserver_MB é apenas a memória física (memória suportada pela RAM física ou memória confirmada) usada. Esta é a razão pela qual ambos são diferentes. Se você vir a coluna real, a primeira é a Memória física usada e a outra é a Memória virtual confirmada.

Se você deseja ver a memória paginada, essa seria a diferença entre Total_Memory_in_MB e Physical_Memory_usedby_Sqlserver_MB .

NOTA: A memória total usada seria maior que a memória física usada.

Shanky
fonte
5

O SQL Server usa muito mais caches que não o cache de buffer, embora esse seja de longe o maior (um exemplo óbvio é o cache do plano). Você pode examinar mais de perto a memória DBCC MEMORYSTATUSe uma variedade de DMVs. A memória de destino e a memória total referem-se especificamente ao Buffer Pool / Cache.

Trecho do seminal Professional SQL Server 2008 de Christian Bolton Internals e solução de problemas :

  • MSSQL$<instance >:Memory Manager\Total Server Memory (KB):
    Indica o tamanho atual do buffer pool.
  • MSSQL$<instance >:Memory Manager\Target Server Memory (KB):
    Indica o tamanho ideal para o buffer pool. Total e Alvo devem ser quase os mesmos em um servidor sem pressão de memória em execução por um tempo. Se o Total for significativamente menor que o Destino , é provável que o SQL Server não possa aumentar o buffer pool devido à pressão da memória; nesse caso, você poderá investigar mais.
Mark Broadbent
fonte
Apenas para adicionar, mesmo que a memória total e de destino do servidor seja a mesma, não podemos ter 100% de certeza de que não há pressão de memória. Nesse caso, precisamos disparar mais alguns contadores de memória e obter seus dados para chegar a uma conclusão.
shanky
"Total e Target devem ser quase os mesmos em um servidor sem pressão de memória que esteja em execução há algum tempo." Vamos pensar sobre isso. Eu levanto um novo SQL Server com 128 GB de RAM e trago um único banco de dados de 1 GB. Deixe funcionar por um mês. Devo realmente acreditar que Total e Target serão quase os mesmos no final desse mês? Se não estiverem, devo acreditar que o servidor está sob pressão de memória? Acho isso difícil de acreditar.
Mike Sherrill 'Cat Recall'