標籤:blog http 使用 strong 資料 io width 2014
DML語句流程
1 擷取事務鎖和ITL
2 鎖定候選行
3 產生redo
4 產生undo
5 產生redo record寫入log buffer並更改資料區塊
事務提交
1 分配SCN
2 更新事務表,將事務槽狀態改為0x09
3 回收undo塊
4 建立commit redo record
5 將redo從log buffer重新整理
6 釋放表鎖和行鎖
鎖
一個事務由1個TX和若干TM組成,而復原savepoint不會釋放TX鎖;
ITL通過XID指向事務槽,進而指向undo記錄,其UBA也指向undo記錄;
兩者區別在於:事務槽指向undo chain起始位置,而UBA指向事務最近一次改動;
Undo chain:同一事務的undo record形成單向鏈表,新產生的插入隊首;
一個undo塊只能由1個事務使用;
構造CR塊
會話A對塊做DML尚未提交,會話B此時讀取該塊則會探測到1個open ITL,檢查復原段頭的事務表發現狀態為active,則需構造1個CR塊;
複製當前塊,通過復原段頭和復原塊撤銷其最近操作;
通過x$bh.state可查看buffer狀態
0 FREE no valid block image
1 XCUR a current mode block, exclusive to this instance
2 SCUR a current mode block, shared with other instances
3 CR a consistent read (stale) block image
4 READ buffer is reserved for a block being read from disk
5 MREC a block in media recovery mode
6 IREC a block in instance (crash) recovery mode
延遲塊清除
事務提交時只保證將事務槽狀態改為inactive,若此時塊已經不在buffer中,則ITL仍為open;
下次讀取時依據事務槽資訊更新ITL的flag和Commit SCN,以及釋允許存取鎖和fsc(free space credit),期間會產生redo;
有2種例外:
1 事務表槽已被重用,即wrap#>XID.wrap#,則使用復原段頭的CSCN作為upper bound SCN;
2 復原段已刪除,則用undo$中的SCN更新(ITL的flag為CU--);
http://www.laoxiong.net/about-block-delay-cleanout-and-consistent-reads.html
快速塊清除
提交時塊仍在記憶體,更新其ITL的commit SCN(鎖標誌不更新)和flag(-U--),涉及的塊最多達到buffer cache的10%;
若塊已經同步到磁碟即狀態為clean,此操作會讓其重新為dirty需要二次重新整理;
下次讀取該塊時,通過檢查事務槽確認已提交,則將ITL關閉;若對應復原段已刪除,則從undo$中尋找SCN記錄;
事務恢複
1 rollback
反向掃描所有的undo記錄(latest first)並依次應用,ITL會隨之更新;
2 進程crash
PMON負責恢複;可通過10012事件查看;
3 資料庫crash
SMON負責恢複;再次啟動時,優先恢複system復原段的事務 ,先將其他復原段事務設為DEAD,待資料庫OPEN後再次掃描這些復原段並執行復原;
可通過x$ktuxe.ktuxecfl=’DEAD’查詢死事務,其事務槽的cflags=0x10;
10013事件可追蹤資料庫啟動時的事務恢複;10015則dump事務恢複前後的復原段頭;
10153可禁止資料區塊啟動時復原死事務;
隱含參數
_offline_rollback_segments & _corruupted_rollback_segments
指定的復原段在資料庫啟動時不會被掃描,其包含的active事務也不會被復原;
若塊包含open ITL指向_offline復原段,重新讀取該塊時會訪問事務表,若事務已提交則執行塊清除,若active只可構造CR塊;
轉載:http://blog.itpub.net/15480802/viewspace-1086960/