最近发生的几起 enq: TX - row lock contention 等待事件很怪,通过 blocking session id 查看,不是语句是 select,就是会话是 inactive 的。

实验

准备工作

  1. 进入 hr 用户,同时查看会话 id,下面会称为 会话 38

    1

    2

    3

    4

    SQL> select userenv('sid'from dual;

    USERENV('SID')

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

            3

  2. 创建测试表

    1

    create table emp_bak as select from employees

  3. 创建被锁会话,同时查看会话 id,下面会称为 会话 28

    1

    2

    3

    4

    SQL> select userenv('sid'from dual;

    USERENV('SID')

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

            28

测试

  1. 会话 38 产生锁操作,注意,此处不进行提交操作,且操作完不进行 exit 操作

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    SQL> SELECT employee_id, first_name, last_name, salary

      2    FROM emp_bak

      3   WHERE employee_id = 166;

    EMPLOYEE_ID FIRST_NAME                  LAST_NAME                         SALARY

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

        166 Sundar                  Ande                            6400

    SQL> update emp_bak

      2     set salary = salary + 100

      3   where employee_id = 166;

    1 row updated

  2. 会话 28,为了区分操作语句,此处我们执行 delete 操作,此时会出现 hang,暂且不去管它

    1

    2

    SQL> delete from emp_bak

      2   where employee_id = 166

  3. 此时,我们新启会话查一下锁情况

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    col event for a30

    col username for a8

    col process for a7

    col machine for a7

    col program for a30

    col sql for a80

    SELECT a.sid,

           b.status,

           b.event,

           b.USERNAME,

           b.PROCESS,

           b.MACHINE,

           b.program,

           CASE

             WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN

              'CURR'

             ELSE

              'PREV'

           END STAT,

           c.sql_text "SQL"

      FROM v$lock a, v$session b, v$sql c

     WHERE (a.id1, a.id2) IN (SELECT ID1, ID2

                                FROM gv$lock

                               WHERE TYPE = 'TX'

                                 AND request > 0)

       AND a.sid = b.sid

       AND CASE

             WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN

              b.SQL_ADDRESS

             ELSE

              b.PREV_SQL_ADDR

           END = c.address

       AND CASE

             WHEN b.SQL_HASH_VALUE > 0 THEN

              b.SQL_HASH_VALUE

             ELSE

              b.PREV_HASH_VALUE

    END = c.hash_value;

    由于长时间未对数据库进行操作,所以会话状态为 INACTIVE 状态,锁的语句为 update

  4. 那么此时,我们在会话 38 上执行 select 语句,查询的状态是怎样的呢?

    1

    2

    3

    4

    5

    6

    SQL> SELECT employee_id, first_name, last_name, salary

      2    FROM emp_bak

      3   WHERE employee_id = 166;

    EMPLOYEE_ID FIRST_NAME                  LAST_NAME                         SALARY

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

        166 Sundar                  Ande                            6500

  5. 我们此时可以再关联 v$transaction,来查看具体信息

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    SELECT a.sid,

           b.status,

           b.event,

           b.USERNAME,

           b.PROCESS,

           b.MACHINE,

           b.program,

           CASE

             WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN

              'CURR'

             ELSE

              'PREV'

           END STAT,

           c.sql_text "SQL",

           d.start_time,

           d.status,

           d.xid,

           d.USED_UBLK,

           d.USED_UREC

      FROM v$lock a, v$session b, v$sql c, v$transaction d

     WHERE (a.id1, a.id2) IN (SELECT ID1, ID2

                                FROM gv$lock

                               WHERE TYPE = 'TX'

                                 AND request > 0)

       AND a.sid = b.sid

       AND CASE

             WHEN rawtohex(b.SQL_ADDRESS) <> '00' THEN

              b.SQL_ADDRESS

             ELSE

              b.PREV_SQL_ADDR

           END = c.address

       AND CASE

             WHEN b.SQL_HASH_VALUE > 0 THEN

              b.SQL_HASH_VALUE

             ELSE

              b.PREV_HASH_VALUE

           END = c.hash_value

       AND rawtohex(d.addr(+)) = b.taddr;

结论

  1. blocking session id 记录的是谁锁的自己

  2. sqltext 记录的是当前执行的语句,而并非是被哪句锁住了

  3. inactive 仅表示处于此状态的会话没有正在执行,但由于之前执行的语句,依然会产生锁

  4. v$transaction 可以获取事务的状态以及进度,重复查询 USED_UBLK、USED_UREC 这两个值,可以看到变化,可以估计事务的进度,尤其是长时间的回滚操作,当这两个值为0,回滚也就完成了。

Oracle:select 或 inactive 会话语句产生锁?相关推荐

  1. 【DBA笔记2】Oracle之定期清理inactive会话

    目录 背景 例子 1.超60秒会话 2.建存储过程 2.1.直接kill 2.2.完成当前事务后kill 背景 ORACLE数据库会话有ACTIVE.INACTIVE.KILLED. CACHED.S ...

  2. 查询Oracle正在执行的sql语句,锁表,解锁

    原文出处:http://blog.csdn.net/jlds123/article/details/6572559 ----------------------- --查询Oracle正在执行的sql ...

  3. Oracle查询正在执行的语句、锁表、耗费资源的语句

    语句1: --正在执行的语句查询和拼接杀进程 SELECT 'alter system kill session '''||b.sid||','|| b.serial#||''';' as kills ...

  4. ORACLE定期清理INACTIVE会话

    ORACLE数据库会话有ACTIVE.INACTIVE.KILLED. CACHED.SNIPED五种状态.INACTIVE状态的会话表示此会话处于非活动.空闲.等待状态.例如PL/SQL Devel ...

  5. Sqlserver的merge into或delete语句堵塞了不加with (nolock)的select语句,锁类型是LCK_M_IS

    总结 sqlserver遇到delete删除大量数据时,千万不能直接删除,删除过程会堵塞不加with (nolock)的select语句,锁类型是LCK_M_IS,delete删除过程中,虽然加wit ...

  6. oracle 消耗资源的语句,Oracle高资源消耗SQL语句定位

    Oracle高资源消耗SQL语句定位 Oracle SQL语句资源消耗监控最常用的系统视图有v$sql.v$sqlarea.v$sqltext和v$session.本文我们先了解这些视图的作用与区别, ...

  7. Oracle数据库基础知识+sql语句练习

    文章目录 四.数据库 4.1 Oracle 准备知识 SQL基本分类 Oracle数据类型 基本用法 事务 事务特性: 隔离性问题: 隔离级别: 锁 锁的介绍 锁的分类 锁的类型 锁等待和死锁 查看是 ...

  8. oracle笔记一(sql语句方面)

    oracle笔记一(sql语句方面) 一.sql语句 --================================================ 1.增加主键    alter table ...

  9. oracle tabe unlock_oracle数据库管理常用语句(不断更新中)

    1.删除用户及其用户下面的所有对象 drop user branch cascade; 2.删除表空间及其表空间里的所有内容 drop tablespace center INCLUDING CONT ...

最新文章

  1. AHK调用API获取ListView每列的坐标
  2. linux系统添加新用户并赋予相应权限
  3. mysql中数据定义和数据控制语言_MySQL 数据定义语言(DDL)
  4. JWT(Json Web Token)介绍
  5. 什么是迁移学习?它都用在深度学习的哪些场景上?
  6. optimize 回收表空间的一些说明
  7. vue 个人头像修改
  8. 数字信号处理设计与仿真分析
  9. ubuntu和win7共享文件
  10. Python关于pandas中 ValueError: Writing 0 cols but got ”XXX“ aliases的错误
  11. 模糊神经网络应用实例,神经网络与模糊控制
  12. 杀戮尖塔是用java_杀戮尖塔修改class文件图文教程
  13. 修复版动态视频壁纸微信小程序源码下载,支持多种类型流量主收益
  14. 维度诅咒_让我们面对现实:“敏捷”是一个被诅咒的名字
  15. 如何改变视频的MD5值?一分钟让你学会操作
  16. 著作权法_信息网络传播权保护条例_最高人民法院关于审理侵害信息网络传播权民事纠纷案件适用法律若干问题的规定
  17. iOS 数据库-SQLite3 CoreData FMDB
  18. CodeForces - 764B Timofey and cubes
  19. linux卸载命令pkg,[转]软件包管理的命令:pkginfo、pkgadd和pkgrm
  20. 登录拦截之后,登录页面出现在iframe的src里面

热门文章

  1. python itertool_函数式编程的Python实践(2):Itertool
  2. python生成随机数方法_Python生成随机数的方法
  3. centos7.4安装图形界面及报错处理
  4. sql server 2008安装需要一直重启。但重启后又没有达到效果。
  5. 面对对象编程(OOP, Object Oriented Programming)及其三个基本特性
  6. JS中find(), findIndex(), filter(), forEach(), some(), every(), map()方法
  7. Maven-Build Lifecycle(构建生命周期)
  8. Echarts与Highcharts的比较
  9. java游戏开发基础Swing之JRadioButton
  10. PHPstrom怎样设置浏览器