O consumo de "Memória total do servidor" do SQL Server permanece estagnado por meses, com 64 GB ou mais disponíveis

39

Eu deparei com um problema estranho, em que o SQL Server 2016 Standard Edition de 64 bits parecia ter atingido exatamente a metade da memória total alocada para ele (64 GB de 128 GB).

A saída de @@VERSIONé:

Microsoft SQL Server 2016 (SP1-CU7-GDR) (KB4057119) - 13.0.4466.4 (X64) 22 de dezembro de 2017 11:25:00 Copyright (c) Microsoft Corporation Standard Edition (64 bits) no Windows Server 2012 R2 Datacenter 6.3 ( Build 9600:) (Hypervisor)

A saída de sys.dm_os_process_memoryé:

sys.dm_os_process_memory

Quando eu consulto sys.dm_os_performance_counters, vejo que Target Server Memory (KB)está em 131072000e Total Server Memory (KB)está em pouco menos da metade dele em 65308016. Na maioria dos cenários, eu entenderia esse comportamento normal, pois o SQL Server ainda não determinou que ele precisa alocar mais memória para si.

No entanto, ele está "travado" em ~ 64 GB há mais de 2 meses. Durante esse período, realizamos uma quantidade significativa de operações com uso intenso de memória em alguns bancos de dados e adicionamos mais de 40 bancos de dados à instância. Estamos no total de 292 bancos de dados, cada um com arquivos de dados pré-alocados em 4 GB com uma taxa de crescimento automático de 256 MB e arquivos de log de 2 GB com uma taxa de crescimento automático de 128 MB. Eu executo um backup completo uma vez todas as noites às 00:00 e inicio os backups do log de transações de segunda a sexta-feira, começando das 06:00 às 20:00, em um intervalo a cada 15 minutos. Esses bancos de dados são relativamente baixos em sua taxa de transferência geral, mas estou cético quanto a algo estar errado, uma vez que o SQL Server não avançou na direção doTarget Server Memory naturalmente por meio de novas adições ao banco de dados, execuções normais de consulta e pipelines ETL com uso intenso de memória que foram executados.

A instância do SQL Server em si está no topo de um servidor Windows Server 2012R2 virtualizado (VMware) com 12 CPU, 144 GB de memória (128 GB no SQL Server, 16 GB reservados para Windows) e 4 discos virtuais totais no topo de um vSAN com unidades SAS de 15 K . O Windows fica naturalmente em um disco C: de 64 GB com um arquivo de paginação de 32 GB. Os arquivos de dados ficam em um disco D: 2TB, os arquivos de log ficam em cima de um disco L: 2TB e o tempdb fica em um disco T: 256GB com arquivos 8x16GB sem crescimento automático.

Eu verifiquei que não existem outras instâncias do SQL Server em execução no servidor MSSQLSERVER.

Serviços

Esse servidor é totalmente dedicado apenas à instância do SQL Server; portanto, não temos outros aplicativos ou serviços em execução que possam consumir memória.

Monitor de recursos

Utilizo o RedGate SQL Monitor para análise, e abaixo está um histórico dos últimos 18 dias de Total Server Memory. Como você pode ver, a utilização da memória permaneceu totalmente estagnada, exceto por um único aumento de ~ 300 MB no início de abril.

RedGate SQL Monitor

Qual pode ser a causa disso? O que posso examinar mais de perto para determinar por que o SQL Server não está querendo usar os 64 GB + adicionais de memória alocados para ele?

A saída da execução sp_Blitz:

sp_Blitz @OutputType = 'markdown', @CheckServerInfo = 1;

Prioridade 50: Desempenho :

  • Agendadores de CPU offline - Alguns núcleos de CPU não estão acessíveis ao SQL Server devido a problemas de mascaramento de afinidade ou licenciamento.

  • Nós de memória offline - Devido a problemas de mascaramento ou licenciamento de afinidades, parte da memória pode não estar disponível.

Prioridade 50: Confiabilidade :

  • DAC remoto desativado - O acesso remoto ao DAC (Dedicated Admin Connection) não está ativado. O DAC pode facilitar muito a solução de problemas remotos quando o SQL Server não responde.

Prioridade 100: Desempenho :

  • Muitos planos para uma consulta - 300 planos estão presentes para uma única consulta no cache do plano - o que significa que provavelmente temos problemas de parametrização.

  • Acionadores de servidor ativados

    • O acionador do servidor [RG_SQLLighthouse_DDLTrigger] está ativado. Certifique-se de entender o que esse gatilho está fazendo - quanto menos trabalho ele fizer, melhor.

    • O acionador do servidor [SSMSRemoteBlock] está ativado. Certifique-se de entender o que esse gatilho está fazendo - quanto menos trabalho ele fizer, melhor.

