• Oracle阻塞会话源头查找-单机和RAC环境


    在写 Oracle session相关数据字典(一)  这篇文章时,提到使用v$session视图的树形查询可以得到Oracle锁树,这样就便于我们找出阻塞会话的源头,但是仅仅可以在单机环境中使用。今天把单机和RAC的阻塞树都整理了一下,话不多说,直接开干,奥利给。

    (一)单机的阻塞会话树

    单机的不再测试,直接搬以前的记录。EM里面的Blocking session里面看到下图,以折叠图的形式展现,最上面的代表正在阻塞其它session的会话,研究了一下,可以使用v$session来得到类似的效果。

    image

                                                                      图1.blocking session树形图

    我们来做一次测试,对表test01和test02进行DML操作,观察运行情况,操作如下

    (1)创建测试表test01,test02。并在2个表的id列添加主键约束

    image image

             test01表                                                               test02表

    (2)对2个表进行操作,执行顺序如下

    ----------------------------------------test01操作-------------------------------------------------------

    [sessid:27  ]  delete from test01;                                          --删除test01整个表的数据,未提交,阻塞源头

    [sessid:28  ]  update test01 set name = 'aaa' where id = 1;    --更新test01表id=1的行,会话产生等待

    [sessid:142]   insert into test01 values(1,'abc');                     --插入test01表id=1的行,会话产生等待

    [sessid:25 ]   delete from test01 where id = 2;                       --删除test01表id=2的行,会话产生等待

    [sessid:29 ]   update test01 set  name = 'bbb' where id  = 2;  --更新test01表id=2的行,会话产生等待

    -----------------------------------------test02操作--------------------------------------------------------

    [sessid:30 ]  insert into test02 values(3,'augly',3000);          --插入test02表id=3的行,未提交,阻塞源头

    [sessid:23 ]  insert into test02 values(3,'augly',3300);          --插入test02表id=3的行,会话产生等待

    此时我们到EM里面观察,就会发现图1的blocking session树形图。

    在实际环境中,大部分系统是没有安装EM的,在没有EM的情况下,我们依然可以通过v$session得到类似的图形

    --使用v$session来查看单实例的阻塞session信息
    
    SELECT   LPAD(' ',5*(LEVEL-1))||S."USERNAME" AS user_name , 
             LPAD(' ',5*(LEVEL-1))||S."SID" AS session_id,
             S."SERIAL#",
             S."SQL_ID",         S."ROW_WAIT_OBJ#",
             S."WAIT_CLASS",
             S."EVENT",
             S."P1",
             S."P2",
             S."P3",
             S."SECONDS_IN_WAIT"
    FROM     V$SESSION S 
    WHERE    S."BLOCKING_SESSION" IS NOT NULL
    OR       S.SID IN(SELECT DISTINCT BLOCKING_SESSION FROM V$SESSION)
    START WITH S."BLOCKING_SESSION" IS NULL
    CONNECT BY PRIOR S."SID" = S."BLOCKING_SESSION";

    结果如下,红色的为阻塞源头:

    image


    (二)RAC的阻塞会话树

    RAC的阻塞会话,在EM里面是按照实例分开的,没有合并在一起,如下图:

    image

    image


    我们尝试将两个图的结果合并在一起,测试如下:

    (1)创建测试表,并添加主键

    CREATE TABLE test01
    (
       ID      NUMBER,
       NAME    VARCHAR(30),
       age     NUMBER
    );
    ALTER TABLE test01 ADD CONSTRAINT pk_id PRIMARY KEY(ID);


    (2)往测试表里面写入数据,形成跨节点的会话阻塞,执行如下:

    ----------------------------------------test01操作:模拟跨节点阻塞--------------------------------------------

    [节点1:会话36]    INSERT INTO test01 VALUES(1,'lijiaman',18);    --节点1插入数据,未提交,阻塞源头

    [节点2:会话265]  INSERT INTO test01 VALUES(1,'xiaohua',19);    --节点2插入数据,主键相同,阻塞

    [节点1:会话43]    INSERT INTO test01 VALUES(1,'xiaoli',20);        --节点1插入数据,同样被阻塞

    ----------------------------------------test01操作:模拟同一节点阻塞-------------------------------------------

    [节点2:会话34]    INSERT INTO TEST01 VALUES (2, 'b', 18);          --节点2插入数据,未提交,阻塞源头

    [节点2:会话275]  INSERT INTO TEST01 VALUES (2, 'c', 18);           --节点2插入数据,主键相同,阻塞

    使用如下SQL查询RAC和单节点的会话阻塞:

    --使用v$session来查看RAC数据库和单实例阻塞session信息
    
    SELECT   
             LPAD(' ',5*(LEVEL-1))||S."USERNAME" ,  
             LPAD(' ',5*(LEVEL-1))||S."INST_ID"||','||S."SID" ,
             S."SERIAL#" ,
             S."SQL_ID",        
             S."ROW_WAIT_OBJ#",
             S."WAIT_CLASS",
             S."EVENT",
             S."P1",
             S."P2",
             S."P3",
             S."SECONDS_IN_WAIT",
             s."BLOCKING_INSTANCE"||','||s."BLOCKING_SESSION"
    FROM     GV$SESSION S 
    WHERE    S."BLOCKING_SESSION" IS NOT NULL
    OR       (S."INST_ID"||','||S."SID") IN(SELECT DISTINCT BLOCKING_INSTANCE||','||BLOCKING_SESSION FROM GV$SESSION)
    START WITH  (s."BLOCKING_INSTANCE"||','||s."BLOCKING_SESSION") = ','
    CONNECT BY PRIOR (S."INST_ID"||','||S."SID") = (s."BLOCKING_INSTANCE"||','||s."BLOCKING_SESSION");

    结果如下,红色的是阻塞源头:

    image



    【完】

  • 相关阅读:
    C#:基于WMI查询USB设备信息 及 Android设备厂商VID列表
    C#中 @ 的3种用途
    有关于 使用 命名管道 进行网络 进程间通信 的资料收集
    MySql LAST_INSERT_ID 【插入多条数据时】
    两个“不合理继承 ”的判定标识
    MYSQL 函数 字符串到整数
    Spring MVC 对于@ModelAttribute 、@SessionAttributes 的详细处理流程
    重构,拥有多个构造函数(重载)的类
    vue二级联动select
    gulp.dest用法详解
  • 原文地址:https://www.cnblogs.com/lijiaman/p/12961540.html
Copyright © 2020-2023  润新知