Configurando opções do kernel Linux para otimizar o PostgreSQL

Configurando opções do kernel Linux para otimizar o PostgreSQL O desempenho ideal do PostgreSQL depende de parâmetros do sistema operacional definidos corretamente. Configurações de kernel do sistema operacional mal configuradas podem resultar em desempenho insatisfatório do servidor de banco de dados. Portanto, é imprescindível que essas configurações sejam configuradas de acordo com o servidor de banco de dados e sua carga de trabalho. Nesta postagem, discutiremos alguns parâmetros importantes do kernel Linux que podem afetar o desempenho do servidor de banco de dados e como configurá-los.

SHMMAX / SHMALL

SHMMAX é um parâmetro do kernel usado para determinar o tamanho máximo de um único segmento de memória compartilhada que um processo Linux pode alocar. Antes da versão 9.2, o PostgreSQL usava System V (SysV), que requer a configuração SHMMAX. Após a versão 9.2, o PostgreSQL mudou para memória compartilhada POSIX. Portanto, agora são necessários menos bytes de memória compartilhada do System V.

Antes da versão 9.3, SHMMAX era o parâmetro mais importante do kernel. O valor SHMMAX é especificado em bytes.

Similarmente PEQUENO é outro parâmetro do kernel usado para determinar
volume de páginas de memória compartilhada em todo o sistema. Para visualizar os valores atuais de SHMMAX, SHMALL ou SHMMIN, use o comando ipcs.

Detalhes do SHM* - Linux

$ ipcs -lm

------ Shared Memory Limits --------
max number of segments = 4096
max seg size (kbytes) = 1073741824
max total shared memory (kbytes) = 17179869184
min seg size (bytes) = 1

Detalhes do SHM* - MacOS X

$ ipcs -M
IPC status from  as of Thu Aug 16 22:20:35 PKT 2018
shminfo:
	shmmax: 16777216	(max shared memory segment size)
	shmmin:       1	(min shared memory segment size)
	shmmni:      32	(max number of shared memory identifiers)
	shmseg:       8	(max shared memory segments per process)
	shmall:    1024	(max amount of shared memory in pages)

PostgreSQL usa Sistema V IPC para alocar memória compartilhada. Este parâmetro é um dos parâmetros mais importantes do kernel. Sempre que você receber as seguintes mensagens de erro, significa que você tem uma versão mais antiga do PostgreSQL e seu valor SHMMAX está muito baixo. Espera-se que os usuários ajustem e aumentem o valor de acordo com a memória compartilhada que pretendem utilizar.

Possíveis erros de configuração incorreta

Se o SHMMAX não estiver configurado corretamente, você poderá receber um erro ao tentar inicializar um cluster PostgreSQL usando o comando banco de dados de inicialização.

