溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Oracle 事務(wù)流程有哪些

發(fā)布時間:2021-08-06 14:31:12 來源:億速云 閱讀:121 作者:Leah 欄目:關(guān)系型數(shù)據(jù)庫

Oracle 事務(wù)流程有哪些,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

事務(wù)表:
事務(wù)表存放在undo段頭部(undo段頭塊),每一個undo段最多可以存放47個事務(wù)。
事務(wù)表按行存放事務(wù)記錄,每行一個事務(wù)記錄。
事務(wù)開始后,服務(wù)進(jìn)程分配一個XID,將事務(wù)信息(XID UBA)存放在undo的段頭塊。

Oracle盡量一個事務(wù)使用一個回滾段,如果事務(wù)太多,會出現(xiàn)回滾段重用,多個事務(wù)使用同一個回滾段。并且Oracle會均勻的將事務(wù)分配在回滾段中。

查看當(dāng)前事務(wù)信息

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$
從事務(wù)信息中可以看出,當(dāng)前事務(wù)使用的是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段的段頭塊。
可以將其轉(zhuǎn)儲查看事務(wù)表:
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
查看行數(shù)據(jù)所在數(shù)據(jù)塊的位置進(jìn)而轉(zhuǎn)儲查看數(shù)據(jù)塊結(jié)構(gòu)。

事務(wù)槽ITL:
事務(wù)槽存放在數(shù)據(jù)塊的頭部,事務(wù)修改一個數(shù)據(jù)塊,需要在事務(wù)槽中記錄事務(wù)信息。

XID 既是編號 又是地址。
1.使用了哪個回滾段的段頭塊
2.段頭塊使用了哪行來記錄事務(wù)。
3.第幾次覆蓋。 (第幾次循環(huán)使用)。

先簡單敘述一下事務(wù)的流程:

1.開始一個事務(wù),首先Oracle給這個事務(wù)分配XID,并找到一個回滾段,在回滾段頭塊將事務(wù)信息存放在事務(wù)表中,并給這個事務(wù)分配undo塊,并將undo塊的地址也寫入事務(wù)表中(UBA地址) 。
2.事務(wù)準(zhǔn)備修改一個數(shù)據(jù)塊,在該數(shù)據(jù)塊的頭部的事務(wù)槽中寫入事務(wù)信息(XID ,UBA(這個UBA指向相對應(yīng)的undo塊))。
3.開始修改數(shù)據(jù),將數(shù)據(jù)塊修改的前映像存放在undo塊中。

事務(wù)表中與事務(wù)槽中的UBA是不同的:
事務(wù)表中的UBA:

事務(wù)表中的UBA是指向事務(wù)操作的最后一個undo塊,同時也是事務(wù)回滾開始的位置。
rollback回滾時,根據(jù)事務(wù)表中的UBA直接定位事務(wù)回滾的起點(diǎn)。
并且要知道回滾塊與回滾塊之間是串起來。

事務(wù)槽中的UBA:
數(shù)據(jù)塊中事務(wù)槽的UBA指向相對應(yīng)的undo塊,意義在于加快構(gòu)造CR塊的效率,
執(zhí)行select時,服務(wù)進(jìn)程如果發(fā)現(xiàn)該行數(shù)據(jù)正在有事務(wù)進(jìn)行,且未提交,那么就會結(jié)合當(dāng)前塊以及undo塊生成CR塊(能夠更加快速的找到相對應(yīng)的undo塊)。

事務(wù)槽中記錄XID意義在于指向事務(wù)表,直接定位到事務(wù)表的位置,與Oracle提交方式有關(guān),具體原因,后面描述。

一個DML事務(wù)開始時,需要修改的位置:
回滾段頭部的事務(wù)表被修改
數(shù)據(jù)塊塊頭部的事務(wù)槽被修改
undo塊被修改
數(shù)據(jù)塊的行數(shù)據(jù)被修改
(以上四種修改都會產(chǎn)生redo)

事務(wù)槽的數(shù)量查看:
Select ini_trans,max_trans from dba_tables where table_name = ‘T1’

事務(wù)槽的爭用問題:
會話A啟動第一個事務(wù)修改該數(shù)據(jù)塊中的一行數(shù)據(jù),
需要在該數(shù)據(jù)塊中獲取一個事務(wù)槽(未提交)
(沒有提交事務(wù)槽不能被覆蓋,只有事務(wù)已經(jīng)提交的事務(wù)槽才可以被覆蓋)

會話B啟動第二個事務(wù)修改該數(shù)據(jù)塊中另一行數(shù)據(jù)
也需要在該數(shù)據(jù)塊中獲取一個事務(wù)槽
當(dāng)事務(wù)槽獲取上限以后
再來一個事務(wù)修改該數(shù)據(jù)塊的其他行,就需要等待事務(wù)槽釋放。

解決:
可以增加pctfree減少爭用
Oracle為了結(jié)局對事務(wù)槽的爭用,對insert操作,Oracle會將其分布到多個塊中。
但是對update 與 delete無能為力,只能增加事務(wù)槽,所以update與delete容易出現(xiàn)事務(wù)槽爭用。

事務(wù)槽中記錄XID的意義:
Oracle結(jié)合延遲塊的清除實(shí)現(xiàn)快速提交:
如果一個事務(wù)修改了1000個塊,事務(wù)信息在1001個塊中存在(undo段頭部塊)
當(dāng)事務(wù)提交時,需要在1001個塊的位置將事務(wù)記錄修改為已提交的狀態(tài),會很慢。

