PostgreSQL通过MVCC实现多版本并发控制,每次更新会保留旧版本元组,导致表膨胀。事务使用XID和命令ID跟踪可见性,快照隔离决定数据可见性。VACUUM清理死元组,但受事务地平线限制,长事务会阻止清理。子事务和HOT链影响清理效率,需定期维护以避免性能下降。
本文讨论了PostgreSQL中的VACUUM过程,包括堆扫描、索引清理和堆清理三个阶段。VACUUM通过清理死元组和更新可见性图来回收空间,提高数据库性能。文章还强调了VACUUM与VACUUM FULL的区别,后者用于压缩文件大小。
PostgreSQL的锁机制可能导致阻塞和死锁。文章讨论了五种常见的锁行为,包括ACCESS EXCLUSIVE锁的排队、外键约束引发的隐性死锁、唯一约束检查导致的死锁、自动清理的特殊行为以及VACUUM的隐藏ACCESS EXCLUSIVE阶段。建议通过设置锁超时和监控活动来减轻这些问题。
Autovacuum's most powerful tuning lever: the scale factor that determines when dead tuples trigger a vacuum. On large tables, the 20% default waits too long.
PostgreSQL 18 finally fixes the autovacuum formula that left billion-row tables waiting for 200M dead tuples.
PostgreSQL 13 added insert-triggered autovacuum to solve a critical problem: append-only tables never vacuumed, breaking index-only scans and delaying tuple…
Three autovacuum parameters control how often PostgreSQL vacuums, how hard it works, and how long it pauses.
PostgreSQL的多版本并发控制(MVCC)允许读者和写者并行操作而不互相阻塞。每个元组包含两个事务ID(t_xmin和t_xmax),用于确定可见性。更新操作创建新版本并标记旧版本,VACUUM负责清理无效元组,但长时间运行的事务可能会阻止清理,导致空间浪费。不同的隔离级别影响快照的捕获时机,从而影响查询结果。
PostgreSQL中的表膨胀是由于UPDATE或DELETE操作产生的“死元组”未被VACUUM回收,导致数据文件增大。造成膨胀的原因包括长时间运行的事务、未提交的准备事务、启用hot_standby_feedback的备用服务器查询和逻辑复制延迟。解决方法是终止阻止VACUUM的事务或查询。
许多开发者误以为运行VACUUM可以保持PostgreSQL数据库健康,但VACUUM只能删除死元组,无法重组B树索引,导致索引膨胀。处理堆膨胀适合使用VACUUM,而索引膨胀则需手动使用REINDEX。应监控索引状态,及时处理膨胀问题。
PostgreSQL中的“数据库不接受命令”错误通常与事务ID环绕有关。解决方法包括处理旧的准备事务、结束长时间运行的事务、删除过期的复制槽,并执行VACUUM命令。避免使用单用户模式和VACUUM FULL,以减少停机时间,并确保自动清理配置正确,以防未来问题。
我从杜塞尔多夫机场出发前往pgday.at,因技术问题延误,但最终顺利抵达维也纳。在会议上,我意外成为演讲者,分享了现代PostgreSQL VACUUM的内容。活动精彩,结识了许多社区成员,最后在博物馆度过了愉快的早晨。
在PGConf.DE会议前,我参加了汉堡的Debian MiniDebConf,随后前往柏林。会议吸引了340名与会者,讨论了PostgreSQL的VACUUM演变、现代SSL和高可用性策略等主题,促进了社区交流。尽管回程遇到交通堵塞,但整体经历丰富而有意义。
I am (slowly) adding handy PostgreSQL queries to my GitHub, and Vacuum is the newest category. The end goal is to have a compilation of queries for those of us who need to keep an instance...
PostgreSQL通过多版本并发控制(MVCC)实现ACID属性,确保读取和写入操作不互相阻塞。MVCC利用事务ID创建数据快照,支持已提交读、可重复读和可串行化三种隔离级别。VACUUM过程负责清理逻辑删除的行,以维护数据库性能。
缺乏索引是PostgreSQL查询缓慢的主要原因,可能导致全表扫描。通过在相关列上创建索引、定期执行VACUUM清理无效数据、优化查询结构和选择合适的索引类型,可以显著提升查询性能。
2025年2月14日,Nathan Bossart提交补丁,增加了VACUUM/ANALYZE(VERBOSE)和自动清理日志的延迟时间信息,更新了pg_stat_progress_vacuum和pg_stat_progress_analyze视图,并在VACUUM和ANALYZE的输出中显示。
2025年2月11日,Nathan Bossart提交补丁,向pg_stat_progress_vacuum和pg_stat_progress_analyze视图添加了基于成本的延迟时间。新增参数track_cost_delay_timing用于收集信息,显示vacuum因成本延迟而睡眠的时间,增强了进度监控的细节。
PostgreSQL中的错误“found xmin ... from before relfrozenxid ...”表示数据损坏。表的xmin与relfrozenxid需一致,否则VACUUM操作会失败,可能导致数据丢失。解决方法包括导出恢复表、手动更新relfrozenxid或使用pg_surgery扩展。
PostgreSQL 12引入了VACUUM命令的INDEX_CLEANUP选项,但不建议使用。该选项会导致无法清理索引中的死元组,影响查询性能,虽然可以加快速度,但会导致表和索引膨胀。除非紧急情况,否则应避免使用。
完成下面两步后,将自动完成登录并继续当前操作。