暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

MVCC缺陷与高负载PostgreSQL数据库优化要点

白鳝的洞穴 2021-07-01
1403
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的问题。当系统运行一段时间之后,就必须进行停库维护,通过vacuum来完成xid的完全回收,从而防止未回收xid达到20亿这个可能导致数据库停库的问题出现。当时客户已经在讨论是不是要通过更换数据库来彻底解决这个问题了,不过后来的一次数据库优化让这个系统摆脱了xid wraps困境。
整个优化工作也十分简单。仅仅是一些Postgresql参数的调整:

序号

参数

调整值

1

autovacuum_work_mem

2GB

2

autovacuum_vacuum_cost_limit

2000/最终调整为3000

(对于使用SSD盘的环境,缺省的200太保守了)

3

maintenance_work_mem

1GB

4

work_mem

16MB

5

autovacuum_max_workers

5

通过上面的参数调整后,每天可回收的xid超过了5亿,xid wraps问题得到了彻底的解决。
实际上我们遇到的很多PostgreSQL的问题主要是因为我们对PostgreSQL数据库的认知的不足,从而导致我们遇到问题后不知道该如何去解决。不过PostgreSQL的MVCC带来的负面问题也并不是总能够通过调整数据库参数来解决的。事实上,有些应用对数据库的随意使用是导致很多较为难以解决的数据库性能问题的最主要的原因。记得十多年前帮一个运营商解决的buffer busy waits导致的性能问题,最终也是把那张update十分频繁的花费余额表改造成内存数据库才得以彻底的解决。如果那个场景用PostgreSQL来实现,哪怕是十多年后的硬件环境下,因为MVCC实现技术方面的缺陷,恐怕PG数据库依然是搞不定的。
所以说虽然我们能够通过数据库优化的手段去解决大部分的PostgreSQL数据库的问题,我们还需要应用开发者了解数据库存在的一些缺陷,从而在应用架构设计以及应用开发时能够尽可能规避PostgreSQL的一些缺陷,让应用系统运行的更好。
文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论