Melhores práticas de desempenho: memória do SQL Server em Linux

Aplica-se a:SQL Server em Linux

Este artigo aborda a configuração de memória para SQL Server em Linux, incluindo mssql-conf limites de memória, definições do grupo de controlo (cgroup), exemplos de memória de contentor Docker e considerações sobre espaço de troca.

Note

Para recomendações de armazenamento, kernel, CPU e rede, consulte as melhores práticas de desempenho: Armazenamento, kernel, CPU e rede para SQL Server em Linux.

Defina um limite de memória usando mssql-conf

Para garantir que há memória física livre suficiente para o sistema operativo Linux, o processo do SQL Server usa apenas 80 por cento da RAM física por defeito. Para alguns sistemas com grandes quantidades de RAM física, 20 por cento pode ser um número significativo. Por exemplo, num sistema com 1 TB de RAM, a definição padrão deixa cerca de 200 GB de RAM por usar. Nessa situação, convém configurar o limite de memória para um valor mais alto.

Pode ajustar este valor usando a mssql-conf ferramenta ou a MSSQL_MEMORY_LIMIT_MB variável ambiente. Para mais informações, consulte a definição memory.memorylimitmb que controla a memória visível para o SQL Server (em unidades de MB). Para orientações detalhadas sobre dimensionamento, consulte Diretrizes para definir limites de memória no Linux e em containers.

Suporte para cgroup (grupo de controlo) v2

O SQL Server deteta e honra as restrições do grupo de controlo (cgroup) v2, começando com o SQL Server 2025 (17.x) e o SQL Server 2022 (16.x) Cumulative Update (CU) 20. Estas restrições proporcionam controlo detalhado no kernel Linux sobre os recursos da CPU e da memória, e melhoram o isolamento de recursos nos ambientes Docker, Kubernetes e OpenShift.

Em versões anteriores, implementações containerizadas em clusters Kubernetes (por exemplo, Azure Kubernetes Service v1.25+) podiam experienciar erros de falta de memória (OOM) porque o SQL Server não aplicava limites de memória definidos nas especificações de contentores. O suporte para cgroup v2 resolve este problema.

Verifique a versão do cgroup

stat -fc %T /sys/fs/cgroup

Os resultados são os seguintes:

Result Description
cgroup2fs Utilizas o cgroup v2
cgroup Utiliza-se o cgroup v1

Mudar para cgroup v2

O caminho mais fácil é escolher uma distribuição que suporte cgroup v2 fora da caixa.

Se precisares de mudar manualmente, adiciona o seguinte parâmetro à tua configuração do GRUB:

systemd.unified_cgroup_hierarchy=1

Depois atualiza o GRUB. Por exemplo, no Ubuntu, executa:

sudo update-grub

No Red Hat Enterprise Linux (RHEL), execute:

sudo grub2-mkconfig -o /boot/grub2/grub.cfg

Relatórios de limites de CPU com cgroup v2

Quando configuras limites de CPU usando o cgroup v2, o SQL Server não mostra a contagem de núcleos de CPU configurada no registo de erros. Em vez disso, continua a reportar o número total de CPUs anfitriãs.

Para alinhar os planos de agendar e de consulta do SQL Server (por exemplo, decisões de paralelismo) com a contagem de CPUs pretendida definida no cgroup v2, aplique a seguinte configuração.

Configurar afinidade de processador

Define explicitamente a afinidade do processador SQL Server para corresponder à quota de execução do cgroup. No exemplo seguinte, a quota cgroup é de quatro CPUs num host de oito núcleos:

ALTER SERVER CONFIGURATION
SET PROCESS AFFINITY CPU = 0 TO 3;

Esta configuração garante que o SQL Server cria agendadores apenas para o número pretendido de CPUs. Para mais informações, consulte ALTER SERVER CONFIGURATION e Utilize PROCESS AFFINITY para nodos e/ou CPUs.

Ative o indicador de rastreamento 8002 para utilizar afinidade suave na camada SQLPAL:

sudo /opt/mssql/bin/mssql-conf traceflag 8002 on

Por padrão, os escalonadores estão associados a CPUs específicas definidas na máscara de afinidade. O trace flag 8002 permite que os escalonadores se movam entre CPUs, o que geralmente melhora o desempenho enquanto respeita as restrições de afinidade e cgroup. Para obter mais informações, consulte DBCC TRACEON - Trace Flags.

Reinicie o SQL Server depois de ativar a bandeira de rastreamento.

