Oracle RAC环境下定位并杀掉最终阻塞的会话方法是什么

技术Oracle RAC环境下定位并杀掉最终阻塞的会话方法是什么本篇内容介绍了“Oracle RAC环境下定位并杀掉最终阻塞的会话方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带

本文介绍了“在Oracle RAC环境中定位和终止最终被阻止的会话的方法是什么”的知识。很多人在实际案例的操作中会遇到这样的困难。让边肖带领你学习如何处理这些情况。希望大家认真阅读,学点东西!

实验环境:

甲骨文RAC 11.2.0.4(2个节点)

1.模拟失败:会话被级联阻止。

2.常规方法:梳理出最后阻塞的会话。

3.改进方法:立即找出最后阻塞的会话。

其实我之前也写过一篇相关的文章:

如何定位Oracle数据库锁定会话的根目录?

1.模拟故障:会话被级联阻塞

准备工作:

在这里,我在每个实例中打开两个会话来模拟负载平衡模式下RAC的业务会话:

示例:会话1,会话2;

示例2:会话3,会话4;

从时间点1-时间点2-时间点3-时间点4在此时间轴上执行以下操作:

时间点1:

实例1的会话1(INS1-session1)中的执行语句未提交或回滚:

选择* frov $ mystatwhrownum=1;

updateempsetsal=8000 where empno=7788;时间点2:

执行实例2的会话3(INS2-session3)中的语句:

选择* frov $ mystatwhrownum=1;

deletefromempwhereempno=7839

updateempsetjob=' MANAGER ' where empno=7788;

回滚;时间点3:

执行实例2的会话4(INS2-session4)中的语句:

选择* frov $ mystatwhrownum=1;

updateempsetsal=15000 where empno=7839;

回滚;时间点4:

在实例1的会话2(INS1-session2)中执行语句:

选择* frov $ mystatwhrownum=1;

updateempsetjob=' CEO ' where empno=7839;

回滚;这时可以看到,接下来三个时间点操作的会话都挂了,明显是被屏蔽了。4节课的现象如下:

Oracle  RAC环境下定位并杀掉最终阻塞的会话方法是什么

Oracle  RAC环境下定位并杀掉最终阻塞的会话方法是什么

Oracle  RAC环境下定位并杀掉最终阻塞的会话方法是什么

Oracle  RAC环境下定位并杀掉最终阻塞的会话方法是什么

那么他们被谁挡住了呢?下面将详细分析。

00-1010,我们会去GV$SESSION查询blocking_session,然后看这个blocking_ses。

sion有没有又被其他会话阻塞,直到找到根源。

--blocking
set lines 180
col program for a30
col machine for a20
select inst_id,
       SID,
       SERIAL#,
	   event,
	   machine,
       sql_id,
       blocking_session,
       blocking_instance
  from gv$session
 where blocking_session is not null;

结果如下:

SYS@jyzhao1 >--blocking
SYS@jyzhao1 >set lines 180
SYS@jyzhao1 >col program for a30
SYS@jyzhao1 >col machine for a20
SYS@jyzhao1 >select inst_id,
  2         SID,
  3         SERIAL#,
  4        event,
  5        machine,
  6         sql_id,
  7         blocking_session,
  8         blocking_instance
  9    from gv$session
 10   where blocking_session is not null;
   INST_ID        SID    SERIAL# EVENT                                    MACHINE              SQL_ID        BLOCKING_SESSION BLOCKING_INSTANCE
---------- ---------- ---------- ---------------------------------------- -------------------- ------------- ---------------- -----------------
         1        146       6283 enq: TX - row lock contention            jyrac1               052gy77vp276s               25                 2
         2         25      10250 enq: TX - row lock contention            jyrac2               3t2npbvdcf2d2              150                 1
         2        145      32069 enq: TX - row lock contention            jyrac2               0ct116qw46shq               25                 2
SYS@jyzhao1 >

可以看到实例1的sid=146的会话以及实例2的sid=145的会话都被实例2的sid=25的会话阻塞,而实例2的sid=25的这个会话又被实例1的sid=150的会话阻塞。这个例子只模拟了几个会话尚且可以快速定位,但如果是真实故障,很可能受影响的不止这么几个会话,虽然也可以慢慢最终找出来,但毕竟会看的眼花缭乱是不是。我们高傲的DBA又怎么会甘心一直去做这种事情呢?

3.改进方法:立即找出最终阻塞会话

之前我在单实例或者确认业务只跑在某一个节点的环境,一直在用的一个找出最终阻塞会话的脚本:

--cascade blocking
set lines 200 pages 100
col tree for a30
col event for a40
select *
  from (select a.sid, a.serial#,
               a.sql_id,
               a.event,
               a.status,
               connect_by_isleaf as isleaf,
               sys_connect_by_path(SID, '<-') tree,
               level as tree_level
          from v$session a
         start with a.blocking_session is not null
        connect by nocycle a.sid = prior a.blocking_session)
 where isleaf = 1
 order by tree_level asc;

