DBAtlas · Atlas de operações de banco de dados

Medir o risco de wraparound de transaction ID (idade de XID por banco e tabela)

PostgreSQLManutenção

Comando

-- Per database: distance to autovacuum_freeze_max_age and the ~2^31 limit
SELECT datname,
       age(datfrozenxid) AS xid_age,
       mxid_age(datminmxid) AS mxid_age,
       round(100.0 * age(datfrozenxid) / current_setting('autovacuum_freeze_max_age')::int, 1) AS pct_of_freeze_max_age,
       round(100.0 * age(datfrozenxid) / 2147483647, 1) AS pct_of_wraparound
FROM pg_database
ORDER BY age(datfrozenxid) DESC;

-- Oldest tables in the current database (including TOAST)
SELECT c.oid::regclass AS table_name,
       greatest(age(c.relfrozenxid), age(t.relfrozenxid)) AS xid_age,
       mxid_age(c.relminmxid) AS mxid_age,
       pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size,
       s.last_autovacuum,
       s.last_vacuum
FROM pg_class c
LEFT JOIN pg_class t ON t.oid = c.reltoastrelid
LEFT JOIN pg_stat_all_tables s ON s.relid = c.oid
WHERE c.relkind IN ('r', 'm')
ORDER BY 2 DESC
LIMIT 20;

O que faz

Mostra a idade do XID não congelado mais antigo e de multixact de cada banco em relação ao autovacuum_freeze_max_age e ao limite de wraparound; no banco atual, as tabelas mais antigas (incluindo TOAST) com tamanho e horário do último vacuum.

Quando usar

No monitoramento de rotina (limites típicos: pct_of_wraparound 50% aviso / 75% crítico), quando o log mostra 'must be vacuumed within N transactions' e para priorizar o trabalho de freeze.

Atenção

Para tabelas em que pct_of_freeze_max_age passa de 100, o autovacuum inicia um vacuum obrigatório (anti-wraparound); ele é pesado em I/O e reinicia mesmo se encerrado. Se a idade não cair, a causa é quase sempre algo segurando o xmin horizon (transação longa, prepared transaction, replication slot, hot_standby_feedback); corrija isso primeiro, senão nem o VACUUM FREEZE consegue baixar a idade. Perto do limite o servidor primeiro avisa e depois se recusa a atribuir novos XIDs (gravações) quando restam apenas alguns milhões. Para um freeze direcionado: VACUUM (FREEZE, VERBOSE) <table>;

Abrir no DBAtlas →

Relacionados