溫馨提示×

溫馨提示×

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

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

怎么理解Oracle事務(wù)

發(fā)布時間:2021-11-18 14:29:56 來源:億速云 閱讀:187 作者:iii 欄目:關(guān)系型數(shù)據(jù)庫

本篇內(nèi)容主要講解“怎么理解Oracle事務(wù)”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“怎么理解Oracle事務(wù)”吧!

oracle事務(wù)

1概述

事務(wù)由一個或多個DML語句組成,起始于第一條DML語句,終止于DDL或者DCL語句??梢栽谑聞?wù)內(nèi)使用SAVEPOINT命令給出控制程度。,通過事務(wù)機制確保這一組SQL語句所作的操作要么完全成功執(zhí)行,完成整個工作單元操作,要么一點也不執(zhí)行。

2事務(wù)的特性

怎么理解Oracle事務(wù)

3事務(wù)控制

1 COMMIT命令

許多人(甚至某些經(jīng)驗豐富的DBA)在提交處理這個環(huán)節(jié)上都會出現(xiàn)不完全或者完全錯誤的理解oracle體系結(jié)構(gòu)的情況。執(zhí)行COMMIT命令時發(fā)生的所有物理操作時LGWR進(jìn)程將日志緩沖區(qū)的內(nèi)容刷新到磁盤。DBWn進(jìn)程完全沒有執(zhí)行任何操作。對于oracle數(shù)據(jù)庫來說,這是一個非常重要的性能特性。

注意執(zhí)行COMMIT命令時,DBWn進(jìn)程不會進(jìn)行任何操作。 

為了使某個事務(wù)持久,所需的全部工作是將組成這個事務(wù)的變更寫入磁盤(不必使實際表數(shù)據(jù)存在于磁盤的數(shù)據(jù)文件上)。如果變更以多重重做日志文件的形式存在于磁盤上,那么在出現(xiàn)使數(shù)據(jù)庫受損的事件時,通過從數(shù)據(jù)庫受損前所做的備份中還原數(shù)據(jù)文件以及應(yīng)用重做日志文件中的變更,就可以重新實例化事務(wù)。

2 ROLLBACK命令

在事務(wù)處理過程中,Oracle會保存事務(wù)處理之前數(shù)據(jù)的映像。在事務(wù)處理過程中,會將這個映像提供給查詢數(shù)據(jù)的其他會話。如果出現(xiàn)錯誤,或者會話故意請求回滾,那么它也可以用來自動回滾事務(wù)。

回滾之前數(shù)據(jù)的狀態(tài)是,數(shù)據(jù)已經(jīng)改變,但反轉(zhuǎn)這些變更所需的信息是可用的。為了滿足隔離性原則,會將這些信息提供給其他所有會話。回滾會恢復(fù)數(shù)據(jù)改變之前的映像,從而拋棄所有變更;事務(wù)插入的所有行都會刪除,(這里留個疑問)事務(wù)刪除的所有行都會重新插入表中,已經(jīng)更新的行會回到原始狀態(tài)。其他會話根本不知道發(fā)生了什么,它們絕對看不到這些變更。處理事務(wù)的會話現(xiàn)在會將數(shù)據(jù)看做事務(wù)開始之前的數(shù)據(jù)。

3 SAVEPOINT命令

使用保存點就是允許編程人員在事務(wù)中設(shè)置一個標(biāo)記,這個標(biāo)記可以用來控制ROLLBACK命令的效果。除了回滾整個事務(wù)并終止它之外,還可以反轉(zhuǎn)在特定點之后所做的所有變更,同時保持在該點之前所做的變更不變。事務(wù)本身繼續(xù)進(jìn)行:仍然沒有提交,仍然可以回滾,仍然對其他會話不可見。

3.1使用savepoint的規(guī)則:

(1)所有的savepoint語句都必須包含一個名稱。在后臺,您所創(chuàng)建的savepoint名稱會與"系統(tǒng)變更號"(system change number,scn)"相關(guān)聯(lián)。這是savepoint所標(biāo)注的對象。

