Oracle新建或重建索引过程中的锁信息

0    275    2

Tags:

👉 本文共约4316个字,系统预计阅读时间或需17分钟。

简介

可以利用10704和10046事件跟踪新建或重建索引过程中的锁信息,命令为:

新建或重建索引的锁信息如下图所示:

Oracle新建或重建索引过程中的锁信息

不带ONLINE的新建或重建索引的SQL语句获取的是4级TM锁,它会阻塞任何DML操作。

在Oracle 10g中,带ONLINE的新建或重建索引的SQL语句在开始和结束的时候获取的是4级TM锁,而在读取表数据的过程中获取的是2级TM锁,所以,在Oracle 10g中,即使加上ONLINE也会阻塞其它会话的DML操作。

在Oracle 11g中,带ONLINE的新建或重建索引的SQL语句在整个执行过程中获取的是2级TM锁,并不会阻塞其它会话的DML操作,但是在创建或重建索引的过程中,其它的会话产生的事务会阻塞索引的创建或重建操作,所以必须结束其它会话的事务才能让创建或重建索引的操作完成。所以应该避免在业务高峰期创建索引。

在Oracle 11g带ONLINE的新建或重建索引的情况下:

① 过程中会持有OD(ONLINE DDL)、DL(Direct Loader Index Creation)两种类型的锁,在Oracle 10g下只有DL锁没有OD锁。

② 表级锁TM的持有模式为2级RS(Row Share)与3级RX(Row Exclusive)类型的锁互相兼容,因此不会在表级发生阻塞。

③ 阻塞发生在行级锁申请阶段,即请求的4级S(Share)类型的锁与执行DML的会话已经持有的6级X(Exclusive)锁之间存在不兼容的情况;相比非ONLINE方式的表级锁,锁的粒度上更加细化,副作用更小。

④ 新增以“SYSJOURNAL”为前缀的IOT表,记录与索引创建动作同时进行的其它DML操作修改过的记录,等到索引创建完成前将IOT表里的记录合并至索引中并删除IOT表。

本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!

实验

创建或重建索引会阻塞DML操作

版本:11.2.0.3

可以发现在会话1中,在创建索引的过程中会生成2个TM锁,锁类别分别为4和3,根据查询结果发现lmode=4的object_id为77629的对象对应的是T_INDEX_161113这个表,对应的是TM的S锁。另一个lmode=3的锁对象是系统基表OBJ$表,允许其它会话对该表执行DML操作。可以得出这样一个结论:当对表进行创建索引操作时,会伴随出现LMODE=4的S锁。根据锁的兼容模式可以发现S锁和任何DML操作都是冲突的!所以,尤其是在生产上,当在一个很大的表上进行索引创建的时候,任何对该表的DML操作都会被夯住!!!

从DBA_DDL_LOCKS视图可以看到,建索引的同时有6级排它DDL锁。

Oracle 11g下ONLINE选项不会堵塞DML操作

版本:11.2.0.3

接着上面的实验,重建索引的时候加上ONLINE,由于会话断开了,重新开2个会话,会话1为22,会话2为142:

Oracle新建或重建索引过程中的锁信息

可以发现在会话1中,在加上ONLINE重建索引的过程中会生成2个TM锁,锁类别分别为2和4,根据查询结果发现lmode=2的object_id为77629的对象对应的是T_INDEX_161113这个表,对应的是TM的Row-S (SS)锁即行级共享锁,该锁允许其它会话对该表执行DML操作。另一个lmode=4的锁对象是SYS_JOURNAL_77631,应该为系统临时创建的对象,对应的是TM的S锁。
在会话2中,TX为6的锁,阻塞了其它会话,在这里其实是阻塞了会话1的重建索引的操作。
可以得出这样一个结论:当对表进行创建或重建索引操作时,可以加上ONLINE选项,不阻塞其它会话的DML操作,但是在创建或重建索引的过程中,其它的会话产生的事务会阻塞索引的创建或重建操作,所以必须结束其它会话的事务才能让创建或重建索引的操作完成。
注意:在加上ONLINE选项创建索引的过程中,若手动CTRL+C取消后,可能导致索引被锁,出现ORA-08104: this index object 77645 is being online built or rebuilt的错误,这个时候可以利用如下的脚本清理对象,77645为对象的OBJECT_ID:

Oracle 10g下ONLINE选项会堵塞DML操作

版本为:10.2.0.1.0

重新开3个会话,会话1为143,会话2为152,会话3为158:

Oracle新建或重建索引过程中的锁信息

可以发现在会话1中,在加上ONLINE重建索引的过程中会生成2个TM锁,锁类别分别为2和4,根据查询结果发现lmode=2的object_id为53121的对象对应的是T_INDEX_161113这个表,对应的是TM的Row-S (SS)锁即行级共享锁,该锁允许其它会话对该表执行DML操作,但是该会话在请求模式为4的S锁。另一个lmode=4的锁对象是SYS_JOURNAL_53122,为系统临时创建的索引组织表(IOT),对应的是TM的S锁。

在会话2中,请求3级TM锁。会阻塞关系可以看出,会话3阻塞了会话1,而会话1阻塞了会话2,所以提交会话3即可让索引创建完成。

实验10.2.0.1.0

