共計 3679 個字符,預計需要花費 10 分鐘才能閱讀完成。
Oracle 事務流程有哪些,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
事務表:
事務表存放在 undo 段頭部(undo 段頭塊),每一個 undo 段最多可以存放 47 個事務。
事務表按行存放事務記錄,每行一個事務記錄。
事務開始后,服務進程分配一個 XID,將事務信息(XID UBA)存放在 undo 的段頭塊。
Oracle 盡量一個事務使用一個回滾段,如果事務太多,會出現回滾段重用,多個事務使用同一個回滾段。并且 Oracle 會均勻的將事務分配在回滾段中。
查看當前事務信息
select xid,xidusn,xidslot,xidsqn,ubablk,ubafil from v$transaction ;XID XIDUSN XIDSLOT XIDSQN UBABLK UBAFIL
06001C004B040000 6 28 1099 711 3
查看所有回滾段。SYS@prod Select * from v$rollname; 0 SYSTEM
1 _SYSSMU1_3724004606$
2 _SYSSMU2_2996391332$
3 _SYSSMU3_1723003836$
4 _SYSSMU4_1254879796$
5 _SYSSMU5_898567397$
6 _SYSSMU6_1263032392$
7 _SYSSMU7_2070203016$
8 _SYSSMU8_517538920$
9 _SYSSMU9_1650507775$
10 _SYSSMU10_1197734989$
從事務信息中可以看出,當前事務使用的是 6 號 undo 段。找到 6 號 undo 段的段頭塊的位置:SYS@prod select header_file,header_block from dba_segments where segment_name = ‘_SYSSMU6_1263032392$’;
HEADER_FILE HEADER_BLOCK
3 208
3 號文件 208 塊就為 undo 段的段頭塊。可以將其轉儲查看事務表:Alter system dump datafile 3 block 208
select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) block,id
from t1
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) BLOCK ID
1 91041 5
1 91041 5
1 91041 5
查看行數據所在數據塊的位置進而轉儲查看數據塊結構。
事務槽 ITL:
事務槽存放在數據塊的頭部,事務修改一個數據塊,需要在事務槽中記錄事務信息。
XID 既是編號 又是地址。
1. 使用了哪個回滾段的段頭塊
2. 段頭塊使用了哪行來記錄事務。
3. 第幾次覆蓋。(第幾次循環使用)。
先簡單敘述一下事務的流程:
1. 開始一個事務,首先 Oracle 給這個事務分配 XID,并找到一個回滾段,在回滾段頭塊將事務信息存放在事務表中,并給這個事務分配 undo 塊,并將 undo 塊的地址也寫入事務表中(UBA 地址) 。2. 事務準備修改一個數據塊,在該數據塊的頭部的事務槽中寫入事務信息(XID ,UBA(這個 UBA 指向相對應的 undo 塊))。3. 開始修改數據,將數據塊修改的前映像存放在 undo 塊中。
事務表中與事務槽中的 UBA 是不同的:
事務表中的 UBA:
事務表中的 UBA 是指向事務操作的最后一個 undo 塊,同時也是事務回滾開始的位置。
rollback 回滾時,根據事務表中的 UBA 直接定位事務回滾的起點。
并且要知道回滾塊與回滾塊之間是串起來。
事務槽中的 UBA:
數據塊中事務槽的 UBA 指向相對應的 undo 塊,意義在于加快構造 CR 塊的效率,
執行 select 時,服務進程如果發現該行數據正在有事務進行,且未提交,那么就會結合當前塊以及 undo 塊生成 CR 塊(能夠更加快速的找到相對應的 undo 塊)。
事務槽中記錄 XID 意義在于指向事務表,直接定位到事務表的位置,與 Oracle 提交方式有關,具體原因,后面描述。
一個 DML 事務開始時,需要修改的位置:
回滾段頭部的事務表被修改
數據塊塊頭部的事務槽被修改
undo 塊被修改
數據塊的行數據被修改
(以上四種修改都會產生 redo)
事務槽的數量查看:
Select ini_trans,max_trans from dba_tables where table_name =‘T1’
事務槽的爭用問題:
會話 A 啟動第一個事務修改該數據塊中的一行數據,
需要在該數據塊中獲取一個事務槽(未提交)
(沒有提交事務槽不能被覆蓋,只有事務已經提交的事務槽才可以被覆蓋)
會話 B 啟動第二個事務修改該數據塊中另一行數據
也需要在該數據塊中獲取一個事務槽
當事務槽獲取上限以后
再來一個事務修改該數據塊的其他行,就需要等待事務槽釋放。
解決:
可以增加 pctfree 減少爭用
Oracle 為了結局對事務槽的爭用,對 insert 操作,Oracle 會將其分布到多個塊中。
但是對 update 與 delete 無能為力,只能增加事務槽,所以 update 與 delete 容易出現事務槽爭用。
事務槽中記錄 XID 的意義:
Oracle 結合延遲塊的清除實現快速提交:
如果一個事務修改了 1000 個塊,事務信息在 1001 個塊中存在(undo 段頭部塊)
當事務提交時,需要在 1001 個塊的位置將事務記錄修改為已提交的狀態,會很慢。
并且還可能出現一種情況事務修改了 1000 個塊,當要提交時,已經有 800 個塊被寫入磁盤。
Oracle 不可能再將這 800 個塊重新讀入磁盤,來將數據塊頭部事務槽中記錄的事務修改為已提交狀態。
Oracle 延遲塊清除的辦法:
當事務提交時,Oracle 僅更新 undo 段頭的事務信息,根據 buffer 的數量,并且僅會更新部分 buffer,剩余 buffer Oracle 會在下次讀取這些數據塊時清除事務記錄。
所以說 數據塊中事務槽記錄未必準確,如果數據塊中事務槽記錄的事務未提交,Oracle 還需要根據事務槽頭部的 XID 去 undo 段頭事務表來進一步判斷事務是否提交,如果 undo 段頭事務表記錄該事務已經提交,那么 Oracle 會選擇相信 undo 段頭,進而修改數據塊,并且將上一個事務的事務槽中的事務記錄修改為已提交。
Oracle 的多種提交方式:
事務修改的數據塊少時:
事務提交時
修改 undo 段頭記錄的事務狀態
修改數據塊頭部事務槽中記錄的事務狀態
修改數據行標志(事務槽編號,指向事務槽,就是 Oracle 行級鎖)
事務修改的塊一般多時:
事務提交時
會將 undo 段頭的事務表以及數據塊頭部的事務槽中的事務狀態修改為已提交。
數據行標記(行鎖)會在下次 select 訪問時清鎖。
(這也是有時 select 也會產生 redo 日志的原因)
事務修改的塊很多時:
當事務提交時
僅會修改 undo 段頭的記錄。
事務槽,數據行標記(行鎖)在下次 select 訪問時修改清鎖。
另一種情況:
如果一個數據塊長時間未被讀入到 buffer cache,而且數據塊事務槽以及鎖還未清除,如果此時讀取,服務進程會去 undo 段頭的事務表中判斷事務是否已經提交,但是服務進程讀取 undo 段頭的事務表時發現,事務表已經被覆蓋 15 次,此時 Oracle 會認定事務已經提交,因為事務未提交在事務表中不可能被覆蓋,然后服務進程清除該數據塊事務槽的記錄,清除數據塊行鎖。
Select 流程總結:
(數據塊中每行數據都會有指向事務槽的標記)
當客戶端執行 select 查詢時,服務進程接收請求,將符合要求的數據塊讀入到 buffer cache 中,服務進程會先去讀取數據塊中的行。
如果數據塊的行上有事務槽標記(行鎖), 服務進程會去事務槽中查看該事務槽中記錄的事務是否已經提交。(由于快速提交,延遲塊清除原則,鎖信息并不代表事務情況)
如果事務槽中記錄的事務已經提交,那么服務進程會清除數據塊中這行記錄的事務槽標記(行鎖),直接讀取該行數據。
如果事務槽中記錄的事務沒有提交,Oracle 會產生懷疑,服務進程會根據事務槽中的 XID 去 undo 段頭部中的事務表中讀取事務狀態(事務槽中記錄 XID 的意義)。
如果事務表中的事務狀態為已提交,那么服務進程會認定這行數據所對應的事務已經提交,清空行標記,將事務槽中未提交狀態修改為已提交。
如果事務表中的事務狀態為未提交,那么 Oracle 會認定該數據塊中行對應的事務未提交,此時服務進程就會根據當前塊中的行數據來結合 undo 塊來構造 CR 塊,用于一致性讀。
Update 流程總結:
簡單的說,就是如果該行數據有事務正在進行,那么就需要等待
如果該行數據沒有事務正在進行,那么就正常修改。
Oracle 兩個事務可以同時修改一個數據塊,只要行不沖突即可。行級鎖的并發性
關于 Oracle 事務流程有哪些問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注丸趣 TV 行業資訊頻道了解更多相關知識。