在Oracle数据库性能报告AWRRPT分析时,发现top 5等待事件第一位的是enq: TX - row lock contention。这个等待事件消耗了绝大多数的CPU资源,导致系统整理性能下降。有些查询以前只要几个毫秒,现在变成了数分钟。CPU使用率长时间维持在100%。

声明一下,数据库版本是10g for linux x86 64bit。

在AWRRPT中看到的top 5等待如下:

Rpt代码
  1. Top 5 Timed Events
  2. Event    Waits    Time(s)    Avg Wait(ms)    % Total Call Time    Wait Class
  3. enq: TX - row lock contention    27,190    62,674    2,305    63.1    Application
  4. CPU time         36,227         36.5
  5. log file sync    133,744    52    0    .1    Commit
  6. log file parallel write    143,992    29    0    .0    System I/O
  7. db file sequential read    49,403    23    0    .0    User I/O
Top 5 Timed EventsEvent    Waits    Time(s)    Avg Wait(ms)    % Total Call Time    Wait Classenq: TX - row lock contention    27,190    62,674    2,305    63.1    ApplicationCPU time         36,227         36.5     log file sync    133,744    52    0    .1    Commitlog file parallel write    143,992    29    0    .0    System I/Odb file sequential read    49,403    23    0    .0    User I/O