Falha no initdb
DETAIL: Failed system call was shmget(key=1, size=2072576, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter. 
You can either reduce the request size or reconfigure the kernel with larger SHMMAX. To reduce the request size (currently 2072576 bytes),
reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration. child process exited with exit code 1

Da mesma forma, você pode receber um erro ao iniciar o servidor PostgreSQL usando o comando pg_ctl.

Falha em pg_ctl
DETAIL: Failed system call was shmget(key=5432001, size=14385152, 03600).

HINT: This error usually means that PostgreSQL's request for a shared memory segment exceeded your kernel's SHMMAX parameter.

You can either reduce the request size or reconfigure the kernel with larger SHMMAX.; To reduce the request size (currently 14385152 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.

If the request size is already small, it's possible that it is less than your kernel's SHMMIN parameter,
in which case raising the request size or reconfiguring SHMMIN is called for.

The PostgreSQL documentation contains more information about shared memory configuration.

Compreendendo as diferenças nas definições

A definição dos parâmetros SHMMAX/SHMALL é um pouco diferente no Linux e no MacOS X:

  • Linux: kernel.shmmax, kernel.shmall
  • MacOS X: kern.sysv.shmmax, kern.sysv.shmall

Equipe sysctl pode ser usado para alterar temporariamente o valor. Para definir valores constantes, adicione uma entrada a /etc/sysctl.conf. Os detalhes estão abaixo.

Alterando as configurações do kernel no MacOS X

# Get the value of SHMMAX
sudo sysctl kern.sysv.shmmax
kern.sysv.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kern.sysv.shmall 
kern.sysv.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kern.sysv.shmmax=16777216
kern.sysv.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kern.sysv.shmall=16777216
kern.sysv.shmall: 4096 -> 16777216

Alterando os parâmetros do kernel no Linux

# Get the value of SHMMAX
sudo sysctl kernel.shmmax
kernel.shmmax: 4096

# Get the value of SHMALL
sudo sysctl kernel.shmall
kernel.shmall: 4096

# Set the value of SHMMAX
sudo sysctl -w kernel.shmmax=16777216
kernel.shmmax: 4096 -> 16777216

# Set the value of SHMALL 
sudo sysctl -w kernel.shmall=16777216
kernel.shmall: 4096 -> 16777216

Não se esqueça: Para tornar as alterações permanentes, adicione esses valores a /etc/sysctl.conf

Páginas enormes

O Linux usa páginas de memória de 4 KB por padrão, o BSD usa páginas de memória de XNUMX KB. Super Pagese no Windows - Páginas grandes. Uma página é um pedaço de RAM alocado para um processo. Um processo pode ter múltiplas páginas dependendo dos requisitos de memória. Quanto mais memória um processo requer, mais páginas ele é alocada. O sistema operacional mantém uma tabela de alocação de páginas para processos. Quanto menor o tamanho da página, maior a tabela e mais tempo leva para encontrar uma página nessa tabela de páginas. Portanto, páginas grandes permitem que grandes quantidades de memória sejam usadas com sobrecarga reduzida; menos visualizações de página, menos falhas de página, operações de leitura/gravação mais rápidas em buffers maiores. O resultado é um melhor desempenho.

PostgreSQL suporta apenas páginas grandes no Linux. Por padrão, o Linux usa páginas de memória de 4 KB, portanto, nos casos em que há muitas operações de memória, é necessário definir páginas maiores. Ganhos de desempenho são observados ao utilizar páginas grandes de 2 MB e até 1 GB. O tamanho grande da página pode ser definido durante a inicialização. Você pode verificar facilmente os parâmetros de páginas grandes e seu uso em sua máquina Linux usando o comando gato /proc/meminfo | grep -i enorme.

Obtendo informações sobre páginas grandes (somente Linux)

Note: This is only for Linux, for other OS this operation is ignored$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

Neste exemplo, embora o tamanho da página grande esteja definido como 2048 (2 MB), o número total de páginas grandes está definido como 0. Isso significa que as páginas grandes estão desabilitadas.

Script para determinar o número de páginas grandes

Este script simples retorna o número necessário de páginas grandes. Execute o script em seu servidor Linux enquanto o PostgreSQL estiver em execução. Certifique-se de que para a variável de ambiente $PGDATA O diretório de dados PostgreSQL é especificado.

Obtendo o número de páginas grandes necessárias

#!/bin/bash
pid=`head -1 $PGDATA/postmaster.pid`
echo "Pid:            $pid"
peak=`grep ^VmPeak /proc/$pid/status | awk '{ print $2 }'`
echo "VmPeak:            $peak kB"
hps=`grep ^Hugepagesize /proc/meminfo | awk '{ print $2 }'`
echo "Hugepagesize:   $hps kB"
hp=$((peak/hps))
echo Set Huge Pages:     $hp

A saída do script é semelhante a esta:

Saída de script

Pid:            12737
VmPeak:         180932 kB
Hugepagesize:   2048 kB
Set Huge Pages: 88

O valor recomendado para páginas grandes é 88, portanto você deve defini-lo como 88.

Instalando páginas grandes

sysctl -w vm.nr_hugepages=88

Verifique páginas grandes agora, você verá que páginas grandes não são usadas (HugePages_Free = HugePages_Total).

Páginas grandes revisitadas (somente Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       88
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

Agora defina o parâmetro Huge_pages como "on" em $PGDATA/postgresql.conf e reinicie o servidor.

Mais uma vez, informações sobre páginas grandes (somente Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       81
HugePages_Rsvd:       64
HugePages_Surp:        0
Hugepagesize:       2048 kB

Agora você pode ver que poucas páginas grandes estão sendo usadas. Vamos agora tentar adicionar alguns dados ao banco de dados.

Algumas operações de banco de dados para reciclar páginas grandes

postgres=# CREATE TABLE foo(a INTEGER);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(generate_Series(1,10000000));
INSERT 0 10000000

Vamos ver se estamos usando mais páginas grandes agora do que antes.

Mais informações sobre páginas grandes (somente Linux)

$ cat /proc/meminfo | grep -i huge
AnonHugePages:         0 kB
ShmemHugePages:        0 kB
HugePages_Total:      88
HugePages_Free:       18
HugePages_Rsvd:        1
HugePages_Surp:        0
Hugepagesize:       2048 kB

Agora você pode ver que a maioria das páginas grandes está sendo usada.

Nota: O valor estimado para HugePages usado aqui é muito baixo, o que não é um valor normal para uma máquina executando um ambiente de produto. Estime o número necessário de páginas para o seu sistema e defina-as de acordo com a carga e os recursos.

vm.swappiness

vm.swappiness é outro parâmetro do kernel que pode afetar o desempenho do banco de dados. Esta opção é usada para controlar o comportamento de troca (troca de páginas dentro e fora da memória) no Linux. O valor varia de 0 a 100. Determina quanta memória será paginada ou paginada. Zero significa nenhuma troca e 100 significa troca agressiva.

Você pode obter um bom desempenho definindo valores mais baixos.

Definir como 0 em kernels mais recentes pode fazer com que o OOM Killer (processo de limpeza de memória do Linux) interrompa o processo. Portanto, é seguro defini-lo como 1 se quiser minimizar a troca. O valor padrão no Linux é 60. Um valor mais alto faz com que a MMU (unidade de gerenciamento de memória) use mais espaço de troca do que a RAM, enquanto um valor mais baixo mantém mais dados/código na memória.

Um valor mais baixo é uma boa aposta para melhorar o desempenho no PostgreSQL.

vm.overcommit_memory / vm.overcommit_ratio

Os aplicativos adquirem memória e a liberam quando ela não é mais necessária. Mas, em alguns casos, o aplicativo ocupa muita memória e não a libera. Isso pode causar um assassino OOM. Aqui estão os possíveis valores dos parâmetros vm.overcommit_memory com uma descrição para cada um:

  1. Supercomprometimento heurístico (padrão); heurística baseada em kernel
  2. Permitir supercomprometimento de qualquer maneira
  3. Não exagere, não exceda a taxa de supercomprometimento.

Ссылка: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

vm.overcommit_ratio — porcentagem de RAM disponível para sobrecarga. Um valor de 50% em um sistema com 2 GB de RAM pode alocar até 3 GB de RAM.

Um valor 2 para vm.overcommit_memory fornece melhor desempenho para PostgreSQL. Esse valor maximiza o uso de RAM do processo do servidor sem qualquer risco significativo de ser eliminado pelo processo eliminador do OOM. O aplicativo poderá recarregar, mas apenas dentro dos limites de saturação, o que reduz o risco de um assassino OOM interromper o processo. Portanto, um valor 2 oferece melhor desempenho do que o valor padrão 0. No entanto, a confiabilidade pode ser melhorada garantindo que a memória fora da faixa não fique sobrecarregada. Isso elimina o risco de o processo ser eliminado por um assassino OOM.

Em sistemas sem swap, pode ocorrer problema com vm.overcommit_memory igual a 2.

https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMIT

vm.dirty_background_ratio / vm.dirty_background_bytes

vm.dirty_background_ratio é a porcentagem de memória preenchida com páginas sujas que precisam ser gravadas no disco. A liberação para o disco ocorre em segundo plano. O valor deste parâmetro varia de 0 a 100; entretanto, um valor abaixo de 5 pode ser ineficaz e alguns kernels não suportam isso. 10 é o padrão na maioria dos sistemas Linux. Você pode melhorar o desempenho de operações com uso intensivo de gravação por um fator menor, o que significa que o Linux liberará páginas sujas em segundo plano.

Você precisa definir o valor vm.dirty_background_bytes dependendo da velocidade da sua unidade.

Não existem valores “bons” para esses dois parâmetros, pois ambos dependem do hardware. No entanto, definir vm.dirty_background_ratio como 5 e vm.dirty_background_bytes como 25% da velocidade do disco melhora o desempenho para aproximadamente 25% na maioria dos casos.

vm.dirty_ratio/dirty_bytes

Este é o mesmo que vm.dirty_background_ratio/dirty_background_bytes, exceto que a redefinição é realizada em uma sessão de trabalho, bloqueando o aplicativo. Portanto vm.dirty_ratio deve ser maior que vm.dirty_background_ratio. Isso garante que os processos em segundo plano sejam iniciados mais cedo para evitar ao máximo o bloqueio do aplicativo. Você pode ajustar a diferença entre essas duas proporções dependendo da carga de E/S do disco.

Total

Você pode ajustar outras configurações para melhorar o desempenho, mas as melhorias serão mínimas e você não verá muitos benefícios. Devemos lembrar que nem todas as opções se aplicam a todos os tipos de aplicações. Alguns aplicativos funcionam melhor quando ajustamos algumas configurações, outros não. Você deve encontrar o equilíbrio certo entre definir essas configurações para a carga de trabalho e o tipo de aplicativo esperados e também deve considerar o comportamento do sistema operacional ao ajustar. Configurar parâmetros do kernel não é tão fácil quanto configurar parâmetros de banco de dados; é mais difícil fazer recomendações.

Fonte: habr.com

Adicionar um comentário