版本为:10.2.0.1.0
重新开3个会话,会话1为143,会话2为152,会话3为158,会话1插入一条记录:

Oracle新建或重建索引过程中的锁信息

从上面的结果可以知道,会话2即创建索引的会话一共出现了4个锁,两个DL锁,一个针对表T_INDEX_161113的TM锁,一个是online rebuild index时需要的一个中间表的TM锁,中间表用于记录rebuild期间的增量数据,原理类似于物化视图日志,其object_id为53162,这是一个索引组织表(IOT),从这里我们也可以发现IOT的优点和适合的场合,这张中间表只有插入,不会有删除和修改操作,而且只有主键条件查询,正是IOT最合适的场景。

会话2在请求一个模式为4的TM锁,模式4会阻塞这个表上的所有DML操作,所以这时再往这个表上执行DML也会挂起。

会话3删除一条语句:

会话3请求模式为3的TM锁无法获得,会话被阻塞。这是因为锁请求是需要排队的,即使会话3和会话1是可以并发的,但由于会话2先请求锁并进入等待队列,后来的会话3也只好进入队列等待。所以,如果在执行rebuild index online前有长事务,并且并发量比较大,则一旦执行alter index rebuild online,可能因为长事务阻塞,可能导致系统瞬间出现大量的锁,对于压力比较大的系统,这是一个不小的风险。这是需要迅速找出导致阻塞的会话kill掉,rebuild index online一旦执行,不可轻易中断,否则可能遇到ORA-08104。

从会话级别可以看出,会话1阻塞了会话2,会话2阻塞了会话3,在会话1执行rollback,可以发现很短时间内会话3也正常执行完毕,说明会话2持有模式4的TM锁的时间很短,然后在rebuild online的进行过程中,对表加的是模式为2的TM锁,所以这段时间不会阻塞DML操作:

回滚会话1,然后观察锁的情况:

会话2又开始在请求模式4的TM锁,被会话3阻塞!这时在会话1再执行DML操作,同样会被会话2阻塞,进入锁等待队列。

在会话3执行rollback或者commit以后,会话2和会话3都很快执行完毕。

从上面的试验可以发现,虽然rebuild index online在执行期间只持有模式2的TM锁,不会阻塞DML操作,但在操作的开始和结束阶段,是需要短暂的持有模式为4的TM锁的,这段会阻塞表上的所有DML操作。我们在做rebuild index online的时候,一定要在开始和结束阶段观察系统中是否有长事务的存储,对于并发量较大的系统,最严重的后果,可能在这两个关键点导致数据库产生大量锁等待,系统负载飙升,甚至宕机。

实验11.2.0.3.0

版本为:11.2.0.3.0

开3个会话,会话1为16,会话2为27,会话3为150,会话1删除一条记录:

Oracle新建或重建索引过程中的锁信息

可以看到会话2正在请求一个模式为4的TX锁,注意和Oracle 10g请求的TM锁是不一样的,而且在我们以前的概念中,TX锁的模式都是6,这里出现了模式4的TX锁请求,应该是Oracle 11g中新引入的。那么模式4的TX锁和TM锁有什么不同呢?我们继续前面的实验步骤:

会话3的DML操作顺利完成,没有被阻塞。而在10g当中,会话3是会被会话2请求的TM锁所阻塞的,这一点改进是非常有意思的,这样即使rebuid online操作被会话1的长事务阻塞,其他会话的DML操作,只要不和会话1冲突,都可以继续操作,在Oracle 10g及以前版本中的执行rebuild index online而造成锁等待的风险被大大的降低了。

依次提交会话1和会话3,则会话2成功完成。

Oracle 11g在很多细节方面确实做了不少的优化,而且像这样的优化,对于提高系统的高可用性的好处是不言而喻的,在Oracle 11g中,执行rebuild index online的风险将比10g以及更老版本中小得多,因为从头至尾都不再阻塞DML操作了,终于可以算得上名副其实的online操作了。

利用10704和10046跟踪锁

使用10704事件跟踪以下四类操作并对比跟踪结果:

  • create index
  • alter index rebuild
  • create index online
  • alter index rebuild online

1、create index与alter index rebuild所获取的TM锁完全一致
2、create index online与alter index rebuild online所获取的TM锁、临时表完全一致

10g

版本:10.2.0.1

create index

trace文件,搜字符串“cf81”:

alter index ... rebuild

trace文件,搜字符串“cf81”:

create index ... online

trace文件,搜字符串“cf81”:

alter index ... rebuild online

trace文件,搜字符串“cf81”:

11g

版本:11.2.0.3

create index

trace文件,搜字符串“12f3d”:

alter index ... rebuild

trace文件,搜字符串“12f3d”:

create index ... online

trace文件,搜字符串“12f3d”:

alter index ... rebuild online

trace文件,搜字符串“12f3d”:

实验SQL

查询锁用到的SQL语句

扩展

有关Oracle数据库锁的更多内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2128896/

标签:

头像

小麦苗

学习或考证,均可联系麦老师,请加微信db_bao或QQ646634621

您可能还喜欢...

发表回复

嘿,我是小麦,需要帮助随时找我哦
  • 18509239930
  • 个人微信

  • 麦老师QQ聊天
  • 个人邮箱
  • 点击加入QQ群
  • 个人微店

  • 回到顶部
返回顶部