
O desempenho ideal do PostgreSQL depende dos parâmetros do sistema operacional definidos corretamente. Os parâmetros do kernel do sistema operacional mal ajustados podem prejudicar o desempenho do servidor de banco de dados. Portanto, é imperativo que esses parâmetros sejam configurados de acordo com o servidor de banco de dados e sua carga de trabalho. Nesta postagem, discutiremos alguns parâmetros importantes do kernel do Linux que podem afetar o desempenho do servidor de banco de dados e como ajustá-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 o System V (SysV), que requer configuração SHMMAX. Após a versão 9.2, o PostgreSQL mudou para a 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, o SHMMAX era o parâmetro mais importante do kernel. O valor SHMMAX é especificado em bytes.
Da mesma forma,
SHMALL é outro parâmetro do kernel usado para determinar
páginas de memória compartilhada em todo o sistema. Use o comando
ipcs para visualizar os valores atuais SHMMAX, SHMALL ou SHMMIN.
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)
O PostgreSQL usa o
System 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ê possui uma versão mais antiga do PostgreSQL e possui um valor SHMMAX muito baixo. Espera-se que os usuários ajustem e aumentem o valor de acordo com a memória compartilhada que eles irão usar.
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 do PostgreSQL usando o comando
initdb .
falha do initdbDETAIL: 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 de pg_ctlDETAIL: 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 MacOS X:
- Linux: kernel.shmmax, kernel.shmall
- MacOS X: kern.sysv.shmmax, kern.sysv.shmall
O comando
sysctl pode ser usado para alterar temporariamente um valor. Para definir valores constantes, adicione uma entrada no
/etc/sysctl.conf . Os detalhes são fornecidos abaixo.
Alterar 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 Parâmetros do Kernel 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
Lembre - se : para tornar as alterações permanentes, adicione esses valores ao /etc/sysctl.confPáginas grandes (páginas grandes)
O Linux usa como padrão páginas 4K, o BSD usa
Super Pages e o Windows usa
Large Pages . Uma página é uma parte da RAM alocada para um processo. Um processo pode ter várias páginas, dependendo dos requisitos de memória. Quanto mais memória um processo precisar, mais páginas ele será alocado. O sistema operacional suporta uma tabela de alocação de página para processos. Quanto menor o tamanho da página, maior a tabela, mais tempo leva para encontrar uma página nessa tabela. Portanto, páginas grandes permitem que você use uma grande quantidade de memória com sobrecarga reduzida; menos visualizações de página, menos erros de página, operações de leitura / gravação mais rápidas em buffers grandes. O resultado é um desempenho aprimorado.
O PostgreSQL suporta apenas páginas grandes no Linux. Por padrão, o Linux usa 4 KB de páginas de memória; portanto, se você tiver muitas operações de memória, deverá instalar páginas maiores. Há um ganho de desempenho ao usar páginas grandes de 2 MB e até 1 GB. Tamanho de página grande pode ser definido no momento da inicialização. Você pode verificar facilmente os parâmetros da página grande e seu uso em seu computador Linux usando o comando
cat / 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 é 0. Isso significa que as páginas grandes estão desativadas.
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 no seu servidor Linux enquanto o PostgreSQL estiver em execução. Verifique se o diretório de dados do PostgreSQL está definido para a variável de ambiente
$ PGDATA .
Obtendo o número de páginas grandes necessárias
A saída do script é a seguinte:
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.
Instale 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).
Informações sobre páginas grandes novamente (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 enormes_páginas "on" como $ PGDATA / postgresql.conf e reinicie o servidor.
E, novamente, 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 são usadas. Vamos agora tentar adicionar alguns dados ao banco de dados.
Algumas operações de banco de dados para reciclar páginas grandes postgres=
Vamos ver se usamos mais páginas grandes agora do que antes.
Mais uma vez informações em 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á em uso.
Nota: o valor aproximado para HugePages usado aqui é muito baixo, o que não é um valor normal para uma máquina em um ambiente de alimentos. Avalie 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. Este parâmetro é usado para controlar o comportamento de troca (troca de páginas para e da memória) no Linux. O valor varia de 0 a 100. Determina quanta memória será descarregada ou descarregada. Zero significa desativar a troca e 100 significa troca agressiva.
Você pode obter um bom desempenho definindo valores mais baixos.
Definir o valor como 0 em kernels mais recentes pode fazer com que o OOM Killer (processo de limpeza de memória do Linux) acabe com o processo. Assim, você pode definir com segurança o valor como 1 se desejar 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 paginação que a RAM, enquanto um valor mais baixo salva 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 recebem memória e liberam quando não são mais necessários. Mas, em alguns casos, o aplicativo ganha muita memória e não a liberta. Isso pode causar um assassino de OOM. Aqui estão os valores possíveis para o parâmetro
vm.overcommit_memory com uma descrição para cada um:
- Supercomprometimento heurístico (padrão); heurística baseada em núcleo
- Permitir confirmação excessiva de qualquer maneira
- Não exagere, não exceda a taxa de supercomprometimento.
Link: https://www.kernel.org/doc/Documentation/vm/overcommit-accountingvm.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 o PostgreSQL. Esse valor maximiza o uso da RAM pelo processo do servidor sem nenhum risco significativo de ser morto pelo processo do OOM killer. O aplicativo poderá reiniciar, mas apenas com gastos excessivos, o que reduz o risco de o OOM killer matar o processo. Portanto, um valor 2 oferece um desempenho melhor que o valor padrão de 0. No entanto, a confiabilidade pode ser melhorada, garantindo que a memória fora do intervalo aceitável não seja sobrecarregada. Isso elimina o risco de que o processo seja morto pelo OOM-killer.
Em sistemas sem paginação, pode ocorrer um problema com vm.overcommit_memory igual a 2.
https://www.postgresql.org/docs/current/static/kernel-resources.html#LINUX-MEMORY-OVERCOMMITvm.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. Redefina para o disco em segundo plano. O valor deste parâmetro varia de 0 a 100; no entanto, um valor abaixo de 5 pode ser ineficiente e alguns kernels não o suportam. 10 é o valor padrão na maioria dos sistemas Linux. Você pode melhorar o desempenho de operações intensivas de gravação a uma taxa mais baixa, o que significa que o Linux lançará páginas sujas em segundo plano.
Você precisa definir o valor de
vm.dirty_background_bytes, dependendo da velocidade do seu disco.
Não há 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 em 25% da velocidade do disco aumentará o desempenho para ~ 25% na maioria dos casos.
vm.dirty_ratio / dirty_bytes
É 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, a fim de evitar o máximo possível de bloqueio do aplicativo. Você pode ajustar a diferença entre essas duas proporções, dependendo da carga de E / S do disco.
Sumário
Você pode configurar outros parâmetros para aumentar a produtividade, mas as melhorias serão mínimas e você não obterá muitos benefícios. Devemos lembrar que nem todos os parâmetros se aplicam a todos os tipos de aplicações. Alguns aplicativos funcionam melhor quando definimos algumas configurações, e outros não. Você deve encontrar o equilíbrio certo entre as configurações desses parâmetros para a carga de trabalho esperada e o tipo de aplicativo e, ao configurar, deve levar em consideração o comportamento do sistema operacional. Configurar parâmetros do kernel não é tão fácil quanto ajustar os parâmetros do banco de dados: é mais difícil dar suas recomendações aqui.