暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

数据库前台进程干脏活引发的执行效率下降问题

白鳝的洞穴 2025-05-23
116
前阵子有个朋友遇到一个PG的应用的性能问题,说是有一条SQL本来执行得挺稳定的,最近开始不稳定了,时快时慢,有时候执行效率相差数倍。他们跟踪了一下发现这个执行SELECT操作的会话居然在写数据,他感到十分不解。一听到他的描述,我就明白了,他遇到了backend刷脏块的问题了。当PG库的脏块产生得比较快,而写IO性能或者效率不是很高的时候,bgwriter每次刷脏块的数量因为受到参数的限制而无法完成所有脏块的写盘,PG的设计者这里故意设计了Backend刷脏块的机制,把这些写IO分散到多个Backend中去,用牺牲Backend少许性能的方式来换取IO系统的负载平稳。好处是在高负载下,数据库整体平稳了,坏处是这些需要刷脏的会话正在执行的SQL性能就会波动。这种情况下,如果内存够用,适当加大shared buffers会缓解这方面的问题。
我把这个机制告诉朋友后,他说为啥要设计这种SB机制,还是Oracle好,不会设计这么奇葩的功能,前台进程就不应该做后台进程干的脏活累活。确实最好的数据库功能分工是前台进程只做SQL应该做的事情,绝大多数维护性的工作都交给后台进程去做,这是确保SQL执行效率稳定的关键。虽然总体设计的原则如此,不过要完全做到并非易事。很多数据库都存在类似的前台进程帮助后台进程干脏活的情况,即使是那位朋友说的那个无所不能的Oracle,也是如此。
差不多二十年前我就遇到过一个运营商十分棘手的问题,有一个月底的统计分析任务突然变慢了很多。从SQL的执行计划和访问的数据表的数据量来说,都没有发生变化,但是明显多跑了好几十分钟,而且月月都是如此。第三个月后,他们忍无可忍,就让我帮忙分析分析。我当是也是一头雾水,看着两份Statspack报告,十分不解。当是的数据库监控手段十分欠缺,除了Statspack报告之外,就找不到其他的可分析的数据了。幸亏当是灵光一现,看到了两份报告中的REDO量的差异,于是经过一番脑补,想到了Delayed Block Cleanup,如果在执行这条SQL之前,相关的表上有一个大型的修改事务,那么那个事务提交之后,数据块上的itl清理工作并非实时进行的,因为如果某个事物在数万个BLOCK上修改了数据,那么这个清理工作耗时很长,会大幅增加提交的延时。Oracle采取的方法是,当清理块数达到一个阈值的时候,就放弃清理,把这些脏活累活留给下回第一次访问这个数据块的倒霉蛋。而我客户的这个统计模块正好成了这个倒霉蛋。经过确认,确实几个小时前扎帐工作结束后会对数据做一个预处理,会修改大量的数据。于是我建议他们上一个任务结束后,增加一个收尾任务,对修改过的这几张大表做一个无用的全表扫描操作。根据我的建议优化后,这个问题真的解决了。
其实在十多年前,遇到类似的事情的朋友很多,十年前我还遇到一个朋友说他遇到了一个SELECT操作引起大量写操作的事情,十分不解,我推测可能也是与延迟块清理有关的。
类似延迟块清理这样的工作还有很多,另外一个在各种数据块中普遍存在的问题是索引维护的问题。我还是以Oracle数据库为例举个例子,以免国产数据库又被吐槽。如果一个会话在INSERT一条不带LOB,行长度不太长的数据的时候,会产生多少物理读?似乎应该很少吧。如果我说看到一条简单的单条INSERT语句产生了200M+的物理读,执行时间超过10秒钟,你可能觉得不可思议,不过这种情况确实存在。如果前台进程要去INSERT一条记录的时候,索引的维护操作也是它顺带做的。如果维护索引的时候,它发现索引页写不下新纪录了,那它就必须做索引页的分裂操作,更不幸的是当索引页分裂的时候,它发现还必须顺带做一下枝节点的分裂,才能写入新的索引页,那么工作量就更大了。更可怕的是,当分裂枝节点的时候,发现B-LEVEL也要调整了,那么就更麻烦了。于是一条原本10毫秒完成的INSERT语句,突然就执行了十几秒了。
前台进程干脏活是避免不了的,但是它们确实会引发应用执行效率的不稳定。如果这些业务是关键的,对延时十分敏感的关键交易(比如股票、期货交易),那么就会产生巨大的负面影响。我们很难预测这种情况发生的时间,也无法通过参数调整来关闭这种特性。因此我们只能从应用层面去解决这些问题。比如对交易延时特别敏感的交易操作,是否通过非数据库的方式去解决,交易提交与数据库落盘解耦。通过HASH分区表,并通过调整PCTFREE等参数,定期REBUILD索引,避免在日交易高峰时候发生B-LEVEL变更。
数据库是超级复杂的,某些理论知识都只能简化了再告诉你,否则你可能就会越学越迷糊。而这些被简化掉的技术特性,往往就是解决百思不得其解的疑难杂症的钥匙。所以遇到数据库的“灵异”问题,还是不要轻易下结论。

文章转载自白鳝的洞穴,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论