上线即变龟速的系统

作者简介: 许超,现就职北京海天起点技术服务股份有限公司,ORACLE 6年从业经验,拥有11g ocm,12c ocm,mysql ocp等认证,擅长数据库故障诊断与处理,性能优化等工作,目前服务于电力行业。

问题发生:

今年5月份的某一天,接到业务运维工程师发过来的问题。说是前端业务人员反馈,业务系统突然就变得非常慢,业务不能正常办理,怀疑是数据库出现了问题,让帮忙查看。

这套业务是今年新上的业务,前段时间还处于测试阶段。前段时间接入了部分正式业务,进入上线试运行的阶段。

初步考虑这种情况下sql有问题,表设计有问题的概率非常大。

查找问题:

接到这个问题后我立即要来了数据库主机的密码,登陆查看了一下主机的状况,发现cpu和内存使用比较正常。然后分别在两个数据库节点生成了一份最近时间的awr报告。

结果问题非常明显的暴露出来了,如下是awr的截图:


出现了直接路径读,direct path read方式触发的条件之中就有一条大表的全表扫描,绕过buffer cache,这样的全表扫描就是物理读了。接下来看sql



出现了两个比较有意思的sqlid,一个是select一个是delete均是同一张表,执行速度均是慢的令人发指,并且执行频率却非常之高。

sql是这样的:select a,b from table1 where a=xx and b=xx ;

delete from table1 where xxxxx;

非常之简单的两条sql。

其实到了这里问题已经很明显了,该业务很大一部分前台操作会触发该表的select或者delete操作。检查表结构,和预想的一样,无主键,无索引,大约150w行的数据。

和业务运维工程确认了一下,该表是业务使用的一张临时数据存放表,因为业务需求,会频繁的inset和delete,每次业务请求均产生select。

解决问题:

1对该表增加索引,

2将delete频率降低由业务触发改为定时执行,问题得到解决。

反思问题:

为了有明显的对比,将1周前的awr拿出来对比一下,11g的awr能保存8天,将最早时间的awr报告生成出来:


可以看到当时的测试期间select执行时间是2s,而问题出现时候是20min,相差600倍的速度。

量变引起质变,当业务高峰期到来,业务量增大到一定时候,delete变慢,表变大,表越大,delete越慢,陷入死循环,到达cbo的临界值,从全表扫描多块读,变为了直接路径读。后期处理问题之后加索引之后变成索引等值查询。

我们回过头来总结一下:

问题处理起来非常简单,看起来是个技术上的小问题,只是1条索引就解决了。但是业务在测试的时候却并没有发现,在设计表和写sql的时候也没有注意到这个问题。从而导致了在业务上线后的某一天,业务变成了龟速。技术上的小细节,业务上的大问题,领导眼中的大事件。

其根本原因还是两个老生常谈的问题:1开发人员为实现功能而进行开发,而对于表的设计和sql的雕琢并不到位。2对oracle各个版本的cbo理解并不深刻。每个厂商的数据库,每个版本的数据库在不通业务环境下在处理同一条sql的时候也许后台的算法大相径庭。

未经允许不得转载:Oracle一体机用户组 » 上线即变龟速的系统

相关推荐