Oracle事務(wù)表實(shí)驗(yàn)
回滾段頭中,有一項(xiàng)非常重要的信息,就是事務(wù)表。對(duì)事務(wù)表頻繁的訪問(wèn),可能會(huì)造成回滾段頭的爭(zhēng)用。了解什么樣的操作會(huì)訪問(wèn)事務(wù)表,對(duì)于了解回滾段頭爭(zhēng)用的原因非常重要。下面我們來(lái)做一些實(shí)驗(yàn)來(lái)驗(yàn)證一下,什么樣的操作才會(huì)訪問(wèn)事務(wù)表。
首 先簡(jiǎn)單介紹一個(gè)視圖,備份x$bh.對(duì)這個(gè)視圖我想大家都有一定的了解,bh即buffer header 的簡(jiǎn)寫(xiě)。在buffer header中有 一個(gè)TCH 列,表示塊被訪問(wèn)的次數(shù)。我們通過(guò)他來(lái)驗(yàn)證事務(wù)表什么時(shí)候被訪問(wèn)。需要注意的是。TCH列每3秒,才會(huì)重新計(jì)算一次,3秒之內(nèi)無(wú)論訪問(wèn)某一個(gè) 塊多少次。TCH列只會(huì)增加1.
在會(huì)話A開(kāi)啟一個(gè)事務(wù)后:
步驟一:通過(guò)v$transaction視圖找到XID
SQL> select xidusn,ubablk,ubafil from v$transaction;
XIDUSN UBABLK UBAFIL
---------- ---------- ----------
13 97 5
步驟二:通過(guò)回滾段編號(hào),可得知事務(wù)所占回滾段名,并用此查找事務(wù)頭塊號(hào),文件號(hào)
SQL> select header_block,header_file from dba_segments where segment_name='_SYSSMU13$';
HEADER_BLOCK HEADER_FILE
------------ -----------
41 5
步驟三:查看x$bh視圖中,TCH值的增加。
SQL> select addr,tch from x$bh where dbarfil=5 and dbablk=41;
ADDR TCH
-------- ----------
080B5208 41
步驟四:查找完TCH后,馬上執(zhí)行要測(cè)試的命令(會(huì)話B),
SQL> select * from jj_3;
ID NA
---------- --
1 aa
2 aa
3 aa
4 aa
5 CN
步驟五:再次查看x$bh視圖
SQL> select addr,tch from x$bh where dbarfil=5 and dbablk=41;
ADDR TCH
-------- ----------
080B5208 42
注意:步驟三四五應(yīng)盡快完成。避免oracle的其他內(nèi)部操作影響測(cè)試結(jié)果。(因?yàn)閛racle內(nèi)部的操作也會(huì)造成回滾段頭的tch值增加,特別在10G中,這種情況更為明顯,不過(guò)我沒(méi)有跟蹤是什么oracle的內(nèi)部操作造成的)
小結(jié):從結(jié)果集來(lái)看,在另一會(huì)話中訪問(wèn)未提交數(shù)據(jù)的select語(yǔ)句會(huì)訪問(wèn)事務(wù)表,那么其他的DML操作呢?(希望大家也都試試,我的結(jié)果是都會(huì)增加TCH值)。上面我的步驟四是全表掃描。如果我的表有兩個(gè)塊,分別是塊一塊二,在塊一中修改行A,按照rowid訪問(wèn)塊一中的行B,這樣會(huì)訪問(wèn)事務(wù)表嗎?如果
按照rowid訪問(wèn)塊二中的行,會(huì)訪問(wèn)事務(wù)表嗎?下面我來(lái)實(shí)驗(yàn)下看結(jié)果是什么:
步一:利用函數(shù)查看該表的塊號(hào)。
SQL> select rowid,dbms_rowid.rowid_block_number(rowid) from jj_3;
ROWID DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------ ------------------------------------
AAAMvjAAKAAAAEdAAA 285
AAAMvjAAKAAAAEdAAB 285
AAAMvjAAKAAAAEdAAC 285
AAAMvjAAKAAAAEeAAA 286
步二: 在B會(huì)話中通過(guò)AAAMvjAAKAAAAEdAAC修改表。
SQL> update jj_3 set id=10 where rowid='AAAMvjAAKAAAAEdAAC';
已更新 1 行。
步三: 在A會(huì)話中通過(guò)AAAMvjAAKAAAAEdAAA查看行
SQL> select * from jj_3 where rowid='AAAMvjAAKAAAAEdAAA';
ID NA
---------- --
4 aa
在做步一和二之前,先查看一下X$BH,因?yàn)樗麜?huì)因?yàn)閛racle的內(nèi)部操作而增加,
實(shí)驗(yàn)前查看結(jié)果:
SQL> select addr,tch from x$bh where dbarfil=5 and dbablk=41;
ADDR TCH
-------- ----------
080B51BC 63
實(shí)驗(yàn)后查看結(jié)果:
SQL> select addr,tch from x$bh where dbarfil=5 and dbablk=41;
ADDR TCH
-------- ----------
080B51BC 64
結(jié)論一:在塊一中修改行A,按照rowid訪問(wèn)塊一中的行B,這樣會(huì)訪問(wèn)事務(wù)表;再試試不同的塊
操作前先查看下X$BH:
SQL> select addr,tch from x$bh where dbarfil=5 and dbablk=41;
ADDR TCH
-------- ----------
080B51BC 67
接著剛才的實(shí)驗(yàn),我又訪問(wèn)了不同的塊:
SQL> select * from jj_3 where rowid='AAAMvjAAKAAAAEeAAA';
ID NA
---------- --
4 aa
再次查看X$BH的結(jié)果是:
SQL> select addr,tch from x$bh where dbarfil=5 and dbablk=41;
ADDR TCH
-------- ----------
080B51BC 67
結(jié)果很明顯了,用rowid訪問(wèn)不同的塊,是不會(huì)增加TCH值的。也就是說(shuō)不會(huì)有CR塊產(chǎn)生。
在晶晶實(shí)驗(yàn)六中,已經(jīng)證明了在生成CR塊時(shí),oracle可以根據(jù)數(shù)據(jù)塊頭部的ITL槽中的UBA,找到存放數(shù)據(jù)塊回滾信息的回 滾塊和回滾記錄,通過(guò)這個(gè)UBA就可以構(gòu)造CR塊咯,oracle為什么還要再去訪問(wèn)事務(wù)表呢?這是因?yàn)椋琽racle的提交有時(shí)會(huì) 是延遲提交。oracle并不清除延遲提交所涉及的塊中的事務(wù)信息,如:事務(wù)所占ITL槽和行鎖。而把清除事務(wù)信息這個(gè)操作 放到了以后的塊清除中(塊清除在以后的實(shí)驗(yàn)會(huì)詳細(xì)講述),oracle這樣做的目的是為加快提交速度。如果一個(gè)事務(wù)涉及到了過(guò)多的塊,單單是提交時(shí)清除每個(gè)塊中的事務(wù)信息就需要耗費(fèi)很長(zhǎng)時(shí)間。這降低了提交速度。有可能使提交成為最易 引起爭(zhēng)用的操作。當(dāng)事務(wù)提交時(shí),對(duì)事務(wù)所涉及的塊,不做任何操作,塊將保持事務(wù)仍在持續(xù)時(shí)的信息。當(dāng)一個(gè)select操作 查詢到這個(gè)塊時(shí),ITL槽中的提交標(biāo)志為未提交,但實(shí)際上這個(gè)事務(wù)是已經(jīng)提交的。就是因?yàn)橛辛搜舆t提交oracle無(wú)法根 據(jù)ITL槽中的提交標(biāo)志來(lái)判斷一個(gè)塊中的事務(wù)是否真的提交。他必須根據(jù)ITL中的XID 去訪問(wèn)事務(wù)表。才能確定此塊中的事務(wù)是否真的提交。在生成CR塊前,oracle先要判斷是否真的有必要為此塊生成CR塊。這就要去訪問(wèn)事務(wù)表。