create index...online操作過程中會申請持有哪些鎖
11g下,在給表建立索引時如果加上online選項,不會阻塞同時進行的DML操作,相當給力的一個功能。
與不帶online的索引建立方式相比在鎖的申請與持有機制上有何區別,我們來比較一下
###建立測試表
sqlplus ad/Uiop246!
create table t0528_1 as select * from all_users;
select object_id from dba_objects where object_name='T0528_1';
OBJECT_ID
----------
17177
---session 1: update但不提交
select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
27 0 0
update t0528_1 set username=dbms_random.string('u',5) where user_id=0;
---session 2: create index(非online方式)
select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
100 0 0
create index ind_uname on t0528_1(username) tablespace ts_pub; <---直接報錯退出
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired
alter session set ddl_lock_timeout=60; <---設定ddl timeout為60s,以便觀察到後面create index時請求的鎖模式
create index ind_uname on t0528_1(username); <---操作被掛起
---session 3: 觀察session 1持有的鎖、session 2請求的鎖
select sid,id1,id2,type,lmode,request from v$lock where sid in (27,100) order by sid;
SID ID1 ID2 TY LMODE REQUEST
---------- ---------- ---------- -- ---------- ----------
27 17177 0 TM 3 0 <---持有lockmode=3的鎖,即型別為row-X (SX)的鎖
27 100 0 AE 4 0
27 65566 340 TX 6 0
100 100 0 AE 4 0
100 17177 0 TM 0 4 <---請求lockmode=4的鎖,即型別為share (S)的鎖
以上資訊可以看出,針對t0528_1(object_id=17177)表,在session 1已經持有了SX鎖的情況下,session 2請求S鎖,由於S與SX鎖不相容,所以session 2會遇到ORA-00054
等待session 2超時後改用online方式create index
---session 2: create index ... online
alter session set ddl_lock_timeout=0; <---復位ddl timeout為0
create index ind_uname on t0528_1(username) online; <----操作掛起,等待session 1的事務結束
---session 3:觀察session 1、session 2上持有的鎖
select sid,id1,id2,type,lmode,request from v$lock where sid in (27,100) order by sid;
SID ID1 ID2 TY LMODE REQUEST
---------- ---------- ---------- -- ---------- ----------
27 100 0 AE 4 0
27 17177 0 TM 3 0 <---依舊持有lockmode=3的鎖,即型別為row-X (SX)的鎖
27 65566 340 TX 6 0
100 100 0 AE 4 0
100 17177 0 TM 2 0 <---轉而持有lockmode=2的鎖,即型別為row-S (SS)的鎖
100 17179 0 TM 4 0 <---object_id=17179指向新增的IOT表SYS_JOURNAL_17178
100 458752 331 TX 6 0
100 17177 0 OD 4 0 <---online模式下才有的OD型別的鎖,它代表online ddl
100 17177 0 DL 3 0 <---online模式下才有的DL型別的鎖,它代表direct loader index creation
100 17177 0 DL 3 0
100 65566 340 TX 0 4 <---在事務級請求持有share (S)鎖,需等待session 1持有的exclusive (X)級的事務鎖釋放,才能申請成功
col type format a5
col name format a40
col description format a60
set linesize 130
select type,name,description from v$lock_type where type in ('OD','DL');
TYPE NAME DESCRIPTION
----- ---------------------------------------- ------------------------------------------------------------
DL Direct Loader Index Creation Lock to prevent index DDL during direct load
OD Online DDLs Lock to prevent concurrent online DDLs
SQL> col object_name format a30
SQL> set linesize 100
SQL> select owner,object_name,object_id from dba_objects where object_id=17179
OWNER OBJECT_NAME OBJECT_ID
------------------------------ ------------------------------ ----------
SYS SYS_JOURNAL_17178 17179
SQL> select owner,table_name,iot_type from dba_tables where table_name='SYS_JOURNAL_17178';
OWNER TABLE_NAME IOT_TYPE
------------------------------ ------------------------------ ------------
SYS SYS_JOURNAL_17178 IOT
和前一次create index情況下持有及請求的鎖資源相比,create index ... online方式有以下一些改變:
(1) 過程中會持有OD(ONLINE DDL)、DL(Direct Loader Index Creation)兩種型別的鎖
(2) 表級鎖TM的持有模式為row-S (SS),與row-X (SX)型別的鎖互相相容,因此不會在表級發生阻塞
(3) 阻塞發生在行級鎖申請階段,即請求的share (S)型別的鎖與執行DML的session已經持有的exclusive (X)鎖之間存在不相容的情況;相比非online方式的表級鎖,鎖的粒度上更加細化,副作用更小
(4) 新增以SYS_JOURNAL_為字首的IOT表,記錄與索引建立動作同時進行的其它DML操作修改過的記錄,等到索引建立完成前將IOT表裡的記錄合併至索引中
session 2等待期間如果再開一個session對t0528_1表進行dml操作,這個操作依然會成功
---session 4:insert into ...
select * from v$mystat where rownum=1;
SID STATISTIC# VALUE
---------- ---------- ----------
22 0 0
insert into t0528_1 values('AAA',999,to_Date('20160528','yyyymmdd')); <---注意這裡並沒有commit
---session 3:觀察session 1、session 2、session 4上持有和請求的鎖
SQL> select sid,id1,id2,type,lmode,request from v$lock where sid in (27,100,22) order by sid;
SID ID1 ID2 TYPE LMODE REQUEST
---------- ---------- ---------- ----- ---------- ----------
22 262163 345 TX 6 0
22 100 0 AE 4 0
22 17177 0 TM 3 0
27 65566 340 TX 6 0
27 17177 0 TM 3 0
27 100 0 AE 4 0
100 458752 331 TX 6 0
100 17179 0 TM 4 0
100 17177 0 TM 2 0
100 100 0 AE 4 0
100 17177 0 OD 4 0
100 17177 0 DL 3 0
100 17177 0 DL 3 0
100 65566 340 TX 0 4
現有的等待鏈有兩組:session 1(update)->session 2(create index online)和session 4(insert)->session 2(create index online),可以看出並不因為session 4的insert比session 2的create index ... online晚發起而出現前者被後者阻塞的情況,所以create index online線上建立索引的方式對於DML操作不會產生干擾,但是如果併發的DML操作很多,會增加索引建立的耗時
消除這個等待鏈,只需分別在session 1、session 4執行commit
---session 1
commit;
---session 4
commit;
索引建立成功, SYS_JOURNAL_為字首的IOT表也已被清理
col table_name format a20
col column_name format a40
col index_name format a30
set linesize 130
select table_name,column_name,index_name from dba_ind_columns where table_name='T0528_1'
TABLE_NAME COLUMN_NAME INDEX_NAME
-------------------- ---------------------------------------- ------------------------------
T0528_1 USERNAME IND_UNAME
SQL> select * from sys.SYS_JOURNAL_17178;
select * from sys.SYS_JOURNAL_17178
*
ERROR at line 1:
ORA-00942: table or view does not exist
由於我們測試表過小所以create index很快結束,沒能觀察到SYS_JOURNAL_字首的表到底存放了哪些內容,下面再補充一個小測試
create table t0528_2 as select rownum rn,t.* from dba_tables t connect by level<3;
create index ind_rn on t0528_2(rn) online tablespace ts_pub;
在create index尚在執行時另開一session執行
update t0528_2 set rn=99999 where rn=1;
commit;
檢查IOT表
SELECT * FROM AD.SYS_JOURNAL_9845625;
C0 O PARTNO RID
---------- - ---------- ------------------
99999 I 0 D/////ANYAAC2CTAAA
1 D 0 D/////ANYAAC2CTAAA
存放形式有點類似與MV log,舊值1被標記為Delete,新值99999標記為Insert,唯一不同的是RID列記錄的並非是完整的rowid值
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/53956/viewspace-2109017/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 刪除列過程中,需要持有物件的鎖物件
- 不同的SQL語句執行時需要申請並持有對應的鎖SQL
- 哪些操作易引起儲存過程失效?儲存過程
- Linux中斷申請Linux
- postgresql create index concurrently過程描述SQLIndex
- 參加招聘會,申請加3分
- Laravel 列印請求過程中的所有 SQLLaravelSQL
- 筆記: Oracle 10g中一些操作持有鎖的小節筆記Oracle 10g
- Web請求過程Web
- php請求全過程PHP
- ORACLE 死鎖分析過程Oracle
- 加分申請
- 申請加分
- oracle 加密儲存過程create_wrappedOracle加密儲存過程APP
- 探討BPM流程申請活動與退回操作的建模
- HTTP的請求過程HTTP
- 申請英國公司需要什麼條件?都有哪些型別?型別
- 螢幕也能指紋解鎖?蘋果新專利申請曝光蘋果
- asp.Net請求過程及管道中的事件ASP.NET事件
- 在C++中申請堆區空間與在C中申請堆區空間的異同點C++
- AG介面申請
- 期末申請加分
- java操作儲存過程Java儲存過程
- 申請SSL證書如何進行操作DNS域名驗證DNS
- Go中協程死鎖Go
- 想做共享wifi,需要投入哪些費用?該如何申請加盟呢?WiFi
- 在K8S中,Deployment 升級過程有哪些?K8S
- 記一次排查線上MySQL死鎖過程,不能只會curd,還要知道加鎖原理MySql
- 【原創】ORA-00054問題的解決(plan_table在autotrace過程中會被鎖定)
- 四人團隊專案申請-----已通過
- [小白求教] jmeter 持續加壓的過程中,會突然出現無請求的情況,請問這正常嗎?JMeter
- OGG實施操作步驟(包括操作過程中的所有步驟)
- LINUX中斷--申請中斷和解除安裝中斷Linux
- Kill會話過程分析會話
- 為什麼要用SSL證書?如何申請?要注意哪些問題?
- 一對一交友原始碼,需要申請的資料有哪些?原始碼
- 申請加入BCG第三篇破文:鬧鐘&笑話1.0破解過程 (2千字)
- Oracle MOS:CSI 申請Oracle