rebuild index online的鎖機制淺析
一般都說,rebuild index online不阻塞DML操作,這是相對於rebuild index來說的,加上了online,只是在rebuild的期間不阻塞DML,但是在開始和結束階段還是可能阻塞其他程式的DML的,要弄清楚到底是阻塞還是不阻塞,何處阻塞,為什麼阻塞,還是要從鎖的角度來分析。本文實驗環境為Oracle 10.2.0.4。
Oracle中的鎖,一共有6兩種模式:
- 0:none
- 1:null 空
- 2:Row-S 行共享(RS):共享表鎖,sub share
- 3:Row-X 行獨佔(RX):用於行的修改,sub exclusive
- 4:Share 共享鎖(S):阻止其他DML操作,share
- 5:S/Row-X 共享行獨佔(SRX):阻止其他事務操作,share/sub exclusive
- 6:exclusive 獨佔(X):獨立訪問使用,exclusive
我們知道,DML操作一般要加兩個鎖,一個是對錶加模式為3的TM鎖,一個是對資料行的模式為6的TX鎖。只要操作的不是同一行資料,是互不阻塞的。但是rebuild index online在開始和結束的時候是需要對錶加一個模式為4的TM鎖的,這個可以很容易通過實驗觀察到,實驗中的測試表t是通過create table t as select * from all_objects生成,並且多次執行insert into t select * from t產生較多的資料,以便延遲rebuild的時間來觀察系統中鎖的情況:
session 1:
SQL> delete from t where object_id=28; 1 row deleted.
session 2:
SQL> alter index ix_t rebuild online;
Session 2被阻塞,會話掛起,這時查詢v$lock,可以得到如下結果:
SQL> select sid,type,id1,id2,lmode,request from v$lock where type in('DL','TM','TX'); SID TY ID1 ID2 LMODE REQUEST ---------- -- ---------- ---------- ---------- ---------- 1643 DL 10599 0 3 0 1643 DL 10599 0 3 0 1622 TM 10599 0 3 0 1643 TM 10599 0 2 4 1643 TM 10607 0 4 0 1622 TX 655398 1361 6 0
從上面的結果可以知道,1622是session 1,1643是session 2,session 2一共出現了4個鎖,兩個DL鎖,一個針對表t的TM鎖,一個是online rebuild index時需要的一箇中間表的TM鎖,中間表用於記錄rebuild期間的增量資料,原理類似於物化檢視日誌,其object_id為10607,這是一個索引組織表(IOT),從這裡我們也可以發現IOT的優點和適合的場合,這張中間表只有插入,不會有刪除和修改操作,而且只有主鍵條件查詢,正是IOT最合適的場景:
SQL> select object_name,object_type from all_objects where object_id=10607; OBJECT_NAME OBJECT_TYPE ------------------------------ ------------------- SYS_JOURNAL_10602 TABLE SQL> select table_name,iot_type from all_tables where table_name='SYS_JOURNAL_10602'; TABLE_NAME IOT_TYPE ------------------------------ ------------ SYS_JOURNAL_10602 IOT
Session 2在請求一個模式為4的TM鎖,模式4會阻塞這個表上的所有DML操作,所以這是再往這個表上執行DML也會掛起
session 3:
SQL> delete from t where object_id=46; SQL> select sid,type,id1,id2,lmode,request from v$lock where type in('DL','TM','TX'); SID TY ID1 ID2 LMODE REQUEST ---------- -- ---------- ---------- ---------- ---------- 1643 DL 10599 0 3 0 1643 DL 10599 0 3 0 1622 TM 10599 0 3 0 1643 TM 10599 0 2 4 1643 TM 10607 0 4 0 1627 TM 10599 0 0 3 1622 TX 655398 1361 6 0
1627就是session 3,請求模式為3的TM鎖無法獲得,會話被阻塞。這是因為鎖請求是需要排隊的,即使session 3和session 1是可以併發的,但由於session 2先請求鎖並進入等待佇列,或來的session 3也只好進入佇列等待。所以如果在執行rebuild index online前長事務,並且併發量比較大,則一旦執行alter index rebuild online,可能因為長事務阻塞,可能導致系統瞬間出現大量的鎖,對於壓力比較大的系統,這是一個不小的風險。這是需要迅速找出導致阻塞的會話kill掉,rebuild index online一旦執行,不可輕易中斷,否則可能遇到ORA-08104。
在session 1執行rollback,可以發現很短時間內session 3也正常執行完畢,說明session 2只有模式4的TM鎖的時間很短,然後在rebuild online的進行過程中,對錶加的是模式為2的TM鎖,所以這段時間不會阻塞DML操作:
SQL> select sid,type,id1,id2,lmode,request from v$lock where type in('DL','TM','TX'); SID TY ID1 ID2 LMODE REQUEST ---------- -- ---------- ---------- ---------- ---------- 1643 DL 10599 0 3 0 1643 DL 10599 0 3 0 1643 TM 10599 0 2 0 1643 TM 10607 0 4 0 1627 TM 10599 0 3 0 1627 TX 655392 1361 6 0
保持session 3的事務不提交,等待一段時間後,session 2始終無法完成操作,再觀察系統中鎖的情況,可以發現又發生了變化:
SQL> select sid,type,id1,id2,lmode,request from v$lock where type in('DL','TM','TX'); SID TY ID1 ID2 LMODE REQUEST ---------- -- ---------- ---------- ---------- ---------- 1643 DL 10599 0 3 0 1643 DL 10599 0 3 0 1643 TM 10599 0 2 4 1643 TM 10607 0 4 0 1627 TM 10599 0 3 0 1643 TX 589852 258 6 0 1627 TX 655392 1361 6 0
Session 2又開始在請求模式4的TM鎖,被session 3阻塞!這是在session 1再執行DML操作,同樣會被session 2阻塞,進入鎖等待佇列。
Session 1:
SQL>delete from t where object_id=11; SQL> select sid,type,id1,id2,lmode,request from v$lock where type in('DL','TM','TX'); SID TY ID1 ID2 LMODE REQUEST ---------- -- ---------- ---------- ---------- ---------- 1643 DL 10599 0 3 0 1643 DL 10599 0 3 0 1622 TM 10599 0 0 3 1643 TM 10599 0 2 4 1643 TM 10607 0 4 0 1627 TM 10599 0 3 0 1643 TX 589852 258 6 0 1627 TX 655392 1361 6 0
在session 3執行rollback或者commit以後,session 2和session 3都很快執行完畢。
從上面的試驗可以發現,雖然rebuild index online在執行期間只持有模式2的TM鎖,不會阻塞DML操作,但在操作的開始和結束階段,是需要短暫的持有模式為4的TM鎖的,這段會阻塞表上的所有DML操作。我們在做rebuild index online的時候,一定要在開始和結束階段觀察系統中是否有長事務的儲存,對於併發量較大的系統,最嚴重的後果,可能在這兩個關鍵點導致資料庫產生大量鎖等待,系統負載飆升,甚至當機。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22907091/viewspace-747916/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- alter index ... rebuild online的機制(zt)IndexRebuild
- 【羅玄】從鎖的角度看rebuild index online和rebuild indexRebuildIndex
- Index Online RebuildIndexRebuild
- alter index rebuild 與 rebuild onlineIndexRebuild
- create index online 與rebuild index onlineIndexRebuild
- create index online 與rebuild index onlineIndexRebuild
- alter index rebuild和rebuild online的區別IndexRebuild
- index rebuild online的問題IndexRebuild
- 聊聊索引Index Rebuild和Rebuild Online(下)索引IndexRebuild
- 聊聊索引Index Rebuild和Rebuild Online(上)索引IndexRebuild
- rebuild index online和create index online及沒有online的區別RebuildIndex
- alter index ind1 rebuild 和alter index ind1 rebuild onlineIndexRebuild
- alter index rebuild online引發的血案IndexRebuild
- 測試index online rebuild故障記錄IndexRebuild
- “rebuild index online hang住" 問題解析RebuildIndex
- MVVM機制淺析MVVM
- 淺析java的反射機制Java反射
- 關於rebuild index online 及drop index後重建問題RebuildIndex
- Online rebuild index遭遇ORA-08104RebuildIndex
- java中的反射機制淺析Java反射
- oracle的resetlogs機制淺析Oracle
- 請版主講一下rebuild index的執行機制吧?RebuildIndex
- 重建索引index rebuild online vs offline vs index coalesce vs index shrik space索引IndexRebuild
- js執行機制淺析JS
- Libco Hook 機制淺析Hook
- PostgreSQL MVCC快照機制淺析SQLMVC
- NX實現機制淺析
- Android Binder機制淺析Android
- JavaScript執行機制淺析JavaScript
- 淺析雙親委派機制
- rebuild indexRebuildIndex
- index rebuildIndexRebuild
- 淺析JavaScript的事件迴圈機制JavaScript事件
- JavaScript的事件迴圈機制淺析JavaScript事件
- 微信小程式的require機制淺析微信小程式UI
- 轉:oracle的resetlogs機制淺析Oracle
- "Alter index rebuild online parallel n"會修改索引的degree屬性IndexRebuildParallel索引
- 微前端無界機制淺析前端