Comportamento esperado

Após o reinício:

  • O SQL Server cria apenas o número de agendadores definidos pela definição de afinidade (por exemplo, quatro agendadores).

  • O kernel Linux continua a impor a quota de execução de CPU cgroup v2.

  • As decisões de otimização de consultas e paralelismo baseiam-se no número de CPUs pretendido, em vez do total de CPUs do host.

Note

O registo de erros do SQL Server pode continuar a mostrar a contagem total de CPUs do anfitrião. Este comportamento de registo e exibição não afeta o uso real da CPU, a criação do escalonador ou a aplicação da CPU pelo cgroup v2 ou pela afinidade do processador.

Para obter mais informações, consulte os seguintes recursos:

Diretrizes para definir limites de memória no Linux e em contentores

O SQL Server em Linux tem múltiplos controlos de memória que operam em diferentes níveis. A tabela e o diagrama seguintes mostram como cada nível reduz a memória disponível, desde a RAM do anfitrião até ao pool de buffers.

Nível Definido por Description
Host Configuração de hardware / VM RAM física no servidor ou máquina virtual (VM).
Limite de grupo (docker run --memory, systemd, ou manual) Tempo de execução, systemd fatia ou configuração manual cgroup do contentor Limite máximo imposto pelo kernel (memory.max) para todos os processos em cgroup. Opcional no Linux bare metal.
Processo do SQL Server (memorylimitmb / MSSQL_MEMORY_LIMIT_MB) mssql-conf ou a variável de ambiente Memória total em todos os componentes do SQL Server. Deve ser inferior ao limite cgroup (caso exista) ou à memória do anfitrião.
Conjunto de buffers (max_server_memory) sp_configure A memória cache das páginas de dados de 8 KB. Deve ser inferior a memorylimitmb.
Headroom Calculado (intervalo entre limites) A diferença entre o limite cgroup (ou memória do anfitrião) e memorylimitmb, reservada para a sobrecarga do sistema operativo e processos auxiliares.

Diagrama que mostra camadas de controlo de memória aninhadas.

Ao definir limites de memória para SQL Server no Linux, considere as seguintes diretrizes:

  • Em implementações de contentores, use-se cgroup para limitar a memória total disponível para o contentor. Esta definição estabelece o limite superior para todos os processos dentro do contentor.

  • O limite de memória (seja definido por memorylimitmb ou pela MSSQL_MEMORY_LIMIT_MB variável de ambiente) controla a memória total que o SQL Server no Linux pode alocar em todos os seus componentes, como o buffer pool, SQLPAL, SQL Server Agent, LibOS, PolyBase, Full-Text Search e qualquer outro processo carregado no SQL Server no Linux.

  • A variável de ambiente MSSQL_MEMORY_LIMIT_MB tem precedência sobre a definida em memorylimitmbmssql.conf.

  • memorylimitmb não pode exceder a memória física real do sistema anfitrião.

  • Define memorylimitmb abaixo a memória do sistema anfitrião e o cgroup limite (se existir), para garantir que há memória física livre suficiente para o sistema operativo Linux. Se não definires memorylimitmbexplicitamente , o SQL Server usa 80 por cento do valor menor entre a memória total do sistema e o cgroup limite (se existir).

  • A opção de configuração max_server_memory servidor limita apenas o tamanho do buffer pool do SQL Server e não regula o uso total de memória do SQL Server no Linux. Defina sempre este valor por baixo de memorylimitmb para garantir que permanece memória suficiente para os outros componentes descritos no tópico anterior.

Margem entre o SQL Server e os limites de memória do contentor

Ao executar o SQL Server num contentor com um limite de memória configurado (por exemplo, a definição cgroupmemory.max), mantenha uma margem entre memory.memorylimitmb e o limite de memória do contentor. Esta margem assegura a capacidade necessária para o funcionamento do sistema operativo e dos processos auxiliares no interior do contentor.

  • Para a maioria das implementações, reserve entre 10 e 20 por cento da memória contentor para o sistema operativo e processos não-SQL Server, e defina memory.memorylimitmb abaixo da capacidade restante.

  • Para configurações de memória grande, um buffer baseado em percentagem pode reservar mais memória do que o necessário. Por exemplo, 10 por cento de um contentor de 256 GB equivale a cerca de 25 GB, o que é razoável para a sobrecarga do sistema operativo. No entanto, 10 por cento de um contentor de 512 GB corresponde a cerca de 51 GB, o que provavelmente é mais do que o sistema operativo exige. Nestes casos, use um buffer fixo, dimensionado adequadamente à carga de trabalho e sobrecarga do sistema operativo, e aloque o restante ao SQL Server.

  • Ajuste o buffer com base nas características da carga de trabalho, outros serviços a correr no contentor e a configuração do host.

