[20120730]11g下Oracle Index rebuild online之2.txt
[20120730]11g下Oracle Index rebuild online之2.txt
oracle rebuild online時要建立一張IOT表,為了保證事務依舊能操作,需要記錄索引rebuild期間的DML操作。
前面已經介紹了10g與11g下rebuild的機制有一些不同。再補充一些.
index online rebuild 前先建立一張IOT表跟蹤後續DML操作,然後merge全部的改變到索引中。
1.開始測試:
會話1插入1行:
會話2插入1行:
回到回話1執行:
--可以發現因為前面的事務沒有rollback/commit,online rebuild的過程掛起.
2.開啟新回話3:
--journal table 中記錄還存在! rebuild online還在進行中(因為回話1的事務沒有提交).
3.現在在回話3中修改記錄:
SQL> update t set id=102,name='b' where id=103;
1 row updated.
--再看看SYS_JOURNAL_101585中記錄如何呢?
--可以看到僅僅記錄2條.索引的修改相當於delete+insert.
--原來c0=103的 OPCODE 從"I"=>"D".插入的id=102.
再修改一條記錄:
--這樣在rebuild online 時merge journal table階段,因為IOT表是按照C0,RID為主鍵的組織的,如果我們順序掃描IOT,可以看出.
102 I 0 D/////AAEAAAACmAAB
103 D 0 D/////AAEAAAACmAAB
C0=103的這條103 D 0 D/////AAEAAAACmAAB,
先執行插入的是102,後執行delete103.
執行的delete操作時,應該是操作物件不存在.因為前面的插入是id=102.但是這樣並沒有導致索引不一致的情況.
4.現在在回話3中:
做一個奇怪delete的操作看看:
掛起!
回到回話1
可以發現SYS_JOURNAL_101585在share模式,其他使用者不能對該表直接進行DML操作.
回到回話3,按ctrl+c取消操作.
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation
5.回到回話2,按ctrl+c取消rebuild online操作.
--可以發現journal table SYS_JOURNAL_101585依舊存在.
--再次執行rebuild online.看看如何?(注意這是回話1沒有提交).
google發現許多連結:
要使用dbms_repair包,但是奇怪這樣呼叫有問題:(恢復SYS_JOURNAL_101585 IOT表.)
這個函式返回型別是boolean型別的.
看文件的例子如下:
修改如下:
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 <=100;
commit ;
1.開始測試:
會話1插入1行:
SQL> select * from v$mystat where rownum<=1;
SID STATISTIC# VALUE
---------- ---------- ----------
133 0 0
insert into t values (101,'a');
會話2插入1行:
SQL> select * from v$mystat where rownum<=1;
SID STATISTIC# VALUE
---------- ---------- ----------
192 0 0
alter index i_t_id rebuild online ;
回到回話1執行:
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
------ ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ------ ---------- -------------------- ----- --------------------
192 SCOTT oracle11g hisdg DML Share None 101683 0 SCOTT TABLE SYS_JOURNAL_101585 No 00000000DFC524D0
192 SCOTT oracle11g hisdg DML Row-S (SS) None 101584 0 SCOTT TABLE T No 00000000DFC524D0
133 SCOTT oracle11g hisdg DML Row-X (SX) None 101584 0 SCOTT TABLE T No
133 SCOTT oracle11g hisdg Transaction Exclusive None 655364 6348 Yes
192 SCOTT oracle11g hisdg Transaction None Share 655364 6348 No 00000000DFC524D0
192 SCOTT oracle11g hisdg Transaction Exclusive None 589841 7146 No 00000000DFC524D0
6 rows selected.
--可以發現因為前面的事務沒有rollback/commit,online rebuild的過程掛起.
2.開啟新回話3:
SQL> select * from v$mystat where rownum<=1;
SID STATISTIC# VALUE
---------- ---------- ----------
70 0 0
SQL> select * from SYS_JOURNAL_101585;
no rows selected
SQL> insert into t values (103,'c');
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
------ ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ------ ---------- -------------------- ----- --------------------
192 SCOTT oracle11g hisdg DML Share None 101683 0 SCOTT TABLE SYS_JOURNAL_101585 No 00000000DFC524D0
192 SCOTT oracle11g hisdg DML Row-S (SS) None 101584 0 SCOTT TABLE T No 00000000DFC524D0
133 SCOTT oracle11g hisdg DML Row-X (SX) None 101584 0 SCOTT TABLE T No
70 SCOTT oracle11g hisdg DML Row-X (SX) None 101584 0 SCOTT TABLE T No
133 SCOTT oracle11g hisdg Transaction Exclusive None 655364 6348 Yes
192 SCOTT oracle11g hisdg Transaction None Share 655364 6348 No 00000000DFC524D0
70 SCOTT oracle11g hisdg Transaction Exclusive None 327685 7460 No
192 SCOTT oracle11g hisdg Transaction Exclusive None 589841 7146 No 00000000DFC524D0
8 rows selected.
SQL> select * from SYS_JOURNAL_101585;
C0 O PARTNO RID
---------- - ---------- ------------------
103 I 0 D/////AAEAAAACmAAB
--檢查IOT表可以發現記錄一條記錄。
SQL> commit ;
Commit complete.
SQL> select * from SYS_JOURNAL_101585;
C0 O PARTNO RID
---------- - ---------- ------------------
103 I 0 D/////AAEAAAACmAAB
--journal table 中記錄還存在! rebuild online還在進行中(因為回話1的事務沒有提交).
3.現在在回話3中修改記錄:
SQL> update t set id=102,name='b' where id=103;
1 row updated.
--再看看SYS_JOURNAL_101585中記錄如何呢?
SQL> select * from SYS_JOURNAL_101585;
C0 O PARTNO RID
---------- - ---------- ------------------
102 I 0 D/////AAEAAAACmAAB
103 D 0 D/////AAEAAAACmAAB
--可以看到僅僅記錄2條.索引的修改相當於delete+insert.
--原來c0=103的 OPCODE 從"I"=>"D".插入的id=102.
再修改一條記錄:
SQL> update t set id=999,name='z' where id=100;
1 row updated.
SQL> select * from SYS_JOURNAL_101585;
C0 O PARTNO RID
---------- - ---------- ------------------
100 D 0 D/////AAEAAAAClABj
102 I 0 D/////AAEAAAACmAAB
103 D 0 D/////AAEAAAACmAAB
999 I 0 D/////AAEAAAAClABj
--再次看出索引的修改相當於 delete+insert.
--這樣在rebuild online 時merge journal table階段,因為IOT表是按照C0,RID為主鍵的組織的,如果我們順序掃描IOT,可以看出.
102 I 0 D/////AAEAAAACmAAB
103 D 0 D/////AAEAAAACmAAB
C0=103的這條103 D 0 D/////AAEAAAACmAAB,
先執行插入的是102,後執行delete103.
執行的delete操作時,應該是操作物件不存在.因為前面的插入是id=102.但是這樣並沒有導致索引不一致的情況.
4.現在在回話3中:
做一個奇怪delete的操作看看:
commit;
delete from SYS_JOURNAL_101585 where rid='D/////AAEAAAAClABj';
掛起!
回到回話1
SQL> @viewlock ;
SID USERNAME OSUSER MACHINE LOCK_TYPE MODE_HELD MODE_REQUE LOCK_ID1 LOCK_ID2 OWNER OBJECT_TYP OBJECT_NAME BLOCK LOCKWAIT
------ ---------- ---------- ---------- ------------ ---------- ---------- ---------- ---------- ------ ---------- -------------------- ----- --------------------
70 SCOTT oracle11g hisdg DML None Row-X (SX) 101686 0 SCOTT TABLE SYS_JOURNAL_101585 No 00000000DCB9C248
192 SCOTT oracle11g hisdg DML Share None 101686 0 SCOTT TABLE SYS_JOURNAL_101585 Yes 00000000DFC52670
133 SCOTT oracle11g hisdg DML Row-X (SX) None 101584 0 SCOTT TABLE T No
192 SCOTT oracle11g hisdg DML Row-S (SS) None 101584 0 SCOTT TABLE T No 00000000DFC52670
133 SCOTT oracle11g hisdg Transaction Exclusive None 393224 8268 Yes
192 SCOTT oracle11g hisdg Transaction None Share 393224 8268 No 00000000DFC52670
192 SCOTT oracle11g hisdg Transaction Exclusive None 196617 7070 No 00000000DFC52670
7 rows selected.
可以發現SYS_JOURNAL_101585在share模式,其他使用者不能對該表直接進行DML操作.
回到回話3,按ctrl+c取消操作.
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation
5.回到回話2,按ctrl+c取消rebuild online操作.
SQL> alter index i_t_id rebuild online ;
alter index i_t_id rebuild online
*
ERROR at line 1:
ORA-01013: user requested cancel of current operation
SQL> select * from SYS_JOURNAL_101585;
C0 O PARTNO RID
---------- - ---------- ------------------
100 D 0 D/////AAEAAAAClABj
102 I 0 D/////AAEAAAACmAAB
103 D 0 D/////AAEAAAACmAAB
999 I 0 D/////AAEAAAAClABj
--可以發現journal table SYS_JOURNAL_101585依舊存在.
--再次執行rebuild online.看看如何?(注意這是回話1沒有提交).
SQL> alter index i_t_id rebuild online ;
alter index i_t_id rebuild online
*
ERROR at line 1:
ORA-08104: this index object 101585 is being online built or rebuilt
$ oerr ORA 8104
08104, 00000, "this index object %s is being online built or rebuilt"
// *Cause: the index is being created or rebuild or waited for recovering
// from the online (re)build
// *Action: wait the online index build or recovery to complete
SQL> drop table SYS_JOURNAL_101585;
Table dropped.
SQL> alter index i_t_id rebuild online ;
alter index i_t_id rebuild online
*
ERROR at line 1:
ORA-08104: this index object 101585 is being online built or rebuilt--可以發現即使刪除 SYS_JOURNAL_101585 IOT表,在rebuild online時一樣報錯!why?該如何解決呢?
google發現許多連結:
要使用dbms_repair包,但是奇怪這樣呼叫有問題:(恢復SYS_JOURNAL_101585 IOT表.)
SQL> select sys.dbms_repair.online_index_clean(101585) from dual;
select sys.dbms_repair.online_index_clean(101585) from dual
*
ERROR at line 1:
ORA-06552: PL/SQL: Statement ignored
ORA-06553: PLS-382: expression is of wrong type
這個函式返回型別是boolean型別的.
看文件的例子如下:
function online_index_clean(
object_id IN binary_integer DEFAULT ALL_INDEX_ID,
wait_for_lock IN binary_integer DEFAULT LOCK_WAIT)
return boolean;
-- Example Usage of online_index_clean:
-- DECLARE
-- isClean BOOLEAN;
-- BEGIN
--
-- isClean := FALSE;
-- WHILE isClean=FALSE
-- LOOP
-- isClean := DBMS_REPAIR.ONLINE_INDEX_CLEAN(DBMS_REPAIR.ALL_INDEX_ID,
-- DBMS_REPAIR.LOCK_WAIT);
-- DBMS_LOCK.SLEEP(10);
-- END LOOP;
--
-- EXCEPTION
-- WHEN OTHERS THEN
-- RAISE;
-- END;
-- /
修改如下:
DECLARE
isClean BOOLEAN;
BEGIN
isClean := FALSE;
isClean := DBMS_REPAIR.ONLINE_INDEX_CLEAN(101585,DBMS_REPAIR.LOCK_WAIT);
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-739206/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 聊聊索引Index Rebuild和Rebuild Online(下)索引IndexRebuild
- Index Online RebuildIndexRebuild
- alter index rebuild 與 rebuild onlineIndexRebuild
- create index online 與rebuild index onlineIndexRebuild
- create index online 與rebuild index onlineIndexRebuild
- 聊聊索引Index Rebuild和Rebuild Online(上)索引IndexRebuild
- alter index rebuild和rebuild online的區別IndexRebuild
- 【羅玄】從鎖的角度看rebuild index online和rebuild indexRebuildIndex
- index rebuild online的問題IndexRebuild
- alter index ind1 rebuild 和alter index ind1 rebuild onlineIndexRebuild
- rebuild index online和create index online及沒有online的區別RebuildIndex
- oracle10g_alter index rebuild_online_重構索引OracleIndexRebuild索引
- alter index rebuild online引發的血案IndexRebuild
- 測試index online rebuild故障記錄IndexRebuild
- alter index ... rebuild online的機制(zt)IndexRebuild
- “rebuild index online hang住" 問題解析RebuildIndex
- Oracle什麼情況下需要rebuild indexOracleRebuildIndex
- Oracle效能優化之“少做事”(rebuild index)Oracle優化RebuildIndex
- ORACLE中index的rebuildOracleIndexRebuild
- 關於rebuild index online 及drop index後重建問題RebuildIndex
- rebuild index online的鎖機制淺析RebuildIndex
- Online rebuild index遭遇ORA-08104RebuildIndex
- Oracle alter index rebuild 說明OracleIndexRebuild
- 重建索引index rebuild online vs offline vs index coalesce vs index shrik space索引IndexRebuild
- rebuild indexRebuildIndex
- index rebuildIndexRebuild
- (轉)Index Rebuild Online 過程(9i)完整版IndexRebuild
- rebuild index 排序RebuildIndex排序
- sybase rebuild indexRebuildIndex
- rebuild與rebuild online效率比對Rebuild
- "Alter index rebuild online parallel n"會修改索引的degree屬性IndexRebuildParallel索引
- best practice of rebuild your partition table local index online by using: "update indexes"RebuildIndex
- Index rebuild --case 1IndexRebuild
- 索引rebuild和rebuild online時要慎重索引Rebuild
- alter index rebuild與index_statsIndexRebuild
- 索引rebuild和rebuild online時要慎重(轉載)索引Rebuild
- rebuild index 和 recreate index (重新建立index) 的區別RebuildIndex
- create index , rebuild index troubleshooting 索引故障解決IndexRebuild索引