(2)在一個事務(wù)中不應(yīng)當(dāng)重復(fù)savepoint的名稱,事務(wù)是以提交事件作為結(jié)束的一連串的SQL語句。如果重復(fù)一個名稱,那么不會看到語法錯誤或執(zhí)行錯誤。相反,新的savepoint會覆蓋較早的savepoint,從效果上是將之前的存儲點刪除了。

(3)一旦提交事件發(fā)生,無論是顯示或隱式提交事件,則所有現(xiàn)有的存儲點都將會從內(nèi)存中被刪除。

4 SELECT FOR UPDATE

最后一個事務(wù)控制語句是SELECT FOR UPDATE。在默認(rèn)情況下,Oracle提供最高級別的并發(fā)性:讀者不打斷寫者,寫者也不打斷讀者?;蛘吆唵蔚恼f,一個會話查詢另一個會話正在更新的數(shù)據(jù),或者一個會話更新另一個會話正在查詢的數(shù)據(jù),這都沒有問題。然而,有時需要改變這種行為,防止改變正在被查詢的數(shù)據(jù)。

應(yīng)用程序使用SELECT命令檢索一組行,將它們提供給用戶精讀,并給用戶提示所做的變更,這種情況不是不常見。因為ORACLE是一個多用戶數(shù)據(jù)庫,所以另一個會話也要檢索這些行也不是不可能。如果這兩個會話都要做出變更,那么會出現(xiàn)一些奇怪的效果。

 

Session1

Session2

 

select * from emp;  

出現(xiàn)N條數(shù)據(jù),其中包括id=1的數(shù)據(jù)

 
  

用戶刪除emp表一條數(shù)據(jù)

delete from emp where id=1;  

 

update emp set name='test' where id=1; 

此時會出現(xiàn)"0 rows updated"

 
 

解決這個問題的方法之一就是鎖定用戶感興趣的行:

select * from emp for update;  

 

FOR UPDATE子句會鎖定所有檢索的行。除了發(fā)出命令的會話之外,其他任何會話都不能改變它們,因此后面的更新操作就會成功。這意味著一個會話有一致的數(shù)據(jù)視圖(不會改變),但付出的代價是如果其他會話要更新鎖定的行,它們就會掛起(當(dāng)天他們可以查詢)。

在發(fā)出命令的會話發(fā)出COMMIT或ROLLBACK命令之前,會一直保持FOR UPDATE子句設(shè)置的鎖定。必須這樣來釋放鎖定,即使沒有執(zhí)行DML命令。

5 所謂的"自動提交"

在結(jié)束對提交處理的討論之前,我們有必要闡明一下經(jīng)常被提及的"自動提交"(有時候也被稱為隱式提交)。您經(jīng)常會聽到這樣的說法:Oracle在某些情況下可以進(jìn)行"自動提交"。

執(zhí)行DDL語句就是其中一種情況,

退出某個用戶進(jìn)程(SQL*Plus)則是另一種情況。

"自動提交"純屬子虛烏有。執(zhí)行某條DDL語句時,實現(xiàn)這個DDL命令的源代碼包含了一個完全正規(guī)的COMMIT命令。但是,退出用戶進(jìn)程時的情況是怎樣呢?

 

執(zhí)行"退出"命令(正常)

直接點擊右上角關(guān)閉(異常)

Windows

提交

回滾

Linux

提交

回滾

如果在WINDOWS終端上使用SQL*Plus并執(zhí)行一條DML語句,然后再執(zhí)行"退出"命令,就會提交事務(wù)。這是因為SQL*Plus中的"退出"命令嵌入了一條COMMIT語句。

但是,單擊SQL*Plus窗口的右上角此時,關(guān)閉SQL*Plus窗口,如果再次登錄SQL*Plus,您會發(fā)現(xiàn)已回滾了事務(wù)。這是因為為Microsoft Windows編寫SQL*Plus的編程人員在關(guān)閉SQL*Plus窗口的代碼中嵌入了一條ROLLBACK語句。

