事务ID回卷预防
PostgreSQL事务ID回卷预防:XID机制、FREEZE、autovacuum_freeze_max_age与紧急处理
1. 事务ID机制
PostgreSQL 事务ID(XID)是 32 位无符号整数,范围 (约21亿)。
2. 回卷问题
当 XID 达到最大值后回卷到 0,导致旧事务看起来像是未来事务,数据变得不可见。
XID 顺序:... → 2^31-2 → 2^31-1 → 0 → 1 → 2 → ...
↑ 回卷点
3. FREEZE 机制
-- VACUUM FREEZE 将旧行的 xmin 标记为 FrozenTransactionId
-- 冻结后的行对所有事务可见,不再依赖 XID 比较
-- 手动冻结
VACUUM FREEZE employees;
-- 自动冻结阈值
ALTER SYSTEM SET autovacuum_freeze_max_age = 200000000; -- 2亿
-- 当 age(relfrozenxid) 超过此值,autovacuum 自动 FREEZE
4. 紧急处理
-- 查看接近回卷的数据库
SELECT datname, age(datfrozenxid) AS xid_age
FROM pg_database
ORDER BY xid_age DESC;
-- 如果 age 接近 autovacuum_freeze_max_age,需要紧急 VACUUM FREEZE
VACUUM FREEZE;
-- 最坏情况:数据库进入只读模式
-- 必须执行 VACUUM FREEZE 恢复
5. 监控
-- 查看各表的 XID 年龄
SELECT relname, age(relfrozenxid) AS xid_age,
pg_size_pretty(pg_total_relation_size(oid)) AS size
FROM pg_class
WHERE relkind IN ('r', 'm')
ORDER BY xid_age DESC;
-- 设置告警
-- 当 age(relfrozenxid) > autovacuum_freeze_max_age * 0.8 时告警