9I/10G 11G online index的實現過程分析
[i=s] 本帖最後由 wei-xh 於 2012-5-9 15:42 編輯
ORACLE 的ONLINE 建立索引在很多手冊上被描述為:不阻塞寫的安全操作。但是11G前,ORACLE一直沒能真正做到這一點。
MYSQL ,POSTGRES裡好像也一直沒能實現ORACLE ONLINE的功能,他們的建立都會阻塞寫操作。我們這裡分析下ORACLE ONLINE建立索引的步驟。
9I、10G版本下ONLINE REBUILD建立索引的過程。
建立索引前,開啟如下跟蹤事件,第一個等待事件,可以觀察到鎖的申請情況。第二個等待事件可以觀察到遞迴執行的SQL。
alter session set events '10704 trace name context forever,level 10';
alter session set events '10046 trace name context forever,level 12';
ORACLE ONLINE REBUILD索引的思路就是透過:
索引建立開始時候的資料+MRGEE索引建立過程中的增量來完成整個建立。
索引建立開始時候的資料:透過一致性讀來實現
索引建立過程中的增量: 透過IOT表記錄的變化日誌來實現。
整個過程分為如下幾個步驟:
1.申請表上型別為2的TM鎖。建立IOT表,用來捕獲增量。
*** 2010-07-27 23:07:16.000
ksqcmi: TM,18fe,0 mode=2 timeout=21474836
ksqcmi: returns 0
create table "SYS_JOURNAL_6399" (C0 NUMBER, opcode char(1), partno number, rid rowid, primary key( C0 , rid ))
organization index TABLESPACE "USERS"
CREATE UNIQUE INDEX "SYS_IOT_TOP_6406" on "SYS_JOURNAL_6399"("C0","RID") INDEX ONLY TOPLEVEL TABLESPACE "USERS" NOPARALLEL
建立IOT表的時候,持有的是原表上2的TM鎖。這是個非常低階別的鎖。即使此時,表上有未提交事務,也不會阻塞這個操作,因為DML操作獲得的3型別的TM鎖與2型別的TM鎖具有相容性。
2.將型別為2的鎖轉化為型別為4的TM鎖。為了阻塞後續的DML操作。
ORACLE在ONLIEN建立索引過程中,透過一致性讀取表段+IOT表增量 來完成整個建立。IOT表記錄了,一致性讀取表資料後的發生的所有資料變化。
因此在真正開始一致性複製舊資料之前,需要確保表上沒有事務。
可以設想一下,如果ORACLE不保證表上所有的事務已結束就開始一致性讀取,那麼一致性讀取表資料建立的索引段+IOT表MERGE完成後,就會丟失資料。IOT表只記錄了一致性讀取表資料後的所有資料變化。對於之前的變更不做記錄。
舉個例子:資料塊1的一條記錄做了修改,把A值變為了B值,但是這個事務沒提交,如果ORACLE不等待這個事務結束就開始建立索引,那麼一致性讀取資料塊的內容,讀取到的將是內容A。在建立索引過程中,這個事務提交了,但是這個B並不會進入到IOT表裡,因為這個事務是索引建立開始前開始的,IOT表不記錄。最終索引建立完成後,這個B會丟失。
因此ORACLE在這個步驟裡申請了一個等級稍微高點的TM 4鎖,假如表上存在事務,那麼這個4的TM鎖將不能獲得,因為它與事務的TM 3鎖衝突。持有這個TM 4鎖,還為了阻塞後面的DML操作,為了讓索引重建儘快可以開始。而這個持有的TM 4鎖,經常是我們在ONLINE 建立索引過程中,風險最大的地方。因為這個4鎖一旦獲得不了,它將會阻塞後續的所有的DML操作。
*** 2010-07-27 23:07:16.000
ksqcmi: TM,18fe,0 mode=4 timeout=21474836
WAIT #1: nam='enqueue' ela= 3072242 p1=1414332420 p2=6398 p3=0
3.因為DML操作都獲得的是TM為3的鎖,它跟4 TM鎖不相容,因此一旦可以獲取到型別為4的TM鎖,代表表上事務都已經結束,這個時候,就可以釋放這個TM 4鎖,將鎖降級為型別為2的TM鎖。至此,開始讀取表資料建立索引。需要注意的是,這裡的讀取表資料,是一致性讀取。
建立新索引的時間要依據表的大小。整個過程要做的事情就是一致性讀取表資料+排序
*** 2010-07-27 23:07:41.000
ksqcmi: TM,18fe,0 mode=2 timeout=21474836
ksqcmi: returns 0
4.讀取IOT表上的變更,在新的索引段上進行MERGE.這個過程中會發現IOT表的記錄數逐漸在減少。最終完成時,只剩下未提交事務所修改的記錄保留在IOT表裡。類似如下的情況。由於這些記錄還沒提交,ONLIEN程式就只能等待。
C0 OP PARTNO RID
---------- -- ---------- ------------------
11 I 0 D/////AAGAAAe4DAAa
11 I 0 D/////AAGAAAe4DAAb
12 D 0 D/////AAGAAAe4DAAa
12 D 0 D/////AAGAAAe4DAAb
12 D 0 D/////AAGAAAe4DAAc
12 D 0 D/////AAGAAAe4DAAd
5.獲取表上型別為4的TM鎖,等待未提交的事務結束,阻塞後續的事務,以免讓索引重建過程“無限期”的等待。這裡又是一個風險點,因為申請了一個TM 4鎖,會阻塞後面的DML操作。
一旦步驟4裡涉及的變更記錄都已經提交,那麼就會把最終的這批記錄MERGE進新索引裡。最後刪除IOT表。整個過程完畢。
有個疑問,就是在進行MERGE過程中,ORACLE依據什麼判斷IOT表裡那些記錄已經提交,那些沒提交?IOT表裡貌似沒這個欄位。
看來ORACLE 9I、10G所謂的ONLINE其實並不安全,因為裡面有幾個地方,會申請一個TM 4的鎖,這個鎖一旦獲取不了,就會導致DML操作的阻塞。
11G後,這個情況完全變了,ORACLE做到了真正的ONLINE.
11G ONLINE REBUILD建立索引的過程。
1.申請表上型別為2的TM鎖,建立IOT表。
2.建立完IOT表後,如果表上存在事務,那麼會發生等待,不過這個發生的等待是TX事務等待,不是在表上的TM等待了。
3.建立索引程式會被未提交的事務掛起,但是這個時候存在DML操作的話,可以正常進行。但是這些DML操作變更並不會記錄進IOT表裡。
4.如果表上事務都已經提交,那麼進行一致性讀取表上的舊資料的過程,然後對資料排序。例如:如果表上存在3個沒有提交的事務,那麼會先等待事務1,事務1提交後,會等待事務2,事務2提交後,會等待事務3.直到事務3提交,那麼才可以進行下一步。這個過程可以透過觀察 v$session的P1,P2引數來了解,隨著事務的提交,P1,P2的值也會發生變化,P1,P2的值反應了當前等待在哪個事務上。這個過程雖然不會阻塞事務,但是我們不難發現,如果表上事務併發比較大,那麼重建索引的進行就會被延期。知道表上的“那一刻”不存在事務。
5.把IOT表裡的資料在新索引段上進行MERGE,這個過程中,會發現IOT表的資料逐漸減少。最終只剩下沒提交事務的資料。
6.等待IOT表裡未提交的事務進行提交,這個時候後臺會等待TX事務鎖,型別為4.直到所有的事務都已經提交,這個過程才會完成。這個
過程不會阻塞新進的事務,ORACLE會把變更的資料記錄進IOT表裡(當然要涉及到跟索引欄位相關的資料才會被記錄進IOT表裡)。
11G最大的特點是不需要對TM鎖進行鎖轉化了,11G前由於這種鎖轉化,可能會阻塞DML操作,可能會引起故障。
但是理論上11G這種做法也會引起問題,因為在第4、6步,在等待事務結束期間,一直有源源不斷的事務進來,如果運氣差的話,那麼你的索引重建時間就會非常長。
ORACLE 的ONLINE 建立索引在很多手冊上被描述為:不阻塞寫的安全操作。但是11G前,ORACLE一直沒能真正做到這一點。
MYSQL ,POSTGRES裡好像也一直沒能實現ORACLE ONLINE的功能,他們的建立都會阻塞寫操作。我們這裡分析下ORACLE ONLINE建立索引的步驟。
9I、10G版本下ONLINE REBUILD建立索引的過程。
建立索引前,開啟如下跟蹤事件,第一個等待事件,可以觀察到鎖的申請情況。第二個等待事件可以觀察到遞迴執行的SQL。
alter session set events '10704 trace name context forever,level 10';
alter session set events '10046 trace name context forever,level 12';
ORACLE ONLINE REBUILD索引的思路就是透過:
索引建立開始時候的資料+MRGEE索引建立過程中的增量來完成整個建立。
索引建立開始時候的資料:透過一致性讀來實現
索引建立過程中的增量: 透過IOT表記錄的變化日誌來實現。
整個過程分為如下幾個步驟:
1.申請表上型別為2的TM鎖。建立IOT表,用來捕獲增量。
CODE:
跟蹤檔案摘要:*** 2010-07-27 23:07:16.000
ksqcmi: TM,18fe,0 mode=2 timeout=21474836
ksqcmi: returns 0
create table "SYS_JOURNAL_6399" (C0 NUMBER, opcode char(1), partno number, rid rowid, primary key( C0 , rid ))
organization index TABLESPACE "USERS"
CREATE UNIQUE INDEX "SYS_IOT_TOP_6406" on "SYS_JOURNAL_6399"("C0","RID") INDEX ONLY TOPLEVEL TABLESPACE "USERS" NOPARALLEL
建立IOT表的時候,持有的是原表上2的TM鎖。這是個非常低階別的鎖。即使此時,表上有未提交事務,也不會阻塞這個操作,因為DML操作獲得的3型別的TM鎖與2型別的TM鎖具有相容性。
2.將型別為2的鎖轉化為型別為4的TM鎖。為了阻塞後續的DML操作。
ORACLE在ONLIEN建立索引過程中,透過一致性讀取表段+IOT表增量 來完成整個建立。IOT表記錄了,一致性讀取表資料後的發生的所有資料變化。
因此在真正開始一致性複製舊資料之前,需要確保表上沒有事務。
可以設想一下,如果ORACLE不保證表上所有的事務已結束就開始一致性讀取,那麼一致性讀取表資料建立的索引段+IOT表MERGE完成後,就會丟失資料。IOT表只記錄了一致性讀取表資料後的所有資料變化。對於之前的變更不做記錄。
舉個例子:資料塊1的一條記錄做了修改,把A值變為了B值,但是這個事務沒提交,如果ORACLE不等待這個事務結束就開始建立索引,那麼一致性讀取資料塊的內容,讀取到的將是內容A。在建立索引過程中,這個事務提交了,但是這個B並不會進入到IOT表裡,因為這個事務是索引建立開始前開始的,IOT表不記錄。最終索引建立完成後,這個B會丟失。
因此ORACLE在這個步驟裡申請了一個等級稍微高點的TM 4鎖,假如表上存在事務,那麼這個4的TM鎖將不能獲得,因為它與事務的TM 3鎖衝突。持有這個TM 4鎖,還為了阻塞後面的DML操作,為了讓索引重建儘快可以開始。而這個持有的TM 4鎖,經常是我們在ONLINE 建立索引過程中,風險最大的地方。因為這個4鎖一旦獲得不了,它將會阻塞後續的所有的DML操作。
CODE:
跟蹤檔案摘要:*** 2010-07-27 23:07:16.000
ksqcmi: TM,18fe,0 mode=4 timeout=21474836
WAIT #1: nam='enqueue' ela= 3072242 p1=1414332420 p2=6398 p3=0
3.因為DML操作都獲得的是TM為3的鎖,它跟4 TM鎖不相容,因此一旦可以獲取到型別為4的TM鎖,代表表上事務都已經結束,這個時候,就可以釋放這個TM 4鎖,將鎖降級為型別為2的TM鎖。至此,開始讀取表資料建立索引。需要注意的是,這裡的讀取表資料,是一致性讀取。
建立新索引的時間要依據表的大小。整個過程要做的事情就是一致性讀取表資料+排序
CODE:
跟蹤檔案摘要:*** 2010-07-27 23:07:41.000
ksqcmi: TM,18fe,0 mode=2 timeout=21474836
ksqcmi: returns 0
4.讀取IOT表上的變更,在新的索引段上進行MERGE.這個過程中會發現IOT表的記錄數逐漸在減少。最終完成時,只剩下未提交事務所修改的記錄保留在IOT表裡。類似如下的情況。由於這些記錄還沒提交,ONLIEN程式就只能等待。
CODE:
select * from SYS_JOURNAL_207626;C0 OP PARTNO RID
---------- -- ---------- ------------------
11 I 0 D/////AAGAAAe4DAAa
11 I 0 D/////AAGAAAe4DAAb
12 D 0 D/////AAGAAAe4DAAa
12 D 0 D/////AAGAAAe4DAAb
12 D 0 D/////AAGAAAe4DAAc
12 D 0 D/////AAGAAAe4DAAd
5.獲取表上型別為4的TM鎖,等待未提交的事務結束,阻塞後續的事務,以免讓索引重建過程“無限期”的等待。這裡又是一個風險點,因為申請了一個TM 4鎖,會阻塞後面的DML操作。
一旦步驟4裡涉及的變更記錄都已經提交,那麼就會把最終的這批記錄MERGE進新索引裡。最後刪除IOT表。整個過程完畢。
有個疑問,就是在進行MERGE過程中,ORACLE依據什麼判斷IOT表裡那些記錄已經提交,那些沒提交?IOT表裡貌似沒這個欄位。
看來ORACLE 9I、10G所謂的ONLINE其實並不安全,因為裡面有幾個地方,會申請一個TM 4的鎖,這個鎖一旦獲取不了,就會導致DML操作的阻塞。
11G後,這個情況完全變了,ORACLE做到了真正的ONLINE.
11G ONLINE REBUILD建立索引的過程。
1.申請表上型別為2的TM鎖,建立IOT表。
2.建立完IOT表後,如果表上存在事務,那麼會發生等待,不過這個發生的等待是TX事務等待,不是在表上的TM等待了。
3.建立索引程式會被未提交的事務掛起,但是這個時候存在DML操作的話,可以正常進行。但是這些DML操作變更並不會記錄進IOT表裡。
4.如果表上事務都已經提交,那麼進行一致性讀取表上的舊資料的過程,然後對資料排序。例如:如果表上存在3個沒有提交的事務,那麼會先等待事務1,事務1提交後,會等待事務2,事務2提交後,會等待事務3.直到事務3提交,那麼才可以進行下一步。這個過程可以透過觀察 v$session的P1,P2引數來了解,隨著事務的提交,P1,P2的值也會發生變化,P1,P2的值反應了當前等待在哪個事務上。這個過程雖然不會阻塞事務,但是我們不難發現,如果表上事務併發比較大,那麼重建索引的進行就會被延期。知道表上的“那一刻”不存在事務。
5.把IOT表裡的資料在新索引段上進行MERGE,這個過程中,會發現IOT表的資料逐漸減少。最終只剩下沒提交事務的資料。
6.等待IOT表裡未提交的事務進行提交,這個時候後臺會等待TX事務鎖,型別為4.直到所有的事務都已經提交,這個過程才會完成。這個
過程不會阻塞新進的事務,ORACLE會把變更的資料記錄進IOT表裡(當然要涉及到跟索引欄位相關的資料才會被記錄進IOT表裡)。
11G最大的特點是不需要對TM鎖進行鎖轉化了,11G前由於這種鎖轉化,可能會阻塞DML操作,可能會引起故障。
但是理論上11G這種做法也會引起問題,因為在第4、6步,在等待事務結束期間,一直有源源不斷的事務進來,如果運氣差的話,那麼你的索引重建時間就會非常長。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22034023/viewspace-723144/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- create index .. onlineIndex
- Oracle 9i, 10g, and 11g RAC on Linux所需要的Hangcheck-Timer Module介紹OracleLinuxGC
- android中foreground水波實現過程分析Android
- postgresql create index concurrently過程描述SQLIndex
- 詳細分析連結串列的資料結構的實現過程(Java 實現)資料結構Java
- promise實現過程Promise
- pt-online-schema-change工作過程介紹
- 詳細分析棧和佇列的資料結構的實現過程(Java 實現)佇列資料結構Java
- 9i和10g上rman全備的一點差別
- 9i and 10g 透過SQL_ADDRESS 或sql_id查詢執行計劃SQL
- Spring AOP實現過程Spring
- SignalR簡版web聊天室(實現過程分析篇)SignalRWeb
- 《黑色沙漠Online》的過去、現在和未來
- Oracle 10g(10.1.0.2)中的OPTIMIZER_INDEX_COST_ADJ(轉)Oracle 10gIndex
- 手寫IOC實現過程
- 手寫AOP實現過程
- 換膚功能實現過程
- Oralce 入門教程:Oracle Database 9i 10g 11g程式設計藝術 深入資料庫體系結構 第2版OracleDatabase程式設計資料庫
- synchronized的實現原理——鎖膨脹過程synchronized
- 【Node】詳解模組的實現過程
- vertica 如何實現儲存過程?儲存過程
- JWT實現過程及應用JWT
- Spring MVC實現過程淺析SpringMVC
- HDFS寫過程分析
- 驗證Oracle 10g線上整理碎片索引是否失效過程Oracle 10g索引
- django 動態查詢實現過程Django
- oracle監聽檔案listener.ora for 10g/11gOracle
- 全面分析全息投影的成像過程
- JavaScript的預編譯過程分析JavaScript編譯
- Glide的load()過程原始碼分析IDE原始碼
- java中listFiles(Filefilter filter)檔案過濾器的實現過程JavaFilter過濾器
- JVM系列(四):java方法的查詢過程實現JVMJava
- 案例展示自定義C函式的實現過程函式
- @ComponentScan註解的實現,Spring掃描包的過程Spring
- 復現MySQL的索引選擇失誤以及透過OPTIMIZER_TRACE分析過程MySql索引
- TorchV的RAG實踐分享(三):解析llama_index的資料儲存結構和召回策略過程Index
- Oracle從10g升級到11g詳細步驟Oracle
- Liferay 啟動過程分析
- 資料需求分析過程