SQL*Plusz在其他平臺上的行為可能有所不同,唯一的確認(rèn)方法是測試。因此,以不同方式退出某個程序時是否能夠進(jìn)行"自動提交"完全取決于編程人員如果編寫用戶進(jìn)程。Oracle服務(wù)器只是按照指令進(jìn)行操作。

4 oracle提交數(shù)據(jù)的類型

1 顯式提交

用COMMIT命令直接完成的提交為顯式提交。

其格式為:SQL>COMMIT; 

2 隱式提交

用SQL命令間接完成的提交為隱式提交

這些命令是:ALTER,AUDIT,COMMENT,CONNECT,CREATE,DISCONNECT,DROP,EXIT,GRANT,NOAUDIT,QUIT,REVOKE,RENAME。 執(zhí)行這些命令前oracle會執(zhí)行一次commit,命令執(zhí)行完后oracle也會自動執(zhí)行一次commit 

3 自動提交

若把AUTOCOMMIT設(shè)置為ON,則在插入、修改、刪除語句執(zhí)行后,系統(tǒng)將自動進(jìn)行提交,這就是自動提交。 其格式為:SQL>SET AUTOCOMMIT ON; 它只是DML語句執(zhí)行后的自動提交,對會話的正常退出或異常退出都沒有作用。

這個參數(shù)屬于客戶端sqlplus,oracle自身并沒有這個參數(shù)

查看這個參數(shù)的值:

SHOW AUTOCOMMIT

設(shè)置這個參數(shù)的值:

SET AUTO[COMMIT] { OFF | ON | IMM[EDIATE] | n } 

5 ITL(事務(wù)槽)

1 ITL描述

怎么理解Oracle事務(wù)ITL(Interested Transaction List)是Oracle數(shù)據(jù)塊內(nèi)部的一個組成部分,位于數(shù)據(jù)塊頭(block header),

每一個oracle塊的頭部都有事務(wù)槽,oracle塊里有一個PCT_free的概念,即oracle會預(yù)留塊大小的10%作為緩沖,當(dāng)修改oracle的事務(wù)增加時,事務(wù)槽向下增長,當(dāng)更新oracle塊的數(shù)據(jù)時,數(shù)據(jù)向上增長,PCT_free的空間被壓縮。當(dāng)PCT_free被用完時,oracle就徹底填滿了,如果還有事務(wù)要修改Oracle塊,就需要在事務(wù)隊列中等待這叫做事務(wù)槽的爭用。

怎么理解Oracle事務(wù)itl由xid,uba,flag,lck和scn/fsc組成,用來記錄該塊所有發(fā)生的事務(wù),一個itl可以看作是一條事務(wù)記錄。當(dāng)然,如果這個事務(wù)已經(jīng)提交,那么這個itl的位置就可以被反復(fù)使用了,因為itl類似記錄,所以,有的時候也叫itl槽位。如果一個事務(wù)一直沒有提交,那么,這個事務(wù)將一直占用一個itl槽位,itl里面記錄了事務(wù)信息,回滾段的入口,事務(wù)類型等等。如果這個事務(wù)已經(jīng)提交,那么,itl槽位中還保存的有這個事務(wù)提交時候的SCN號。

dump一個數(shù)據(jù)塊可以在事務(wù)區(qū)看到ITL信息

Block header dump:  0x01001543

Object id on Block? Y

seg/obj: 0x15c5a  csc: 0x00.1ce6af  itc: 3  flg: E  typ: 1 - DATA

    brn: 0  bdba: 0x1001540 ver: 0x01 opc: 0

    inc: 0  exflg: 0

 

Itl           Xid                  Uba          Flag  Lck        Scn/Fsc

0x01   0xffff.000.00000000  0x00000000.0000.00   C---    0  scn 0x0000.001ce6af

0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

0x03   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

bdba: 0x01001543

Object id on Block? Y是表示是否是對象的塊

 

0x01001543是數(shù)據(jù)文件號塊號

 