(miki西游 @mikixiyou 原文链接: http://mikixiyou.iteye.com/blog/1771648)

通常情况下,Oracle数据库的等待事件enq: TX - row lock contention会在下列三种情况下会出现。

第一种情况,是真正的业务逻辑上的行锁冲突,如一条记录被多个人同时修改。这种锁对应的请求模式是6。

第二种情况,是唯一键冲突,如主键字段相同的多条记录同时插入。这种锁对应的请求模式是4。这也是应用逻辑问题。

第三种情况,是bitmap索引的更新冲突,就是多个会话同时更新bitmap索引的同一个数据块。此时会话请求锁的对应的请求模式是4。

bitmap索引的物理结构和普通索引一样,也是 B-tree 结构。但它存储的数据记录的逻辑结构为"key_value,start_rowid,end_rowid,bitmap"。

其内容类似这样:

"‘8088’,00000000000,10000034441,1001000100001111000"

Bitmap是一个二进制,表示 START_ROWID 到 END_ROWID 的记录, 1 表示等于 key_value 即‘8088’的 ROWID 记录, 0 则表示不是这个记录。

在了解bitmap索引的结构之后,我们就能理解同时插入多条记录到拥有bitmap索引的表时,就会同时更新bitmap索引中一个块中的记录,等于某一个记录被同时更新,自然就会出现行锁等待。插入并发量越大,等待越严重。

等待事件enq: TX - row lock contention中的enq是enquence的简写。enquence是协调访问数据库资源的内部锁。

所有以“enq:”打头的等待事件都表示这个会话正在等待另一个会话持有的内部锁释放,它的名称格式是enq:enqueue_type - related_details。这里的enqueue_type是TX,related_details是row lock contention。数据库动态性能视图v$event_name提供所有以“enq:”开头的等待事件的列表。

虽然在awrrpt中看到大量enq: TX - row lock contention的等待,但这些是事后看到的信息。根据AWRRPT,我们无法只能该等待事件的请求模式是什么,是6还是4。

如果数据库一出现enq: TX - row lock contention等待,可以去看v$session和v$session_wait等视图。

在v$session和v$session_wait中,如果看到的event列是enq: TX - row lock contention的,就表示这个会话正处于行锁等待。该等待事件的请求模式可以从v$session和v$session_wait的p1列中得到。

select sid,

chr(bitand(p1, -16777216) / 16777215) ||

chr(bitand(p1, 16711680) / 65535) "Name",

(bitand(p1, 65535)) "Mode"

from v$session_wait

where event like 'enq%';

通过这个SQL可以将p1转换为易阅读的文字。

我针对这三种情况,分别进行测试。

首先,我准备一下测试表和数据。
--创建测试表和数据
create table t_all_objs as select owner,object_id,object_name from all_objects where 0=1;
alter table T_ALL_OBJS  add constraint pk_t_all_objs primary key (OBJECT_ID);
insert into t_all_objs(owner,object_id,object_name) values('TEST',2013011701,'test1');
insert into t_all_objs(owner,object_id,object_name) values('TEST',2013011702,'test2');
commit;

第一种情况,不同会话同时更新同一条记录
--test1
--sid=1015
update t_all_objs set object_name='test11' where object_id=2013011701;

--sid=1065
update t_all_objs set object_name='test101' where object_id=2013011701;

--第三个会话中查询
select sid,sql_id,blocking_session,event,p1text,p1,wait_class,state from v$session where sid in (1015, 1065);
select * from v$session_wait where sid in (1015, 1065);

SID    SQL_ID    BLOCKING_SESSION    EVENT    P1TEXT    P1    WAIT_CLASS    STATE
1    1015            SQL*Net message from client    driver id    1413697536    Idle    WAITING
2    1065    6y6u0gx4qa5v5    1015    enq: TX - row lock contention    name|mode    1415053318    Application    WAITING

SID    SEQ#    EVENT    P1TEXT    P1    P1RAW    P2TEXT    P2    P2RAW    P3TEXT    P3    P3RAW    WAIT_CLASS_ID    WAIT_CLASS#    WAIT_CLASS    WAIT_TIME    SECONDS_IN_WAIT    STATE
1    1015    44    SQL*Net message from client    driver id    1413697536    54435000    #bytes    1    00000001        0    00    2723168908    6    Idle    0    1306    WAITING
2    1065    41    enq: TX - row lock contention    name|mode    1415053318    54580006    usn<<16 | slot    655407    000A002F    sequence    92680    00016A08    4217450380    1    Application    0    1291    WAITING

--得到sql_id值,查询出SQL信息。
select sql_text,s.EXECUTIONS,s.ELAPSED_TIME/1000000 from v$sql s where sql_id = '6y6u0gx4qa5v5';

SQL_TEXT    EXECUTIONS    S.ELAPSED_TIME/1000000
1     update t_all_objs set object_name='test11' where object_id=2013011701     0    1286.977282

--再查询锁信息
select * from v$lock where sid in (1015, 1065) order by sid, type;

ADDR    KADDR    SID    TYPE    ID1    ID2    LMODE    REQUEST    CTIME    BLOCK
1    31AA5BC4    31AA5BDC    1015    TM    191499    0    3    0    1306    0
2    30D135B0    30D136CC    1015    TX    655407    92680    6    0    1306    1
3    31AA5C88    31AA5CA0    1065    TM    191499    0    3    0    1291    0
4    32034928    3203493C    1065    TX    655407    92680    0    6    1291    0

第二种情况,不同会话中同时插入主键字段相同的记录
--test2
--sid=1015
insert into t_all_objs(owner,object_id,object_name) values('TEST',2013011703,'test1');

--sid=1065
insert into t_all_objs(owner,object_id,object_name) values('TEST',2013011703,'test11');

--第三个会话中查询
select sid,sql_id,blocking_session,event,p1text,p1,wait_class,state from v$session where sid in (1015, 1065);
select * from v$session_wait where sid in (1015, 1065);

SID    SQL_ID    BLOCKING_SESSION    EVENT    P1TEXT    P1    WAIT_CLASS    STATE
1    1015            SQL*Net message from client    driver id    1413697536    Idle    WAITING
2    1065    bmv0jcs53zkad    1015    enq: TX - row lock contention    name|mode    1415053316    Application    WAITING

SID    SEQ#    EVENT    P1TEXT    P1    P1RAW    P2TEXT    P2    P2RAW    P3TEXT    P3    P3RAW    WAIT_CLASS_ID    WAIT_CLASS#    WAIT_CLASS    WAIT_TIME    SECONDS_IN_WAIT    STATE
1    1015    59    SQL*Net message from client    driver id    1413697536    54435000    #bytes    1    00000001        0    00    2723168908    6    Idle    0    69    WAITING
2    1065    69    enq: TX - row lock contention    name|mode    1415053316    54580004    usn<<16 | slot    458790    00070026    sequence    92434    00016912    4217450380    1    Application    0    12    WAITING

--得到sql_id值,查询出SQL信息。
select sql_text,s.EXECUTIONS,s.ELAPSED_TIME/1000000 from v$sql s where sql_id = 'bmv0jcs53zkad';

SQL_TEXT    EXECUTIONS    S.ELAPSED_TIME/1000000
1     insert into t_all_objs(owner,object_id,object_name) values('TEST',2013011703,'test11')     0    11.992511

--再查询锁信息
select * from v$lock where sid in (1015, 1065) order by sid, type;

ADDR    KADDR    SID    TYPE    ID1    ID2    LMODE    REQUEST    CTIME    BLOCK
1    31AA5BC4    31AA5BDC    1015    TM    191499    0    3    0    69    0
2    30D135B0    30D136CC    1015    TX    458790    92434    6    0    69    1
3    31AA5C88    31AA5CA0    1065    TM    191499    0    3    0    12    0
4    32034928    3203493C    1065    TX    458790    92434    0    4    12    0
5    30E30A50    30E30B6C    1065    TX    589865    106712    6    0    12    0

第三种情况,不同会话中同时bitmap索引列值相同的记录

--test3
--创建一个bitmap索引
create bitmap index ind_T_ALL_OBJS on T_ALL_OBJS (owner);

--sid=1015
insert into t_all_objs(owner,object_id,object_name) values('TEST',2013011703,'test11');

--sid=1065
insert into t_all_objs(owner,object_id,object_name) values('TEST',2013011703,'test12');

--第三个会话中查询
select sid,sql_id,blocking_session,event,p1text,p1,wait_class,state from v$session where sid in (1015, 1065);
select * from v$session_wait where sid in (1015, 1065);

SID    SQL_ID    BLOCKING_SESSION    EVENT    P1TEXT    P1    WAIT_CLASS    STATE
1    1015            SQL*Net message from client    driver id    1413697536    Idle    WAITING
2    1065    gsf39j000n6ys    1015    enq: TX - row lock contention    name|mode    1415053316    Application    WAITING

SID    SEQ#    EVENT    P1TEXT    P1    P1RAW    P2TEXT    P2    P2RAW    P3TEXT    P3    P3RAW    WAIT_CLASS_ID    WAIT_CLASS#    WAIT_CLASS    WAIT_TIME    SECONDS_IN_WAIT    STATE
1    1015    74    SQL*Net message from client    driver id    1413697536    54435000    #bytes    1    00000001        0    00    2723168908    6    Idle    0    24    WAITING
2    1065    85    enq: TX - row lock contention    name|mode    1415053316    54580004    usn<<16 | slot    524294    00080006    sequence    106695    0001A0C7    4217450380    1    Application    0    15    WAITING

--得到sql_id值,查询出SQL信息。
select sql_text,s.EXECUTIONS,s.ELAPSED_TIME/1000000 from v$sql s where sql_id = 'gsf39j000n6ys';

SQL_TEXT    EXECUTIONS    S.ELAPSED_TIME/1000000
1        0    11.988711

--再查询锁信息
select * from v$lock where sid in (1015, 1065) order by sid, type;

ADDR    KADDR    SID    TYPE    ID1    ID2    LMODE    REQUEST    CTIME    BLOCK
1    31AA5BC4    31AA5BDC    1015    TM    191499    0    3    0    24    0
2    30D135B0    30D136CC    1015    TX    524294    106695    6    0    24    1
3    31AA5C88    31AA5CA0    1065    TM    191499    0    3    0    15    0
4    32034928    3203493C    1065    TX    524294    106695    0    4    15    0
5    30E30A50    30E30B6C    1065    TX    458798    92446    6    0    15    0

在数据库的awrrpt中我还看到关于某个表的大量insert操作,每次操作执行时间都很长,这要么是应用逻辑问题,要么就是bitmap索引记录更新等待。开发人员证实逻辑问题不可能,查询表的索引状况,确实有bitmap索引。

http://mikixiyou.iteye.com/blog/1771648

等待事件enq TX row lock contention分析相关推荐

  1. 等待事件 enq:TX - row lock contention分析与解决

    6月30日,数据库发生了大量锁表.大概持续1小时,并且越锁越多.后来通过业务人员停掉程序,并kill掉会话后解决. 几天后再EM上查看CPU占用: CPU发生了明显等待. 主要是由于enq:TX - ...

  2. 【故障处理】队列等待之enq: TX - row lock contention

    [故障处理]队列等待之enq: TX - row lock contention 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能, ...

  3. 队列等待之enq: TX - row lock contention

    [性能优化]队列等待之enq: TX - row lock contention 问题背景: 客户反映某条sql DELETE SHAREINNERDOC WHERE SOURCEID=:B1< ...

  4. Oracle死锁问题: enq: TX - row lock contention

    前言 这篇文章也是记录近期遇到的问题以及从中学到的知识 ,近期一直在救火,有些问题自认为还是挺有代表性的,有兴趣的话再继续向下看 问题现象 线上反馈,执行批量处理EXCEL数据时,系统一直卡在进度滚动 ...

  5. enq: TX - row lock contention案例

    在Oracle数据库性能报告AWRRPT分析时,发现top 5等待事件第一位的是enq: TX - row lock contention.这个等待事件消耗了绝大多数的CPU资源,导致系统整理性能下降 ...

  6. enq: TX - row lock contention等待事件

    http://www.oracleonlinux.cn/2012/11/resolve-row-lock-contention/ enq: TX - row lock contention 等待事件 ...

  7. 一次大量enq: TX - row lock contention锁等待的问题

    今天下午接到业务报障,系统出现问题,可能是数据库的问题 1,登录系统,查看等待事件,大量row lock 6:12:58] [16:12:58] SID SERIAL# OSUSER USERNAME ...

  8. Oracle-enq: TX - row lock contention 等待事件分析

    什么是enq:TX - row lock contention等待: 等待事件enq:TX - row lock contention 是Oracle常见的几大等待事件之一,在开启的事务中,为了维护事 ...

  9. 详述由ENQ:TX – ROW LOCK CONTENTION引起的全局死锁处理过程

    墨墨导读:ENQ: TX - row lock contention等待事件,是Oracle数据库里最常见的等待事件之一,一般是由于不同的session更新或删除同一条记录.唯一索引有重复索引.位图索 ...

