众所周知,rebuild index online不会阻塞DML操作,而rebulid index却会阻塞DML操作。现在我们来看一下在rebuild index online及rebulid index下的锁
os: rhel 3
db: oracle 9.2.0.6
在Session 1下的操作
Table created.
SQL> insert into test_object (select * from test_object);
23926 rows created.
SQL> /
47852 rows created.
SQL> /
95704 rows created.
SQL> /
191408 rows created.
SQL> /
382816 rows created.
SQL> commit;
Commit complete.
说明:插入那么多行,为了重建索引的时间长点,能够查到rebuild index在v$lock中的信息。(可能有更好方法)
Index created.
SQL> alter index ind_test_object_id rebuild; (在这个过程中,在session 2中查询v$lock信息)
同时在session 2中查v$lock的信息
SID Lo LOCK_ID1 Locked Mode Requested CTIME BLOCK
-------- -- -------------------- -------------------------- -------------
15 TM TEST_OBJECT Share None 4 0
15 DL 76449 Row-X (SX) None 4 0
发现锁的类型为DL和create index时候的锁类型相同。Document上关于DL锁类型的说明:
DL Direct loader parallel index create
接下来看一下rebuild index online
Session 1中操作
(在这个过程中,在session 2中查询v$lock信息;其实这里会阻塞的,如果session 3插入数据早于rebuild online的完成时间,插入数据并没有提交,这个情况最后再说)
同时Session 2中查询
-------- -- -------------------- -------------------------- ---------------
15 TM SYS_JOURNAL_76454 Share None 1 0
15 DL 76449 Row-X (SX) None 3 0
15 TM TEST_OBJECT Row-S (SS) None 1 0
完成session2查询,马上在Session 3中插入操作
1 row created.
这里不要提交,session 1中的rebuild index online操作就会hang了。(在这步操作时,rebuild index online还没有完成,这个情况最后再说,先说session 3中的DML操作不会堵塞)
为什么在session 3中的不会堵塞呢???你没有发现在v$lock信息中多了一张表SYS_JOURNAL_76454出来(在metalink有这样一句话:At the same time it will maintain a journal table for DML data, which has changed during this index rebuilding operation.)
既然这样,我们就来验证一下这个过程,用10046事件
Session 1:
Session altered.
SQL> alter index IND_TEST_OBJECT_ID rebuild online;
(这里会阻塞的,如果session 2不提交)
在session2中插入数据:
1 row created.
SQL> commit; (commit后,session1中的rebuild index online继续)
Commit complete.
在session1操作
Session altered.
查看跟踪文件
create table "TAOBAO"."SYS_JOURNAL_76454" (C0 NUMBER, opcode char(1), partno number, rid rowid, primary key( C0 , rid )) organization index TABLESPACE "TBS_INDEX1"
value="SYS_JOURNAL_76454"
value="SYS_JOURNAL_76454"
CREATE UNIQUE INDEX "TAOBAO"."SYS_IOT_TOP_76510" on "TAOBAO"."SYS_JOURNAL_76454"("C0","RID") INDEX ONLY TOPLEVEL TABLESPACE "TBS_INDEX1" NOPARALLEL
drop table "TAOBAO"."SYS_JOURNAL_76454"
value="SYS_JOURNAL_76454"
value="SYS_JOURNAL_76454"
value="SYS_JOURNAL_76454"
这里可以发现很多信息,oracle自动创建了中间表SYS_JOURNAL_76454(索引组织表),奇怪的一点:我插入完数据,并提交,应该会在update或insert SYS_JOURNAL_76454这个表的。但做了两遍,结果都没有发现(知道者,告诉一声,先谢了)。不知道oracle是怎么去更新SYS_JOURNAL_76454,来记录rebuild online index过程中,表(这里指test_object)被DML操作的信息。
这里来看上面rebuild index online被hang住的情况
再来整理一下流程
Session 1:
(这个过程比较长)
Session 2:
SID Lo LOCK_ID1 Locked Mode Requested CTIME BLOCK
-------- -- -------------------- -------------------------- --------------
15 TM SYS_JOURNAL_76454 Share None 1 0
15 DL 76449 Row-X (SX) None 3 0
15 TM TEST_OBJECT Row-S (SS) None 1 0
Session 3 :
1 row created.
这里先不提交commit
再查session 2中:
-------- -- -------------------- -------------------------- ---------------
12 TM TEST_OBJECT Row-X (SX) None 1 1
12 TX USN: 19 RWO: IND_TES Exclusive None 1 0
15 TX USN: 11 RWO: IND_TES Exclusive None 2 0
15 TM TEST_OBJECT Row-S (SS) Share 5 0
15 DL 76449 Row-X (SX) None 7 0
15 TM SYS_JOURNAL_76454 Share None 5 0
发现sid为12的session会阻塞sid为15的(看sid为12的block字段为1),因为sid为12的session插入数据后(未提交),获得了Exclusive,将导致DDL操作挂起。从测试发现,如果DDL操作到一半,对测试表进行DML操作后(如果允许),不提交,DDL操作同样会挂起。
--EOF--
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9390331/viewspace-731431/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9390331/viewspace-731431/