seg/obj: 0x15c5a是對象id 89178,它是rowid的前6個64進(jìn)制字符AAAVxa的16進(jìn)制形式,在dump(rowid,16)中的前4位中也可以看出,可參考:http://blog.itpub.net/28539951/viewspace-1986647/

 

csc: 0x00.1ce6af是The cleanout SCN that is used during read consistency

 

itc: 3是塊中itl slot的數(shù)量

flg: E

E是使用ASSM

O是使用free list

 

typ: 1 - DATA 1是數(shù)據(jù),2是索引

 

brn: 0

 

bdba: 0x1001540是Block relative data block address

 

ver: 0x01

 

opc: 0

inc: 0

exflg: 0

 

Itl是塊上相關(guān)事務(wù)列表interested transaction list

每條記錄中的行級鎖對應(yīng)于Itl列表中的序號,即哪個事務(wù)在該記錄上產(chǎn)生的鎖

 

Xid是事務(wù)id.Xid=Undo Segment Number XIDUSN+Transaction Table Slot Number XIDSLOT+ Wrap   XID = usn#.slot#.warp#

 

Uba是該事務(wù)對應(yīng)的回滾段地址.Uba=回滾塊地址(undo文件號UBAFIL和數(shù)據(jù)塊號UBABLK)+回滾序列號UBASQN+回滾記錄號UBAREC

 

Flag是事務(wù)標(biāo)志位

---= 事務(wù)是活動的,或者在塊清除前提交事務(wù)

C  =事務(wù)已經(jīng)提交并且清除了行鎖定

B  = this undo record contains the undo for this ITL entry

U  =事務(wù)已經(jīng)提交(SCN已經(jīng)是最大值),但是鎖定還沒有清除(快速清除)

T  = transaction was still active at block cleanout SCN

 

Lck是這個事務(wù)影響的行數(shù)

 

Scn/Fsc是scn或者free space credit

相關(guān)實驗可以參考

https://blog.csdn.net/gumengkai/article/details/63684545

2事務(wù)槽參數(shù)

每個塊都有一個塊首部。這個塊首部中有一個事務(wù)表。事務(wù)表中會建立一些條目來描述哪些事務(wù)將塊上的哪些行/元素鎖定。這個事務(wù)表的初始大小由對象的INITRANS 設(shè)置指定。對于表,這個值默認(rèn)為2(索引的INITRANS 也默認(rèn)為2)。事務(wù)表會根據(jù)需要動態(tài)擴(kuò)展,最大達(dá)到MAXTRANS 個條目(假設(shè)塊上有足夠的自由空間)。所分配的每個事務(wù)條目需要占用塊首部中的23~24 字節(jié)的存儲空間。注意,對于Oracle 10g,MAXTRANS 則會忽略,所有段的MAXTRANS 都是255。

設(shè)initrans值為2,則數(shù)據(jù)庫服務(wù)器在一個數(shù)據(jù)塊中最多有兩個并行的事務(wù)可以獨立、并行的通過自己的事務(wù)槽,實現(xiàn)對共享數(shù)據(jù)塊中的行數(shù)據(jù)的事務(wù)操作。

也就是說,如果某個事物鎖定了這個塊的數(shù)據(jù),則會在這個地方記錄事務(wù)的標(biāo)識,當(dāng)然那個事務(wù)要先看一下這個地方是不是已經(jīng)有人占用了,如果有,則去看看那個事務(wù)是否為活動狀態(tài)。如果不活動,比如已經(jīng)提交或者回滾,則可以覆蓋這個地方。如果活動,則需要等待(閂的作用)。所以,如果有大量的并發(fā)訪問使用的這個塊,則參數(shù)不能太小,否則資源競爭將導(dǎo)致系統(tǒng)并發(fā)性能下降。

ORACLE 并發(fā)insert事務(wù)的時候的塊分配和ITL管理

  1. INITRANS =1 時 并發(fā)多個INSERT 事務(wù)(本次測試最多5個)的時候并不會由于ITL的爭用而等待組塞,ORACLE 采取的策略是每個INSERT事物分配不同的一些塊來使用,這樣各個會話之間就不會產(chǎn)生沖突,除非段沒有多余的塊。