最新文章

  1. 15.linux-LCD层次分析(详解)
  2. Metasploit profiling工具的利用
  3. adding oracle jvm 慢,java – 什么JVM优化导致这些性能结果?
  4. 关于table和ul/ol还有span.
  5. ios开发中,User Defined Runtime Attributes的应用
  6. 洛谷 P4430 小猴打架
  7. HTML MySQL实现登录注册_servlet+html+mysql实现登录注册功能
  8. 构建高性能WEB站点笔记二
  9. android x86 arm translator,让x86的android模拟器能模拟arm架构系统
  10. 小白学python3实战做量化分析平台_Python3 量化分析从小白到破产笔记
  11. 这四行棘手的C代码背后的概念
  12. cimco edit v5_iA Writer for Mac(写作软件)v5.6.3
  13. rails 表单嵌套
  14. 美化滚动条jquery.nicescroll.js
  15. mysql的语句大全_mysql语句大全
  16. 一次从ZoomeyeAPI脚本编写到提权的***实践
  17. Java 查询企业基本信息接口实现(企查查)
  18. 使用pca进行坐标系转换、降维
  19. Win11退Win10/重装Win10教程
  20. 数字人民币来了!它与支付宝、微信有什么区别吗?

热门文章

  1. 对称加密和非对称加密算法分类,国密算法分类。
  2. steam创建账号一直验证人工操作_steam手机版官网版-steam手机版下载
  3. oracle 索引快速全扫描,oracle中的索引扫描
  4. Centos8 yum被删除后怎么安装
  5. android进阶(九)-----Android四大组件的工作过程
  6. 文件上传漏洞(一句话木马)-学习笔记
  7. sip软电话yate client的编译过程
  8. C#串口通讯之-PC串口发送数据
  9. 震惊!680万用户信息泄露,国内某人脸识别公司数据库“裸奔”
  10. python制作查询软件_python 制作本地应用搜索工具