UNDO 資料表空間管理
1、對於DML語句來說,只要修改了資料區塊,Oracle資料庫就會將修改前的資料區塊保留下來,儲存在undo segment裡面,而undo segment則儲存在undo資料表空間中
2、undo的管理
自動undo管理(Oracle9i開始)AUM
手工undo管理MUM
9i以後,就建議使用AUM,因此就不再討論MUM
一條DML語句的執行流程update t set coll=‘A’ where coll=‘B’
1、在shared pool裡面進行解析,從而產生執行計畫
2、根據執行計畫,得出coll=‘B’的記錄存放在10號資料檔案的54號資料區塊裡面
3、伺服器處理序首先在buffer cache尋找一個可用的undo資料區塊(如果一個事物已經提交,那麼這個事務曾經使用過的undo資料區塊就可以被使用),如果沒有發現,則到undo資料表空間裡找到一個可用的undo資料區塊,並調入到buffer cache。假設獲得的undo資料區塊號為24號,位於11號undo資料檔案裡
4、將改變前的值,也就是B放入24號undo資料區塊(buffer cache中)
5、由於undo資料區塊發生了變化(只要是資料區塊發生變化,那麼就產生重做記錄),於是產生重做記錄,假設重做記錄號是120
650) this.width=650;" border=0>
6、在buffer cache裡面找到54號資料區塊,如果沒有,則從10號資料檔案調入
7、將改變後的值,也就是A放入54號資料區塊
8、由於資料區塊發生了變化,於是產生重做記錄,假設重做記錄號是121
650) this.width=650;" border=0>
9、控制權返回給使用者,如果使用SQLPLUS,那麼表現為游標返回
10、使用者發出commit命令,觸發LGWR,將120、121這兩個重做記錄寫入聯機重做記錄檔中,將54號、24號兩個資料區塊頭部所記錄的事務狀態標記設定為已提交,控制權返回給使用者,如果使用SQLPLUS,那麼表現為游標返回
11、這個時侯,54號和24號資料區塊並不一定被DBWr寫入資料檔案,只有在髒資料區塊的數量達到一定程度的時候才會被寫入
事務提交以後,該事務所使用的undo資料區塊就可以被覆蓋,上面的例子中,第10步使用者提交以後,24號undo資料區塊就可以被覆蓋
Undo的作用
1、提供讀一執性
2、復原事務
3、執行個體恢複
讀一致性
一個情境描述
讀一致性是相對髒讀而言的,表T中有10000條記錄,擷取所有的記錄需要15分鐘的時間,目前時間為9點整,使用者發出一條select * from T命令,該語句在9:15完成。當使用者執行該語句到9:10分的時候,另外一個使用者發出了一條刪除命令,將最後一條記錄刪除,並且進行了提交。
到9點15分的時候,使用者返回了多少條記錄。
如果是9999條,那麼就是髒讀、如果是10000條,那麼就是讀一致性。
Oracle不會出現髒讀,提供讀一致性,而且沒有阻塞DML操作
Oracle如何?讀一致性呢?
1、使用者在9點發出select語句的時候,伺服器處理序會記錄9點那個時刻的SCN號(SCN號是以時間(timestamp)作為參數的一個函數傳回值,調用函數(預設以timestamp為參數)隨時可以返回這個時刻的SCN號,可以使用函數在SCN和timestamp之間進行轉換),假設該SCN號是SCN9:00,那麼SCN9:00一定大於等於記錄在所有資料區塊頭部的ITL槽中的SCN號(如果有多個ITL槽,SCN最大的那個)
2、伺服器處理序掃描T表的時候,會把掃描的資料區塊頭部的ITL槽中的SCN號與SCN9:00進行比較,哪個更大。如果資料區塊頭部的SCN小於SCN9:00,那麼說明這個資料區塊在9:00以後沒有更改過,可以直接讀取,如果資料區塊頭部的SCN號大於SCN9:00,則說明該資料區塊在9:00以後更改過,已經不是9:00那個時刻的資料了於是要藉助undo塊
3、9點10分,使用者更改了T表的最後一條記錄並提交(無論是否提交,只要是更改了T表,使用者就會去讀undo資料區塊),假設被更改的是N號資料區塊,那麼N號資料區塊頭部的ITL槽中記錄的SCN被修改為SCN9:10,當伺服器處理序掃描到這個資料區塊的時候,發現ITL槽中的SCN9:10大於SCN9:00,說明該資料區塊在9:00以後被更新了,於是伺服器處理序到N號塊的頭部,找到SCN9:10所在ITL槽,由於ITL槽記錄了對應的undo塊的地址,於是伺服器處理序找到undo資料區塊,結合undo資料區塊給使用者提供讀一致性。
更多Oracle相關資訊見Oracle 專題頁面 http://www.bkjia.com/topicnews.aspx?tid=12