Oracle 11g undo_retention 以及retention guarantee 小結
undo 裡面記錄的是被修改的資料區塊的前鏡像,但是他並不是原資料區塊的copy,而是一個改變向量,真正的一致性讀要藉助CR塊,Cr塊也就是consistent read塊它用來維護Oracle的讀一致性的資料區塊。當查詢某些資料的時候,探索資料塊的版本比我們要查詢的新,例如session1執行了dml操作並沒有提交,session2此時尋找跟session1相關的dml操作的資料資訊,此時查詢的資料卻是原來的資料資訊。
查詢的過程會在undo段中尋找該資料區塊的前映像後,然後把前映像和current塊合并形成了一個CR block,通過查詢cr block就可以滿足資料的一致性了。
CR block存在於sga的buffer cache中,在db cache裡申請一個資料區塊(當前塊),然後和對應的復原段的前映像產生cr block。
關於undo的參數:
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
從11g開始oracle預設都是undo tablespace 自動管理,並且如果你沒有指定undo_tablespace 這個參數,也就是說沒有undo資料表空間,那麼oracle就會把修改塊的前鏡像放到system資料表空間裡面,並且會在alert日誌裡面警示:資料庫 running without an undo tablespace。
下面重點解釋 undo_retention
我們知道undo segments的extents 的狀態共有四種,free ,active , inacitve, expired
SQL> select SEGMENT_NAME,TABLESPACE_NAME,STATUS from dba_undo_extents;
SEGMENT_NAME TABLESPACE_NAME STATUS
------------------------------ ------------------------------ ---------
_SYSSMU10_3534552179$ UNDOTBS1 EXPIRED
_SYSSMU10_3534552179$ UNDOTBS1 EXPIRED
_SYSSMU10_3534552179$ UNDOTBS1 UNEXPIRED
_SYSSMU10_3534552179$ UNDOTBS1 EXPIRED
_SYSSMU10_3534552179$ UNDOTBS1 EXPIRED
_SYSSMU10_3534552179$ UNDOTBS1 EXPIRED
_SYSSMU9_3683992930$ UNDOTBS1 EXPIRED
_SYSSMU9_3683992930$ UNDOTBS1 EXPIRED
_SYSSMU9_3683992930$ UNDOTBS1 EXPIRED
1)free:沒有分配給任何一個段
2)active:區中有事務沒有提交
3)inactive:區中的事務提交了但是還沒有達到 undo_retention 的時間
4)expired:事務提交而且達到了undo_retention
註:我們可以通過設定undo_retention來保住inactive的區,若沒有free,則自動擴充;若擴充不了,則優先使用expired;若還不夠,則就會使用inactive,但如果此時retention是guarantee保證的(也就是ALTER TABLESPACE undotbs1 RETENTION GUARANTEE),則無法使用inactive,會報ORA-30036。
小結 :如果你傾向於保證資料一致性,也就是專註於查詢,那麼你有必要通過ALTER TABLESPACE undotbs1 RETENTION GUARANTEE,來保證一致性,也就是不管你空間夠不夠用,你都不可以使用inactive狀態的區,這樣就有可能導致由於沒有可用的undo空間而導致資料庫hang住,但是這樣你可以保證查詢語句執行時間在 undo_retention值 之內的所有查詢 的一致性。如果你的業務傾向於事務,你可以不去設定 RETENTION GUARANTEE,這樣當沒有可用的undo空間時,可以去覆蓋inactive狀態的區,這樣就有可能報錯ora-01555,不能一致讀了,因為你的undo_retention 值是通過諮詢你們當前業務的查詢語句執行時間最長的那個時間來確定的,也就是說undo_retention > sql執行最長時間,因此你使用不使用GUARANTEE取決於你業務的需求。