創(chuàng)建一張表,并查看建表的參數(shù)

create table t1(id int,num int);

select TABLE_NAME,STATUS,PCT_FREE,PCT_USED,INI_TRANS,MAX_TRANS,INITIAL_EXTENT,NEXT_EXTENT,MIN_EXTENTS,MAX_EXTENTS,PCT_INCREASE from user_tables where table_name='T1';

怎么理解Oracle事務(wù)

插入數(shù)據(jù)

insert into t1 values(1,1);

insert into t1 values(2,1);

insert into t1 values(3,1);

insert into t1 values(4,1);

commit;

查看表的數(shù)據(jù)的分布

select ID,num ,dbms_rowid.rowid_relative_fno(rowid) file#, dbms_rowid.rowid_block_number(rowid) block# from T1;

怎么理解Oracle事務(wù)

會話1

插入數(shù)據(jù)查看,發(fā)現(xiàn)插入到4號文件的532號塊

insert into t1 values(5,1);

select ID,num ,dbms_rowid.rowid_relative_fno(rowid) file#, dbms_rowid.rowid_block_number(rowid) block# from T1;

怎么理解Oracle事務(wù)

會話2

插入數(shù)據(jù)查看,發(fā)現(xiàn)插入到4號文件的533號塊

insert into t1 values(6,1);

select ID,num ,dbms_rowid.rowid_relative_fno(rowid) file#, dbms_rowid.rowid_block_number(rowid) block# from T1;怎么理解Oracle事務(wù)

會話2

插入數(shù)據(jù)查看,發(fā)現(xiàn)插入到4號文件的535號塊

insert into t1 values(9,9);

select ID,num ,dbms_rowid.rowid_relative_fno(rowid) file#, dbms_rowid.rowid_block_number(rowid) block# from T1;

怎么理解Oracle事務(wù)

綜上所述INSERT事物分配不同的一些塊來使用,這樣各個會話之間就不會產(chǎn)生沖突,除非段沒有多余的塊

ORACLE 并發(fā)update事務(wù)的時候的塊分配和ITL管理

  1. INITRANS =1 時 并發(fā)多個UPDATE事務(wù)(本次測試最多7個)的時候也不會由于ITL的爭用而導(dǎo)致等待產(chǎn)生,此時ORACLE除了使用默認(rèn)的ITL之外,另外動態(tài)擴(kuò)展所需要的ITL,緊緊在非常極端的情況下才會出現(xiàn)等待。

1) 該BLOCK沒有FREE空間了,注意FREE參數(shù)的設(shè)置不能太小。

2) 該塊使用的ITL總數(shù),超過該塊允許的ITL的最大值min(round(block_size*0.5/24) - 2 ,255) 。

要達(dá)到這樣的極端情況實際的生產(chǎn)情況是很難的,應(yīng)該比業(yè)務(wù)SQL的死鎖出現(xiàn)的概率更小。

3 ITL等待

發(fā)生等待的場景:

1.超過maxtrans配置的最大ITL數(shù)

2.initrans不足,沒有足夠的free space來擴(kuò)展ITL

解決方法:

  1. maxtrans不足:

這一情況是由高并發(fā)引起的:同一數(shù)據(jù)塊上的事務(wù)量已經(jīng)超出了其實際允許的ITL數(shù)。因此,要解決這類問題就需要從應(yīng)用著手,減少事務(wù)的并發(fā)量;長事務(wù),在保證數(shù)據(jù)完整性的前提下,增加commit的頻率,修改為短事務(wù),減少資源占用事件。而對于OLAP系統(tǒng)來說(例如,其存在高并發(fā)量的數(shù)據(jù)錄入模塊),可以考慮增大數(shù)據(jù)塊大小。

  1. initrans不足:

    數(shù)據(jù)塊上的ITL數(shù)量并沒有達(dá)到MAX TRANS的限制,發(fā)生這種情況的表通常會被經(jīng)常UPDATE,從而造成預(yù)留空間(PCTFREE)被填滿。如果我們發(fā)現(xiàn)這類ITL等待對系統(tǒng)已經(jīng)造成影響,可以通過增加表的INITRANS或者PCTFREE來解決(視該表上的并發(fā)事務(wù)量而定,通常,如果并發(fā)量高,建議優(yōu)先增加INITRANS,反之,則優(yōu)先考慮增加PCTFREE)。

