暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

Oracle锁概念与常见锁分析详谈(传承篇)

OCM之家 2021-08-19
1413


3.Enqueue锁


3.1知识点

enqueue是共享内存结构(锁),用于串行化访问数据库资源。参考如下:

WAITEVENT:"enqueue" Reference Note (文档 ID 34566.1)

VIEW:"V$LOCK" Reference Note (文档 ID 29787.1)

在很多trc中,我们会看到enqueue的表现格式为:"TYPE-ID1-ID2",如:

*** 2015-10-1511:15:28.960

ksqgtl *** TM-0001598e-00000000 mode=4 flags=0x401timeout=0 ***

ksqgtl: xcb=0x14b7203f8,ktcdix=2147483647, topxcb=0x14b7203f8

在Oracle 9i的等待事件中,没有把enqueue进行细分,所以如果需要在9i中具体判断是什么enqueue锁,需要通过v$session_wait中enqueue等待事件的P1进行计算。转换方法可以参考:34566.1

 SELECT sid,chr(to_char(bitand(p1,-16777216))/16777215)||

         chr(to_char(bitand(p1,16711680))/65535) "Lock",

         to_char( bitand(p1, 65535) )    "Mode", p1, p2, p3

    FROM v$session_wait

   WHERE event = 'enqueue';


其实转换的原理很简单,通过查询v$event_name可以得到解释:


SQL> selectname,PARAMETER1, PARAMETER2, PARAMETER3 from v$event_name e where e.NAME ='enqueue';

SQL> selectname,PARAMETER1, PARAMETER2, PARAMETER3 from v$event_name e where e.NAME ='enqueue';



转换的方法是v$session_wait查到的行,把P1RAW进行拆分,如64位系统中,高8位是锁名称,而低8位是请求的锁模式。具体示例如下:

selectsid,seq#,event,p1raw from v$session_wait

where event in('enqueue')

order by p1;



P1RAW是十六进制数,其中4857是锁名称,转成ASCII码为:

SQL> SELECTutl_raw.cast_to_varchar2(replace('4857',' ')) value

     FROM dual;

VALUE

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

HW


所以会话请求HW的排它锁(REQUEST=6,一般发生锁等待事件,都是请求者,所以这里是REQUEST)发生等待。具体什么情况会发生HW的排它锁等待,本篇内容暂不展开讨论。


在Oracle 10g里对enqueue进行了细分,而10g里已经没有enqueue这个等待事件,而是拆分成各个详细的“enq: <TYPE>”类型的等待事件。在10g中'enq: <TYPE>%'类型的等待事件有220多个。

SQL> select* from v$event_name e where e.NAME like 'enq: TX%';


3.2Event

对于想要诊断一个会话在执行过程中需要获取什么锁,可能通过设置10704 Event进行跟踪。

$ oerr ora10704

10704, 00000,"Print out information about what enqueues are being obtained"

//*Cause:  When enabled, prints outarguments to calls to ksqcmi and

//          ksqlrl and the return values.

// *Action:Level indicates details:

//   Level: 1-4: print out basic info for ksqlrl,ksqcmi

//          5-9: also print out stuff incallbacks:  ksqlac, ksqlop

//          10+: also print out time for eachline

 

SQL>oradebug setmypid;

Statementprocessed.

SQL>oradebug event 10704 trace name context forever,level 10;

Statementprocessed.

SQL>lock  table t1 in share mode;

Table(s)Locked.

SQL>oradebug tracefile_name;

/oracle/diag/rdbms/test3/test3/trace/test3_ora_37916.trc

locktable获取的enqueue锁如下:

*** 2015-10-1914:55:41.182

ksqgtl *** CU-4e845ff8-00000001 mode=6flags=0x10000 timeout=300 ***

ksqgtl: notransaction

ksqgtl: useexisting ksusetxn DID

ksqgtl:

        ksqlkdid: 0001-001E-000030CF

 

*** 2015-10-1914:55:41.182

***ksudidTrace: ksqgtl

        ksusesdi:   0000-0000-00000000

        ksusetxn:   0001-001E-000030CF

ksqgtl:RETURNS 0

 

*** 2015-10-1914:55:41.192

ksqrcl:CU,4e845ff8,1

ksqrcl:returns 0

 

*** 2015-10-1914:55:41.193

ksqgtl *** TM-000159cc-00000000 mode=4flags=0x401 timeout=21474836 ***

ksqgtl:xcb=0x14b6f8c20, ktcdix=2147483647, topxcb=0x14b6f8c20

        ktcipt(topxcb)=0x0

 

*** 2015-10-1914:55:41.193

ksucti: inittxn DID from session DID

ksqgtl:

        ksqlkdid: 0001-001E-000030CF

 

*** 2015-10-1914:55:41.193

***ksudidTrace: ksqgtl

        ktcmydid(): 0001-001E-000030CF

        ksusesdi:   0000-0000-00000000

        ksusetxn:   0001-001E-000030CF

ksqgtl:RETURNS 0


3.3TX


