Configurando o PostgreSQL para desempenho de gravação

30

Um dos meus servidores PostgreSQL hospeda vários (1-3) bancos de dados que recebem um fluxo constante de dados. Os dados não são particularmente estruturados, equivalem ao tempo atual e a uma variedade de dados observados para esse instante em particular. A taxa de dados é bastante alta; funciona cerca de um gigabyte por dia para um banco de dados, cerca de um décimo disso para outro. Não espero que essa taxa aumente. O desempenho da leitura é uma prioridade muito menor e atualmente é aceitável.

Nos logs, tenho esta mensagem:

LOG:  checkpoints are occurring too frequently (15 seconds apart)
HINT:  Consider increasing the configuration parameter "checkpoint_segments".

Atualmente, este valor está definido como 16, o que é cortesia pgtune.

Quais são as configurações que devo considerar para melhorar o desempenho da gravação? Eu preferiria manter o máximo de segurança possível. Considerando o volume de dados recebidos, eu poderia aceitar perder alguns dados recentes em uma falha, desde que a maior parte dos dados estivesse intacta.

Edit: Estou usando o PostgreSQL 9.0 por enquanto, mas pretendo atualizar para a 9.1. Não estou publicando os detalhes do hardware porque, embora reconheça sua importância, em última análise, precisarei fazer essa otimização em várias máquinas com hardware muito diversificado. Se o hardware for essencial para a resposta, forneça as informações gerais para que eu possa aplicar a resposta a máquinas com diferentes configurações de hardware.

Daniel Lyons
fonte
Você pode postar sua versão e, de preferência, alguns detalhes sobre o seu hardware de armazenamento?
Jack Douglas
Você aumentou checkpoint_segmentsconforme recomendado? O que aconteceu?
a_horse_with_no_name
3
Outro excelente recurso para esse tipo de pergunta é o livro PostgreSQL 9.0 High Performance, de Gregory Smith .
jp

Respostas:

24

1 Gigabyte por dia não é tão alto quanto uma carga de gravação. Espalhado ao longo do dia, chega a cerca de 50kbytes por segundo. Um pen drive USB lento pode lidar com isso. Eu estou assumindo que é mais estourado embora. Como sugere um a_horse_with_no_name, aumente os segmentos do ponto de verificação. 100 ou mais não é fora do comum.

Em seguida, aumente checkpoint_timeoutpara 1 hora e tente aumentar checkpoint_completion_targetpara algo mais próximo de 1,0 (100%). O objetivo de conclusão informa ao PostgreSQL a forma agressiva de gravar em segundo plano, para que seja x% concluído antes de executar um ponto de verificação, o que força todos os dados a serem gravados ao mesmo tempo no WAL e atrasa o sistema a rastrear enquanto está acontecendo.

O motivo pelo qual você normalmente não o define como 100% é que é bastante comum gravar no mesmo bloco mais de uma vez e, ao atrasar as gravações do WAL na loja principal, você evita que o mesmo bloco seja gravado duas vezes sem motivo.

Se é improvável que você esteja gravando no mesmo bloco mais de uma vez antes que o tempo limite ocorra, ou seja, tudo o que você faz é inserir e configurá-lo bem alto faz sentido elevá-lo para 0,9 ou mais. O pior que pode acontecer é que você escreva um pouco mais frequentemente do que o necessário, mas o impacto nos pontos de verificação será bastante reduzido.

Scott Marlowe
fonte
Na verdade, o volume de gravação é quase completamente uniforme: esse é o repositório de dados do software de monitoramento de hardware que pesquisa a cada segundo, continuamente, 24x7. Eu poderia calcular a taxa de dados exata, mas ela flutua um pouco à medida que os programadores adicionam e removem pontos do monitor.
Daniel Daniel Lyons
11
Bem, se a taxa é de 1G por dia e é suave, quase todos os subsistemas podem lidar com a carga de gravação, você só quer mantê-la suave, que o destino de conclusão do ponto de verificação está sendo definido como próximo a 1,0 e um tempo limite longo do ponto de verificação deve levá-lo.
Scott Marlowe
10

Em um sistema muito "pesado de gravação", é provável que você seja limitado pela taxa em que o WAL pode ser gravado durante o pico de atividade.

Se você realmente pode "aceitar perder alguns dados recentes em uma falha", pode desativar a confirmação síncrona que:

pode ser uma alternativa útil quando o desempenho é mais importante do que a certeza exata sobre a durabilidade de uma transação

Se você puder alterar seu hardware, considere qualquer um destes para otimizar gravações:

  • RAID10 sobre RAID5
  • Muitos eixos (pode significar 2,5 "em vez de 3,5", por exemplo)
  • SAS sobre SATA
  • 15K mais de 10K unidades
  • SSD

--editar

Com base no seu comentário na excelente resposta de @ Scott : "O volume de gravação é quase completamente uniforme" e a taxa de dados implícita de "50kbytes por segundo", duvido que você precise fazer qualquer coisa que arrisque a perda de dados. Talvez ajude a saber o que alguns de seus outros parâmetros de configuração estão definidos.

Jack Douglas
fonte
3
Se o desempenho da gravação for importante, um controlador com bateria entre o SO e os discos rígidos giratórios pode fazer uma enorme diferença.
9788 Scott Marlowe
5

Você também pode verificar a frequência / tamanho de seus commit: recentemente, deparei-me com um problema no qual estava tentando atualizar> 1 milhão de registros em uma única transação. Recebi mensagens de log semelhantes às descritas pelo OP, mas a transação não pôde ser concluída mesmo depois de várias horas. Quando dividi a gravação em várias transações menores (aproximadamente 10.000 registros), o tempo total necessário caiu para cerca de 15 minutos.

O que eu acho que aconteceu foi que o Postgres passou tanto tempo escrevendo os logs que o checkpoint_timeout decorreu antes que pudesse fazer um progresso substancial ao salvar os registros. Não tenho certeza se essa explicação se mantém. Ainda recebo os avisos, mas todas as gravações acabam sendo processadas. No entanto, eu precisava (e encontrei) uma solução programática em vez de uma que exigisse reconfiguração do banco de dados.

Veja também http://www.postgresql.org/docs/9.3/static/wal-configuration.html

Sarah Messer
fonte