Prioridade 150: Desempenho :

  • Consultas forçando dicas de junção - 1480 instâncias de dicas de junção foram registradas desde a reinicialização. Isso significa que as consultas estão dominando o otimizador do SQL Server e, se elas não sabem o que estão fazendo, isso pode causar mais danos do que benefícios. Isso também pode explicar por que os esforços de ajuste do DBA não estão funcionando.

  • Consultas forçando dicas de pedidos - 2153 instâncias de dicas de pedidos foram registradas desde o reinício. Isso significa que as consultas estão dominando o otimizador do SQL Server e, se elas não sabem o que estão fazendo, isso pode causar mais danos do que benefícios. Isso também pode explicar por que os esforços de ajuste do DBA não estão funcionando.

Prioridade 170: Configuração do arquivo :

  • Banco de dados do sistema na unidade C

    • master - O banco de dados mestre possui um arquivo na unidade C. A colocação de bancos de dados do sistema na unidade C corre o risco de travar o servidor quando ficar sem espaço.

    • model - O banco de dados do modelo possui um arquivo na unidade C. A colocação de bancos de dados do sistema na unidade C corre o risco de travar o servidor quando ficar sem espaço.

    • msdb - O banco de dados msdb tem um arquivo na unidade C. A colocação de bancos de dados do sistema na unidade C corre o risco de travar o servidor quando ficar sem espaço.

Prioridade 200: Informativo :

  • Trabalhos do agente iniciando simultaneamente - vários trabalhos do SQL Server Agent são configurados para iniciar simultaneamente. Para listagens detalhadas da programação, consulte a consulta no URL.

  • Tabelas no mestre do banco de dados mestre - A tabela CommandLog no banco de dados mestre foi criada pelos usuários finais em 30 de julho de 2017 às 17:22. As tabelas no banco de dados mestre não podem ser restauradas no caso de um desastre.

  • TraceFlag On

    • O sinalizador de rastreamento 1118 está ativado globalmente.

    • O sinalizador de rastreamento 1222 está ativado globalmente.

    • O sinalizador de rastreamento 2371 está ativado globalmente.

Prioridade 200: configuração de servidor não padrão :

  • Agent XPs - Esta opção sp_configure foi alterada. Seu valor padrão é 0 e foi definido como 1.

  • padrão de soma de verificação de backup - Esta opção sp_configure foi alterada. Seu valor padrão é 0 e foi definido como 1.

  • padrão de compactação de backup - Esta opção sp_configure foi alterada. Seu valor padrão é 0 e foi definido como 1.

  • limite de custo para paralelismo - Esta opção sp_configure foi alterada. Seu valor padrão é 5 e foi definido como 48.

  • grau máximo de paralelismo - Esta opção sp_configure foi alterada. Seu valor padrão é 0 e foi definido como 12.

  • memória máxima do servidor (MB) - Esta opção sp_configure foi alterada. Seu valor padrão é 2147483647 e foi definido como 128000.

  • otimizar para cargas de trabalho ad hoc - Esta opção sp_configure foi alterada. Seu valor padrão é 0 e foi definido como 1.

  • mostre opções avançadas - Esta opção sp_configure foi alterada. Seu valor padrão é 0 e foi definido como 1.

  • xp_cmdshell - Esta opção sp_configure foi alterada. Seu valor padrão é 0 e foi definido como 1.

Prioridade 200: Confiabilidade :

  • Procedimentos armazenados estendidos no mestre

  • master - O procedimento armazenado estendido [sqbdata] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqbdir] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqbmemory] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqbstatus] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqbtest] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqbtestcancel] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqbteststatus] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqbutility] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

    • master - O procedimento armazenado estendido [sqlbackup] está no banco de dados mestre. O CLR pode estar em uso e o banco de dados mestre agora precisa fazer parte do seu planejamento de backup / recuperação.

Prioridade 210: Configuração não padrão do banco de dados :

  • Isolamento de Captura Instantânea Confirmada de Leitura Ativado - Esta configuração do banco de dados não é o padrão.

    • RedGate

    • RedGateMonitor

  • Isolamento de instantâneo ativado - esta configuração do banco de dados não é o padrão.

    • RedGate

    • RedGateMonitor

Prioridade 240: Estatísticas de espera :

  • 1 - SOS_SCHEDULER_YIELD - 1770,8 horas de espera, 115,9 minutos de tempo médio de espera por hora, 100,0% de espera de sinal, 1419212079 tarefas de espera, 4,5 ms de tempo médio de espera.