要注意的一點是,如果是使用ALTER TABLE的方式修改這2個參數(shù)的話,只會影響新的數(shù)據(jù)塊,而不會改變已有數(shù)據(jù)的數(shù)據(jù)塊——要做的這一點,需要將數(shù)據(jù)導(dǎo)出/導(dǎo)入、重建表。

Oracle事務(wù)相關(guān)概念

1 事務(wù)id

每一個事物都有一個自己的事物ID,就像身份證號一樣。

在v$transaction數(shù)據(jù)字典中xid就是事物ID,xid既是一個編號,也是一個地址,xid中內(nèi)容的有

     1、使用哪個回滾段的段頭塊;XIDUSN

     2、一個undo段最多同時能有47個活動事物,一個undo段只有一個事物表,47個事物的情況都在事物表中 ,一個事物占用一行,此次事物使用47中的哪一行;XIDSLOT

     3、該行被覆蓋的次數(shù)。XIDSQN

select xid,xidusn,xidslot,xidsqn,start_time,start_scnb,used_ublk,used_urec,log_io,phy_io from v$transaction; 

怎么理解Oracle事務(wù)

注:過一段時間在查詢,若used_urec 字段不斷增加,說明該事物正在繼續(xù),如果該字段不斷下降,說明該事物正在回滾 

聯(lián)合v$session 再查一次,這樣就知道是哪個用戶的哪些事務(wù)了并且獲取sid

select b.sid,b.username,xid,a.status,start_time,used_ublk,used_urec,log_io,phy_io from v$transaction a,v$session b where a.ses_addr = b.saddr; 

獲得sid這樣就知道是哪個用戶的哪些事務(wù)了,進(jìn)而可以跟蹤到sql

select sql_text from v$sqlarea a,v$session b where a.SQL_ID=b.PREV_SQL_ID and b.SID=&sid;

V$TRANSACTION各列字段的含意

