PostgreSQL的MVCC实现机制是采用数据块中生成多个副本的方式的,这种机制被很多DBA和架构师认为是PostgreSQL数据库在大型高负载系统中的一个巨大的缺陷。实际上不只是PostgreSQL采用了多副本行元来实现MVCC,目前比较热门的基于LSM-Tree存储引擎的数据库系统(比如阿里的Oceanbase,PingCAP的TiDB)也采用了这种方式。LSM-Tree需要通过Compare And Merge这种开销更大的方式来进行老元组的合并重组,而PostgreSQL使用Vacuum机制来进行数据整理。
可能很多朋友都认为Vacuum的开销很大,对数据库表的性能影响也很大,甚至在出现过Vacuum影响业务系统之后,关闭了AutoVacuum。在PostgreSQL 9之前,Vacuum的算法确实对高负载数据库的影响很大,甚至那时候笔者认为PostgreSQL的MVCC的缺陷会影响PostgreSQL在企业级应用中的使用。不过随着这些年PostgreSQL数据库的快速发展,每个版本对Vacuum的算法都有了极大的改善,在目前硬件性能极大提升与PostgreSQL Vacuum的算法的优化双重作用下,目前Vacuum对高负载数据库的影响也越来越低了。
可能还有一些朋友可以举出一些反例,说我们的数据库因为Vacuum而导致数据库性能出现严重问题了。确实可能会出现这样的反例,不过如果仔细分析一下,通过对PostgreSQL数据库的性能优化,这些反例中遇到的问题大多数都是可以解决的。
前阵子我在网上看到过一个某互联网汽车租赁公司的案例,他们的PostgreSQL数据库的AutoVacuum出现了严重的性能问题,租车订单表每天要消耗几百万个xid,而每天的autovacuum只能回收其中70%的xid,这意味着一个十分严重的问题,xid wraps的问题。当系统运行一段时间之后,就