您好,登錄后才能下訂單哦!
本篇文章給大家分享的是有關(guān)如何解析Oracle SCN,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。
Oracle中的SCN(system change number)和我們的北京時(shí)間的意義是相同的,SCN是Oracle中的時(shí)間號(hào)。
為什么Oracle不用時(shí)間來(lái)界定呢?
我在北京時(shí)間8:00的時(shí)候執(zhí)行一條DML語(yǔ)句,然后修改機(jī)器上的時(shí)間為7:00,再執(zhí)行一條DML語(yǔ)句。如果用機(jī)器上的時(shí)間區(qū)分的話(huà),那Oracle根本區(qū)分不出來(lái)這兩條DML語(yǔ)句的執(zhí)行順序——而這一點(diǎn)對(duì)于Oracle是很重要的。所以它采用自己產(chǎn)生的SCN來(lái)區(qū)分所有操作的先后順序。
SCN設(shè)計(jì)的值很大,所以不用擔(dān)心達(dá)到最大值后怎么辦。
可以查看系統(tǒng)當(dāng)前的SCN號(hào):
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
464640326
也可以查看系統(tǒng)當(dāng)前保存的SCN號(hào):
SQL> select checkpoint_change# from v$database
CHECKPOINT_CHANGE#
------------------
464639929
如果此時(shí)數(shù)據(jù)庫(kù)損壞,當(dāng)重啟時(shí)候需要修復(fù)的,就是這兩個(gè)SCN之間的數(shù)據(jù)。這些數(shù)據(jù)保存在在線(xiàn)重做日志文件中:
SQL> select GROUP#, STATUS, FIRST_CHANGE# from v$log;
GROUP# STATUS FIRST_CHANGE#
---------- ------------------------------ -------------
1 INACTIVE 464633029
2 INACTIVE 464637664
3 CURRENT 464638303
group1中保存的數(shù)據(jù)產(chǎn)生的SCN號(hào)為 464633029 至 464637664;group2中的SCN號(hào)為 464637664 至 464638303;group3中的SCN號(hào)為 464638303 至 464640326(當(dāng)前SCN號(hào))。
所以,若此時(shí)執(zhí)行shutdown abort并重啟,執(zhí)行crash recovery時(shí),使用的在線(xiàn)重做日志文件為group3中的member。而通過(guò)v$log.status字段也能看到:group3的狀態(tài)為current。
Part I. 透析SCN號(hào)
SCN是當(dāng)Oracle數(shù)據(jù)庫(kù)更新后,由DBMS自動(dòng)維護(hù)去累積遞增的一個(gè)數(shù)字。當(dāng)一筆交易commit時(shí),LGWR會(huì)將log buffer寫(xiě)入redo log file,同時(shí)也會(huì)將該筆交易的SCN同步寫(xiě)入到redo log file內(nèi)(wait-until-completed)。因此當(dāng)你commit transaction時(shí),在交易成功的訊息返回之前,LGWR必須先完整的完成上述行為之后,否則你是看不到提交成功的回應(yīng)訊息。
可以查詢(xún)目前系統(tǒng)最新的SCN
SQL>select dbms_flashback.get_system_change_number from dual;
可以理解,這里返回的SCN,也是目前redo log file最新的SCN紀(jì)錄。因?yàn)閏ommit后的交易才會(huì)有SCN,而一旦commit就會(huì)立刻寫(xiě)入redo log file中。
CHECKPOINT和SCN的關(guān)聯(lián)
Checkpoint發(fā)生的目的就是要把存儲(chǔ)在buffer內(nèi)的已提交交易寫(xiě)回disk,否則一旦發(fā)生crash,需要進(jìn)行recovery時(shí),就必須花很多時(shí)間從redo log file內(nèi)最后的SCN交易開(kāi)始進(jìn)行recovery,這樣在商業(yè)應(yīng)用上是很浪費(fèi)時(shí)間和沒(méi)有效率的。
當(dāng)commit一筆交易時(shí),只會(huì)立刻將redo buffer寫(xiě)入redo log file內(nèi),但是并不會(huì)馬上將該update后的block(dirty block)同步寫(xiě)回disk datafile中,這是為了減少過(guò)多disk IO,所以采取batch方式寫(xiě)入。
When a checkpoint occurs. Oracle must update the headers of all datafiles to record the details of the checkpoint. This is done by the CKPT process. The CKPT process does not write blocks to disk; DBWn always performs that work.
在shutdown normal or shutdown immediate下,也就是所謂的clean shutdown, checkpoint也會(huì)自動(dòng)觸發(fā)。當(dāng)發(fā)生checkpoint時(shí),會(huì)把SCN寫(xiě)到四個(gè)地方去。三個(gè)地方在control file 內(nèi),一個(gè)在datafile header。
Control file三個(gè)地方為:
1、 System checkpoint SCN
SQL> select to_char(checkpoint_change#, 'XXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-----------------------------------------------------------------
7161D7365DC
2、 Datafile checkpoint SCN
SQL> select name, to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$datafile where name like '%gisdts01%';
NAME
-------------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7365DC
3、 Stop SCN
SQL> select name,last_change# from v$datafile where name like '%gisdts01%';
NAME
--------------------------------
/gisdata/datafile/gisdts01.dbf
正常datafile在read-write mode運(yùn)作下,last_change#一定是null
還有一個(gè)SCN在datafile header內(nèi)
4、 Start SCN
SQL>select name,to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$datafile_header where name like '%gisdts01%';
NAME
---------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
---------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7365DC
為什么儲(chǔ)存在control file中要分為兩個(gè)地方(system checkpoint scn, datafile checkpoint scn?)。當(dāng)把一個(gè)tbs設(shè)為read-only時(shí),他的scn會(huì)凍結(jié)停止,此時(shí)datafile checkpoint scn是不會(huì)再遞增改變的,但是整體的system checkpoint scn卻仍然會(huì)不斷遞增前進(jìn)。所以這是為什么需要分別在兩個(gè)地方儲(chǔ)存SCN。
正常shutdown database后,SCN會(huì)發(fā)生什么變化?
可以把數(shù)據(jù)庫(kù)開(kāi)在mount mode
SQL> select to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$database;
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------
7161D7455B9
SQL>select name,to_char(checkpoint_change#,’XXXXXXXXXXXX’),to_char(last_change#
,’XXXXXXXXXXXX’) from v$datafile where name like '%gisdts01%';
NAME
-------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------
TO_CHAR(LAST_CHANGE#,'XXXXXXXX
-------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7455B9
7161D7455B9
可以看到儲(chǔ)存在control file中的三個(gè)SCN的數(shù)值都是相同的,注意此時(shí)的stop scn不會(huì)是null,而是等于start scn。
再來(lái)查詢(xún)datafile header中的SCN:
SQL> select name, to_char(checkpoint_change#,'XXXXXXXXXXXX') from v$datafile_hea
der where name like '%gisdts01%';
NAME
-------------------------------------------------------------------
TO_CHAR(CHECKPOINT_CHANGE#,'XX
-------------------------------------------------------------------
/gisdata/datafile/gisdts01.dbf
7161D7455B9
當(dāng)clean shutdown時(shí),checkpoint會(huì)進(jìn)行,并且此時(shí)datafile的stop scn和start scn會(huì)相同。等我們打開(kāi)數(shù)據(jù)庫(kù)時(shí),oracle會(huì)檢查datafile header中的start scn和存于control file中的datafile的scn是否相同,如果相同,接著檢查start scn和stop scn是否相同,如果仍然相同,數(shù)據(jù)庫(kù)會(huì)正常啟動(dòng),否則就需要recovery….等到數(shù)據(jù)庫(kù)open后,儲(chǔ)存在control file中的stop scn就會(huì)恢復(fù)為null值,此時(shí)表示datafile是open在正常模式下。
如果不正常shutdown(shutdown abort),則mount數(shù)據(jù)庫(kù)后,會(huì)發(fā)現(xiàn)stop scn并不等于其它位置的scn,而是等于null。這表示oracle在shutdown時(shí)沒(méi)有進(jìn)行checkpoint,下次啟動(dòng)必須進(jìn)行crash recovery。
Part II. Oracle SCN機(jī)制解析
SCN(System Chang Number)作為oracle中的一個(gè)重要機(jī)制,在數(shù)據(jù)恢復(fù)、Data Guard、Streams復(fù)制、RAC節(jié)點(diǎn)間的同步等各個(gè)功能中起著重要作用。理解SCN的運(yùn)作機(jī)制,可以幫助你更加深入地了解上述功能。
在理解SCN之前,我們先看下oracle事務(wù)中的數(shù)據(jù)變化是如何寫(xiě)入數(shù)據(jù)文件的:
1、 事務(wù)開(kāi)始;
2、 在buffer cache中找到需要的數(shù)據(jù)塊,如果沒(méi)有找到,則從數(shù)據(jù)文件中載入buffer cache中;
3、 事務(wù)修改buffer cache的數(shù)據(jù)塊,該數(shù)據(jù)被標(biāo)識(shí)為“臟數(shù)據(jù)”,并被寫(xiě)入log buffer中;
4、 事務(wù)提交,LGWR進(jìn)程將log buffer中的“臟數(shù)據(jù)”寫(xiě)入redo log file中;
5、 當(dāng)發(fā)生checkpoint,CKPT進(jìn)程更新所有數(shù)據(jù)文件的文件頭中的信息,DBWn進(jìn)程則負(fù)責(zé)將Buffer Cache中的臟數(shù)據(jù)寫(xiě)入到數(shù)據(jù)文件中。
經(jīng)過(guò)上述5個(gè)步驟,事務(wù)中的數(shù)據(jù)變化最終被寫(xiě)入到數(shù)據(jù)文件中。但是,一旦在上述中間環(huán)節(jié)時(shí),數(shù)據(jù)庫(kù)意外宕機(jī)了,在重新啟動(dòng)時(shí)如何知道哪些數(shù)據(jù)已經(jīng)寫(xiě)入數(shù)據(jù)文件、哪些沒(méi)有寫(xiě)呢(同樣,在DG、streams中也存在類(lèi)似疑問(wèn):redo log中哪些是上一次同步已經(jīng)復(fù)制過(guò)的數(shù)據(jù)、哪些沒(méi)有)?SCN機(jī)制就能比較完善的解決上述問(wèn)題。
SCN是一個(gè)數(shù)字,確切的說(shuō)是一個(gè)只會(huì)增加、不會(huì)減少的數(shù)字。正是它這種只會(huì)增加的特性確保了Oracle知道哪些應(yīng)該被恢復(fù)、哪些應(yīng)該被復(fù)制。
總共有4中SCN:系統(tǒng)檢查點(diǎn)(System Checkpoint)SCN、數(shù)據(jù)文件檢查點(diǎn)(Datafile Checkpoint)SCN、結(jié)束SCN(Stop SCN)、開(kāi)始SCN(Start SCN)。其中其面3中SCN存在于控制文件中,最后一種則存在于數(shù)據(jù)文件的文件頭中。
在控制文件中,System Checkpoint SCN是針對(duì)整個(gè)數(shù)據(jù)庫(kù)全局的,因而之存在一個(gè),而Datafile Checkpoint SCN和Stop SCN是針對(duì)每個(gè)數(shù)據(jù)文件的,因而一個(gè)數(shù)據(jù)文件就對(duì)應(yīng)在控制文件中存在一份Datafile Checkpoint SCN和Stop SCN。在數(shù)據(jù)庫(kù)正常運(yùn)行期間,Stop SCN(通過(guò)視圖v$datafile的字段last_change#可以查詢(xún))是一個(gè)無(wú)窮大的數(shù)字或者說(shuō)是NULL。
在一個(gè)事務(wù)提交后(上述第四個(gè)步驟),會(huì)在redo log中存在一條redo記錄,同時(shí),系統(tǒng)為其提供一個(gè)最新的SCN(通過(guò)函數(shù)dbms_flashback.get_system_change_number可以知道當(dāng)前的最新SCN),記錄在該條記錄中。如果該條記錄是在redo log被清空(日志滿(mǎn)做切換時(shí)或發(fā)生checkpoint時(shí),所有變化日志已經(jīng)被寫(xiě)入數(shù)據(jù)文件中),則其SCN被記錄為redo log的low SCN。以后在日志再次被清空前寫(xiě)入的redo記錄中SCN則成為Next SCN。
當(dāng)日志切換或發(fā)生checkpoint(上述第五個(gè)步驟)時(shí),從Low SCN到Next SCN之間的所有redo記錄的數(shù)據(jù)就被DBWn進(jìn)程寫(xiě)入數(shù)據(jù)文件中,而CKPT進(jìn)程則將所有數(shù)據(jù)文件(無(wú)論redo log中的數(shù)據(jù)是否影響到該數(shù)據(jù)文件)的文件頭上記錄的Start SCN(通過(guò)視圖v$datafile_header的字段checkpoint_change#可以查詢(xún))更新為Next SCN,同時(shí)將控制文件中的System Checkpoint SCN(通過(guò)視圖v$database的字段checkpoint_change#可以查詢(xún))、每個(gè)數(shù)據(jù)文件對(duì)應(yīng)的Datafile Checkpoint(通過(guò)視圖v$datafile的字段checkpoint_change#可以查詢(xún))也更新為Next SCN。但是,如果該數(shù)據(jù)文件所在的表空間被設(shè)置為read-only時(shí),數(shù)據(jù)文件的Start SCN和控制文件中Datafile Checkpoint SCN都不會(huì)被更新。
那系統(tǒng)是如何產(chǎn)生一個(gè)最新的SCN的?實(shí)際上,這個(gè)數(shù)字是由當(dāng)時(shí)的timestamp轉(zhuǎn)換過(guò)來(lái)的。每當(dāng)需要產(chǎn)生一個(gè)最新的SCN到redo記錄時(shí),系統(tǒng)獲取當(dāng)時(shí)的timestamp,將其轉(zhuǎn)換為數(shù)字作為SCN。我們可以通過(guò)函數(shù)SCN_TO_TIMESTAMP(10g以后)將其轉(zhuǎn)換回timestamp:
SQL> select dbms_flashback.get_system_change_number, SCN_TO_TIMESTAMP(dbms_flashback
.get_system_change_number) from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER)
---------------------------------------------------------------------------
2877076756
17-AUG-07 02.15.26.000000000 PM
也可以用函數(shù)timestamp_to_scn將一個(gè)timestamp轉(zhuǎn)換為SCN:
SQL> select timestamp_to_scn(SYSTIMESTAMP) as scn from dual;
SCN
----------
2877078439
最后,SCN除了作為反映事務(wù)數(shù)據(jù)變化并保持同步外,它還起到系統(tǒng)的“心跳”作用——每隔3秒左右系統(tǒng)會(huì)刷新一次系統(tǒng)SCN。
下面,在簡(jiǎn)單介紹一下SCN如何在數(shù)據(jù)庫(kù)恢復(fù)中起作用。
數(shù)據(jù)庫(kù)在正常關(guān)閉(shutdown immediate/normal)時(shí),會(huì)先做一次checkpoint,將log file中的數(shù)據(jù)寫(xiě)入數(shù)據(jù)文件中,將控制文件、數(shù)據(jù)文件中的SCN(包括控制文件中的Stop SCN)都更新為最新的SCN。
數(shù)據(jù)庫(kù)異常/意外關(guān)閉不會(huì)或者只更新部分Stop SCN。
當(dāng)數(shù)據(jù)庫(kù)啟動(dòng)時(shí),Oracle先檢查控制文件中的每個(gè)Datafile Checkpoint SCN和數(shù)據(jù)文件中的Start SCN是否相同,再檢查每個(gè)Datafile Checkpoint SCN和Stop SCN是否相同。如果發(fā)現(xiàn)有不同,就從Redo Log中找到丟失的SCN,重新寫(xiě)入數(shù)據(jù)文件中進(jìn)行恢復(fù)。具體的數(shù)據(jù)恢復(fù)過(guò)程這里就不再贅述。
SCN作為Oracle中的一個(gè)重要機(jī)制,在多個(gè)重要功能中起著“控制器”的作用。了解SCN的產(chǎn)生和實(shí)現(xiàn)方式,幫助DBA理解和處理恢復(fù)、DG、Streams復(fù)制的問(wèn)題。
最后提一句,利用SCN機(jī)制,在Oracle10g、11g中又增加了一些很實(shí)用的功能——數(shù)據(jù)庫(kù)閃回、數(shù)據(jù)庫(kù)負(fù)載重現(xiàn)等。
Part III. scn(系統(tǒng)改變號(hào))信息與恢復(fù)
control中有三種SCN分別為,system SCN、datafile SCN、last SCN,數(shù)據(jù)文件頭中有一種SCN start SCN
system scn從視圖v$database中獲得,對(duì)應(yīng)checkpoint_change#字段,datafile scn、last scn分別對(duì)應(yīng)視圖v$datafile中的checkpoint_change#,last_change#,而 start scn則從v$datafile_header中checkpoint_change#得到。
數(shù)據(jù)庫(kù)在正常啟動(dòng)后下,system scn,datafile scn,start scn會(huì)相等,而last scn會(huì)被置于無(wú)窮大,這里為null。
正常關(guān)閉后(immediate,noraml,translate),上面四個(gè)scn會(huì)應(yīng)執(zhí)行full checkpoint 而相等。
當(dāng)系統(tǒng)在非正常關(guān)閉后,如shutdown abort,這個(gè)時(shí)候last scn依然為無(wú)窮大,那么當(dāng)重新啟動(dòng)實(shí)例時(shí),系統(tǒng)首先會(huì)比較start scn與system scn,如果一致,那么再比較start scn 與last scan是否一樣大,因?yàn)槭欠钦jP(guān)閉,這里會(huì)不一樣大,那么就需要例程恢復(fù)。
如果打開(kāi)數(shù)據(jù)庫(kù)時(shí)發(fā)現(xiàn)system scn>datafile scn,那么以為著使用舊的備份數(shù)據(jù)文件,也就是需要介質(zhì)恢復(fù)
如果是system scn<datafile scn,及控制文件scn是舊的,代表使用了老的控制文件,需要recover using backup controlfile進(jìn)行恢復(fù)。
1、正常啟動(dòng)時(shí)
SQL> select checkpoint_change# from v$database; --控制文件中的scn
CHECKPOINT_CHANGE#
------------------
5534071
SQL> select file#,checkpoint_change# from v$datafile_header; --start scn
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 5534071
2 5534071
3 5534071
4 5534071
5 5534071
SQL> select file#,checkpoint_change#,last_change# from v$datafile; --datafile scn & last scn
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 5534071
2 5534071
3 5534071
4 5534071
5 5534071
2、正常關(guān)閉后,然后在startup mount;
SQL> shutdown immediate;
數(shù)據(jù)庫(kù)已經(jīng)關(guān)閉。
已經(jīng)卸載數(shù)據(jù)庫(kù)。
ORACLE 例程已經(jīng)關(guān)閉。
SQL> startup mount;
ORACLE 例程已經(jīng)啟動(dòng)。
Total System Global Area 319888364 bytes
Fixed Size 453612 bytes
Variable Size 192937984 bytes
Database Buffers 125829120 bytes
Redo Buffers 667648 bytes
數(shù)據(jù)庫(kù)裝載完畢。
SQL> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 5534485
2 5534485
3 5534485
4 5534485
5 5534485
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
5534485
SQL> select file#,checkpoint_change#,last_change# from v$datafile;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 5534485 5534485
2 5534485 5534485
3 5534485 5534485
4 5534485 5534485
5 5534485 5534485
--發(fā)現(xiàn)start scn=last scn,證明系統(tǒng)是正常關(guān)閉
SQL> alter database open;
數(shù)據(jù)庫(kù)已更改。
3、在正常打開(kāi)狀態(tài)下進(jìn)行事務(wù)操作
SQL> create table t(a number);
表已創(chuàng)建。
SQL> insert into t values (1);
已創(chuàng)建 1 行。
SQL> commit;
提交完成。
SQL> insert into t values(2);
已創(chuàng)建 1 行。
4、非正常關(guān)閉
SQL> shutdown abort;
ORACLE 例程已經(jīng)關(guān)閉。
SQL>
5、打開(kāi)到mount狀態(tài)下,觀看scn
SQL> startup mount;
ORACLE 例程已經(jīng)啟動(dòng)。
Total System Global Area 319888364 bytes
Fixed Size 453612 bytes
Variable Size 192937984 bytes
Database Buffers 125829120 bytes
Redo Buffers 667648 bytes
數(shù)據(jù)庫(kù)裝載完畢。
SQL> select file#,checkpoint_change#,last_change# from v$datafile;
FILE# CHECKPOINT_CHANGE# LAST_CHANGE#
---------- ------------------ ------------
1 5534486
2 5534486
3 5534486
4 5534486
5 5534486
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
5534486
SQL> select file#,checkpoint_change# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 5534486
2 5534486
3 5534486
4 5534486
5 5534486
--這時(shí)發(fā)現(xiàn)start scn 與last scn不等,last scn為無(wú)窮大,需要例程恢復(fù)
6、改變數(shù)據(jù)庫(kù)狀態(tài)為open,并查看該階段運(yùn)行日志
SQL> select * from wen.t;
select * from wen.t
*
ERROR 位于第 1 行:
ORA-01219: 數(shù)據(jù)庫(kù)未打開(kāi): 僅允許在固定表/視圖中查詢(xún)
SQL> alter database open;
數(shù)據(jù)庫(kù)已更改。
SQL> select * from wen.t;
A
----------
1
--發(fā)現(xiàn)沒(méi)有提交的事務(wù)丟失。
查看日志如下:
Completed: ALTER DATABASE MOUNT
Wed May 17 21:35:46 2006
alter database open
Wed May 17 21:35:46 2006
Beginning crash recovery of 1 threads --會(huì)自動(dòng)判斷是否需要恢復(fù),這里開(kāi)始例程恢復(fù)
Wed May 17 21:35:46 2006
Started first pass scan
Wed May 17 21:35:47 2006
Completed first pass scan
206 redo blocks read, 90 data blocks need recovery
Wed May 17 21:35:47 2006
Started recovery at
Thread 1: logseq 167, block 271, scn 0.0
Recovery of Online Redo Log: Thread 1 Group 2 Seq 167 Reading mem 0 --恢復(fù)用的在線(xiàn)重做日志
Mem# 0 errs 0: D:ORACLEORADATADB1REDO02.LOG
Wed May 17 21:35:47 2006
Ended recovery at
Thread 1: logseq 167, block 477, scn 0.5554724
90 data blocks read, 90 data blocks written, 206 redo blocks read
Crash recovery completed successfully --恢復(fù)完成
Wed May 17 21:35:47 2006
LGWR: Primary database is in CLUSTER CONSISTENT mode
Thread 1 advanced to log sequence 168
Thread 1 opened at log sequence 168
Current log# 3 seq# 168 mem# 0: D:ORACLEORADATADB1REDO03.LOG
Successful open of redo thread 1.
Wed May 17 21:35:48 2006
SMON: enabling cache recovery
Wed May 17 21:35:48 2006
ARC0: Evaluating archive log 2 thread 1 sequence 167
ARC0: Beginning to archive log 2 thread 1 sequence 167
Creating archive destination LOG_ARCHIVE_DEST_1: 'D:DBBKARC00167.001'
ARC0: Completed archiving log 2 thread 1 sequence 167
Wed May 17 21:35:48 2006
Undo Segment 1 Onlined
Undo Segment 2 Onlined
Undo Segment 3 Onlined
Undo Segment 4 Onlined
Undo Segment 5 Onlined
Undo Segment 6 Onlined
Part IV. 關(guān)于SCN的理解
1.oracle正常運(yùn)行時(shí),control文件的SCN是個(gè)很大的數(shù),與redo log文件、數(shù)據(jù)文件的SCN不同,正常關(guān)閉時(shí),做完checkpoint后,三者的SCN值相同;
Biti:日志文件中scn有起始和結(jié)束2個(gè)(高低),在current log中高scn同樣為無(wú)窮大。
2.當(dāng)一個(gè)事務(wù)commit成功時(shí),redo log文件中的SCN+1,當(dāng)該事務(wù)所做的修改寫(xiě)入數(shù)據(jù)文件后,數(shù)據(jù)文件的SCN+1;
Biti:commit的時(shí)候加1,其他很多時(shí)候也會(huì)加1,只要數(shù)據(jù)庫(kù)發(fā)生了變化都會(huì)增加。數(shù)據(jù)寫(xiě)入數(shù)據(jù)文件時(shí)scn不是加1而是由ckpt更新,檢查點(diǎn)發(fā)生的時(shí)候才修改數(shù)據(jù)文件頭的檢查點(diǎn)計(jì)數(shù)并更新scn。
3.疑問(wèn):
是不是如果一個(gè)事務(wù)比較大,在事務(wù)提交前就發(fā)生redo log entries、data buffer的寫(xiě)入,此時(shí)斷電,則數(shù)據(jù)文件、redo log文件的SCN沒(méi)有+1,且相同,但控制文件SCN不同,數(shù)據(jù)庫(kù)startup時(shí)發(fā)生回滾。
Biti:數(shù)據(jù)文件是由ckpt進(jìn)程更新文件頭的,scn不是加1,而是更新為檢查點(diǎn)發(fā)生那時(shí)的scn,回滾是根據(jù)回滾段頭的事務(wù)表狀態(tài)來(lái)進(jìn)行的。
4.數(shù)據(jù)寫(xiě)入數(shù)據(jù)文件scn不是加1而是ckpt 更新,檢查點(diǎn)發(fā)生的時(shí)候才修改數(shù)據(jù)文件頭的 檢查點(diǎn)計(jì)數(shù)和更新scn
是不是應(yīng)該這么說(shuō)?:
當(dāng)ckpt 更新時(shí)發(fā)生數(shù)據(jù)寫(xiě)入,同時(shí)修改數(shù)據(jù)文件頭的 檢查點(diǎn)計(jì)數(shù)和更新scn 。當(dāng)出現(xiàn)其他情況下的數(shù)據(jù)寫(xiě)入時(shí)(如無(wú)空閑緩沖等),不發(fā)生ckpt ,但SCN會(huì)增加。
Biti:這個(gè)時(shí)候修改的是數(shù)據(jù)塊但不是數(shù)據(jù)文件頭,只有檢查點(diǎn)發(fā)生的時(shí)候才更新數(shù)據(jù)文件頭,也就是說(shuō)只有ckpt進(jìn)程更新數(shù)據(jù)文件頭(oracle8以前如果沒(méi)有ckpt進(jìn)程就是lgwr更新),dbwr只寫(xiě)數(shù)據(jù)塊。
BTW:看樣DBWR只是些數(shù)據(jù)塊,只有CKPT進(jìn)程才能更新數(shù)據(jù)文件頭;
5.commit的時(shí)候加一,其他很多時(shí)候也會(huì)加1,只要數(shù)據(jù)庫(kù)發(fā)生了變化都會(huì)增加。
很多時(shí)候,能否舉一些例子
Biti: dml一發(fā)生即使沒(méi)有提交也會(huì)增加scn, job進(jìn)程一樣產(chǎn)生scn,只要對(duì)數(shù)據(jù)庫(kù)中文件發(fā)生任何的改變都有可能產(chǎn)生scn,SCN: system change number, not system commit number .也就是系統(tǒng)發(fā)生變化時(shí)所產(chǎn)生的一個(gè)時(shí)間點(diǎn)
標(biāo)志。不是提交的標(biāo)志,只是因?yàn)樘峤灰彩窍到y(tǒng)的變化之一而已。
6.Biti:檢查點(diǎn)的發(fā)生,跟寫(xiě)日志文件是沒(méi)有必然聯(lián)系的
檢查點(diǎn)通知 DBWR 寫(xiě)數(shù)據(jù)文件,寫(xiě)完后ckpt更新控制文件頭和數(shù)據(jù)文件頭。
當(dāng)DBWR寫(xiě)數(shù)據(jù)塊的時(shí)候若發(fā)現(xiàn)數(shù)據(jù)塊的相關(guān) RDBA (位于日志文件的位置) 的 log block 還沒(méi)有被寫(xiě)入日志文件,則在dbwr寫(xiě)塊之前必須通知lgwr把log buffer 中日志寫(xiě)入日志文件。
7.data block 里面的SCN是當(dāng) block 被更改的時(shí)候的SCN
而數(shù)據(jù)文件有那么多 block,自然不同的 block有不同的SCN
block中存在 block SCN 和 ITL 中的commit SCN
block SCN 又在塊頭和塊尾都有,若不一致意味著block損壞(熱備可能出現(xiàn)這個(gè)情況,需要從redo log中拷貝回來(lái),若是正在修改的過(guò)程中由于進(jìn)程死掉則 pmon負(fù)責(zé)清理。若 由于一些以外發(fā)生這樣的不一致的情況,則查詢(xún)的時(shí)候出現(xiàn) 1578 錯(cuò)誤,當(dāng)然該錯(cuò)誤號(hào)也可能是物理磁盤(pán)損壞,這里表示邏輯的損壞!)這個(gè)頭和尾的SCN的檢查時(shí)機(jī)跟這兩個(gè)參數(shù)有關(guān):
db_block_checking boolean FALSE
db_block_checksum boolean FALSE
該2參數(shù)信息請(qǐng)查閱 http://tahiti.oracle.com
而ITL 中的 commit SCN 則跟 consistent gets and delay block cleanout 有關(guān)
數(shù)據(jù)文件頭的 SCN 是檢查點(diǎn)發(fā)生時(shí)更新的
代表著 當(dāng) 恢復(fù)的時(shí)候從這個(gè) SCN 點(diǎn) 開(kāi)始在 log file 中尋找 redo 開(kāi)始做恢復(fù)
8.According to Rama Velpuri's book, CKPT updates controlfiles, not their headers. It makes sense because if you look at a controlfile dump, the header doesn't even have an SCN. But the file body has sections for each datafile, and therefore each of them has an SCN to be updated.
It's odd that most books and also documentation don't even say CKPT updates controlfiles.
Follow-up to bellsz's original message. In controlfiles, the stop SCN is not a very big number; it's in fact set to infinity when the database is open. Also, SCNs are incremented for many reasons, mostly due to recursive transactions. Read Steve Adams and Hemant Chitale's answers at
http://groups.google.com/groups?sel...t_nospam.com.sg
9.
系統(tǒng)檢查點(diǎn)scn(v$database(checkpoint_change#))
數(shù)據(jù)文件檢查點(diǎn)(v$datafile(checkpoint_change#))
數(shù)據(jù)文件終止scn(v$datafile(last_change#))
數(shù)據(jù)文件中存放的檢查點(diǎn)
啟動(dòng)scn (v$datafile_header(checkpoint_change#)
1>系統(tǒng)檢查點(diǎn)scn
當(dāng)一個(gè)檢查點(diǎn)動(dòng)作完成之后,Oracle就把系統(tǒng)檢查點(diǎn)的SCN存儲(chǔ)到控制文件中。
select checkpoint_change# from v$database
2>數(shù)據(jù)文件檢查點(diǎn)scn
當(dāng)一個(gè)檢查點(diǎn)動(dòng)作完成之后,Oracle就把每個(gè)數(shù)據(jù)文件的scn單獨(dú)存放在控制文件
中。
select name,checkpoint_change# from v$datafile
3>啟動(dòng)scn
Oracle把這個(gè)檢查點(diǎn)的scn存儲(chǔ)在每個(gè)數(shù)據(jù)文件的文件頭中,這個(gè)值稱(chēng)為啟動(dòng)scn,
因?yàn)樗糜谠跀?shù)據(jù)庫(kù)實(shí)例啟動(dòng)時(shí),檢查是否需要執(zhí)行數(shù)據(jù)庫(kù)恢復(fù)。
select name,checkpoint_change# from v$datafile_header
4>終止scn
每個(gè)數(shù)據(jù)文件的終止scn都存儲(chǔ)在控制文件中。
select name,last_change# from v$datafile
在正常的數(shù)據(jù)庫(kù)操作過(guò)程中,所有正處于聯(lián)機(jī)讀寫(xiě)模式下的數(shù)據(jù)文件的終止scn都為null.
5>在數(shù)據(jù)庫(kù)運(yùn)行期間的scn值
在數(shù)據(jù)庫(kù)打開(kāi)并運(yùn)行之后,控制文件中的系統(tǒng)檢查點(diǎn)、控制文件中的數(shù)據(jù)文件檢查點(diǎn)scn
和每個(gè)數(shù)據(jù)文件頭中的啟動(dòng)scn都是相同的??刂莆募械拿總€(gè)數(shù)據(jù)文件的終止scn都為null.
在安全關(guān)閉數(shù)據(jù)庫(kù)的過(guò)程中,系統(tǒng)會(huì)執(zhí)行一個(gè)檢查點(diǎn)動(dòng)作,這時(shí)所有數(shù)據(jù)文件的終止scn
都會(huì)設(shè)置成數(shù)據(jù)文件頭中的那個(gè)啟動(dòng)scn的值。在數(shù)據(jù)庫(kù)重新啟動(dòng)的時(shí)候,
Oracle將文件頭中的那個(gè)啟動(dòng)scn與數(shù)據(jù)庫(kù)文件檢查點(diǎn)scn進(jìn)行比較,
如果這兩個(gè)值相互匹配,oracle接下來(lái)還要比較數(shù)據(jù)文件頭中的啟動(dòng)scn和控制文件
中數(shù)據(jù)文件的終止scn。如果這兩個(gè)值也一致,就意味著所有數(shù)據(jù)塊多已經(jīng)提交,所有
對(duì)數(shù)據(jù)庫(kù)的修改都沒(méi)有在關(guān)閉數(shù)據(jù)庫(kù)的過(guò)程中丟失,因此這次啟動(dòng)數(shù)據(jù)庫(kù)的過(guò)程
也不需要任何恢復(fù)操作,此時(shí)數(shù)據(jù)庫(kù)就可以打開(kāi)了。當(dāng)所有的數(shù)據(jù)庫(kù)都打開(kāi)之后,
存儲(chǔ)在控制文件中的數(shù)據(jù)文件終止scn的值再次被更改為null,
這表示數(shù)據(jù)文件已經(jīng)打開(kāi)并能夠正常使用了。
10.
找了一些網(wǎng)頁(yè),發(fā)現(xiàn)SCN確實(shí)不只在事務(wù)提交時(shí)增加,以下是網(wǎng)頁(yè)上的摘要:
1)
SCN means "System Change Number" not "System Commit Number".
However, because the SCN is always incremented at commits and seldom otherwise, it is OK to use the two terms interchangeably.
2)
The SCN is incremented whenever a transaction commits. However, this is not the only source of increments. In a seemingly idle database, the SCN gets incremented also through AQ, SMON, job queues...
1中說(shuō)了 oracle seldom操作也會(huì)引起SCN的增加,2中更明確說(shuō)了AQ, SMON, job queues... 會(huì)導(dǎo)致SCN的增加,因此應(yīng)該得出結(jié)論,在ORACLE中除了COMMIT會(huì)導(dǎo)致SCN增加外還有其它的ORACLE后臺(tái)進(jìn)程會(huì)導(dǎo)致SCN增加.
但是,是否是普通的DML導(dǎo)致了SCN的增加,還是由于DML操作過(guò)程中后臺(tái)進(jìn)程導(dǎo)致了SCN增加的假象?請(qǐng)大家踴躍討論!
還有ORACLE后臺(tái)進(jìn)程在何時(shí),何種情況下導(dǎo)致了SCN增加,也請(qǐng)大家踴躍討論!
Biti:這句話(huà)我應(yīng)該更準(zhǔn)確第表達(dá)一下
如果一個(gè)dml導(dǎo)致產(chǎn)生事務(wù),則會(huì)產(chǎn)生一個(gè)scn。這個(gè)意思是說(shuō)
如果一個(gè)事務(wù)包含多個(gè)dml,則只有第一個(gè)初始產(chǎn)生事務(wù)的dml產(chǎn)生scn,提交的時(shí)候又是一個(gè)scn
如果一個(gè)事務(wù)只有一個(gè)dml,拿看起來(lái)就是dml產(chǎn)生一個(gè)scn,提交或者回滾產(chǎn)生一個(gè)scn
這是經(jīng)過(guò)實(shí)驗(yàn)測(cè)試過(guò)的,如果你又興趣,不緊緊是要找資料看,還可以動(dòng)手證明。
你可以理解為 begin transaction and commit tansaction
至于沒(méi)有dml的commit ,那不叫一個(gè) transaction
你不做任何dml 而發(fā)出rollback命令 將會(huì)發(fā)現(xiàn) v$sysstat 中 user rollbacks 將會(huì)增加 而 transactions 不會(huì)增加
所以你可以把結(jié)論定義為 事務(wù)的開(kāi)始 和事務(wù)的結(jié)束都會(huì)導(dǎo)致 SCN 的增加,其他如 AQ/JOB 等也會(huì)產(chǎn)生SCN ……
同一個(gè)block上在一個(gè)事務(wù)中連續(xù)發(fā)生255個(gè)DML后scn也會(huì)增加
……
11.sys@DBAP01> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUX
------------------------------
52211024
已用時(shí)間: 00: 00: 00.00
sys@DBAP01> alter system checkpoint;
系統(tǒng)已更改。
已用時(shí)間: 00: 00: 00.06
sys@DBAP01> select CHECKPOINT_CHANGE# from v$database;
CHECKPOINT_CHANGE#
------------------
52211055
已用時(shí)間: 00: 00: 00.00
sys@DBAP01> select max(ktuxescnw*power(2,32)+ktuxescnb) from x$ktuxe;
MAX(KTUXESCNW*POWER(2,32)+KTUX
------------------------------
52211053
x$ktuxe 計(jì)算出來(lái)的是已經(jīng)結(jié)束的最新的事務(wù)的commit scn ,所以可小于當(dāng)前系統(tǒng)scn。 檢查點(diǎn)scn 自然也小于當(dāng)前系統(tǒng)scn。 但是 檢查點(diǎn)scn 和 x$ktuxe 計(jì)算出來(lái)的大小卻倚賴(lài)于 系統(tǒng)狀況了。
current scn 是 系統(tǒng)當(dāng)前所產(chǎn)生的最大 scn ,可能是當(dāng)前未結(jié)束事務(wù)所產(chǎn)生的scn。 在9i 的dbms_flashback.get_system_change_number可以得到這個(gè)值,這個(gè)值應(yīng)該是大于等于 x$ktuxe SCN (這個(gè)view 記錄的是 當(dāng)前數(shù)據(jù)庫(kù)結(jié)束事務(wù)的最大scn)
以上就是如何解析Oracle SCN,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。