用戶所執行 DML (即執行事務)操作在 Oracle 內部按如下順序進行。
1.相應事務分配回滾段( undo segment ), 這時優先使用當前聯機狀態的回滾段中一個。回滾段的選擇是隨機的,若另外的事務正在使用則重試 3 次, 在此過程中失敗, 則將未聯機的回滾段聯機後使用。 如果此過程也失敗, 就會創建新的回滾段, 通過這個過程也沒有分配到回滾段, 則使用 Oracle 8i 中使用的回滾段( rollback segment ) 算法。即,使用另外事務使用中的回滾段中用量最少的回滾段。 如果服務器進程在獲得回滾段時沒有適當的聯機狀態的回滾段, 則等待 enq:US-contention 事件, 直到有適當的聯機狀態的回滾段爲止。
2.分配回滾段後,在回滾段頭上創建事務表 Slot ( transaction table slot )。
3.創建事務表後會生成 TXID ( Transaction ID ),再將此 TXID 分配給當前事務。 TXID 通過 V$TRANSACTION 視圖的 XIDUSN 、 XIDSLOT 、 XIDSQN 表現, 這個值指向分給事務的回滾段頭上存在的事務表的準確位置。事務必須在分配撤銷區域後得到 TXID 。
4.事務對象的 數據塊載入到高速緩衝區,在塊頭的 ITL ( Interested Transaction List )上登記事務條目( transaction entry )。如果 ITL 上沒有登記條目所需的空間,直到有空間爲止,一直等待 enq : TX-allocate ITL entry 事件。
5.將需要修改的塊的修改信息存儲到 PGA , 存儲名爲 Change Vector 。修改一行時,一般分別創建撤銷頭塊( change vector#1 )、撤銷塊( change vector#2 )、 數據塊( change vector#3 )相應的 change vector 。 進程將 PGA 的 change vector 以名爲 redo record (或 redo entry )複製到重做緩衝區。在複製到重做緩衝區的過程中, 需獲得 redo copy 鎖存器、 redo allocation 鎖存器、 redo writing 鎖存器, 在此過程中若發生鎖存器爭用, 分別等待 latch: redo copy 、 latch: redo allocation 、 latch: redo writing 事件。
6.將之前映像信息( before image ) 記錄到撤銷塊, 繼而修改數據塊, 被修改的數據塊變爲髒狀態。 而且, 高速緩衝區上創建關於已修改的數據塊的 CR ( consistent read ) 塊。 如果需修改的行正在被另外事務所改變(即,修改後事務尚未結束的 狀態), 就要等待事務結束, 此時會等待 enq:TX-row lock contention 事件。
7.執行提交( commit )後給事務分配 SCN ,提交信息存儲在重做緩衝區。
8.回滾段頭的事務表中存儲已成功提交的信息,解除包括 TX 鎖在內的所有資源佔有。
9.重做緩衝區的內容記錄在重做日誌文件上,修改的塊之後被 DBWR 記錄到數據文件中。
事物執行用僞碼錶示如下:
//1.分配回滾段,優先從online undo space中分配
if(online undo segments no space){
for(i=0;i++,i<3){
//新事物從新循環申請三次回滾段
}
}
if(新事物還沒有申請到空間){
//聯機offline undo segments,從中分配空間
}
if(還沒有申請到回滾段空間){
//使用rollback segment算法,使用另外事物使用中的回滾段中用量最少的回滾段
}
if(還沒有申請到undo segments){
//則發生enq:US-contention等待事件,直到能夠分配到適當的回滾段爲止
}
//2.在分配到的回滾段頭創建事物表Slot(transaction table slot)
//3.生成TXID(Transaction ID),並把TXID分配給當前事物
//4.往高速緩衝區載入事物對象關聯的數據塊,在塊頭的TIL(Interested Transaction List)上
登記事物條目(transaction entry)
if(如果塊頭上沒有登記ITL所需空間){
//則發生enq:TX-allocate-ITL entry等待事件,直到有空間爲止
}
//5.往PGA存儲修改塊的修改信息,以Change Vector的格式,Change Vector裏面包含(創建撤銷塊頭,撤銷塊,數據塊信息)
進程將PGA的change vector 以名爲redo record(或redo entry)複製到重做緩衝區
//6.將之前映像信息(before image)記錄到撤銷塊,繼而修改數據塊,被修改的數據塊變爲髒狀態
並且會在高速緩衝區中創建已修改數據塊的一致讀塊
if(需修改的塊正在被另外事物所改變){
//發生enq:TX-row lock contention等待事件
}
//7.執行提交(commit)後給事物分配SCN,提交信息存儲在重做緩衝區。
//8.回滾段頭的事物表中存儲已成功提交的信息,解除包括TX鎖在內的所有資源佔用。
//9.重做緩衝區內容記錄在redo log上,修改該的塊之後被DBWR記錄到數據文件中。