在Oracle数据库性能报告AWRRPT分析时,发现top 5等待事件第一位的是enq: TX - row lock contention。这个等待事件消耗了绝大多数的CPU资源,导致系统整理性能下降。有些查询以前只要几个毫秒,现在变成了数分钟。CPU使用率长时间维持在100%。
声明一下,数据库版本是10g for linux x86 64bit。
在AWRRPT中看到的top 5等待如下:
Top 5 Timed Events Event Waits Time(s) Avg Wait(ms) % Total Call Time Wait Class enq: TX - row lock contention 27,190 62,674 2,305 63.1 Application CPU time 36,227 36.5 log file sync 133,744 52 0 .1 Commit log file parallel write 143,992 29 0 .0 System I/O db 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索引。
相关推荐
cause:当插入新的索引条目时,发现索引块中没有足够的空间容纳新的索引条目,索引块就会产生分裂(分为5-5分裂...这时就会表现为enq: TX - index contention。本例中索引块分裂属于5-5 分裂,此分裂可以通过awr报告观察
BLOG_【AWR分析】Oracle_lhr_队列等待之enq IV - contention案例.pdfBLOG_【AWR分析】Oracle_lhr_队列等待之enq IV - contention案例.pdf
BLOG_Oracle_lhr_【等待事件】序列等待事件总结(enq SQ - contention、row cache lock、DFS lock handle和enq SV - contention).pdfBLOG_Oracle_lhr_【等待事件】序列等待事件总结(enq SQ - contention、row ...
enq PS - contention.pdf enq PS - contention.pdfenq PS - contention.pdf
Buffer busy waits异常等待事件分析与处理。 Buffer latch异常等待事件分析与处理。 Db file parallel read异常等待事件分析与处理。 Db file sequential read异常等待事件分析与处理。 Db file scattered read异常...
BLOG_【故障处理】Oracle_lhr_队列等待之TX - allocate ITL entry案例.pdfBLOG_【故障处理】Oracle_lhr_队列等待之TX - allocate ITL entry案例.pdf
BLOG_Oracle_lhr_ 【等待事件】等待事件系列(5.1)--Enqueue(队列等待) .pdfBLOG_Oracle_lhr_ 【等待事件】等待事件系列(5.1)--Enqueue(队列等待) .pdf
当系统activity增加或者降低的时候,oracle SMON进程会自动ONLINE或者OFFLINE rollback segments。这样导致某些与undo segments相关的latch或者enqueue被...导致系统很多活跃session都开始等待enq: US - contention。
linux实验 linux 作业调度程序 C语言 源码 可执行文件 enq deq stat
/*等待队列的队首结点(懒加载,这里体现为竞争失败的情况下,加入同步队列的线程执行到enq方法的时候会创 建一个Head结点)。该结点只能被setHead方法修改。并且结点的waitStatus不能为CANCELLED*/ private transient...
ИмяпользователяПервое,чтовследуетсделатьпослеустановкиGit —указатьвашеимяиадресэлект。 Этоважно,потомуч...
网络通信命令详解网络通信命令详解网络通信命令详解
通过该程序,你可以用来销售小量各类数字卡币。 主要功能: 1,采用预存方式时实交易数字卡。便利数字卡网上即使交易的特性。 2,带积分、消费总金额、交易历史等统计功能。 3,客户预存点,可采用发行充值卡方式。...
反馈——优先级会根据等待时间变化轮转——同优先级的作业轮流进行具体要求:要求实现3个队列,每个队列时间片不一样:最高优先级队列的轮转时间为1s,次高优先级为2s,最低优先级为5s;当有新作业加入,抢占式运行...
ASCII字符集中的功能控制字符 4 – EOT – E nd O f T ransmission 传输结束 5 – ENQ – ENQ uiry 请求 6 – ACK – ACK nowledgment 回应 / 响应 7 – BEL – [audible] BEL l
priorityqueue.js Node.js的... enq ( { cash : 250 , name : 'Valentina' } ) ;queue . enq ( { cash : 300 , name : 'Jano' } ) ;queue . enq ( { cash : 150 , name : 'Fran' } ) ;queue . size ( ) ; // 3queue . p
ASCII (American Standard Code for Information Interchange) ASCII码大致由以下两部分组成: ...ENQ ACK BEL BS HT LF VT FF CR So SI DLE DCI DC2 DC3 DC4 NAK SYN TB CAN EM SUB ESC FS GS RS Us
ENQ 询问字符 DLE 空格 ESC 换码 ACK 承认 DC1 设备控制1 FS 文字分隔符 BEL 报警 DC2 设备控制2 GS 组分隔符 BS 退一格 DC3 设备控制3 RS 记录分隔符 HT 横向列表 DC4 设备控制4 US 单元分隔符 LF 换行 NAK 否定 ...
ITRI CIM Emulator能够读取SML档案,主要功能是用来测试半导体设备的通讯功能,它支持SECS-I/SECS-II/HSMS-SS通讯协议...Send Non-ENQ Bad Length Byte Bad Checksum T1 Timeout T2 Timeout for Length Byte T4 Timeout
def enQ(): queue.append(raw_input('Enter new string: ').strip()) #调用list的列表的pop()函数.pop(0)为列表的第一个元素 def deQ(): if len(queue) == 0: print 'Cannot pop from an empty queue!' else: ...