Estou utilizando o PostgreSQL (8.4) para armazenar dados produzidos por uma aplicação que faz inserções frequentes (na estrutura da tabela descrita abaixo).
O banco de dados continua crescendo com o tempo e, como os dados mais recentes são mais relevantes do que os dados mais antigos (neste aplicativo específico), excluir as linhas mais antigas é uma solução razoável (com base em lower id
ou old input_datetime
, que é mais ou menos o mesmo) .
Para evitar que problemas relacionados a este banco de dados (o único banco de dados executado neste servidor) afetem o restante do sistema, coloquei o diretório de dados do PostgreSQL em sua própria partição (ext3, em um sistema Linux). No entanto, quando essa partição fica cheia, isso causa vários problemas.
Estou pensando em excluir dados antigos regularmente (por exemplo, por DELETE FROM data_group WHERE id <= ...
meio de um trabalho cron) para lidar com isso.
Em primeiro lugar, meu entendimento VACUUM
(conforme realizado pelo vácuo automático, que está ativado) é que, embora não devolva necessariamente o espaço em disco ao sistema operacional (como VACUUM FULL
faria), ele ainda permite que alguns novos dados sejam inseridos no espaço em disco já utilizado (ou seja, os DELETE
s não afetam necessariamente o tamanho do arquivo, mas ainda liberam espaço nas próprias estruturas de dados do PostgreSQL). Isso está correto? (Percebi que VACUUM FULL
causou alguns problemas com o próprio aplicativo, provavelmente por causa dos bloqueios que ele usa.)
Nesse caso, também parece que SELECT pg_database_size('my_database')
reflete o tamanho usado no disco, o que não necessariamente reflete o que está disponível para inserções posteriores. Existe outra maneira de estimar quanto espaço está disponível para novas inserções?
Além disso, quando é tarde demais e a partição está preenchida em 100%, executar esta DELETE
instrução causa este erro e trava o serviço PostgreSQL:
PANIC: não foi possível gravar no arquivo "pg_xlog/xlogtemp.7810": não há mais espaço no dispositivo
A parada do daemon do PostgreSQL é obviamente um grande problema (e não há outro disco para onde mover o cluster nesta máquina).
Existem estratégias gerais para evitar que esse tipo de problema ocorra (sabendo que o espaço em disco é limitado em uma determinada partição, mas que pode ser aceitável excluir dados mais antigos)? Eu gostaria de automatizar o máximo possível, sem root
ou postgres
(ou intervenção do administrador do PostgreSQL).
CREATE TABLE data_group (
id SERIAL PRIMARY KEY,
name TEXT,
input_datetime TIMESTAMPTZ
);
CREATE TABLE data_item (
id SERIAL PRIMARY KEY,
group_id INTEGER NOT NULL REFERENCES data_group(id) ON DELETE CASCADE ON UPDATE CASCADE,
position INTEGER NOT NULL,
data BYTEA
);
Por um lado, você pode dar uma olhada em uma das minhas respostas anteriores para ver como você pode manter um tamanho de mesa mais ou menos estável. Lá você encontrará uma solução com gatilhos - claro, isso também pode ser resolvido usando um cron job. No último caso, primeiro verificaria se o número da linha excedeu um certo limite e excluiria as linhas mais antigas ou eliminaria uma partição.
Por outro lado, como você já percebeu, é preciso cuidar do espaço em disco onde
pg_xlog
está. Quando fica cheio, não é tão fácil de recuperar... Mas verificando as configurações do seu banco de dados você pode ter uma estimativa justa de quanto espaço você precisa:Se você não tiver configurado a replicação, o máximo é
3 * checkpoint_segments + 1
(vezes 16 MB). Uma configuração típica sem replicação precisará de menos de 10 GB parapg_xlog
, eu acho.