Note

Não existe um valor recomendado de altura para a cabeça que se aplica a todos os ambientes. Valide as definições de memória através de testes para garantir a estabilidade do sistema sob carga máxima.

Evite configurar limites de memória superiores à memória disponível

Não configure memory.memorylimitmb valores superiores à memória física disponível no host nem superiores ao limite de memória imposta pelo contenteur. Se o fizer, o SQL Server pode consumir memória de forma agressiva, deixando capacidade insuficiente para o sistema operativo e os processos de suporte. Esta configuração pode resultar em:

  • Aumento da pressão de memória.
  • Redução da estabilidade do sistema e interrupções inesperadas de serviço.
  • O sistema operativo termina o sqlservr processo devido a condições de falta de memória (OOM).

Configure os limites de memória do SQL Server abaixo da memória efetiva disponível para o anfitrião ou contentor, e deixe espaço de buffer adequado para o sistema operativo e os serviços de execução.

Exemplos de configuração de memória Docker

A docker run --memory opção define o cgroup limite de memória para o contentor. Este limite é o teto rígido imposto pelo kernel para todos os processos no contentor. MSSQL_MEMORY_LIMIT_MB(ou memory.memorylimitmb) controla quanta dessa memória o SQL Server pode usar. Como descrito nas diretrizes anteriores, defina MSSQL_MEMORY_LIMIT_MB sempre abaixo do limite de memória do contentor para deixar margem para o sistema operativo e processos auxiliares.

Os exemplos seguintes utilizam um host com 16 GB de RAM. Ajusta os valores para o teu ambiente.

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
   -e "MSSQL_MEMORY_LIMIT_MB=14336" \
   -p 1433:1433 \
   -d mcr.microsoft.com/mssql/server:2022-latest

Sem --memory, o contentor não tem cgroup teto. MSSQL_MEMORY_LIMIT_MB restringe o SQL Server, mas outros processos dentro do contentor ainda podem consumir memória do anfitrião sem limites.

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
   -e "MSSQL_MEMORY_LIMIT_MB=12288" \
   --memory 12g \
   -p 1433:1433 \
   -d mcr.microsoft.com/mssql/server:2022-latest

Ambos os limites são definidos para 12 GB (--memory 12g = 12.288 MB). Não resta margem para sobrecarga do sistema operativo ou processos auxiliares, o que pode levar a eliminações por OOM.

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
   -e "MSSQL_MEMORY_LIMIT_MB=14336" \
   --memory 12g \
   -p 1433:1433 \
   -d mcr.microsoft.com/mssql/server:2022-latest

MSSQL_MEMORY_LIMIT_MB (14 GB) ultrapassa o limite de contentores (12 GB). Este cenário conduz às condições de OOM descritas em Evitar configurar limites de memória superiores à memória disponível.

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=<password>" \
   -e "MSSQL_MEMORY_LIMIT_MB=10240" \
   --memory 12g \
   -p 1433:1433 \
   -d mcr.microsoft.com/mssql/server:2022-latest

O contentor está limitado a 12 GB (--memory 12g), e o SQL Server está configurado para usar até 10 GB (MSSQL_MEMORY_LIMIT_MB=10240). Os restantes 2 GB (cerca de 17 por cento) fornecem margem para o sistema operativo e outros processos.

Considerações sobre o espaço de troca

Quando executa o SQL Server num contentor, ative o espaço de swap ao nível do host para ajudar a proteger o sistema operativo e os processos que não são do SQL Server. No entanto, configure o SQL Server para operar dentro dos seus limites de memória configurados e não dependa do swap durante o funcionamento normal.

  • Siga as diretrizes do limite de memória para garantir que o SQL Server opera dentro da memória física ou do limite de memória aplicávelcgroup.

  • Se o swap estiver ativado, trate-o como uma rede de segurança para pressão de memória transitória no host, e não como capacidade para cargas de trabalho do SQL Server em estado permanente.

Importante

O desempenho do SQL Server pode degradar-se significativamente se a pressão de memória causar trocas. O dimensionamento adequado da memória é o principal mecanismo para prevenir falhas relacionadas com a memória.