TX锁的具体概念,可以参考:TX Lock "TransactionEnqueue" (文档 ID 197057.1)。

TX锁是事务enqueue锁,会话持有了TX锁,就表明会话做了事务(如:INSERT, UPDATE, DELETE……),TX锁一般在COMMIT和ROLLBACK后释放。TX锁主要作为排队机制,其它会话修改相同数据时,必须要等到本事务结束。当某个事务的开始时间小于某个查询的开始时间时,TX锁也用于构建数据的一致性读的前景象。


TX锁的ID1和ID2字段说明:

SQL> selecttype, name, id1_tag, id2_tag from v$lock_type l where l.TYPE = 'TX';



TX锁的ID1的高4位就是USN,ID2的低4位是slot,验证如下:

SQL>update t1 set name = 'a' where id = 1517;

1row updated.

SQL> selects.sid,

       t.XIDUSN,

       t.XIDSLOT,

       t.XIDSQN,

       l.TYPE,

       trunc(l.ID1/power(2,16)) as id1_usn,

       bitand(l.ID1,to_number('ffff','xxxx'))as id1_slot,

       l.ID2,

       l.LMODE,

       l.REQUEST

  from v$lock l, v$transaction t, v$session s

 where s.SADDR = t.SES_ADDR

   and s.SID = l.SID

   and l.type = 'TX';

 

TX锁的ID1与ID2与v$transaction上的信息一致,其中USN、SLOT、SQN三个字段组成XID(Transaction ID)。

SQL> selectdbms_rowid.rowid_relative_fno(rowid) as fno,

            dbms_rowid.rowid_block_number(rowid) asbno

       from t1 where id = 1517;


转储block后,ITL信息如下:

Object id onBlock? Y

  seg/obj: 0x159cc  csc: 0x00.3863ba  itc: 2 flg: -  typ: 1 - DATA

     fsl: 0 fnx: 0x0 ver: 0x01

 

 Itl          Xid                  Uba         Flag Lck        Scn/Fsc

0x01   0x000a.003.000020c9  0x00c00120.0d7f.07  ----   1  fsc 0x0003.00000000

0x02   0x0003.017.00000580  0x00c03d49.03d0.09  C---   0  scn 0x0000.00365455


  • USN为回滚段号

  • SLOT为事务槽号

  • SQN为序号(该值暂时不解释,请参考相关文档)

SQL> selects.segment_name from dba_rollback_segs s where s.segment_id = 10;

SEGMENT_NAME

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

_SYSSMU10_1197734989$

SQL> ALTERSYSTEM DUMP UNDO HEADER '_SYSSMU10_1197734989$';

Systemaltered.


转储回滚段头后,检查相应的槽位信息如下,state=10表明该槽位上有个活跃事务:


所以TX锁的ID1和ID2就指到了回滚段的事务槽。每次开始新事务,都需要先分配事务槽,被修改数据块上的ITL的XID信息也指向了相应的事务槽。如果另一个事务修改相同数据块的相同行,发现ITL指向了同一个事务槽,那后来进行的会话就会挂起,等待TX锁。

3.4TM

TM锁比较简单,事务执行INSERT,UPDATE,DELETE,MERGE,SELECT FOR UPDATE,或LOCK TABLE等SQL语句修改一个表时,需要获取'TM'(Table Manipulation)DML队列。持有TM锁,表明事务对相关表有DML操作的权力,并且防止DDL操作与本事务的冲突。假如已经有会话在对表进行DDL操作,如果有其它会话要修改这张表的数据,就首先要申请TM锁,而这时申请TM锁会被挂住,等待事件就是enq: TM - contention。

3.5特殊的锁

3.5.1.  DFS lock handle等待

一个会话的等待事件为DFS lock handle,表明这个会话在等待一个全局锁请求的锁句柄。在Oracle RAC中,一些对象级别的State Object会演化为全局锁,如Drop Table,Truncate Table等引起的Table对象变化,另外RAC中sequence创建为ordered类型,那当访问这个sequence时,需要给节点分配全局锁,当访问sequence并发较高时,也会导致DFS lock handle。

SQL> select* from v$event_name e where e.NAME = 'DFS lock handle';




观察DFS lock handle等待事件的定义,其中p1是锁的类型和模式,p2、p3是id1和id2,其实这个等待事件也是与v$lock相关。

例如:以下是DFS lock handle等待信息

SID  SEQ# EVENT                   P1     P2 P3

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

767 24410 DFSlock handle 1398145029 696629  0

查看锁的信息如下:

SELECT chr(to_char(bitand(1398145029,-16777216))/16777215)||

       chr(to_char(bitand(1398145029,16711680))/65535) "Lock",

       to_char( bitand(1398145029, 65535))  "Mode"

  FROM dual;

 

Lock Mode

---- -----

SV   5

这是SV锁是与sequence相关的锁,而p2=696629是这个sequence的object_id。




中国OCM之家

专注数据    共现梦想

QQ群:554334183


文章转载自OCM之家,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论