Eu tenho um banco de dados Postgres(9.1) de 14,7 TB que precisa suportar gravações pesadas por longos períodos de tempo. Eu sei que preciso gerenciar de perto meus IDs de transação para evitar o bloqueio do banco de dados. Recentemente, notei que as consultas estavam diminuindo e vi que havia vários autovacuums em execução em nossas enormes tabelas somente leitura, com o subscrito "(para evitar quebra automática)". Parei o software em execução e executei um vacuumdb -F -a
comando. No entanto, quando executo select current_query from pg_stat_activity
, vejo que os processos de autovacuum ainda estão em execução, mesmo durante um vácuo manual. Eu tentei matar os autovacuums select pg_cancel_backend(pid)
e eles morreram, mas imediatamente reiniciei novamente. Minhas perguntas:
- O autovacuum deve continuar a ser executado durante um vácuo manual de db?
- Como faço para efetivamente parar esses processos de autovacuum?
- Por que esses autovacuums continuariam sendo executados em uma tabela somente leitura? O que há para aspirar?
O Autovacuum é acionado pelas estatísticas da tabela na mesa, e enquanto seu manual
VACUUM (FREEZE)
não for feito, eles não serão atualizados. É por isso que os processos de autovacuum anti-wraparound ainda serão iniciados.Mas isso não é um grande problema: apenas um
VACUUM
pode ser executado em uma mesa a qualquer momento. Agora, os trabalhadores de autovacuum anti-wraparound não desistirão quando bloquearem outro processo, nesse caso, seu manualVACUUM
. Mas se você matar os trabalhadores de autovacuum anti-wraparound, seu manualVACUUM
obtém o bloqueio e agora é o trabalhador de autovacuum anti-wraparound reiniciado que está bloqueado. Olhepg_locks
para verificar se eles estão aguardando um bloqueio (granted = FALSE
).Agora seus
vacuumdb
processos são uma tabela após a outra, então você deve estar pronto para matar os trabalhadores de autovacuum assim que ele começar a processar a próxima tabela e for bloqueado por um novo trabalhador de autovacuum lá.Pode ser mais fácil iniciar manualmente
VACUUM
nessas grandes tabelas somente leitura em vez de usarvacuumdb
, porque assim você pode controlar quando qual tabela será limpa.Certifique-se de definir
maintenance_work_mem
alto para acelerarVACUUM
. Você também deve definirautovacuum_vacuum_cost_delay
para 2ms ou menos nessas tabelas grandes, para que futuras execuções de autovacuum sejam feitas mais rapidamente.Para reduzir a dor no futuro, abaixe
autovacuum_freeze_max_age
substancialmente as tabelas afetadas. Então o próximo vácuo anti-envoltório entrará em ação mais cedo e será feito mais rapidamente.O melhor de tudo, atualize para a v13 o mais rápido possível, porque a partir dessa versão as tabelas somente de inserção também receberão execuções regulares de vácuo, o que deve acabar com o problema.