[20120712]11g下Oracle Index rebuild online.txt
oracle rebuild online时要建立一张IOT表,为了保证事务依旧能操作,需要记录索引rebuild期间的DML操作。
但是10g与11g下rebuild的机制有一些不同。
index online rebuild 前先建立一张IOT表跟踪后续DML操作,然后merge全部的改变到索引中。
下面通过例子来说明:
1.开始测试:
会话1插入1行:
会话2索引rebuild online:
可以发现系统挂起!
执行如下:
--可以发现会话1(SID=133)的事务没有提交,rebuild online无法获得exclusive lock锁。但是如果仔细看LOCK_TYPE=DML的行,block字段发现都是No。
--也就是DML的操作不会出现阻塞。
打开会话3:
会话3并没有挂起!而是正常执行。
--检查IOT表可以发现记录一条记录。
--不知道为什么有1点不同?
2.继续测试,回到会话1:
--回到会话3提交事务并且修改1条记录。
回话3
再回到会话1执行:
在会话1执行rollback;
--回到会话3
--可以发现在rebuild期间的会话3(SID=71)的事务没有提交,回话2的rebuild online无法完成,但是并不影响其他dml操作。
3.回到会话3,执行提交语句:
commit;
检查会话2,可以发现rebuild online完成。
@viewlock.sql
no rows selected
总结:
在11G下,索引的rebuild online与10g不同。
oracle rebuild online时要建立一张IOT表,为了保证事务依旧能操作,需要记录索引rebuild期间的DML操作。
但是10g与11g下rebuild的机制有一些不同。
index online rebuild 前先建立一张IOT表跟踪后续DML操作,然后merge全部的改变到索引中。
下面通过例子来说明:
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
create table t (id number,name varchar2(10));
create index i_t_id on t(id);
insert into t select rownum id ,'test' name from dual connect by level
commit ;
1.开始测试:
会话1插入1行:
SQL> select * from v$mystat where rownum
SID STATISTIC# VALUE
---------- ---------- ----------
133 0 0
insert into t values (101,'a');
会话2索引rebuild online:
SQL> select * from v$mystat where rownum
SID STATISTIC# VALUE
---------- ---------- ----------
198 0 0
alter index i_t_id rebuild online ;
可以发现系统挂起!
执行如下:
SQL> host cat viewlock.sql
SELECT lk.SID, se.username, se.osuser, se.machine,
DECODE (lk.TYPE, 'TX', 'Transaction', 'TM', 'DML', 'UL', 'PL/SQL User Lock', lk.TYPE) lock_type,
DECODE (lk.lmode,
0, 'None',
1, 'Null',
2, 'Row-S (SS)',
3, 'Row-X (SX)',
4, 'Share',
5, 'S/Row-X (SSX)',
6, 'Exclusive',
TO_CHAR (lk.lmode)
) mode_held,
DECODE (lk.request,
0, 'None',
1, 'Null',
2, 'Row-S (SS)',
3, 'Row-X (SX)',
4, 'Share',
5, 'S/Row-X (SSX)',
6, 'Exclusive',
TO_CHAR (lk.request)
) mode_requested,
TO_CHAR (lk.id1) lock_id1, TO_CHAR (lk.id2) lock_id2, ob.owner, ob.object_type, ob.object_name,
DECODE (lk.BLOCK, 0, 'No', 1, 'Yes', 2, 'Global') BLOCK, se.lockwait
FROM v$lock lk, dba_objects ob, v$session se
WHERE lk.TYPE IN ('TX','TM','UL') AND lk.SID = se.SID AND lk.id1 = ob.object_id(+);
SQL> @viewlock
SID USERNAME OSUSER MACHINE LOCK_TYPE MODE_HELD MODE_REQUE LOCK_ID1 LOCK_ID2 OWNER OBJECT_TYP OBJECT_NAME BLOCK LOCKWAIT
------ ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ------ ---------- -------------------- ----- --------------------
133 SCOTT oracle11g hisdg DML Row-X (SX) None 99886 0 SCOTT TABLE T No
198 SCOTT oracle11g hisdg DML Row-S (SS) None 99886 0 SCOTT TABLE T No 00000000DFC52400
198 SCOTT oracle11g hisdg DML Share None 99895 0 SCOTT TABLE SYS_JOURNAL_99887 No 00000000DFC52400
198 SCOTT oracle11g hisdg Transaction Exclusive None 589830 6686 No 00000000DFC52400
133 SCOTT oracle11g hisdg Transaction Exclusive None 655380 5893 Yes
198 SCOTT oracle11g hisdg Transaction None Share 655380 5893 No 00000000DFC52400
6 rows selected.
--可以发现会话1(SID=133)的事务没有提交,rebuild online无法获得exclusive lock锁。但是如果仔细看LOCK_TYPE=DML的行,block字段发现都是No。
--也就是DML的操作不会出现阻塞。
打开会话3:
SQL> select * from v$mystat where rownum
SID STATISTIC# VALUE
------ ---------- ----------
71 0 0
SQL> select * from SYS_JOURNAL_99887;
no rows selected
SQL> insert into t values (102,'b');
1 row created.
会话3并没有挂起!而是正常执行。
SQL> @viewlock
SID USERNAME OSUSER MACHINE LOCK_TYPE MODE_HELD MODE_REQUE LOCK_ID1 LOCK_ID2 OWNER OBJECT_TYP OBJECT_NAME BLOCK LOCKWAIT
------ ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ------ ---------- -------------------- ----- --------------------
133 SCOTT oracle11g hisdg DML Row-X (SX) None 99886 0 SCOTT TABLE T No
71 SCOTT oracle11g hisdg DML Row-X (SX) None 99886 0 SCOTT TABLE T No
198 SCOTT oracle11g hisdg DML Row-S (SS) None 99886 0 SCOTT TABLE T No 00000000DFC52400
198 SCOTT oracle11g hisdg DML Share None 99895 0 SCOTT TABLE SYS_JOURNAL_99887 No 00000000DFC52400
71 SCOTT oracle11g hisdg Transaction Exclusive None 262145 6207 No
198 SCOTT oracle11g hisdg Transaction Exclusive None 589830 6686 No 00000000DFC52400
133 SCOTT oracle11g hisdg Transaction Exclusive None 655380 5893 Yes
198 SCOTT oracle11g hisdg Transaction None Share 655380 5893 No 00000000DFC52400
8 rows selected.
SQL> select * from SYS_JOURNAL_99887;
C0 O PARTNO RID
---------- - ---------- ------------------
102 I 0 D/////AAEAAAA+eAAA
--检查IOT表可以发现记录一条记录。
SQL> select rowid x ,t.* from t where id=102;
X ID NAME
------------------ ---------- ----------
AAAYYuAAEAAAA+eAAA 102 b
--不知道为什么有1点不同?
2.继续测试,回到会话1:
SQL> select * from SYS_JOURNAL_99887;
no rows selected--这里没看见,因为会话3的事务没有提交。
--回到会话3提交事务并且修改1条记录。
回话3
SQL> commit ;
SQL> update t set id=103,name='c' where id=100;
SQL> select * from SYS_JOURNAL_99887;
C0 O PARTNO RID
---------- - ---------- ------------------
100 D 0 D/////AAEAAAA+dABj
102 I 0 D/////AAEAAAA+eAAA
103 I 0 D/////AAEAAAA+dABj--可以发现索引修改实际上是delete再insert。
再回到会话1执行:
SQL> select * from SYS_JOURNAL_99887;
C0 O PARTNO RID
---------- - ---------- ------------------
102 I 0 D/////AAEAAAA+eAAA
在会话1执行rollback;
SQL> rollback;
Rollback complete.
SQL> @viewlock
SID USERNAME OSUSER MACHINE LOCK_TYPE MODE_HELD MODE_REQUE LOCK_ID1 LOCK_ID2 OWNER OBJECT_TYP OBJECT_NAME BLOCK LOCKWAIT
------ ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ------ ---------- -------------------- ----- --------------------
71 SCOTT oracle11g hisdg DML Row-X (SX) None 99886 0 SCOTT TABLE T No
198 SCOTT oracle11g hisdg DML Row-S (SS) None 99886 0 SCOTT TABLE T No 00000000DFC52400
198 SCOTT oracle11g hisdg DML Share None 99895 0 SCOTT TABLE SYS_JOURNAL_99887 No 00000000DFC52400
71 SCOTT oracle11g hisdg Transaction Exclusive None 131072 6470 Yes
198 SCOTT oracle11g hisdg Transaction None Share 131072 6470 No 00000000DFC52400
198 SCOTT oracle11g hisdg Transaction Exclusive None 589830 6686 No 00000000DFC52400
6 rows selected.
--回到会话3
SQL> select * from SYS_JOURNAL_99887;
C0 O PARTNO RID
---------- - ---------- ------------------
100 D 0 D/////AAEAAAA+dABj
103 I 0 D/////AAEAAAA+dABj
--可以发现在rebuild期间的会话3(SID=71)的事务没有提交,回话2的rebuild online无法完成,但是并不影响其他dml操作。
3.回到会话3,执行提交语句:
commit;
检查会话2,可以发现rebuild online完成。
@viewlock.sql
no rows selected
总结:
在11G下,索引的rebuild online与10g不同。