这个脚本用到了start with connect by prior 的递归查询用法,非常方便可以直接找出最终阻塞的会话;可如果是RAC,业务是负载均衡跑在多个节点的,那上面的这个脚本就不好用了,比如我上面构造的这个例子,就需要明确查出各个会话分别在哪个实例上,否则你怎么确认去哪里杀呢,怎么办呢?其实也简单,只需要稍加改动下这个脚本即可,改后如下:

--cascade blocking@gv$session
select *
  from (select a.inst_id, a.sid, a.serial#,
               a.sql_id,
               a.event,
               a.status,
               connect_by_isleaf as isleaf,
               sys_connect_by_path(a.SID||'@'||a.inst_id, ' <- ') tree,
               level as tree_level
          from gv$session a
         start with a.blocking_session is not null
        connect by (a.sid||'@'||a.inst_id) = prior (a.blocking_session||'@'||a.blocking_instance))
 where isleaf = 1
 order by tree_level asc;

结果如下:

SYS@jyzhao1 >--cascade blocking@gv$session
SYS@jyzhao1 >select *
  2    from (select a.inst_id, a.sid, a.serial#,
  3                 a.sql_id,
  4                 a.event,
  5                 a.status,
  6                 connect_by_isleaf as isleaf,
  7                 sys_connect_by_path(a.SID||'@'||a.inst_id, ' <- ') tree,
  8                 level as tree_level
  9            from gv$session a
 10           start with a.blocking_session is not null
 11          connect by (a.sid||'@'||a.inst_id) = prior (a.blocking_session||'@'||a.blocking_instance))
 12   where isleaf = 1
 13   order by tree_level asc;
   INST_ID        SID    SERIAL# SQL_ID        EVENT                                    STATUS       ISLEAF TREE                           TREE_LEVEL
---------- ---------- ---------- ------------- ---------------------------------------- -------- ---------- ------------------------------ ----------
         1        150       8742               SQL*Net message from client              INACTIVE          1  <- 25@2 <- 150@1                       2
         1        150       8742               SQL*Net message from client              INACTIVE          1  <- 145@2 <- 25@2 <- 150@1              3
         1        150       8742               SQL*Net message from client              INACTIVE          1  <- 146@1 <- 25@2 <- 150@1              3
SYS@jyzhao1 >

非常清晰可以看到最终阻塞其他会话的会话是实例1的sid=150,serial#=8742的会话。
那么与相关人员都确认后,就可以直接杀掉这个最终阻塞会话:

SYS@jyzhao1 >alter system kill session '150,8742' immediate;
System altered.

再次查询,恢复正常,不再有堵塞了:

SYS@jyzhao1 >--cascade blocking@gv$session
SYS@jyzhao1 >select *
  2    from (select a.inst_id, a.sid, a.serial#,
  3                 a.sql_id,
  4                 a.event,
  5                 a.status,
  6                 connect_by_isleaf as isleaf,
  7                 sys_connect_by_path(a.SID||'@'||a.inst_id, ' <- ') tree,
  8                 level as tree_level
  9            from gv$session a
 10           start with a.blocking_session is not null
 11          connect by (a.sid||'@'||a.inst_id) = prior (a.blocking_session||'@'||a.blocking_instance))
 12   where isleaf = 1
 13   order by tree_level asc;
no rows selected
SYS@jyzhao1 >

“Oracle RAC环境下定位并杀掉最终阻塞的会话方法是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/68679.html

(0)

相关推荐

  • python文本进度条怎么实现

    技术python文本进度条怎么实现本篇内容介绍了“python文本进度条怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有

    攻略 2021年12月9日
  • 如何将eclipse项目导入myeclipse(可以同时安装eclipse和myeclipse)

    技术如何进行MyEclipse6.5+Eclipse3.4的中文问题浅析今天就跟大家聊聊有关如何进行MyEclipse6.5+Eclipse3.4的中文问题浅析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了

    攻略 2021年12月18日
  • 笑的种类,笑的方式有几种?都是什么笑

    技术笑的种类,笑的方式有几种?都是什么笑你好笑的种类,我是联盟微笑,是一名搞笑创作者,对你的问题有一下见解1.会心的笑是微笑2.傲慢的笑是嘲笑3.难堪的笑是干笑4.无可奈何的笑是苦笑
    5.最优美的笑是自然的笑
    6.最热闹

    生活 2021年10月20日
  • 孩子生在美国,去美国生子孩子有必要吗

    技术孩子生在美国,去美国生子孩子有必要吗想要顺利去美国生宝宝,具有关键性的一部是办理签证,只有拿到签证才能进入美国孩子生在美国。当然了,美国的签证也有很多种类,可分为移民签证和非移民签证两种,非移民签证主要为“短期”或“

    生活 2021年10月23日
  • Golang和Lua相遇会擦出什么火花

    技术Golang和Lua相遇会擦出什么火花这篇文章主要介绍“Golang和Lua相遇会擦出什么火花”,在日常操作中,相信很多人在Golang和Lua相遇会擦出什么火花问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操

    攻略 2021年11月9日
  • 如何实现SAP ERP分类与C4C同步

    技术SAP ERP classification和C4C的同步怎么实现这篇文章主要介绍“SAP ERP classification和C4C的同步怎么实现”,在日常操作中,相信很多人在SAP ERP classifica

    攻略 2021年12月24日