注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

天涯倦客的博客

祝福你朋友永远快乐!

 
 
 

日志

 
 

对oracle ITL(事务槽)的理解  

2013-08-14 16:15:51|  分类: Oracle |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 一、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的独一致性。
  评论这张
 
阅读(404)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017