Prioridade 250: Informativo :

  • O SQL Server está sendo executado em uma conta do Serviço NT - estou executando como NT Service \ MSSQLSERVER. Gostaria de ter uma conta de serviço do Active Directory.

Prioridade 250: Informações do servidor :

  • Conteúdo de rastreamento padrão - O rastreamento padrão contém 36 horas de dados entre 14 de abril de 2018 às 23:21 e 16 de abril de 2018 às 11:13. Os arquivos de rastreamento padrão estão localizados em: C: \ Arquivos de Programas \ Microsoft SQL Server \ MSSQL13.MSSQLSERVER \ MSSQL \ Log

  • Unidade C Space - 196816.00MB grátis na unidade C

  • Drive D Space - 894823.00MB grátis na unidade E

  • Drive L Space - 1361367,00MB grátis na unidade F

  • Drive T Space - 114441.00MB grátis no G drive

  • Hardware - Processadores lógicos: 12. Memória física: 144GB.

  • Hardware - NUMA Config

    • Nó: 0 Estado: ONLINE Agendadores online: 4 Agendadores offline: 2 Grupo de processadores: 0 Nó de memória: 0 GB de memória VAS reservado GB: 186

    • Nó: 1 Estado: OFFLINE Agendadores online: 0 Agendadores offline: 6 Grupo de processadores: 0 Nó de memória: 0 GB de memória VAS reservado GB: 186

  • Inicialização instantânea de arquivo ativada - A conta de serviço tem a permissão Executar tarefas de manutenção de volume.

  • Plano de energia - Seu servidor possui CPUs de 2,60 GHz e está no modo de energia balanceada - Uh ... você quer que suas CPUs funcionem a toda velocidade, certo?

  • Última reinicialização do servidor - 9 de março de 2018 7:27

  • Nome do servidor - [redigido]

  • Serviços

    • Serviço: o SQL Server (MSSQLSERVER) é executado na conta de serviço NT Service \ MSSQLSERVER. Última hora de inicialização: 9 de março de 2018 às 07:27. Tipo de inicialização: Automático, atualmente em execução.

    • Serviço: o SQL Server Agent (MSSQLSERVER) é executado na conta de serviço LocalSystem. Último horário de inicialização: não mostrado. Tipo de inicialização: Automático, atualmente em execução.

  • Última reinicialização do SQL Server - 9 de março de 2018 6h27

  • Serviço SQL Server - Versão: 13.0.4466.4. Nível do patch: SP1. Atualização cumulativa: CU7. Edição: Standard Edition (64 bits). Grupos de disponibilidade ativados: 0. Status do gerente de grupos de disponibilidade: 2

  • Servidor virtual - Tipo: (HYPERVISOR)

  • Versão do Windows - Você está executando uma versão bastante moderna do Windows: Server 2012R2 era, versão 6.3

Prioridade 254 :undundação :

  • Log do capitão: estrelar algo e algo ...
Pico de Gallo
fonte
Esta resposta pode ajudar a SQL Server não usar toda a memória
SqlWorldWide
Adicione a saída completa de select @@versione select * from sys.dm_os_process_memorypara a pergunta. Você tentou analisar o valor Total Server Memory (KB)do perfmon counter?
Shanky
@SqlWorldWide Eu já fiz essa pergunta e o conselho dado é essencialmente o que forneço no meu tópico principal. Não consegui encontrar uma solução nessa postagem para o meu cenário.
PicoDeGallo
@ Shanky Adicionei as saídas solicitadas. Total Server Memory (KB)foi fornecido a partir de sys.dm_os_performance_counters.
PicoDeGallo 16/04

Respostas:

51

Aposto que você configurou as CPUs virtuais de uma maneira que alguns dos nós da CPU e / ou nós da memória estão offline.

Faça o download do sp_Blitz (aviso: sou um dos autores desse script de código aberto gratuito) e execute-o:

sp_Blitz @CheckServerInfo = 1;

Procure avisos sobre a CPU e / ou nós de memória estarem offline. O SQL Server Standard Edition vê apenas os 4 primeiros soquetes da CPU e você pode ter configurado a VM como algo como 6 CPUs de núcleo duplo. Isso acabará atingindo um problema semelhante ao modo como os limites de 20 núcleos do Enterprise Edition limitam a quantidade de memória que você pode ver .

Se você deseja compartilhar a saída do sp_Blitz aqui, você pode executá-la dessa maneira para a saída no Markdown, que pode ser copiada / colada na sua pergunta:

sp_Blitz @OutputType = 'markdown', @CheckServerInfo = 1;

Atualização 16/04/2018 - confirmada. Você anexou a saída sp_Blitz (obrigado por isso!) E ela realmente mostra que você possui nós de CPU e memória offline. Quem construiu a VM, configurou-a como 12 CPUs de núcleo único; portanto, o SQL Server Standard Edition só vê os 4 primeiros soquetes (núcleos) e a memória anexada a eles.

