Oracle最经典的性能故障案例,都在这里了...

作者:IT邦德
中国DBA联盟(ACDU)成员,10余年DBA工作经验
擅长主流数据Oracle、MySQL、PG、openGauss运维
备份恢复,安装迁移,性能优化、故障应急处理等

可提供技术业务:
1.DB故障处理/疑难杂症远程支援
2.Mysql/PG/Oracle/openGauss
数据库部署及数仓搭建

•••
微信:jem_db
QQ交流群:587159446
公众号:IT邦德

前言

本文给大家分享DBA花式甩锅的日常案例,非常的有趣,该谁的责任,谁承担

1.业务不规范的锅

小美是某国企的一名外包DBA运维人员,很难得抽出周末半天跟男朋友出去吃了一顿海底捞,这不一个紧急电话又打来了核心系统又频繁出现卡顿了,已经连续3个月不间断出现
客户要求要给出解决或者方案,严重影响生产,要给出改善优化方案作为随身携带电脑的小美,开始了远程排查故障.

1.1 故障现象

之前频发发生的索引分裂事件,重建索引后稳定了一段时间后,又开始不稳定了。
从AWR报告中明显能发现leaf node splitis等待事件严重.

1.2 故障分析

当索引块分裂发生时, 负责实施分裂 split 的进程会持有相关的队列锁enqueue TX 锁,
直到该进程完成Split操作才会释放该enqueue Tx,在这个过程中负责split的进程需要找到合适的新块并将对应的数据移动到该新块中。 若在此split过程中,有其他进程INSERT数据到该索引块中,则将进入 enq: TX – index contention等待事件,直到split结束enqueue TX被释放。

1.3 与业务沟通分析

与开发人员沟通的过程中,发现数据库里一个核心表的timekey字段会从sequence里面取,大概定位是这个sequence引起index contention。

1.4 故障甩锅解决

通过AWR/ASH/ADDM,找到了热点表的分区索引。分析发现,这两个索引的列,取值都是从sequence中取的,也就是列值是顺序增长的。知道了原因,就好办了。找到对应的开发人员,咨询该列取值是否可以改为不用sequence,而是采用随机数。经过沟通,开发人员将列的取值直接用sys_guid()函数来产生,修改过后,索引分裂明显降低

2.报表开发的锅

某工厂的一套核心生产系统,24小时的运营模式长达一个月出现性能问题,做为一名DBA和硬件管理员,小张已经被领导PO了10多次,也是憋屈业务方一直抱怨是网络、硬件导致的相关的数据库性能问题而且总是出现的半夜,那么具体的问题是什么呢?小张又是如何找出元凶,甩锅的呢?

2.1 故障现象

本次故障刚开始是由于系统卡顿长达一个月之久,也是近期直接爆发,核心业务系统出站异常,设备报错,消息超时严重,产线停产同时出站并发事务长达3秒,直接造成系统hang住.

2.2 故障分析

以AWR报告看出TP10等待事件在前10位的是什么事件,基本上就可以判断出性能瓶颈在什么地方。通常,在没有问题的数据库中,CPU time总是列在第一个。我们发现出现了gc buffer busy等待事件.

调用ASH报告,通过对SQL执行计划的分析,发现这条诡异的SQL执行计划错了,运行长达1个小时,长时间占有历史表明显执行计划中显示的row跟实际的行数差异巨大

2.3 网络排查

AWR中新引入的后台进程ping会定期测量网络统计信息。它会定期唤醒(大约每5分钟唤醒一次),并测量消息传送和块传送的延迟。在每次唤醒时,它向所有集群节点发送两条消息(分别为500字节和8192字节),计算往返延迟

netstat -s看网路reassembles failed没有较大变化,排查发现DB服务器和心跳交换机的 mtu 值一致延迟正常, 平均ms级,网络一切正常

2.4 故障甩锅解决

本次故障就是因为开发人员写了这一个低效的SQL,加上报表界面时间选择不做限制导致条件筛选谓词越界,执行计划走错,并且OLTP的系统跟报表系统混合使用一套数据库导致的性能问题,这样小张也就成功的甩锅了

那么最终的解决办法就是让报表开发人员改了SQL逻辑,在报表前段对时间筛选做了限定,避免了谓词越界现象

2.5 知识点

谓词越界常见发生在where谓词是时间字段的,总的来说统计信息记录的是一个过旧的时间,而SQL传入的时间是一个最新的时间范围(往往是<time time1<c<time2),
由于统计信息不全,按照CBO计算出来的结果集就很小,
在多表关联的情况下,CBO就会选择认为的最优的关联方式,而实际执行时发现不是那么回事,有大量结果集需要扫描,就会爆发SQL性能问题。

谓词越界就是select的谓词的条件不在统计信息low_value 和 high_value 之间,
在实际选择结果集要大于CBO记录的结果集数量,即实际的selectivity偏大,
这种情况下CBO评估出来的selectivity会出现严重的偏差,导致CBO选错执行计划。

如何避免谓词越界呢?
1.在Oracle中,避免谓词越界通常意味着要确保在使用BETWEEN时不要超出范围,
或者在使用IN、LIKE等操作时不要超出字符长度限制。
2.定期的手动收集统计信息

3.开发人员SQL不规范的锅

3.1 故障现象

下面这个案例说明了隐式数据类型转换导致执行计划错误,
对语句性能产生的严重影响,在对某客户生产库巡检时发现,
其AWR的TOP SQL中遇到了这个问题SQL:

3.2 故障分析

SQL代码非常简单:
SELECT NVL(MAX(DCC_PROC_ID),0)
FROM P_SERV A
WHERE ACC_NBR = :B2 AND SERV_ID <> :B1;

其中ACC_NBR(varchar2类型)和SERV_ID都是选择性很好的字段,两个字段上都有索引,
因为SERV_ID是不等于条件,不能使用索引,那么这个SQL正常情况应该是使用ACC_NBR
字段上的索引才是最佳路径。而且平均执行时间不应该超过1毫秒,实际显示平均执行
时间达到了540毫秒,肯定有问题。
通过收集该SQL相关信息,发现SQL的执行计划有3个:
其中1最好,2和3都与1差了几百倍的性能。
而根据常理,只有执行计划1才是比较正常的性能表现。

3.3 故障处理

经过核对代码,分析发现这段SQL在两个不同的代码段中被调用,一段代码使用了正确的绑定变量类型
(varchar2),而另一段则使用了number类型的绑定变量,这就造成了同一个sql_id,同时存在多个不同执行计划的情况。

研发人员将使用number类型的绑定变量更换成varchar2类型后,SQL就都使用执行计划1了,执行效率大幅提高,CPU使用率也下降很多。

有时遇到这种多个执行计划同时存在的情况(这个情况比较特殊),可能会考虑使用SQL profile来固定执行计划,但是固定的执行计划只对正确使用绑定变量类型的SQL生效,对于不正确绑定变量类型,SQL profile也不起作用。

4.总结

数据库的故障是一个综合分析解决的过程,定位到问题很关键,作为一名DBA要学会找原因,学会甩锅,提出更好的预防措施,这样才能减少客户漫无目的的抱怨,提升自己的技术影响力!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT邦德

客户部署资料,步骤超详细

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值