列名      數(shù)據(jù)類型          含義 ADDR     RAW(4|8)         Address of the transaction state object XIDUSN   NUMBER           使用的回滾段號,可以和v$rollstat對應(yīng) XIDSLOT  NUMBER           RBS TX 表中的槽號 USN.SLOT.SQN XIDSQN   NUMBER           序列號,slot被重復(fù)使用的次數(shù)TX-USNxSLOT-SQNxxxxx UBAFIL   NUMBER           最后一個撤銷塊地址所在的文件號 UBABLK   NUMBER           UBA  塊號 UBASQN   NUMBER           UBA  序列號 UBAREC   NUMBER           UBA  記錄號 STATUS   VARCHAR2(16)     當(dāng)前事務(wù)的狀態(tài) START_TIME   VARCHAR2(20) Start time (wall clock) START_SCNB   NUMBER       開始的系統(tǒng)改變號 START_SCNW   NUMBER       Start SCN wrap START_UEXT   NUMBER       Start extent number START_UBAFIL   NUMBER     Start UBA file number START_UBABLK   NUMBER     Start UBA block number START_UBASQN   NUMBER     Start UBA sequence number START_UBAREC   NUMBER     Start UBA record number SES_ADDR RAW(4|8)         用戶會話對象地址,對v$session 的saddr列 FLAG   NUMBER Flag SPACE  VARCHAR2(3)       YES if a space transaction RECURSIVE   VARCHAR2(3)   YES if a recursive transaction NOUNDO   VARCHAR2(3)      YES if a no undo transaction PTX   VARCHAR 2(3)        YES if parallel transaction NAME   VARCHAR2(256)      Name of a named transaction PRV_XIDUSN   NUMBER       Previous transaction undo segment number PRV_XIDSLT   NUMBER       Previous transaction slot number PRV_XIDSQN   NUMBER       Previous transaction sequence number PTX_XIDUSN   NUMBER       Rollback segment number of the parent XID PTX_XIDSLT   NUMBER       Slot number of the parent XID PTX_XIDSQN   NUMBER       Sequence number of the parent XID DSCN-B   NUMBER           This column is obsolete and maintained for backward compatibility. The value of this column is always equal to the value in DSCN_BASE. DSCN-W   NUMBER           This column is obsolete and maintained for backward compatibility. The value of this column is always equal to the value in DSCN_WRAP. USED_UBLK   NUMBER        已占用的undo 塊數(shù) USED_UREC   NUMBER        已使用的undo 記錄數(shù) LOG_IO   NUMBER           邏輯 I/O PHY_IO   NUMBER           物理 I/O CR_GET   NUMBER           一致讀的次數(shù) CR_CHANGE   NUMBER        Consistent changes START_DATE   DATE         Start time (wall clock) DSCN_BASE   NUMBER        Dependent SCN base DSCN_WRAP   NUMBER        Dependent SCN wrap START_SCN   NUMBER        Start SCN DEPENDENT_SCN   NUMBER    Dependent SCN XID   RAW(8)              Transaction XID PRV_XID   RAW(8)          Previous transaction XID PTX_XID   RAW(8)          Parent transaction XID 

通過xid獲取usn/slot/sqn方式如下:

with v as(select '0200010068050000' xid from dual)

select to_number(substr(v.xid,3,2)||substr(v.xid,1,2),'xxxx') usn,

      to_number(substr(v.xid,7,2)||substr(v.xid,5,2),'xxxx') slot,

      to_number(substr(v.xid,15,6)||substr(v.xid,13,2)||substr(v.xid,11,2)||substr(v.xid,9,2),'xxxxxxxxxx') sqn

from v;

2 事務(wù)表

undo表空間的undo段的第一個數(shù)據(jù)塊(即undo段的段頭塊)里放事物表,共有47行。事物開始第一件事就是在事物表中找到一個空行,寫上事物信息。也就是說undo段最多47個活動事物,但是oracle會盡量將一個事物放到一個段上,為了均勻分配(undo段的段頭塊的位置在dba_segments表空間可以查得)。

事務(wù)管理起始于undo段,并以此為中心。undo段的第一個塊(段頭塊)包含如下結(jié)構(gòu):擴(kuò)展映射,擴(kuò)展控制頭(跟其他類型的段頭塊一樣),事務(wù)表,事務(wù)控制區(qū)(特殊的結(jié)構(gòu))。事務(wù)表的大概結(jié)構(gòu)如下:

dump一個undo段的一個塊可以看到事務(wù)表


index 表示事務(wù)表中槽號,只是一個序列而已,從0x00開始到0x21結(jié)束,11g的版本有34個槽。

 

state 表示事務(wù)狀態(tài):9代表事務(wù)不活動,10代表事務(wù)正在活動,從這里我們看出16進(jìn)制第0x17號槽上的事務(wù)正在活動。大家有沒有發(fā)現(xiàn),我們在發(fā)生事務(wù)前,Oracle會找事務(wù)控制列表中的chd=0x0017,說白了就是重從index=0x17的槽,存放當(dāng)前最新的事務(wù):

 

注:下面的事務(wù)控制,是我在發(fā)生事務(wù)前(即做update gyj_test set name='GGGGG' where id=1;前所DUMP的事務(wù)控制)

 

  TRN CTL:: seq: 0x000d chd: 0x0017 ctl: 0x000b inc: 0x00000000 nfb:0x0001

 

          mgc: 0xb000 xts: 0x0068 flg: 0x0001 opt: 2147483646 (0x7ffffffe)

 

          uba: 0x0280000a.000d.2b scn: 0x0000.0028a26a

 