Para corrigi-lo, desligue a VM, configure-a como uma VM de 2 soquetes e 6 núcleos e o SQL Server Standard Edition verá todos os núcleos e memória. Isso também reduzirá suas esperas SOS_SCHEDULER_YIELD - agora, seu SQL Server está martelando os 4 primeiros núcleos, mas é isso. Após essa correção, ele poderá trabalhar em todos os 12 núcleos.

Brent Ozar
fonte
3
diferente página , mesmo vídeo suponho
Marian
@BrentOzar Compartilhei meus resultados antes / depois dessa alteração de configuração aqui . Agradeço a assistência - você nos salvou muita dor de cabeça!
PicoDeGallo 17/04/19
@PicoDeGallo, de nada! Sim, é por isso que eu coloquei no sp_Blitz - encontramos muitos desses tipos de problemas comuns, e eles são tão fáceis de sair apenas executando esse processo de verificação de saúde gratuito. Ame sua salsa, a propósito. (Espere, isso errado soou.)
Brent Ozar
8

Como um adendo ao plano de ação de Brent Ozar , eu queria compartilhar os resultados. Como Brent observou, na VMware configuramos a máquina virtual incorretamente com 12 CPUs de núcleo único. Isso resultou nos 8 núcleos restantes inacessíveis pelo SQL Server e, como resultado, levou ao problema de memória descrito na minha pergunta original. Colocamos nossos serviços no modo de manutenção ontem à noite para reconfigurar a VM adequadamente. Não apenas estamos vendo a memória aumentar de maneira normal, mas como Brent também sugeriu, o número de esperas diminuiu exponencialmente e nosso desempenho geral do SQL Server disparou. As configurações do vNUMA agora são pequenos componentes felizes que estão cortando nossas cargas de trabalho.

Para aqueles que possam estar utilizando o VMware vSphere 6.5, as breves etapas para concluir o item de ação descrito por Brent são as seguintes.

  1. Faça logon no vSphere Web Client para seu cluster VMware e navegue até a Máquina virtual que hospeda o SQL Server. Sua VM deve estar offline para ajustar as configurações de CPU e memória.
  2. No painel principal, vá para Configure > VM hardware, clique no Editbotão no canto superior direito. Você abrirá um menu de contexto que possui Edit Settings. Para referência, a imagem abaixo é a configuração incorreta . Observe que eu Cores per Socketconfigurei para 1. Dadas as limitações do SQL Server Standard Edition, essa é uma configuração incorreta.

    IncorrectConfig

  3. A correção é tão simples quanto ajustar o Cores per Socketvalor. No nosso caso, configuramos para 6o que temos 2 Sockets. Isso permite que o SQL Server utilize todos os 12 processadores.

    CorrectConfig

Uma observação importante: não defina o valor para onde o Number of Coresou o Socketsseria um número ímpar. O NUMA adora o equilíbrio e, de maneira geral, precisa ser divisível por 2. Por exemplo, uma configuração de 4 núcleos a 3 soquetes seria desequilibrada. De fato, se você executasse sp_Blitzcom esse tipo de configuração, seria emitido um aviso sobre isso.

A Seção 3.3 em Arquitetura do Microsoft SQL Server no VMware vSphere (aviso em PDF) descreve isso em detalhes. As práticas descritas no whitepaper são aplicáveis ​​à maioria das virtualizações locais do SQL Server.

Aqui estão mais alguns recursos que compilei durante minha pesquisa após o post de Brent:

Terminarei uma captura do RedGate SQL Monitor nas últimas 24 horas. O ponto principal de observação é a utilização da CPU e o número de esperas - durante o horário de pico de ontem, estávamos enfrentando fortes contenções de uso e espera da CPU. Após essa correção simples, melhoramos o desempenho em dez vezes. Até a nossa E / S de disco reduziu significativamente. Essa é uma configuração aparentemente facilmente ignorada que pode melhorar o desempenho virtual em uma ordem de magnitude. Pelo menos, foi ignorado pelos nossos engenheiros e uma completa d'oh momento.

RedGatePerf

Pico de Gallo
fonte
11
+1 Isso realmente completa a resposta de Brent Ozar.
shanky
-1

Além disso, de acordo com o MSDN , o padrão do SQL Server é limitado a 64 GB de RAM. Nós 'resolvemos' isso dividindo o banco de dados em várias instâncias, mas sua situação pode não permitir isso.

Hmm 2016 parece ter 128 GB como limite, mas a divisão de instância ainda pode ser uma opção.

Xiphalon
fonte