Uma das partes mais úteis da documentação do
PostgreSQL em que trabalhei é Tuning Your PostgreSQL
Server. Quando isso foi escrito no verão de 2008, alguns meses após o
lançamento do PostgreSQL 8.3, era difícil encontrar qualquer guia semelhante que
fosse (relativamente) conciso e atual. Desde então, eu e muitos outros contribuidores do PostgreSQL ajudamos a manter esse documento atualizado
à medida que as alterações no PostgreSQL eram feitas.
A tendência interessante e útil
durante esse período é que os parâmetros continuam desaparecendo do conjunto
daqueles com os quais você precisa se preocupar. No PostgreSQL 8.2, havia uma longa
lista de parâmetros que você provavelmente precisava ajustar para um bom desempenho
em um servidor PostgreSQL:shared_buffers, Effective_cache_size,
checkpoint_segments, autovacuum, max_fsm_pages,
default_statistics_target, work_mem, wal_buffers e (se estiver usando
particionamento) constraint_exclusion.
8.3 tornou o autovacuum padrão para ser
ligado com comportamento razoável, além de remover alguns
parâmetros de gravação em segundo plano que não causavam nada além de problemas (eles
nunca chegaram à lista). 8.4 removeu a necessidade dos dois parâmetros
max_fsm_*, aumentou default_statistics_target para um valor inicial
muito melhor e tornou a configuração constraint_exclusion
desnecessária nos casos mais comuns. São seis parâmetros a menos
que você provavelmente precisará ajustar.
Infelizmente a versão 9.0 só tornou
a configuração do servidor mais complicada. E os kernels Linux mais recentes até
empurraram o comportamento padrão para trás. A partir do kernel Linux
2.6.33, o valor padrão escolhido para wal_sync_method mudou para
open_datasync. Isso acaba tendo implicações terríveis
de desempenho para o PostgreSQL, principalmente quando combinado com a configuração padrão baixa
para wal_buffers no servidor.
Mas a marcha em direção a um comportamento melhor
foi retomada recentemente para o que está planejado para ser
PostgreSQL 9.1. Durante o último CommitFest, um patch que originou o Marti
Raudsepp para corrigir o problema wal_sync_method foi confirmado
após algumas discussões pesadas sobre a forma que essa mudança deveria tomar.
Descobrir que essa mudança de comportamento quebrou completamente o PostgreSQL
ao executar em ext4 com a opção “data=journal” ajudou
a resolver a coisa certa a fazer aqui por padrão.
Dois parâmetros que eu não recomendo
tocar na maioria dos casos são commit_siblings e commit_delay,
artefatos de uma tentativa mais antiga de melhorar o desempenho em sistemas com
tempos de confirmação lentos (o que inclui a maioria dos sistemas que não têm um
cache de gravação com bateria para acelerar essa área). Hoje em dia
desligar o parâmetro synchronous_commit introduzido na versão 8.3
é muito mais provável que ajude aqui. Embora seja improvável que eles melhorem
desempenho, as pessoas que tentam defini-los sofreram mais do que
necessário com as desvantagens dessa decisão. O comportamento do pior caso
aqui foi melhorado consideravelmente em um patch que escrevi para otimizar a execução da lógica que esses parâmetros controlam.
E esta semana o último parâmetro a
ser efetivamente eliminado na maioria dos casos é wal_buffers. Uma mudança
sugeri foi feita para definir isso automaticamente como uma porcentagem do tamanho (cerca de 3%)
alocado para os parâmetros shared_buffers normalmente muito maiores.
Isso define o valor de wal_buffers para o limite superior normal de seu
intervalo efetivo, 16 MB, uma vez que você tenha alocado pelo menos 512 MB para
shared_buffers. E se você aumentou shared_buffers de seu pequeno
padrão, você obterá uma melhoria correspondente neste
importante parâmetro de desempenho de commit. Você terá que se esforçar
para quebrar a configuração desse parâmetro para atingir as
situações ruins possíveis em versões anteriores.
Ter a quantidade de configuração que você
precisa fazer para o servidor por padrão ficar menos complicado é sempre
vale a pena, e ver os parâmetros desaparecerem da lista crítica é
uma mudança bem-vinda. Qual é o próximo? Os principais problemas com alocação de
memória compartilhada em sistemas operacionais derivados do UNIX, particularmente Linux,
tornam muito difícil eliminar shared_buffers. E as preocupações
sobre o servidor assumir o controle do sistema limitam completamente a capacidade
de definir automaticamente parâmetros como work_mem para o intervalo certo.
Algumas propostas para gerenciar melhor o pool de memória de trabalho foram
sugeriu, para que se pudesse ver alguma melhora.
O próximo parâmetro que estou de olho é
checkpoint_segments. Depois de adicionar apenas logs extras nesta área no
último CommitFest, há algumas melhorias nesta área aproximando
commit now para realmente melhorar o comportamento do checkpoint. Espero
eventualmente mudar o ajuste do ponto de verificação para ser estritamente controlado
através de parâmetros orientados ao tempo, em vez de exigir que os usuários
compreendam a mecânica de como o log write-ahead funciona para ajustar o
sistema. Ainda há muitas situações feias possíveis aqui para fazer
isso a tempo para 9.1, mas definir a contagem de segmentos automaticamente é
viável para segmentar para 9.2.