ITPub博客

首页 > 数据库 > Oracle > oracle一次卡顿案例(二)

oracle一次卡顿案例(二)

原创 Oracle 作者:wanglinghua0907 时间:2024-01-09 11:41:32 0 删除 编辑

故障描述

2023 年 09 月 29 号 10:30 左右,应用多次反馈 boss1 的 jsbas 数据库应用程序报错,会话断开。

原因分析

检查会话情况:

检查会话执行的 sql :

从上面可以看出来, JOUR 用户的会话等待事件 row cache lock , sql 文本为“ SELECT * FROM OM_LINE WHERE SUBSCRIBER_INS_ID = 108166239 AND ORDER_STATUS = '0'AND EXEC_TIME > SYSDATE AND BUSI_ITEM_CODE in ('80010032','80010033') ”除了 SUBSCRIBER_INS_ID 这个条件不一样,其他内容是一样的,这个很明显的问题就是没有使用绑定变量。

行缓冲锁( row cache lock )用于在 Shared Pool 内存中锁住数据字典( Data Dictionary )信息。 row cache lock 等待事件是一个共享池相关的等待事件,是由于对字典缓冲的访问造成的。每一个行缓冲队列锁都对应一个特定的数据字典对象,这被叫做队列锁类型,并可以在 V$ROWCACHE 视图中找到。

另外一个等待事件 cusor: pin S wait on X , 这个等待事件是某个会话需要申请S 模式的mutex ,而mutex 被其他会话以X 模式占有了,当前会话会处于 cusor: pin S wait on X 等待事件,结合这些会话的阻塞会话发现,阻塞会话全部是 row cache lock 等待事件的会话,所以说根本原因是 row cache lock 导致的 。

检查 row cache lock 会话 p1 参数:

SQL> select sid,event,p1,program from v$session where event='row cache lock';

       SID EVENT                   P1 PROGRAM

---------- --------------- ---------- ---------------

       569 row cache lock          63 app-node01-srv01

       577 row cache lock          63 app-node01-srv01

       592 row cache lock          63 app-node01-srv01

       769 row cache lock          63 app-node01-srv01

       954 row cache lock          63 app-node01-srv01

       966 row cache lock          63 app-node01-srv01

.................

查看缓存的类型:

SQL> select parameter from v$rowcache where cache#=63;

PARAMETER

--------------------------------

dc_realtime_tabst

dc_realtime_tabst 以前很少会看到这个缓存类型,但是可以推断出 realtime_tabst 应该指的是实时 table statics ,这个是 19C 的新特性,可以判断出这个 row cache lock 等待事件和表的实时统计信息有关系。

检查到表的统计信息,早上刚刚收集过,如下图所示:

可以看出,早上 10:02 这个表刚刚收集过统计信息,不到 20 分钟,统计信息已经过期了,说明这个表数据变化特别快。对于统计信息过期的表, oracle 会进行实时统计信息的收集,实际会延长一段时间之后才收集。

最后是通过杀会话,发现无法杀掉所有的 cursor: pin S wait on X , row cache lock 异常等待事件的会话,不起作用,杀掉后新的会话不断连接进来,最后通过重启应用,断开所有业务会话解决。

总结:结合 row cache lock 的争用的缓存类型 dc_realtime_tabst ,以及这个表的统计信息过期,可以判断在高并发未绑定变量 sql 的会话下, 19C 的新特性实时统计信息收集导致的。

解决办法和建议

1.      建议应用对应用的 sql “ SELECT * FROM OM_LINE WHERE SUBSCRIBER_INS_ID = 108166239 AND ORDER_STATUS = '0'AND EXEC_TIME > SYSDATE AND BUSI_ITEM_CODE in ('80010032','80010033') ”进行整改, SUBSCRIBER_INS_ID 字段明显没有使用绑定变量,建议改为使用绑定变量 。

2.      业务进行 sql 整改 hint 添加“ /*+ NO_GATHER_OPTIMIZER_STATISTICS */ ” 禁止收集实时统计信息。

3.      建议关闭 19C 实时收集统计信息的新特性,默认 "_optimizer_gather_stats_on_conventional_dml" 为 true , 这样实时统计信息将自动启用。我们可以设置这个参数到 "FALSE" 来禁止实时统计信息的收集。

参考

在 19c 中禁用实时统计信息 (Doc ID 2639856.1)


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69980685/viewspace-3003201/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
Oracle ACE、sql server、oceanbase数据库专家,拥有7年以上的大型数据库运维经验,主方向oracle,擅长故障排除、诊断,大体量(TB)迁移,异常故障修复等。拥有丰富主导大型项目经验。服务行业包括:运营商、银行、金融业、政府单位、医疗、制造业、高校等等。

注册时间:2020-07-31

  • 博文量
    116
  • 访问量
    88787