在以前的RDBMS系统中,很多进行事物操作的时候,对行都是进行表锁。在oracle中就不再有锁管理器。当行被事物锁住的时候,相关锁信息放在行所在的块头中。当其他的事物想获得相同块的锁时,无论怎么样都会经过这个行所在的块,这时这个事物就会发现这个行已经被锁住了。这样就不需要再在一个单独的资源例如锁管理器中进行排队了。在数据块头有个位置中包含的锁信息,这种数据结构我们就叫它做ITL。ITL这样一个链接列表数据结构维护事物地址和rowid的信息。ITL为事物包含几个slots。当一个块中的行第一次被锁住的时候。这个事物把锁信息和rowid放置在一个slot当中。当相同的或者另一个事物想要锁另一个行的时候,这些信息放置在另一个slot当中。
当创建表的时候 INITRANS 这个参数决定了多少slot在ITL中是可用的,当事物消耗掉所有的slots的时候,如果还有其他的事物需要锁行,则slots就会进行增长,并且增长的最大值是由 MAXTRANS 控制。
如果块中的ITL已经无法再继续增长了,但是又有事物需要slot。这时锁这个行就需要进行等待,直到slot再次变为可用状态。这个等待叫做ITL waits,让我们看看以下的例子:
假设我们创建了一个表,这个表的 INITRANS 为1, MAXTRANS 为11
因为 INITRANS 为1,所以仅仅有一个slot在ITL中,我们插入几行数据在这个块中,类似如下:
插入数据之后,empty space会降低,假设这时有一个事物, Txn1更新了row1并且没有提交。这时就产生了一个row1的锁,并且事物把这个锁放在ITL的slot中:
当第二个事物 Txn2 更新row2时,进行锁行row2的时候。但是目前没有更多可用的slots用于新的事物。因为 MAXTRANS 为11,所以ITL的slot能够增长为11。并且block中有足够的empty space。所以ITL能够创建slot2分配给Txn2:
目前Empty space已经是有限的了,并且不再有足够的空间去创建一个slot。如果这时有另一个事物去更新row3,但是必须在ITL有一个空闲的slot。 MAXTRANS 为11,当前仅有2个slot被创建。但是在这个块中却没有多余的空间去创建新的slot,所以slot不能被创建,所以Txn3必须等待其他的事物rollback和commit。之后slot就会变为空闲状态。这种时候这个被阻塞的session在v$session表现为ITL waits等待事件。
那怎么降低ITL waits呢?
这就首先看为什么会发生ITL waits,这是由于slots对于事物来说是不足的,或者空余空间无法继续创建slots。所以可以设置一个高的 INITRANS 值来确保有足够多的空闲slots,但是万事没有两全, INITRANS 这个值设置高了,对于真正数据留有的空闲空间就会相对少了。
另一个方法就是确定数据能够较少的使用空间以确保ITL能够有足够的空间使用ITL的爆发性增长。这个能够使用 increasing PCTFREE, increasing FREELISTS and FREELIST GROUPS parameters来实现,这样块就能够使用较少的data空间,并为ITL留有足够的空间增长。这样也会导致这个表会表现为更少的 buffer busy waits 等待事件,增强性能。
当创建表的时候 INITRANS 这个参数决定了多少slot在ITL中是可用的,当事物消耗掉所有的slots的时候,如果还有其他的事物需要锁行,则slots就会进行增长,并且增长的最大值是由 MAXTRANS 控制。
如果块中的ITL已经无法再继续增长了,但是又有事物需要slot。这时锁这个行就需要进行等待,直到slot再次变为可用状态。这个等待叫做ITL waits,让我们看看以下的例子:
假设我们创建了一个表,这个表的 INITRANS 为1, MAXTRANS 为11
![fig1.jpg](https://i-blog.csdnimg.cn/blog_migrate/da08ac51f95e66ecdb33c53651303af2.jpeg)
因为 INITRANS 为1,所以仅仅有一个slot在ITL中,我们插入几行数据在这个块中,类似如下:
![fig2.jpg](https://i-blog.csdnimg.cn/blog_migrate/02aa43bfa08f314e011a34e54811fb68.jpeg)
插入数据之后,empty space会降低,假设这时有一个事物, Txn1更新了row1并且没有提交。这时就产生了一个row1的锁,并且事物把这个锁放在ITL的slot中:
![fig3.jpg](https://i-blog.csdnimg.cn/blog_migrate/154fc1b1ddad78f1ec215f1e9d9c34c4.jpeg)
当第二个事物 Txn2 更新row2时,进行锁行row2的时候。但是目前没有更多可用的slots用于新的事物。因为 MAXTRANS 为11,所以ITL的slot能够增长为11。并且block中有足够的empty space。所以ITL能够创建slot2分配给Txn2:
![fig4.jpg](https://i-blog.csdnimg.cn/blog_migrate/09af36ac44fb3e2a22d910287b0edbec.jpeg)
目前Empty space已经是有限的了,并且不再有足够的空间去创建一个slot。如果这时有另一个事物去更新row3,但是必须在ITL有一个空闲的slot。 MAXTRANS 为11,当前仅有2个slot被创建。但是在这个块中却没有多余的空间去创建新的slot,所以slot不能被创建,所以Txn3必须等待其他的事物rollback和commit。之后slot就会变为空闲状态。这种时候这个被阻塞的session在v$session表现为ITL waits等待事件。
那怎么降低ITL waits呢?
这就首先看为什么会发生ITL waits,这是由于slots对于事物来说是不足的,或者空余空间无法继续创建slots。所以可以设置一个高的 INITRANS 值来确保有足够多的空闲slots,但是万事没有两全, INITRANS 这个值设置高了,对于真正数据留有的空闲空间就会相对少了。
另一个方法就是确定数据能够较少的使用空间以确保ITL能够有足够的空间使用ITL的爆发性增长。这个能够使用 increasing PCTFREE, increasing FREELISTS and FREELIST GROUPS parameters来实现,这样块就能够使用较少的data空间,并为ITL留有足够的空间增长。这样也会导致这个表会表现为更少的 buffer busy waits 等待事件,增强性能。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30291162/viewspace-1721005/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30291162/viewspace-1721005/