【作者】石佛,曾在韓國(guó)留學(xué)獲信息學(xué)理科學(xué)士學(xué)位和應(yīng)用統(tǒng)計(jì)學(xué)碩士學(xué)位。主要擅長(zhǎng)方向:數(shù)據(jù)分析與數(shù)據(jù)挖掘、大數(shù)據(jù)技術(shù)、人工智能與機(jī)器學(xué)習(xí)、 數(shù)據(jù)庫(kù)與系統(tǒng)智能化管理和優(yōu)化。
通俗的理解
中的SCN( )相當(dāng)于數(shù)據(jù)庫(kù)中的一個(gè)時(shí)鐘,只不過(guò)不是用時(shí)分秒來(lái)計(jì)量,這種內(nèi)部時(shí)鐘機(jī)制,可稱為邏輯時(shí)鐘,每個(gè)數(shù)據(jù)庫(kù)都有一個(gè)全局SCN生成器,本質(zhì)上就是不重復(fù)的數(shù)字。
為什么不用系統(tǒng)時(shí)間來(lái)計(jì)錄呢?原因是機(jī)器上的時(shí)間容易被人為修改,從而易造成內(nèi)部記錄的錯(cuò)亂。所以它采用自己產(chǎn)生的SCN來(lái)區(qū)分所有操作的先后順序。
SCN號(hào)具體概述
SCN是當(dāng)數(shù)據(jù)庫(kù)更新后,由DBMS自動(dòng)維護(hù)去累積遞增的一個(gè)數(shù)字。數(shù)據(jù)庫(kù)中一共有4種SCN分別為
系統(tǒng)檢查點(diǎn)SCN: 系統(tǒng)檢查點(diǎn)SCN位于控制文件中,當(dāng)檢查點(diǎn)進(jìn)程啟動(dòng)時(shí)(ckpt),就把系統(tǒng)檢查點(diǎn)的SCN存儲(chǔ)到控制文件中。該SCN是全局范圍的,當(dāng)發(fā)生文件級(jí)別的SCN時(shí),例如將表空間置于只讀狀態(tài),則不會(huì)更新系統(tǒng)檢查點(diǎn)SCN。
查詢系統(tǒng)檢查點(diǎn)SCN的命令如下
SQL> # from v$; #
數(shù)據(jù)文件scn:當(dāng)ckpt進(jìn)程啟動(dòng)時(shí),包括全局范圍的(比如日志切換)以及文件級(jí)別的檢查點(diǎn)(將表空間置為只讀、begin 或?qū)⒛硞€(gè)數(shù)據(jù)文件設(shè)置為等),這時(shí)會(huì)在控制文件中記錄的scn。
查詢數(shù)據(jù)文件SCN的命令如下
SQL> alter users read only;
.
SQL> file#,# from v$;
FILE# #
1
2
3
4
5
SQL> # from v$; #
可以看到4號(hào)文件也就是users表空間所屬的文件scn值和其他文件不一致,且比系統(tǒng)檢查點(diǎn)的scn要大。
結(jié)束scn:每個(gè)數(shù)據(jù)文件都有一個(gè)結(jié)束scn,在數(shù)據(jù)庫(kù)的正常運(yùn)行中,只要數(shù)據(jù)文件在線且是可讀寫(xiě)的,結(jié)束scn為null。否則則存在具體的scn值。結(jié)束scn也記錄在控制文件中。
SQL> , from
TEMP
USERS READ ONLY
SQL> file#,# from v$;
FILE# #
1
2
3
4
5
可以看到除了users表空間的結(jié)束scn不為空,其他數(shù)據(jù)文件的結(jié)束scn為空。
將數(shù)據(jù)庫(kù)至于mount狀態(tài),由于該狀態(tài)下所有的數(shù)據(jù)文件都不可寫(xiě),故mount狀態(tài)下所有的數(shù)據(jù)文件都具有結(jié)束scn。
SQL> ;
SQL> mount;
SQL> file#,# from v$;
FILE# #
1
2
3
4
5
數(shù)據(jù)文件頭scn:不同于上述的SCN數(shù)據(jù)文件開(kāi)始scn記錄在每個(gè)數(shù)據(jù)文件中。當(dāng)發(fā)生系統(tǒng)及文件級(jí)別的檢查點(diǎn)后,不僅將這時(shí)的SCN號(hào)記錄在控制文件中,同樣也記錄在數(shù)據(jù)文件中。
查詢數(shù)據(jù)文件頭SCN的命令如下
SQL> file#,# from v$;
FILE# #
1
2
3
4
5
SCN的機(jī)制
數(shù)據(jù)庫(kù)運(yùn)行時(shí)的SCN
我們先看下事務(wù)中的數(shù)據(jù)變化是如何寫(xiě)入數(shù)據(jù)文件的:
1、 事務(wù)開(kāi)始;
2、 在 cache中找到需要的數(shù)據(jù)塊,如果沒(méi)有找到,則從數(shù)據(jù)文件中載入 cache中;
3、 事務(wù)修改 cache的數(shù)據(jù)塊,該數(shù)據(jù)被標(biāo)識(shí)為“臟數(shù)據(jù)”,并被寫(xiě)入log 中;
4、 事務(wù)提交,LGWR進(jìn)程將log 中的“臟數(shù)據(jù)”寫(xiě)入redo log file中;
5、 當(dāng)發(fā)生,CKPT進(jìn)程更新所有數(shù)據(jù)文件的文件頭中的信息,DBWr進(jìn)程則負(fù)責(zé)將 Cache中的臟數(shù)據(jù)寫(xiě)入到數(shù)據(jù)文件中。
Redo log中的high scn和low scn
的Redo log會(huì)順序紀(jì)錄數(shù)據(jù)庫(kù)的各個(gè)變化。一組redo log文件寫(xiě)滿后,會(huì)自動(dòng)切換到下一組redo log文件。則上一組redo log的high scn就是下一組redo log的low scn。在 log中high scn為無(wú)窮大。
可通過(guò)查詢v$查看 low scn和 high scn。
SQL> recid,#,#,# from v$ ;
RECID # # #
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
查看 中的high scn
SQL> vf.,v.,v.# from v$ vf,v$log v
2 where vf.group#=v.group#
3* and v.=''
#
/u01/app//orcl/.log
SQL>alter dump ' /u01/app//orcl/.log';
SQL> show
NAME TYPE VALUE
/home//admin/c001/udump
打開(kāi)轉(zhuǎn)儲(chǔ)出來(lái)的文件,可以看到
DUMP OF REDO FROM FILE '/u01/app//orcl/.log'
.
RBAs: ..0000 thru ..ffff
SCNs: scn: . thru scn: .
Times: thru
FILE :
Vsn = =
Db ID==, Db
ID==
Seq=696=0x2b8, File size==
File =2, =512, File Type=2 LOG
:" 0001, Seq# , SCN -"
: 1 nab: seq: hws: 0x9 eot: 1 dis: 0
count: scn: . ()
rcv count: 0x0 scn: .
prev count: scn: . (1)
prev rcv count: 0x0 scn: .
Low scn: . () 04/20/2011 09:35:56
Next scn: . 01/01/1988 00:00:00
scn: . () 02/03/2011 18:29:03
scn: . () 04/20/2011 15:29:05
Disk cksum: Calc cksum:
stop scn: .
01/01/1988 00:00:00
Most redo scn: .
LWN: 1920
End-of-redo : No
mode
flags: 0x0
: thr: 0, seq: 0 scn: .
redo log中當(dāng)前系統(tǒng)的SCN記錄當(dāng)前最新的數(shù)據(jù)庫(kù)scn值可通過(guò)如下命令查看
SQL> .mber from dual; MBER
如果需要進(jìn)行實(shí)例恢復(fù),則需要恢復(fù)的記錄為至中redo log中的記錄。
日志切換或者
當(dāng)日志切換或發(fā)生(上述第五個(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$的字段#可以查詢)更新為Next SCN,同時(shí)將控制文件中的 SCN(通過(guò)視圖v$的字段#可以查詢)、每個(gè)數(shù)據(jù)文件對(duì)應(yīng)的 (通過(guò)視圖v$的字段#可以查詢)也更新為Next SCN。但是,如果該數(shù)據(jù)文件所在的表空間被設(shè)置為read-only時(shí),數(shù)據(jù)文件的Start SCN和控制文件中 SCN都不會(huì)被更新。
心跳
在中有一個(gè)事件叫,這個(gè)詞在很多地方被提及,并且有著不同的含義(比如RAC中),我們這里要討論的是CKPT的機(jī)制。
通過(guò)CKPT進(jìn)程每3秒將寫(xiě)入控制文件,以減少故障時(shí)的恢復(fù)時(shí)間。
數(shù)據(jù)庫(kù)正常關(guān)閉啟動(dòng)
數(shù)據(jù)庫(kù)正常關(guān)閉時(shí),系統(tǒng)會(huì)執(zhí)行一個(gè)完全檢查點(diǎn)動(dòng)作,并用該檢查點(diǎn)時(shí)的SCN號(hào)更新上述4個(gè)SCN號(hào),這時(shí)所有數(shù)據(jù)文件的終止SCN號(hào)會(huì)設(shè)置為數(shù)據(jù)文件頭的那個(gè)啟動(dòng)SCN(除了離線和只讀的數(shù)據(jù)文件)。
數(shù)據(jù)庫(kù)重新啟動(dòng)時(shí),將數(shù)據(jù)文件頭中的啟動(dòng)SCN與數(shù)據(jù)文件檢查點(diǎn)SCN比較,如果這 兩個(gè)值匹配,接下來(lái)再比較數(shù)據(jù)文件頭中的SCN和控制文件中數(shù)據(jù)文件的終止SCN,如果這個(gè)值也匹配,就意味著所有數(shù)據(jù)塊已經(jīng)提交,因此數(shù)據(jù) 庫(kù)不需要進(jìn)行恢復(fù),此時(shí)數(shù)據(jù)庫(kù)直接打開(kāi)。當(dāng)所有的數(shù)據(jù)文件都打開(kāi)之后oracle表空間增加文件,在線且可讀寫(xiě)的數(shù)據(jù)文件終止SCN再次被設(shè)置為NULL,表示數(shù)據(jù)文件已經(jīng)打開(kāi)并能 夠正常使用了。有些表空間是只讀的,這時(shí)控制文件中的系統(tǒng)檢查點(diǎn)SCN號(hào)會(huì)不斷增長(zhǎng),而數(shù)據(jù)文件SCN號(hào)和文件頭中的啟動(dòng)SCN(會(huì)停止更新直到表空間又 設(shè)置為可讀寫(xiě)),顯然這時(shí)系統(tǒng)檢查點(diǎn)SCN號(hào)會(huì)大于數(shù)據(jù)文件SCN和文件頭啟動(dòng)SCN。
數(shù)據(jù)庫(kù)非正常關(guān)閉
數(shù)據(jù)庫(kù)非正常關(guān)閉 ( 或稱為實(shí)例崩潰 ) 時(shí),終止 SCN 不會(huì)被設(shè)置,依然為 NULL ,這可以通過(guò)把數(shù)據(jù)庫(kù)啟動(dòng)至mount 狀態(tài)查詢出來(lái)。 這樣重新啟動(dòng)時(shí),SMON進(jìn)程 會(huì)執(zhí)行實(shí)例恢復(fù)工作,即先執(zhí)行前滾、回滾操作,再把數(shù)據(jù)庫(kù)打開(kāi)。
數(shù)據(jù)文件介質(zhì)故障
出現(xiàn)介質(zhì)故障時(shí),數(shù)據(jù)文件檢查點(diǎn)SCN及系統(tǒng)檢查點(diǎn)SCN比文件頭啟動(dòng)SCN大。系統(tǒng)發(fā)生介質(zhì)故障時(shí),數(shù)據(jù)文件被以前的備份代替,控制文件中的數(shù)據(jù)文件檢查點(diǎn)SCN肯定比文件頭中的啟動(dòng)SCN要大,這樣就知道要對(duì)這個(gè)文件進(jìn)行介質(zhì) 恢復(fù)
控制文件介質(zhì)故障
系統(tǒng)檢查點(diǎn)SCN及數(shù)據(jù)文件SCN比數(shù)據(jù)文件頭啟動(dòng)SCN小:
在數(shù)據(jù)庫(kù)恢復(fù)時(shí),控制文件可能不是最新的,即把一個(gè)較早的控制文件還原為當(dāng)前的控制文件,然后再執(zhí)行恢復(fù)操作,這時(shí)控制文件中的系統(tǒng)檢查點(diǎn)SCN和數(shù)據(jù)文 件SCN可能比文件頭的啟動(dòng)SCN小。這時(shí)恢復(fù)數(shù)據(jù)庫(kù)要用下面命令: using 或其他的恢復(fù)語(yǔ)句。
備份時(shí)的實(shí)例崩潰
當(dāng)執(zhí)行begin 時(shí)實(shí)例崩潰:控制文件中的數(shù)據(jù)文件檢查點(diǎn)SCN號(hào)和數(shù)據(jù)文件頭部檢查點(diǎn)SCN號(hào)相同,但是每個(gè)可讀寫(xiě)的在線數(shù)據(jù)文件之間檢查點(diǎn)SCN號(hào)不同, 那么要求介質(zhì)恢復(fù),例如發(fā)出begin 命令后就會(huì)出現(xiàn)這種情況,需要通過(guò)end 命令好才可以打開(kāi)數(shù)據(jù)庫(kù)。
SCN號(hào)的補(bǔ)充內(nèi)容:
SCN號(hào)記錄到日志文件,控制文件,數(shù)據(jù)文件及許多數(shù)據(jù)庫(kù)表記錄。
一、查看數(shù)據(jù)庫(kù)的當(dāng)前SCN號(hào)
SQL> .mber from dual;
SQL> from v$;
二、SCN存儲(chǔ)于在線重做日志文件中
SQL> GROUP#, , # from v$log;
GROUP# #
1
2
3
三、SCN存在于控制文件中
補(bǔ)充:
控制文件中的信息包括:
1.數(shù)據(jù)庫(kù)的名字oracle表空間增加文件,取自初始化參數(shù)說(shuō)明的數(shù)據(jù)庫(kù)名字或 語(yǔ)句中所使用的名字
2.數(shù)據(jù)庫(kù)創(chuàng)建時(shí)間戳,是數(shù)據(jù)庫(kù)創(chuàng)建時(shí)產(chǎn)生的。
3.數(shù)據(jù)庫(kù)標(biāo)識(shí)符,是創(chuàng)建數(shù)據(jù)庫(kù)時(shí)自動(dòng)生成的。
4.聯(lián)機(jī)重做日志文件的名字和準(zhǔn)確位置,增加刪除修改重做日志文件時(shí),會(huì)修改相關(guān)信息。
5.當(dāng)前日志的序列號(hào),是在日志切換時(shí)記錄的。
6.檢查點(diǎn)信息,是在產(chǎn)生校驗(yàn)點(diǎn)時(shí)記錄的以及SCN。
7.日志的歷史信息,是在日志切換時(shí)記錄的。
8.歸檔日志文件的準(zhǔn)確位置和狀態(tài),是在重做日志文件被歸檔(復(fù)制到歸檔日志文件)時(shí)記錄的
9,數(shù)據(jù)文件的名字和準(zhǔn)確位置,增加刪除修改數(shù)據(jù)文件名字,會(huì)修改相關(guān)信息。
10.表空間的相關(guān)信息,增加刪除表空間時(shí),會(huì)修改相關(guān)信息。
11.備份準(zhǔn)確位置和狀態(tài),這些信息是由恢復(fù)管理器記錄的。