Oracle AWR找出元凶,一个诡异SQL把核心系统干翻车了...

📢📢📢📣📣📣

哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验

一位上进心十足的【大数据领域博主】!😜😜😜

中国DBA联盟(ACDU)成员,目前服务于工业互联网

擅长主流Oracle、MySQL、PG、高斯及Greenplum运维开发,备份恢复,安装迁移,性能优化、故障应急处理等。

✨ 如果有对【数据库】感兴趣的【小可爱】,欢迎关注【IT邦德】💞💞💞

❤️❤️❤️感谢各位大可爱小可爱!❤️❤️❤️

文章目录

    • [📣 1.故障现象](#📣 1.故障现象)
    • [📣 2.故障分析](#📣 2.故障分析)
      • [✨ 2.1 AWR报告分析](#✨ 2.1 AWR报告分析)
      • [✨ 2.2 ASH分析](#✨ 2.2 ASH分析)
      • [✨ 2.3 SQL Statistics](#✨ 2.3 SQL Statistics)
      • [✨ 2.4 网络排查](#✨ 2.4 网络排查)
    • [📣 3.解决方案](#📣 3.解决方案)
      • [✨ 3.1 LOAD_BALANCE为OFF](#✨ 3.1 LOAD_BALANCE为OFF)
      • [✨ 3.2 减少分区数据量](#✨ 3.2 减少分区数据量)
      • [✨ 3.3 避免谓词越界](#✨ 3.3 避免谓词越界)
    • [📣 4.结论与建议](#📣 4.结论与建议)
    • [📣 5.总结](#📣 5.总结)

Oracle 性能优化就是通过合理安排资源、调整系统参数使Oracle 运行更快、更节省资源,本案例详细分析了一次性能差导致的系统Down的过程

📣 1.故障现象

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

📣 2.故障分析

✨ 2.1 AWR报告分析

以看出TP10等待事件在前10位的是什么事件,基本上就可以判断出性能瓶颈在什么地方。

通常,在没有问题的数据库中,CPU time总是列在第一个。

我们发现出现了gc buffer busy等待事件

gc buffer busy acquire说明:

session1尝试请求访问远程实例(remote instance)buffer,

但是在session1之前已经有相同实例上

另外一个session2请求访问了相同的buffer,

并且没有完成,那么session#1等待gc buffer busy acquire。
gc buffer busy release说明:

session1之前已经有远程实例的session#2请求访问了相同的buffer,

并且没有完成,

那么session1等待gc buffer busy release。

从Load Profile来看Executes:每秒SQL执行次数达2000多次,并发很大

Segments by Buffer Busy Waits显示并发最大的历史表存在index争用,index最右边的块存在分裂。索引分裂集中在两个分区索引上

✨ 2.2 ASH分析

ASH报告是Oracle数据库中的一种性能诊断工具,全称为Active Session History(活动会话历史记录),它用于临时保存系统当前的性能诊断信息

通过对活动会话跟踪发现,gc current bock busy阻塞 gc buffer busy release

实例1和实例2都存在相同的SQLID 25gcvqkbjt7jd,一直在争用

✨ 2.3 SQL Statistics

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

✨ 2.4 网络排查

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

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

📣 3.解决方案

✨ 3.1 LOAD_BALANCE为OFF

应用连接数据库的配置方式 LOAD_BALANCE为OFF

RAC_LS =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = rac1-vip)(PORT = 1521))

(ADDRESS = (PROTOCOL = TCP)(HOST = rac2-vip)(PORT = 1521))

(LOAD_BALANCE = OFF)

(CONNECT_DATA =

(SERVER = DEDICATED)

(SERVICE_NAME = rac_service)

)

)
LOAD_BALANCE=YES 表示的负载均衡,这个是客户端的负载均衡,就是随机的进行连接分配.同一数据在不同数据库实例上被请求访问。如果应用程序可以实现,那么我们建议不同的应用功能/模块数据分布在不同的数据库实例上被访问,避免同一数据被多个实例交叉访问,可以减少buffer的争用,避免gc等待.

✨ 3.2 减少分区数据量

分区进行停机SPLIT,减少当前分区数据

通过对当前分区拆分,减少当前分区数据,减少热块竞争
ALTER TABLE sales

SPLIT PARTITION sales_q4_2020 AT (TO_DATE('01/01/2021', 'DD/MM/YYYY'))

INTO (PARTITION sales_q4_2020_pre_split VALUES LESS THAN (TO_DATE('01/01/2021', 'DD/MM/YYYY')),

PARTITION sales_q1_2021 VALUES LESS THAN (TO_DATE('01/04/2021', 'DD/MM/YYYY')));

✨ 3.3 避免谓词越界

谓词越界常见发生在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.定期的手动收集统计信息

📣 4.结论与建议

  • 热点块(hot block)
    在AWR中Segments by Global CacheBuffer Busy 记录了访问频繁的gc buffer.
    解决方法可以根据热点块的类型采取不同的解决方法,比如采取分区表,分区索引,hash全局分区索引,反向index等等。
    这点与单机数据库中的buffer busy waits类似。
  • 低效SQL语句
    低效SQL语句会导致不必要的buffer被请求访问,增加了buffer busy的机会。在AWR中可以找到TOP SQL。解决方法可以优化SQL语句减少buffer访问。这点与单机数据库中的buffer busy waits类似。
  • 数据交叉访问。
    RAC数据库,同一数据在不同数据库实例上被请求访问。
    如果应用程序可以实现,那么我们建议不同的应用功能/模块数据分布在不同的数据库实例上被访问,避免同一数据被多个实例交叉访问,可以减少buffer的争用,避免gc等待。
  • Oracle bug
    建议安装Oracle推荐的最新Patch Set和PSU。
    Patch set和PSU信息请参考:Oracle RecommendedPatches -- Oracle Database (Doc ID 756671.1)
    目前Oracle RAC数据库版本为19.3基础版,建议RU升级到19.21
    需求Oracle Database、Grid 和 OJVM 升级到次新或次次新的版本(补丁),版本信息参考DBA推荐的稳定版本

📣 5.总结

性能分析要综合考虑,不能只看等待事件,还有结合低效SQL语句,本次案例就是一次非常好的演示
Oracle数据库优化是多方面的,原则是减少系统的瓶颈,减少资源的占用,提高系统的反应速度。例如,通过优化文件系统,提高磁盘I/O的读写速度;通过优化操作系统调度策略,提高Oracle在高负荷情况下的负载能力;优化表结构、索引、查询语句等使查询响应更快。

相关推荐
Minxinbb3 小时前
MySQL中Performance Schema库的详解(上)
数据库·mysql·dba
mmsx4 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
zpjing~.~5 小时前
Mongo 分页判断是否有下一页
数据库
2401_857600955 小时前
技术与教育的融合:构建现代成绩管理系统
数据库·oracle
秋恬意5 小时前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis
潇湘秦6 小时前
一文了解Oracle数据库如何连接(1)
数据库·oracle
雅冰石6 小时前
oracle怎样使用logmnr恢复误删除的数据
数据库·oracle
web前端神器6 小时前
mongodb给不同的库设置不同的密码进行连接
数据库·mongodb
从以前6 小时前
Berlandesk 注册系统算法实现与解析
数据库·oracle
Muko_0x7d26 小时前
Mongodb
数据库·mongodb