且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

enq: TX - row lock/index contention、allocate ITL等待事件

更新时间:2022-08-30 22:45:48

SQL> select name from v$event_name where name like '%TX%'; NAME ---------------------------------------------------------------- enq: TX - row lock contention enq: TX - allocate ITL entry enq: TX - index contention enq: TX - contention     enqueue TX事务锁 transaction enqueue,顾名思义这个队列锁用来保护事务信息。   当进程修改某块中的一行数据,则Oracle必须将该事务信息与被改变的这一行联系起来,做法是在块中的row piece的lk上标记ITL位,而实际的ITL记录了这个事务相关的回滚段号USN,以便能够定位其撤销链。 这样做的目的有几个:
  1. 允许用户手动rollback或者因为dead transaction的发生而后台(PMON or SMON 取决于_cleanup_rollback_entries)回滚该事务。
  2. 在块中留下Undo线索,才能让查询者Queryer顺藤摸瓜去构造这个块在事务发生前的镜像块

  绝大多数情况下 ,TX enqueue的申请、获得模式总是排他的exclusive的即mode=6/request=6的(v$LOCK),这通常意味着我们的DML操作所感兴趣的数据行正被其他事务锁定着, 但这并不绝对。   有场景中我们会以共享模式Share mode=4/request=4(V$LOCK)去申请、获得TX enqueue锁; 一种场景是进程仅仅先需要申请到数据块(data block包括table/index)上的 ITL(interested transaction lists)事务槽。 以share mode等待(request=4)TX enqueue 的一种可能就是块上无法再扩展本进程所需要的一个ITL了,要么这个块上的ITL 超过MAXTRANS(255)ITL的上限值了,要么是这个块没有更多的空间来容纳更多一个ITL了,(一个ITL 24字节)。   若争用contention缘起于排他的exclusive TX队列申请,则表明有并发事务试图锁住同一行数据。 大多数情况下这是由于应用引起的。 实际上log file sync(其实是写redo慢)也会造成buffer busy wait。   若争用contention缘起于共享shared TX 队列申请,则有可能是一个或多个数据块无法扩展事务表所导致的。在这种情况下可以考虑增加更大的INITTRANS来解决问题: 对于该问题建议做10046 level 8+ buffer cache dump配合V$SESSION fileid/blockid/objno来诊断问题。   从版本9iR2开始可以通过动态性能视图的V$SEGMENT_STATISTICS来判断对象是否经历ITL 等待 ,但是实例参数 STATISTICS_LEVEL必须设置为typical 以上,可以参考statspack中segment by ITL的环节,当然AWR里也有类似的信息: select owner, object_name from v$segment_statistics where statistic_name = 'ITL waits' and value > 0;   TX锁的 ID1/ID2解释 ID1 是用来存放 USN==> Undo Segment Number以及相关的undo segment transaction slot,通过以下转换获得: (undo_segment_number << 16) + slot ID2是事务槽位序列号



本文转自maclean_007 51CTO博客,原文链接:http://blog.51cto.com/maclean/1277922