请选择 进入手机版 | 继续访问电脑版

湖南新梦想

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 332|回复: 0

如何定位Oracle数据库被锁阻塞会话的根源

[复制链接]

2493

主题

2892

帖子

1万

积分

论坛元老

Rank: 8Rank: 8

积分
10294
发表于 2021-6-23 11:17:35 | 显示全部楼层 |阅读模式
本帖最后由 chaomeili 于 2021-6-23 11:18 编辑

      首先再次明确下,数据库因为要同时保证数据的并发性和一致性,所以操作有锁等待是正常的。
  只有那些长时间没有提交或回滚的事物,阻塞了其他业务正常操作,才是需要去定位处理的。
  1. 单实例环境
  实验环境:Oracle 10.2.0.5 单实例
  会话1、模拟业务操作:
  1. SQL> select sid from v$mystat where rownum=1;
  2. SID
  3. ----------
  4. 144
  5. SQL> show user
  6. USER is "JINGYU"
  7. SQL> select * from t1 where id=1 for update;
  8. ID          N CONTENTS
  9. ---------- ---------- ----------------------------------------
  10. 1          1 Alfred Zhao
复制代码

       会话2、模拟业务操作:

  1. SQL> select sid from v$mystat where rownum=1;
  2. SID
  3. ----------
  4. 149
  5. SQL> show user
  6. USER is "JINGYU"
  7. SQL> update t1 set contents='Mcdull' where id=1;
复制代码

这里update操作会卡住不动。用户感知就是长时间无法执行成功,很可能还会直接抱怨数据库性能慢。

  会话3、模拟DBA查看:
  1. SQL> select sid from v$mystat where rownum=1;
  2. SID
  3. ----------
  4. 145
  5. SQL> show user
  6. USER is "SYS"
  7. SQL> select sid, username, blocking_session from v$session where blocking_session is not null;
  8. SID USERNAME                       BLOCKING_SESSION
  9. ---------- ------------------------------ ----------------
  10. 149 JINGYU                                      144
  11. SQL> select sid, serial#, username from v$session where sid=144;
  12. SID    SERIAL# USERNAME
  13. ---------- ---------- ------------------------------
  14. 144        102 JINGYU
复制代码
这里可以清楚的看到会话149是被会话144阻塞,进一步查看会话144的serial#值。
  这时候的处理方式一般有2种方案:
  1)杀掉会话144,当然操作之前需要和应用负责人确认沟通好;
  2)如果可以定位到144会话相关责任人,由他来提交或者回滚事物;
  处理后可以看到会话2的update操作正常执行成功。
  2.RAC环境
  实验环境:Oracle 10.2.0.5 RAC
  如果是RAC环境,还必须要定位到具体是哪个实例的会话,其实方法非常简单,查询时加入blocking_instance字段即可。
 实例2、模拟业务操作:
  select sid from v$mystat where rownum=1;
  select * from t1 where id=1 for update;
  实例1、模拟业务操作:
  select sid from v$mystat where rownum=1;
  update t1 set contents='Mcdull' where id=1;
  会话模拟DBA查看:
  1. SQL> select sid, username, blocking_instance, blocking_session from gv$session where blocking_session is not null;
  2. SID USERNAME                       BLOCKING_INSTANCE BLOCKING_SESSION
  3. ---------- ------------------------------ ----------------- ----------------
  4. 129 JINGYU                                         2              129
  5. SQL> select inst_id, sid, serial#, username from gv$session where sid=129;
  6. INST_ID        SID    SERIAL# USERNAME
  7. ---------- ---------- ---------- ------------------------------
  8. 1        129        617 JINGYU
  9. 2        129        207 JINGYU
复制代码
 查询阻塞会话也要注意当前连接的实例,千万别弄错了,比如上面这个情况,如果确定可以杀掉阻塞会话,那么就需要到实例2去杀掉会话;
  SQL> select instance_number from v$instance;
  INSTANCE_NUMBER
  ---------------
  2
  SQL> alter system kill session '129,207';
  System altered.
  再次看被阻塞的会话操作已经恢复正常。
  后记:
  整理该文主要缘由是在之前的一次面试过程中,发现自己对这样基本的问题反而太依赖于别人写好的SQL,比如下面这类的SQL,开始并不知道此SQL的具体适用场景:



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|湖南新梦想 ( 湘ICP备18019834号-2 )

GMT+8, 2022-5-18 12:18 , Processed in 0.041638 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表