oracle数据库的scn,Oracle数据库SCN详解
SCN號(hào)概述
SCN是當(dāng)Oracle數(shù)據(jù)庫(kù)更新后,由DBMS自動(dòng)維護(hù)去累積遞增的一個(gè)數(shù)字。Oracle數(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),Oracle就把系統(tǒng)檢查點(diǎn)的SCN存儲(chǔ)到控制文件中。該SCN是全局范圍的,當(dāng)發(fā)生文件級(jí)別的SCN時(shí),例如將表空間置于只讀狀態(tài),則不會(huì)更新系統(tǒng)檢查點(diǎn)SCN。
查詢(xún)系統(tǒng)檢查點(diǎn)SCN的命令如下
SQL> select CHECKPOINT_CHANGE# from v$database;
CHECKPOINT_CHANGE#
------------------
590694
數(shù)據(jù)文件scn:當(dāng)ckpt進(jìn)程啟動(dòng)時(shí),包括全局范圍的(比如日志切換)以及文件級(jí)別的檢查點(diǎn)(將表空間置為只讀、begin backup或?qū)⒛硞€(gè)數(shù)據(jù)文件設(shè)置為offline等),這時(shí)會(huì)在控制文件中記錄的scn。
查詢(xún)數(shù)據(jù)文件SCN的命令如下
SQL> alter tablespace users read only;
Tablespace altered.
SQL> select file#,checkpoint_change# from v$datafile;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 ? ? ? ? ? ? 592277
2 ? ? ? ? ? ? 592277
3 ? ? ? ? ? ? 592277
4 ? ? ? ? ? ? 592291
5 ? ? ? ? ? ? 592277
SQL> select checkpoint_change# from v$database;
CHECKPOINT_CHANGE#
------------------
592277
可以看到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>select TABLESPACE_NAME,STATUS from dba_tablespaces
TABLESPACE_NAME ? STATUS
----------------- ---------------------------
SYSTEM ? ? ? ? ? ?ONLINE
UNDOTBS1 ? ? ? ? ?ONLINE
SYSAUX ? ? ? ? ? ?ONLINE
TEMP ? ? ? ? ? ? ?ONLINE
USERS ? ? ? ? ? ? READ ONLY
EXAMPLE ? ? ? ? ? ONLINE
SQL> select file#,LAST_CHANGE# from ?v$datafile;
FILE# LAST_CHANGE#
---------- ------------
1
2
3
4 ? ? ? 592291
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> shutdown immediate;
SQL> startup mount;
SQL> select file#,last_change# from v$datafile;
FILE# LAST_CHANGE#
---------- ------------
1 ? ? ? 592608
2 ? ? ? 592608
3 ? ? ? 592608
4 ? ? ? 592291
5 ? ? ? 592608
數(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ù)文件中。
查詢(xún)數(shù)據(jù)文件頭SCN的命令如下
SQL> select file#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 ? ? ? ? ? ? 592608
2 ? ? ? ? ? ? 592608
3 ? ? ? ? ? ? 592608
4 ? ? ? ? ? ? 592291
5 ? ? ? ? ? ? 592608
SCN的機(jī)制
數(shù)據(jù)庫(kù)運(yùn)行時(shí)的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ù)”;
4、 事務(wù)提交,LGWR進(jìn)程將log buffer中的“臟數(shù)據(jù)”寫(xiě)入redo log file中;
5、 當(dāng)發(fā)生checkpoint,CKPT進(jìn)程更新所有數(shù)據(jù)文件的文件頭中的信息,DBWr進(jìn)程則負(fù)責(zé)將Buffer Cache中的臟數(shù)據(jù)寫(xiě)入到數(shù)據(jù)文件中。
Redo log中的high scn和low scn
Oracle的Redo log會(huì)順序紀(jì)錄數(shù)據(jù)庫(kù)的各個(gè)變化。一組redo log文件寫(xiě)滿(mǎn)后,會(huì)自動(dòng)切換到下一組redo log文件。則上一組redo log的high scn就是下一組redo log的low scn。在current log中high scn為無(wú)窮大。
可通過(guò)查詢(xún)v$log_history查看 low scn和 high scn。
SQL> select recid,sequence#,first_change#,next_change# from v$log_history ;
RECID ?SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#
---------- ---------- ------------- ------------
1 ? ? ? ? ?1 ? ? ? ?446075 ? ? ? 474154
2 ? ? ? ? ?2 ? ? ? ?474154 ? ? ? 497385
3 ? ? ? ? ?3 ? ? ? ?497385 ? ? ? 516087
4 ? ? ? ? ?4 ? ? ? ?516087 ? ? ? 540659
5 ? ? ? ? ?5 ? ? ? ?540659 ? ? ? 564897
6 ? ? ? ? ?6 ? ? ? ?564897 ? ? ? 564903
7 ? ? ? ? ?7 ? ? ? ?564903 ? ? ? 565320
8 ? ? ? ? ?8 ? ? ? ?565320 ? ? ? 565704
9 ? ? ? ? ?9 ? ? ? ?565704 ? ? ? 565715
10 ? ? ? ? 10 ? ? ?565715 ? ? ? 567343
11 ? ? ? ? 11 ? ? ?567343 ? ? ? 587705
查看currnet redolog中的high scn
SQL>select vf.member,v.status,v.first_change# from v$logfile vf,v$log v
2 ? ? ?where vf.group#=v.group#
3* ? and v.status='CURRENT'
MEMBER ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?STATUS ? ? ? ? ? ? FIRST_CHANGE#
------------------------------------------------------------ ? ?-------------- ? ? ? ? ? -------------
/u01/app/oradata/orcl/redo02.log ? ? ? ? ? ? ? ? ? ? ? ? ? ? CURRENT ? ? ? ? 587705
SQL>alter system dump logfile ' /u01/app/oradata/orcl/redo02.log';
SQL> show parameter user_dump
NAME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE ? ? ? ?VALUE
------------------------------------ ----------- ------------------------------
user_dump_dest ? ? ? ? ? ? ? ? ? ? ? string ? ? ?/home/oracle/admin/c001/udump
打開(kāi)轉(zhuǎn)儲(chǔ)出來(lái)的文件,可以看到
DUMP OF REDO FROM FILE '/u01/app/oradata/orcl/redo02.log'
Opcodes *.*
RBAs: 0x000000.00000000.0000 thru 0xffffffff.ffffffff.ffff
SCNs: scn: 0x0000.00000000 thru scn: 0xffff.ffffffff
Times: creation thru eternity
FILE HEADER:
Compatibility Vsn = 169869568=0xa200100
Db ID=1269936864=0x4bb1b2e0, Db Name='ORCL'
Activation ID=1269912032=0x4bb151e0
Control Seq=696=0x2b8, File size=102400=0x19000
File Number=2, Blksiz=512, File Type=2 LOG
descrip:"Thread 0001, Seq# 0000000012, SCN 0x00000008f7b9-0xffffffffffff"
thread: 1 nab: 0x34f6 seq: 0x0000000c hws: 0x9 eot: 1 dis: 0
resetlogs count: 0x2c3c676f scn: 0x0000.0006ce7b (446075)
resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
prev resetlogs count: 0x2184ef74 scn: 0x0000.00000001 (1)
prev resetlogs terminal rcv count: 0x0 scn: 0x0000.00000000
Low ?scn: 0x0000.0008f7b9 (587705) 04/20/2011 09:35:56
Next scn: 0xffff.ffffffff 01/01/1988 00:00:00
Enabled scn: 0x0000.0006ce7b (446075) 02/03/2011 18:29:03
Thread closed scn: 0x0000.00090ae0 (592608) 04/20/2011 15:29:05
Disk cksum: 0x30ee Calc cksum: 0x30ee
Terminal recovery stop scn: 0x0000.00000000
Terminal recovery ?01/01/1988 00:00:00
Most recent redo scn: 0x0000.00000000
Largest LWN: 1920 blocks
End-of-redo stream : No
Unprotected mode
Miscellaneous flags: 0x0
Thread internal enable indicator: thr: 0, seq: 0 scn: 0x0000.00000000
redo log中當(dāng)前系統(tǒng)的SCN記錄當(dāng)前最新的數(shù)據(jù)庫(kù)scn值可通過(guò)如下命令查看
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
594373
如果需要進(jìn)行實(shí)例恢復(fù),則需要恢復(fù)的記錄為587705至594373中redo log中的記錄。
日志切換或者checkpoint
當(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ì)被更新。
心跳
在Oracle中有一個(gè)事件叫Heartbeat,這個(gè)詞在很多地方被提及,并且有著不同的含義(比如RAC中),我們這里要討論的是CKPT的Heartbeat機(jī)制。
Oracle通過(guò)CKPT進(jìn)程每3秒將Heartbeat寫(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í),Oracle將數(shù)據(jù)文件頭中的啟動(dòng)SCN與數(shù)據(jù)文件檢查點(diǎn)SCN比較,如果這 兩個(gè)值匹配,Oracle接下來(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)之后,在線且可讀寫(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)閉 ( 或稱(chēng)為實(shí)例崩潰 ) 時(shí),終止 SCN 不會(huì)被設(shè)置,依然為 NULL ,這可以通過(guò)把數(shù)據(jù)庫(kù)啟動(dòng)至 mount 狀態(tài)查詢(xún)出來(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要大,這樣Oracle就知道要對(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ù)要用下面命令:recover database using Backup Controlfile或其他的恢復(fù)語(yǔ)句。
備份時(shí)的實(shí)例崩潰
當(dāng)執(zhí)行begin backup時(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 backup命令后就會(huì)出現(xiàn)這種情況,需要通過(guò)end backup命令好才可以打開(kāi)數(shù)據(jù)庫(kù)。
來(lái)自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/31448824/viewspace-2136598/,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任。
總結(jié)
以上是生活随笔為你收集整理的oracle数据库的scn,Oracle数据库SCN详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 网站性能优化——雅虎14条
- 下一篇: linux cmake编译源码,linu