zoukankan      html  css  js  c++  java
  • ITL(Interested Transaction List)理解

    一、ITL描述:


    ITL(Interested Transaction List)是Oracle数据块内部的一个组成部分,位于数据块头(block header),itl由xid,uba,flag,lck和scn/fsc组成,用来记录该块所有发生的事务,一个itl可以看作是一条事务记录。当然,如果这个事务已经提交,那么这个itl的位置就可以被反复使用了,因为itl类似记录,所以,有的时候也叫itl槽位。如果一个事务一直没有提交,那么,这个事务将一直占用一个itl槽位,itl里面记录了事务信息,回滚段的入口,事务类型等等。如果这个事务已经提交,那么,itl槽位中还保存的有这个事务提交时候的SCN号。


    ITL个数其最小值为1,由参数initrans控制(由于兼容性的原因,oracle会在对象的存储块分配两个itl,所以initrans的最小值实际上为2),最大值为255,由参数maxtrans控制,最大值参数在10g以后不能被修改,itl是block级的概念,一个itl占用块46B的空间,参数initrans意味着块中除去block header外一部分存储空间无法被记录使用(46B*initrans),当块中还有一定的free space时,oracle可以使用free space构建itl供事务使用,如果没有了free space,那么,这个块因为不能分配新的itl,所以就可能发生itl等待。
    如果在并发量特别大的系统中,最好分配足够的itl个数,其实它并浪费不了太多的空间,或者,设置足够的pctfree,保证itl能扩展,但是pctfree有可能是被行数据给消耗掉的,如update,所以,也有可能导致块内部的空间不够而导致itl等待。


    dump一个块可以看到ITL信息类似如下:
         Itl           Xid                                    Uba                             Flag      Lck        Scn/Fsc
        0x01   0x0006.002.0000158e  0x0080104d.00a1.6e   --U-   734    fsc 0x0000.6c9deff0
        0x02   0x0000.000.00000000  0x00000000.0000.00  ----        0       fsc 0x0000.00000000
     


    Xid:事务id,在回滚段事务表中有一条记录和这个事务对应 


    Uba:回滚段地址,该事务对应的回滚段地址 


      第一段地址:回滚数据块的地址,包括回滚段文件号和数据块号 


      第二段地址:回滚序列号 


      第三段地址:回滚记录号 


      SELECT UBAFIL 回滚段文件号,UBABLK 数据块号,UBASQN 回滚序列号,UBAREC 回滚记录号 FROM v$transaction --查看UBA


    Flag:事务标志位。这个标志位就记录了这个事务的操作,各个标志的含义分别是:


    ----- = 事务是活动的,或者在块清除前提交事务


    C--- = 事务已经提交并且清除了行锁定。


    -B-- = this undo record contains the undo for this ITL entry


    --U- = 事务已经提交(SCN已经是最大值),但是锁定还没有清除(快速清除)。


    ---T =当块清除的SCN被记录时,该事务仍然是活动的,块上如果有已经提交的事务,那么在clean ount的时候,块会被进行清除,但是这个块里面的事务不会被清除。


    Lck:影响的记录数


    Scn/Fsc:快速提交(Fast Commit Fsc)的SCN或者Commit SCN。


    每条记录中的行级锁对应于Itl列表中的序号,即哪个事务在该记录上产生的锁。


      


     二、ITL等待


          发生等待的场景:


         1.超过maxtrans配置的最大ITL数


          2.initrans不足,没有足够的free space来扩展ITL


          解决方法:


          1.maxtrans不足:这一情况是由高并发引起的:同一数据块上的事务量已经超出了其实际允许的ITL数。因此,要解决这类问题就需要从应用着手,减少事务的并发量;长事务,在保证数据完整性的前提下,增加commit的频率,修改为短事务,减少资源占用事件。而对于OLAP系统来说(例如,其存在高并发量的数据录入模块),可以考虑增大数据块大小。


          2.initrans不足:数据块上的ITL数量并没有达到MAX TRANS的限制,发生这种情况的表通常会被经常UPDATE,从而造成预留空间(PCTFREE)被填满。如果我们发现这类ITL等待对系统已经造成影响,可以通过增加表的INITRANS或者PCTFREE来解决(视该表上的并发事务量而定,通常,如果并发量高,建议优先增加INITRANS,反之,则优先考虑增加PCTFREE)。


      要注意的一点是,如果是使用ALTER TABLE的方式修改这2个参数的话,只会影响新的数据块,而不会改变已有数据的数据块——要做的这一点,需要将数据导出/导入、重建表。


     


    ITL重用后如何实现前ITL读一致性:


         ORACLE通过ITL条目中记录的回滚段地址找到回滚段,实现读一致性,如果事务已提交,ITL就可以被重用,但是若前一个ITL被重用,前一个ITL的读一致性是如何实现的呢?


         假定block只有一个itl,假定第一个事务的时候产生了 ITL-0 


         第二个事务来了,产生了 ITL-1 ,ITL-1 里面的UBA 可以找到回滚段地址,回滚段中除了记录了 block用户数据的 before image 外还记录了  ITL-0 的信息。


         第三个事务来了,产生了 ITL-2  , ITL-2 中 UBA 指向回滚段,回滚段中 也记录了 ITL-1 的信息。


         这样当一个查询若需要ITL-0时候的信息,则找到当前block,发现是 ITL-2 ,根据UBA找到回滚段进行 roll 得到  变化前 block ,这个时候发现block中是 ITL-1 . 还不能满足需求。 于是再根据 ITL-1 中的 UBA 又去回滚段中找到数据来进行roll,得到一个block 数据,这个时候block中就有了 ITL-0。


         通过根据当前ITL进行递归的方式找到数据,实现之前ITL的独一致性。






    行锁原理:


    Oracle的锁机制是一种轻量级的锁定机制,不是通过构建锁列表来进行数据的锁定管理,而是直接将锁作为数据块的属性,存储在数据块首部。这个是通过ITL来实现的,一个事务要修改块中的数据,必须获得该块中的一个itl(通过initrans预先分配的或者是通过free space构建的)。通过itl和undo segment header中的transaction table,可以知道事务处于活动阶段,还是已经完成。事务在修改块时(其实就是在修改行)会检查行中row header中的标志位,如果该标志位为0(该行没有被活动的事务锁住,这是可能要进行deferred block cleanout等工作),就把该标志位修改为事务在该块获得的itl的序号,这样当前事务就获得了对记录的锁定,然后就可以修改行数据了,这也就是oracle行锁实现的原理。

  • 相关阅读:
    用 ArcMap 发布 ArcGIS Server FeatureServer Feature Access 服务 PostgreSQL 版本
    ArcMap 发布 ArcGIS Server OGC(WMSServer,MapServer)服务
    ArcScene 创建三维模型数据
    ArcMap 导入自定义样式Symbols
    ArcMap 导入 CGCS2000 线段数据
    ArcMap 导入 CGCS2000 点坐标数据
    ArcGis Server manager 忘记用户名和密码
    The view or its master was not found or no view engine supports the searched locations
    python小记(3)操作文件
    pytest(2) pytest与unittest的区别
  • 原文地址:https://www.cnblogs.com/youngerger/p/8668755.html
Copyright © 2011-2022 走看看