cflags 表示正在使用穿上事務(wù)槽的事務(wù)的狀態(tài):0x00表示非活動事務(wù)、0x80表示活動事務(wù)、0x10表示死事務(wù)、0x90表示被回滾的死事務(wù)

 

平時我們看到的最多就是0x00表示非活動事務(wù)、0x80表示活動事務(wù),后面的很少發(fā)生。

 

wrap# 表示事務(wù)表上的事務(wù)槽被重用的次數(shù),它是XID的一部分。0x001d表示此時事務(wù)槽被重用了29次。

 

uel   表示當(dāng)前活動事務(wù)所在事務(wù)槽的下一個事務(wù)槽的指針(即如果又發(fā)生一個新的事務(wù),此時就會用到UEL指向的事務(wù)槽上的index)。

 

scn   表示務(wù)事啟動、提交、回滾的SCN.

 

dba   表示uba:第一部分的undo塊地址,這個DBA是(rollback)回滾的起始點,也就是說是記錄事務(wù)修改的最后一條記錄所在UNDO塊的地址。

 

nub   表示當(dāng)前事務(wù)所用到的UNDO塊的個數(shù)。

 

cmt   表示最接近當(dāng)前的提交時間戳,是從1970年1月1號零晨開始的(以秒為單位記錄)。0表示事務(wù)正在活動。

oracle中有哪些undo段:

select * from v$rollname;

怎么理解Oracle事務(wù)

3 事物槽

每個數(shù)據(jù)塊的塊頭部分有事物槽,事物槽包括xid、uba(undo block address)等等

當(dāng)事物發(fā)生的時候,

第一件事會在undo表空間的相對空閑的undo段的段頭塊的事物表中找到一個槽位,寫上事物信息(xid),給這個事物分配一個undo塊(undo塊里寫的就是修改之前的數(shù)據(jù)),然后將undo塊的地址(即uba寫到事物表中),所以現(xiàn)在事物表中有xid和uba;

第二件事在要修改的數(shù)據(jù)塊的塊頭的事物槽中找到槽位,寫上事物信息(xid),(目的是通過數(shù)據(jù)塊上的xid可以找到事物表),然后在將要修改的數(shù)據(jù)塊上修改數(shù)據(jù),修改之前的信息寫到undo塊里。同時,在事物槽中也寫上uba地址,指向回滾塊。為什么要在兩個地方寫事物信息呢?下面有解釋。

當(dāng)回滾塊的數(shù)據(jù)寫滿之后,系統(tǒng)會自動分配一個回滾塊,比如該事物修改了較多的數(shù)據(jù),產(chǎn)生3個undo塊,3個undo塊有先后關(guān)系,它們會鏈起來,但是這是事物表中的uba就只是指向最新的undo塊,這是便于回滾。

數(shù)據(jù)塊的事物槽中的uba指向回滾數(shù)據(jù),這便于構(gòu)造CR塊。

一個事物一個事物槽,只有當(dāng)事物提交了,該事物槽才能被覆蓋。

pctfree:1、當(dāng)執(zhí)行更新操作時,也許會占用pctfree的空間。2、當(dāng)多個事物操作該數(shù)據(jù)塊時,需要增加事物槽的數(shù)量,也會占用pctfree,但是如果事物過多,pctfree不夠用了,(之前的事物槽未提交,就不能覆蓋,該數(shù)據(jù)塊又有新的事物產(chǎn)生,需要新的事物槽)這樣就會產(chǎn)生事物槽爭用的情況,大多數(shù)發(fā)生在update和delete的情況,insert不會發(fā)生。因為oracle會盡量的將insert插入的數(shù)據(jù)插入到多個塊中,也就是平均一下,但是update和delete就無能為力了,因為這兩個操作往往是針對某一行進(jìn)行的,而某一行特定就是在這個塊里。

到此,相信大家對“怎么理解Oracle事務(wù)”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

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

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

AI