IT 邦德

PostgreSQL里藏着一个会自己长大的文件,90%的DBA都忽略了

运维PostgreSQL数据库时,你是不是也曾遇到过这样的情况——明明数据量没怎么增长,但磁盘空间却在不断被侵蚀?排查了表、索引、日志,却依然找不到“元凶”?

Image

今天我们要揭开的,就是一个被大多数DBA忽略的“隐藏文件”。它安静地躺在数据目录中,悄无声息地持续增长,甚至可能在某个深夜,突然撑爆你的磁盘。

1.这个文件是谁?

它就是 pg_xact 目录(旧版本中叫 pg_clog)中的事务提交日志文件。

PostgreSQL使用这些文件来记录事务的提交状态。每当有事务提交或回滚,相关信息就会被记录在这里。虽然每个事务只占很小的空间,但在高并发的长期运行实例中,这些文件会逐渐积累,并且不会自动清理。

2.为什么被忽略?

位置隐蔽:位于数据目录下的 pg_xact,并非日常巡检的高频路径;

增长缓慢:不像数据表那样快速增长,容易被忽视;

文档提及少:官方文档中没有特别强调其维护需求。

3.潜在风险

磁盘空间耗尽:长时间不清理,可能占用数十GB空间;

性能影响:过多的提交日志可能轻微影响某些查询性能;

备份膨胀:增加完整备份的大小和耗时。

4.暴涨的元凶

1.长时间未结束的事务(如 idle in transaction 或 长时间运行的查询),这些事务会阻止 VACUUM清理比它更新的事务状态数据,导致相关的事务状态文件无法被回收。

2.失效或积压的逻辑复制槽,逻辑复制槽如果变为非活动状态或应用速度过慢,为了防止复制中断,PostgreSQL 会保留所有未被副本确认的事务日志(包括 WAL 和相关的 pg_xact数据),可能导致 pg_xact数据堆积。

3.未正确处理的预备事务(Prepared Transactions),如果一个两阶段提交的预备事务既未提交也未回滚,它会一直占用资源,并可能阻止 VACUUM清理。

4.激进的 VACUUM FREEZE,为防止事务ID回卷(Wraparound)而触发的 aggressive vacuum 会冻结旧事务的元组。此过程虽然会清理非常旧的 pg_xact文件,但本身是I/O密集型操作,在业务高峰期可能影响性能。

5.孤立的临时表,如果创建临时表的会话异常终止,可能导致临时表无法被正常清理,这些表的事务信息也可能阻碍清理进程。

Image

当pg_database.datfrozenxid更新时,PostgreSQL会尝试删除不必要的阻塞文件,请注意,相应的堵塞页面也会被删除。

5.运维建议

实际上,PostgreSQL会在自动清理进程(autovacuum) 运行时,清理不再需要的提交日志。

1.将 pg_xact 目录大小纳入日常监控指标

2.定期检查长事务:

SELECT * FROM pg_stat_activity WHERE backend_xid IS NOT NULL;

3.确保autovacuum配置合理并正常运行

对于大版本升级,可通过逻辑复制或pg_upgrade来间接清理历史积累

结语

数据库运维无小事。这个“会自己长大”的文件虽然不起眼,却可能在关键时刻给你“惊喜”。好的DBA不仅要关注表和索引,更要了解数据库的每一个角落。