故障描述
2023 年 2 月 3 日早上 10 点 19 分客户打电话找到工程师反应 pacs 数据库系统十分卡顿,事后通过告警日志在 9 点 39 分告警平台已经报警 cpu 使用率已经达到 99% 趋近饱和:


查询数据库当时的运行情况,发现有大量的latch 等待:

这个等待事件 SQL 语句有可能产生非常严重的latch:cache buffers chains 等待,因为每次要访问一个block ,就需要获得该latch ,由于有大量的逻辑读(buffer get) ,那么就增加了latch:cache buffers chains 争用的机率。对于正在运行的SQL 语句,产生非常严重的latch:cache buffers chains 争用。
问题详细诊断过程
工程师第一时间响应,并找出了当时问题时间段的相关 AWR ,并找到了问题语句和相关的应用程序以及客户端机器:


工程师在晚上八点多到达现场后,第一时间展开排查,收集了个2023 年2 月3 日晚八点到八点五十五分的AWR 报告,发现问题sql 和早上发现的问题sql 一致,截取了一段中间的嵌套查询sql 如下:
SELECT patseq, medicalrecordid, patid, patname, patsex, patbirthday, telephoneno, address, inpatientid, outpatientid FROM t_patient p WHERE 1=1 AND p.recorddt >='2019-02-03 20:14:43' AND p.recorddt <='2023-02-03 20:14:43' AND ( p.medicalrecordid = '13699541')
这条sql 没处理前,走的是recorddt 这个列的索引,很慢要几十秒,使用hint medicalrecordid 这个列的索引后,仅需一秒就能完成查询,经过诊断排查后给出两个解决方案。
解决办法和建议
解决办法:
1、 在相关的问题 sql 上加一个 hint 语法,来让 sql 查询走正确的索引执行计划。
2、 删除recorddt 列的索引,让执行计划用medicalrecordid 的索引来检索数据。
建议:
1、 开启统计信息的自动收集,并多关注统计信息是否有过期。
2、 建立索引要在经过充分测试的基础上,确认没有问题后在应用在生产环境上,否则不适当的索引不仅达不到优化的效果,反而会带来更严重的现象。
3、 建议对没有进行绑定变量而又频繁执行查询的语句做绑定变量,这也能一定程度上减轻数据库的负载压力。