并且還可能出現(xiàn)一種情況事務(wù)修改了1000個塊,當(dāng)要提交時,已經(jīng)有800個塊被寫入磁盤。
Oracle不可能再將這800個塊重新讀入磁盤,來將數(shù)據(jù)塊頭部事務(wù)槽中記錄的事務(wù)修改為已提交狀態(tài)。

Oracle延遲塊清除的辦法:
當(dāng)事務(wù)提交時,Oracle僅更新undo段頭的事務(wù)信息,根據(jù)buffer的數(shù)量,并且僅會更新部分buffer,剩余buffer Oracle會在下次讀取這些數(shù)據(jù)塊時清除事務(wù)記錄。

所以說 數(shù)據(jù)塊中事務(wù)槽記錄未必準(zhǔn)確, 如果數(shù)據(jù)塊中事務(wù)槽記錄的事務(wù)未提交,Oracle還需要根據(jù)事務(wù)槽頭部的XID去undo段頭事務(wù)表來進(jìn)一步判斷事務(wù)是否提交,如果undo段頭事務(wù)表記錄該事務(wù)已經(jīng)提交,那么Oracle會選擇相信undo段頭,進(jìn)而修改數(shù)據(jù)塊,并且將上一個事務(wù)的事務(wù)槽中的事務(wù)記錄修改為已提交。

Oracle的多種提交方式:
事務(wù)修改的數(shù)據(jù)塊少時:
事務(wù)提交時
修改undo段頭記錄的事務(wù)狀態(tài)
修改數(shù)據(jù)塊頭部事務(wù)槽中記錄的事務(wù)狀態(tài)
修改數(shù)據(jù)行標(biāo)志(事務(wù)槽編號,指向事務(wù)槽,就是Oracle行級鎖)

事務(wù)修改的塊一般多時:
事務(wù)提交時
會將undo段頭的事務(wù)表以及數(shù)據(jù)塊頭部的事務(wù)槽中的事務(wù)狀態(tài)修改為已提交。
數(shù)據(jù)行標(biāo)記(行鎖)會在下次select訪問時清鎖。
(這也是有時select也會產(chǎn)生redo日志的原因)

事務(wù)修改的塊很多時:
當(dāng)事務(wù)提交時
僅會修改undo段頭的記錄。
事務(wù)槽,數(shù)據(jù)行標(biāo)記(行鎖)在下次select訪問時修改清鎖。

另一種情況:
如果一個數(shù)據(jù)塊長時間未被讀入到buffer cache,而且數(shù)據(jù)塊事務(wù)槽以及鎖還未清除,如果此時讀取,服務(wù)進(jìn)程會去undo段頭的事務(wù)表中判斷事務(wù)是否已經(jīng)提交,但是服務(wù)進(jìn)程讀取undo段頭的事務(wù)表時發(fā)現(xiàn),事務(wù)表已經(jīng)被覆蓋15次,此時Oracle會認(rèn)定事務(wù)已經(jīng)提交,因?yàn)槭聞?wù)未提交在事務(wù)表中不可能被覆蓋,然后服務(wù)進(jìn)程清除該數(shù)據(jù)塊事務(wù)槽的記錄,清除數(shù)據(jù)塊行鎖。

Select流程總結(jié):
(數(shù)據(jù)塊中每行數(shù)據(jù)都會有指向事務(wù)槽的標(biāo)記)
當(dāng)客戶端執(zhí)行select查詢時,服務(wù)進(jìn)程接收請求,將符合要求的數(shù)據(jù)塊讀入到buffer cache中,服務(wù)進(jìn)程會先去讀取數(shù)據(jù)塊中的行。
如果數(shù)據(jù)塊的行上有事務(wù)槽標(biāo)記(行鎖),服務(wù)進(jìn)程會去事務(wù)槽中查看該事務(wù)槽中記錄的事務(wù)是否已經(jīng)提交。(由于快速提交,延遲塊清除原則,鎖信息并不代表事務(wù)情況)
如果事務(wù)槽中記錄的事務(wù)已經(jīng)提交,那么服務(wù)進(jìn)程會清除數(shù)據(jù)塊中這行記錄的事務(wù)槽標(biāo)記(行鎖),直接讀取該行數(shù)據(jù)。
如果事務(wù)槽中記錄的事務(wù)沒有提交,Oracle會產(chǎn)生懷疑,服務(wù)進(jìn)程會根據(jù)事務(wù)槽中的XID去undo段頭部中的事務(wù)表中讀取事務(wù)狀態(tài)(事務(wù)槽中記錄XID的意義)。
如果事務(wù)表中的事務(wù)狀態(tài)為已提交,那么服務(wù)進(jìn)程會認(rèn)定這行數(shù)據(jù)所對應(yīng)的事務(wù)已經(jīng)提交,清空行標(biāo)記,將事務(wù)槽中未提交狀態(tài)修改為已提交。
如果事務(wù)表中的事務(wù)狀態(tài)為未提交,那么Oracle會認(rèn)定該數(shù)據(jù)塊中行對應(yīng)的事務(wù)未提交,此時服務(wù)進(jìn)程就會根據(jù)當(dāng)前塊中的行數(shù)據(jù)來結(jié)合undo塊來構(gòu)造CR塊,用于一致性讀。

Update流程總結(jié):
簡單的說,就是如果該行數(shù)據(jù)有事務(wù)正在進(jìn)行,那么就需要等待
如果該行數(shù)據(jù)沒有事務(wù)正在進(jìn)行,那么就正常修改。
Oracle兩個事務(wù)可以同時修改一個數(shù)據(jù)塊,只要行不沖突即可。行級鎖的并發(fā)性

關(guān)于Oracle 事務(wù)流程有哪些問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI