排行
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
中国数据库
向量数据库
时序数据库
实时数据库
搜索引擎
空间数据库
图数据库
数据仓库
大调查
2021年报告
2022年报告
年度数据库
2020年openGauss
2021年TiDB
2022年PolarDB
2023年OceanBase
首页
资讯
活动
大会
学习
课程中心
推荐优质内容、热门课程
学习路径
预设学习计划、达成学习目标
知识图谱
综合了解技术体系知识点
课程库
快速筛选、搜索相关课程
视频学习
专业视频分享技术知识
电子文档
快速搜索阅览技术文档
文档
问答
服务
智能助手小墨
关于数据库相关的问题,您都可以问我
数据库巡检平台
脚本采集百余项,在线智能分析总结
SQLRUN
在线数据库即时SQL运行平台
数据库实训平台
实操环境、开箱即用、一键连接
数据库管理服务
汇聚顶级数据库专家,具备多数据库运维能力
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
我的订单
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
资讯
活动
大会
课程
文档
排行
问答
我的订单
首页
专家团队
智能助手
在线工具
SQLRUN
在线数据库即时SQL运行平台
数据库在线实训平台
实操环境、开箱即用、一键连接
AWR分析
上传AWR报告,查看分析结果
SQL格式化
快速格式化绝大多数SQL语句
SQL审核
审核编写规范,提升执行效率
PLSQL解密
解密超4000字符的PL/SQL语句
OraC函数
查询Oracle C 函数的详细描述
智能助手小墨
关于数据库相关的问题,您都可以问我
精选案例
新闻资讯
云市场
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
专家团队
智能助手
精选案例
新闻资讯
云市场
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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
领墨值
有奖问卷
意见反馈
客服小墨