作者:IT邦德 中国DBA联盟(ACDU)成员,10余年DBA工作经验 擅长主流数据Oracle、MySQL、PG、openGauss运维 备份恢复,安装迁移,性能优化、故障应急处理等 可提供技术业务: 1.DB故障处理/疑难杂症远程支援 2.Mysql/PG/Oracle/openGauss 数据库部署及数仓搭建 ••• 微信:jem_db QQ交流群:587159446 公众号:IT邦德
本文给大家分享DBA花式甩锅的日常案例,非常的有趣,该谁的责任,谁承担
小美是某国企的一名外包DBA运维人员,很难得抽出周末半天 跟男朋友出去吃了一顿海底捞,这不一个紧急电话又打来了 核心系统又频繁出现卡顿了,已经连续3个月不间断出现 客户要求要给出解决或者方案,严重影响生产,要给出改善优化方案 作为随身携带电脑的小美,开始了远程排查故障

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

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

与开发人员沟通的过程中,发现数据库里一个核心力水表的timekey 字段会从sequence里面取,大概定位是这个sequence引起index contention。
过AWR/ASH/ADDM,找到了热点表的分区索引。 分析发现,这两个索引的列,取值都是从sequence中取的, 也就是列值是顺序增长的。 知道了原因,就好办了。找到对应的开发人员, 咨询该列取值是否可以改为不用sequence, 而是采用随机数。 经过沟通,开发人员将列的取值直接用sys_guid()函数来产生, 修改过后,索引分裂明显降低

某工厂的一套核心生产系统,24小时的运营模式 长达一个月出现性能问题,做为一名DBA和硬件管理员, 小张已经被领导PO了10多次,也是憋屈 业务方一直抱怨是网络、硬件导致的相关的数据库性能问题 而且总是出现的半夜,那么具体的问题是什么呢? 小张又是如何找出元凶,甩锅的呢?
本次故障刚开始是由于系统卡顿长达一个月之久, 也是近期直接爆发,核心业务系统出站异常, 设备报错,消息超时严重,产线停产 同时出站并发事务长达3秒,直接造成系统hang住

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


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

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

netstat -s看网路reassembles failed没有较大变化, 排查发现DB服务器和心跳交换机的 mtu 值一致 延迟正常, 平均ms级,网络一切正常
本次故障就是因为开发人员写了这一个低效的SQL, 加上报表界面时间选择不做限制导致条件筛选谓词越界,执行计划走错 并且OLTP的系统跟报表系统混合使用一套数据库 导致的性能问题,这样小张也就成功的甩锅了 那么最终的解决办法就是让报表开发人员改了SQL逻辑, 在报表前段对时间筛选做了限定,避免了谓词越界现象

谓词越界常见发生在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.定期的手动收集统计信息
下面这个案例说明了隐式数据类型转换导致执行计划错误, 对语句性能产生的严重影响,在对某客户生产库巡检时发现, 其AWR的TOP SQL中遇到了这个问题SQL:

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才是比较正常的性能表现。

经过核对代码,分析发现这段SQL在两个不同的代码段中被调用,一段代码使用了正确的绑定变量类型
(varchar2),而另一段则使用了number类型的绑定变量,这就造成了同一个sql_id,同时存在多个不同执行计划的情况。
研发人员将使用number类型的绑定变量更换成varchar2类型后,SQL就都使用执行计划1了,执行效率大幅提高,CPU使用率也下降很多。
有时遇到这种多个执行计划同时存在的情况(这个情况比较特殊),可能会考虑使用SQL profile来固定执行计划,但是固定的执行计划只对正确使用绑定变量类型的SQL生效,对于不正确绑定变量类型,SQL profile也不起作用。
数据库的故障是一个综合分析解决的过程,定位到问题很关键,作为一名DBA要学会找原因,学会甩锅,提出更好的预防措施,这样才能减少客户漫无目的的抱怨,提升自己的技术影响力!
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69947868/viewspace-3013228/ ,如需转载,请注明出处,否则将追究法律责任。