oracle事務知識點小結

531968912發表於2017-12-19

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指向事務最近一次改動;
 

oracle事務知識點小結


Undo chain:同一事務的undo record形成單向連結串列,新生成的插入隊首;

一個undo塊只能由1個事務使用;
 

oracle事務知識點小結



構造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--);
 


快速塊清除

提交時塊仍在記憶體,更新其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-763084/

http://blog.itpub.net/15480802/viewspace-696089/


 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25462274/viewspace-2148906/,如需轉載,請註明出處,否則將追究法律責任。

相關文章