最近发现有个RAC库后台alert日志中每天都会报出大量全局死锁,并且在AWR中发现TOP5事件中总是存在大量enq: TX - allocate ITL entry等待
如下:
SID SERIAL# STATUS USERNAME PROGRAM EVENT SECONDS_IN_WAIT BLOCKING_SESSION SQL_ID
---------- ---------- -------- ---------- -------------------- ---------------------------------------- --------------- ---------------- -------------
3085 50398 ACTIVE ECMS Aloha.exe enq: TX - allocate ITL entry 28 2826 bhwrndpu3jvpg
1589 56075 ACTIVE ECMS Aloha.exe enq: TX - allocate ITL entry 28 3088 bhwrndpu3jvpg
1833 3652 ACTIVE ECMS Aloha.exe enq: TX - row lock contention 94 3138 bhwrndpu3jvpg
2817 50181 ACTIVE ECMS Aloha.exe enq: TX - row lock contention 94 3088 bhwrndpu3jvpg
问题分析,发生allocate ITL entry等待的原因:
当一个事务需要修改一个数据块时,需要在数据块头部获取一个可用的ITL槽,用于记录事务的id,使用undo数据块地址,scn等信息。如果事务申请不到新的可用ITL槽时,就会产生enq: TX - allocate ITL entry等待。 发生这个等待时,要么是块上的已分配ITL个数(通过ini_trans参数控制)达到了上限255(10g以后没有了max_trans限制参数,无法指定小于255的值),要么是这个块中没有更多的空闲空间来容纳一个ITL了(每个ITL占用24bytes)。 默认情况下创建的表ITL槽数最小为1+1,pctfree为10,那么如果是这样一种情况,如果表中经常执行update语句,然后块中剩余的10%空间所剩无几,而且业务的并发量还很大,此时就很容易遇到enq: TX - allocate ITL entry等待。
如下:
SID SERIAL# STATUS USERNAME PROGRAM EVENT SECONDS_IN_WAIT BLOCKING_SESSION SQL_ID
---------- ---------- -------- ---------- -------------------- ---------------------------------------- --------------- ---------------- -------------
3085 50398 ACTIVE ECMS Aloha.exe enq: TX - allocate ITL entry 28 2826 bhwrndpu3jvpg
1589 56075 ACTIVE ECMS Aloha.exe enq: TX - allocate ITL entry 28 3088 bhwrndpu3jvpg
1833 3652 ACTIVE ECMS Aloha.exe enq: TX - row lock contention 94 3138 bhwrndpu3jvpg
2817 50181 ACTIVE ECMS Aloha.exe enq: TX - row lock contention 94 3088 bhwrndpu3jvpg
问题分析,发生allocate ITL entry等待的原因:
当一个事务需要修改一个数据块时,需要在数据块头部获取一个可用的ITL槽,用于记录事务的id,使用undo数据块地址,scn等信息。如果事务申请不到新的可用ITL槽时,就会产生enq: TX - allocate ITL entry等待。 发生这个等待时,要么是块上的已分配ITL个数(通过ini_trans参数控制)达到了上限255(10g以后没有了max_trans限制参数,无法指定小于255的值),要么是这个块中没有更多的空闲空间来容纳一个ITL了(每个ITL占用24bytes)。 默认情况下创建的表ITL槽数最小为1+1,pctfree为10,那么如果是这样一种情况,如果表中经常执行update语句,然后块中剩余的10%空间所剩无几,而且业务的并发量还很大,此时就很容易遇到enq: TX - allocate ITL entry等待。
问题模拟:
create table ttitl as select * from dba_objects;
select t.object_id,t.object_name,dbms_rowid.rowid_relative_fno(t.rowid),dbms_rowid.rowid_block_number(t.rowid) from ttitl t where dbms_rowid.rowid_block_number(t.rowid)=143612;
通过几个更新语句将默认的ITL槽占满
update ttitl set object_name='xxxxxxxxxxx' where object_id=20;
alter system dump datafile 4 block 143612;
我们要拿4号文件的143612块做实验,目前块中拥有92行数据,现在还需要看块上还存在多少剩余空间? 答案是通过fseo-fsbo或者bbed得到。
fseo=0x342 --=======>>>>>>fseo代表Free Space End offset 空闲空间的结束偏仪量
0x342-0xc8=0x27A
834-200=634
产生一个事务后
fsbo=0xc8
fseo=0x32a
0x32a-0xc8=0x262=610
634-610=24bytes 也正验证了一个itl槽占24bytes的说法
按照这个方式计算,这个块上还能够存在很多事务,610/24=25,该块上还能增加25个事务呢
现在通过update方式将块上的空闲空间缩小
update ttitl set object_name='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' where object_id>60;
现在通过BBED和重新dump该块发现此块空闲空间已经只剩19bytes了
[oracle@test ~]$ cat par.txt
blocksize=8192
listfile=filelist.txt
mode=edit
[oracle@test ~]$ cat filelist.txt
1 /u01/app/oracle/oradata/orcl/system01.dbf 933232640
2 /u01/app/oracle/oradata/orcl/mctpsys.dbf 10485760
3 /u01/app/oracle/oradata/orcl/sysaux01.dbf 618659840
4 /u01/app/oracle/oradata/orcl/users01.dbf 2246574080
5 /u01/app/oracle/oradata/orcl/example01.dbf 104857600
6 /u01/app/oracle/oradata/orcl/users02.dbf 52428800
7 /u01/app/oracle/oradata/orcl/mgmt.dbf 1363148800
8 /u01/app/oracle/oradata/orcl/mgmt_deepdive.dbf 209715200
9 /u01/app/oracle/oradata/orcl/mgmt_ecm_depot1.dbf 41943040
10 /u01/app/oracle/oradata/orcl/EPMRANGE1.dbf 6442450944
11 /u01/app/oracle/oradata/orcl/EPMIDX.dbf 4294967296
12 /u01/app/oracle/oradata/orcl/EPMDAT1.dbf 209715200
13 /u01/app/oracle/oradata/orcl/undotbs02.dbf 5368709120
14 /u01/app/oracle/oradata/orcl/mctpsys1.dbf 314572800
15 /u01/app/oracle/oradata/orcl/mctpsys2.dbf 1073741824
16 /u01/app/oracle/oradata/orcl/rmantbs.dbf 209715200
17 /u01/app/oracle/oradata/orcl/ggs1.dbf 524288000
18 /u01/app/oracle/oradata/orcl/ZZZ1.DBF 20971520
[oracle@test ~]$ bbed parfile=par.txt
Password: blockedit
BBED: Release 2.0.0.0.0 - Limited Production on Mon Apr 20 11:37:30 2015
Copyright (c) 1982, 2007, Oracle. All rights reserved.
************* !!! For Oracle Internal Use only !!! ***************
BBED> set dba 4,143612
DBA 0x010230fc (16920828 4,143612)
BBED> map
File: /u01/app/oracle/oradata/orcl/users01.dbf (4)
Block: 143612 Dba:0x010230fc
------------------------------------------------------------
KTB Data Block (Table/Cluster)
struct kcbh, 20 bytes @0
struct ktbbh, 120 bytes @20
struct kdbh, 14 bytes @148
struct kdbt[1], 4 bytes @162
sb2 kdbr[91] @166
ub1 freespace[19] @348 --====>>>>>>>>>>>>>块上的空闲空间为19bytes
ub1 rowdata[7821] @367
ub4 tailchk @8188
--摘自datafile dump日志
fsbo=0xc8
fseo=0xdb
0xdb-0xc8=0x13=19 这个块上只有19bytes字节的空间了,看来是无法再容纳一个ITL槽了,再新产生一个事务
update ttitl set object_name='I_FILE1' where object_id=41;
此时可以看到enq: TX - allocate ITL entry等待,直至块上的其它事务提交或回滚后,此会话才能继续,否则一直处于等待状态。
SQL> select sid,serial#,status,username,event,seconds_in_wait,sql_id from v$session where serial#<>1 and sql_id is not null and event not like '%SQL*Net message%' and event not like 'Streams AQ%' order by 7;
SID SERIAL# STATUS USERNAME EVENT SECONDS_IN_WAIT SQL_ID
---------- ---------- -------- ---------- ---------------------------------------- --------------- -------------
528 39292 ACTIVE TT enq: TX - allocate ITL entry 4 512zw5fc3bztt
--记录一下enq锁的p1 p2 p3值的含义
select * from v$session where event like 'enq%';
EVENT# 189
EVENT enq: TX - allocate ITL entry
P1TEXT name|mode
P1 1415053316
P1RAW 0000000054580004
P2TEXT usn<<16 | slot
P2 131084
P2RAW 000000000002000C
P3TEXT sequence
P3 88864
P3RAW 0000000000015B20
--P1值与锁名称和锁模式有关1415053316转换成16进制后为54580004,其中54代表字母T,58代表字母X,合一起就是锁的name.
SQL> select dump('T',16),dump('X',16) from dual;
DUMP('T',16) DUMP('X',16)
---------------- ----------------
Typ=96 Len=1: 54 Typ=96 Len=1: 58
--P1值的后4位0004代表申请锁的模式
SQL> select * from v$lock where sid=528;
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
---------------- ---------------- ---------- ---- ---------- ---------- ---------- ---------- ---------- ----------
00000000DEC35368 00000000DEC35388 528 TX 131084 88864 0 4 129 0
00000000DD5099A8 00000000DD5099D0 528 TM 1519283 0 3 0 1294 0
--P2和P3值与事务相关,比如上面的P2值131084代表XIDUSN和XIDSLOT,
select 131084/45536 as usn,round(mod(131084,45536)) slot from dual;
--P3值88864代表xidsqn
ADDR XIDUSN XIDSLOT XIDSQN UBAFIL UBABLK UBASQN UBAREC STATUS START_TIME START_SCNB START_SCNW START_UEXT START_UBAFIL START_UBABLK START_UBASQN START_UBAREC SES_ADDR FLAG SPACE RECURSIVE NOUNDO PTX NAME PRV_XIDUSN PRV_XIDSLT PRV_XIDSQN PTX_XIDUSN PTX_XIDSLT PTX_XIDSQN DSCN-B DSCN-W USED_UBLK USED_UREC LOG_IO PHY_IO CR_GET CR_CHANGE START_DATE DSCN_BASE DSCN_WRAP START_SCN DEPENDENT_SCN XID PRV_XID PTX_XID
---------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------------- -------------------- ---------- ---------- ---------- ------------ ------------ ------------ ------------ ---------------- ---------- ----- --------- ------ --- -------------------------------------------------------------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------- ---------- ---------- ---------- ------------- ---------------- ---------------- ----------------
00000000DD61F730 6 29 74079 19 9504 19040 51 ACTIVE 04/20/15 10:30:56 3585075880 2902 18 19 9504 19040 51 00000000DF221CA0 7683 NO NO NO NO 0 0 0 0 0 0 0 &
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26753337/viewspace-1621028/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/26753337/viewspace-1621028/