Otimizando o PostgreSQL para dados transitórios


8

Eu tenho várias tabelas com 100-300 colunas de tipos inteiros cada, que contêm dados altamente voláteis. Os conjuntos de dados são codificados por uma ou duas chaves primárias e, quando ocorre a atualização, o conjunto de dados inteiro é excluído e novos dados são inseridos em uma transação. O tamanho do conjunto de dados geralmente é de algumas centenas de linhas, mas pode atingir vários milhares de linhas em casos extremos. A atualização ocorre uma vez por segundo e as atualizações do conjunto de dados para chaves diferentes geralmente são desarticuladas, portanto, não é possível soltar e recriar a tabela.

Como ajusto o Postgres para lidar com essa carga? Posso usar a versão mais recente e melhor se isso fizer alguma diferença.

Respostas:


7

Dependendo de quantos conjuntos de dados diferentes existem, uma opção seria particionar as tabelas por conjunto de dados.

Quando um conjunto de dados é atualizado, BEGINuma nova transação, TRUNCATEa tabela, COPYos novos dados nele e COMMIT. O PostgreSQL possui uma otimização na qual COPYuma tabela que foi TRUNCATEd na mesma transação faz muito menos E / S se você estiver usando wal_level = minimal(o padrão).

Se você não puder particionar e truncar (por exemplo, se estiver lidando com dezenas ou centenas de milhares de conjuntos de dados, onde haveria muitas tabelas), será melhor acionar o autovacuum para executar o máximo possível , verifique se você possui bons índices em tudo o que excluir com base e esteja preparado para um desempenho um tanto comum.

Se você não precisa de segurança contra falhas - você não se importa que suas tabelas estejam vazias após uma falha no sistema - você também pode criar suas tabelas como UNLOGGED, o que economizará uma enorme quantidade de custo de E / S.

Se você não se importa em restaurar toda a configuração de um backup após uma falha no sistema, pode ir além e também definir fsync=off, o que basicamente diz ao PostgreSQL "não se preocupe com a segurança de falhas, eu tenho bons backups e não não me importo se meus dados são permanentemente e totalmente irrecuperáveis ​​após uma falha e estou feliz em voltar initdbantes de poder usar meu banco de dados novamente ".

Escrevi um pouco mais sobre isso em um tópico semelhante no Stack Overflow sobre a otimização do PostgreSQL para testes rápidos ; que menciona o ajuste do SO do host, separando o WAL em um disco diferente, se você não estiver usando unloggedtabelas, ajustes no indicador de verificação, etc.

Há também algumas informações nos documentos da página para carregamento rápido de dados e configurações não duráveis .


Obrigado pela dica da partição, nunca pensei em usá-los nesse caso. Quanto às tabelas não registradas - você quer dizer que elas acabam vazias por padrão após a falha do sistema? Não faz diferença, só estou curioso.
— Alex Tokarev

11
@AlexTokarev Isso mesmo; depois que o PostgreSQL é encerrado de maneira não limpa (postmaster ou um back-end segfaults, ciclos de energia do sistema repentinamente, back-end é SIGKILLeditado, etc.), qualquer UNLOGGEDtabela pode ser TRUNCATEd, então ela está vazia na inicialização. Eles não são truncados após um desligamento e uma reinicialização limpos, mas você não deve confiar neles como duráveis.
— Craig Ringer

Obrigada pelo esclarecimento. Não preciso de segurança de dados para as tabelas em questão, os dados neles são transitórios e são atualizados da fonte a cada segundo. Desativar o fsync não é uma opção, pois existem outras tabelas mais tradicionais no mesmo esquema que precisam ser seguras e recuperáveis. Ter a UNLOGGEDopção por mesa é simplesmente ótimo.
— Alex Tokarev

Estou analisando o documento de particionamento e parece que poderia ser uma solução (quase) perfeita para o problema. Porém, uma pergunta: se eu vou ter uma tabela pai para tabelas de esquema e filho para armazenar os dados, vou consultar os dados da tabela pai, certo? Se uma tabela filho para esse intervalo existir, a consulta retornará, caso contrário, retornará um conjunto de dados vazio. Nesse caso, posso até eliminar e recriar tabelas filho para cada lote de dados novo. Dadas as circunstâncias, o que será mais eficaz, TRUNCATEou DROP/CREATE TABLEsequência?
— AlexKarevev

@AlexTokarev Eu recomendo que você TRUNCATE, pessoalmente. A rotatividade de DDL tem seus próprios custos. Como você faz alterações com tanta frequência, será muito importante garantir que você ative a agressividade do autovacuum pg_catalog.pg_classe outras tabelas do sistema que possam inchar com essa carga de trabalho.
— Craig Ringer
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.