SCN號概述
SCN是當Oracle數據庫更新後,由DBMS自動維護去累積遞增的一個數字。Oracle數據庫中一共有4種SCN分別爲
系統檢查點SCN: 系統檢查點SCN位於控制文件中,當檢查點進程啓動時(ckpt),Oracle就把系統檢查點的SCN存儲到控制文件中。該SCN是全局範圍的,當發生文件級別的SCN時,例如將表空間置於只讀狀態,則不會更新系統檢查點SCN。
查詢系統檢查點SCN的命令如下
SQL> select CHECKPOINT_CHANGE# from v$database;
CHECKPOINT_CHANGE#
------------------
590694
數據文件scn:當ckpt進程啓動時,包括全局範圍的(比如日誌切換)以及文件級別的檢查點(將表空間置爲只讀、begin backup或將某個數據文件設置爲offline等),這時會在控制文件中記錄的scn。
查詢數據文件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號文件也就是users表空間所屬的文件scn值和其他文件不一致,且比系統檢查點的scn要大。
結束scn:每個數據文件都有一個結束scn,在數據庫的正常運行中,只要數據文件在線且是可讀寫的,結束scn爲null。否則則存在具體的scn值。結束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表空間的結束scn不爲空,其他數據文件的結束scn爲空。
將數據庫至於mount狀態,由於該狀態下所有的數據文件都不可寫,故mount狀態下所有的數據文件都具有結束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
數據文件頭scn:不同於上述的SCN數據文件開始scn記錄在每個數據文件中。當發生系統及文件級別的檢查點後,不僅將這時的SCN號記錄在控制文件中,同樣也記錄在數據文件中。
查詢數據文件頭SCN的命令如下
SQL> select file#,CHECKPOINT_CHANGE# from v$datafile_header;
FILE# CHECKPOINT_CHANGE#
---------- ------------------
1 592608
2 592608
3 592608
4 592291
5 592608
SCN的機制
數據庫運行時的SCN
我們先看下oracle事務中的數據變化是如何寫入數據文件的:
1、 事務開始;
2、 在buffer cache中找到需要的數據塊,如果沒有找到,則從數據文件中載入buffer cache中;
3、 事務修改buffer cache的數據塊,該數據被標識爲“髒數據”,並被寫入log buffer中;
4、 事務提交,LGWR進程將log buffer中的“髒數據”寫入redo log file中;
5、 當發生checkpoint,CKPT進程更新所有數據文件的文件頭中的信息,DBWr進程則負責將Buffer Cache中的髒數據寫入到數據文件中。
Redo log中的high scn和low scn
Oracle的Redo log會順序紀錄數據庫的各個變化。一組redo log文件寫滿後,會自動切換到下一組redo log文件。則上一組redo log的high scn就是下一組redo log的low scn。在current log中high scn爲無窮大。
可通過查詢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
打開轉儲出來的文件,可以看到
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中當前系統的SCN記錄當前最新的數據庫scn值可通過如下命令查看
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
594373
如果需要進行實例恢復,則需要恢復的記錄爲587705至594373中redo log中的記錄。
日誌切換或者checkpoint
當日志切換或發生checkpoint(上述第五個步驟)時,從Low SCN到Next SCN之間的所有redo記錄的數據就被DBWn進程寫入數據文件中,而CKPT進程則將所有數據文件(無論redo log中的數據是否影響到該數據文件)的文件頭上記錄的Start SCN(通過視圖v$datafile_header的字段checkpoint_change#可以查詢)更新爲Next SCN,同時將控制文件中的System Checkpoint SCN(通過視圖v$database的字段checkpoint_change#可以查詢)、每個數據文件對應的Datafile Checkpoint(通過視圖v$datafile的字段checkpoint_change#可以查詢)也更新爲Next SCN。但是,如果該數據文件所在的表空間被設置爲read-only時,數據文件的Start SCN和控制文件中Datafile Checkpoint SCN都不會被更新。
心跳
在Oracle中有一個事件叫Heartbeat,這個詞在很多地方被提及,並且有着不同的含義(比如RAC中),我們這裏要討論的是CKPT的Heartbeat機制。
Oracle通過CKPT進程每3秒將Heartbeat寫入控制文件,以減少故障時的恢復時間
數據庫正常關閉啓動
數據庫正常關閉時,系統會執行一個完全檢查點動作,並用該檢查點時的SCN號更新上述4個SCN號,這時所有數據文件的終止SCN號會設置爲數據文件頭的那個啓動SCN(除了離線和只讀的數據文件)
數據庫重新啓動時,Oracle將數據文件頭中的啓動SCN與數據文件檢查點SCN比較,如果這兩個值匹配,Oracle接下來再比較數據文件頭中的SCN和控制文件中數據文件的終止SCN,如果這個值也匹配,就意味着所有數據塊已經提交,因此數據庫不需要進行恢復,此時數據庫直接打開。當所有的數據文件都打開之後,在線且可讀寫的數據文件終止SCN再次被設置爲NULL,表示數據文件已經打開並能夠正常使用了。有些表空間是隻讀的,這時控制文件中的系統檢查點SCN號會不斷增長,而數據文件SCN號和文件頭中的啓動SCN(會停止更新直到表空間又設置爲可讀寫),顯然這時系統檢查點SCN號會大於數據文件SCN和文件頭啓動SCN。
數據庫非正常關閉
數據庫非正常關閉(或稱爲實例崩潰)時,終止SCN不會被設置,依然爲NULL,這可以通過把數據庫啓動至mount狀態查詢出來。這樣重新啓動時,SMON進程會執行實例恢復工作,即先執行前滾、回滾操作,再把數據庫打開。
數據文件介質故障
出現介質故障時,數據文件檢查點SCN及系統檢查點SCN比文件頭啓動SCN大。系統發生介質故障時,數據文件被以前的備份代替,控制文件中的數據文件檢查點SCN肯定比文件頭中的啓動SCN要大,這樣Oracle就知道要對這個文件進行介質恢復
控制文件介質故障
系統檢查點SCN及數據文件SCN比數據文件頭啓動SCN小:
在數據庫恢復時,控制文件可能不是最新的,即把一個較早的控制文件還原爲當前的控制文件,然後再執行恢復操作,這時控制文件中的系統檢查點SCN和數據文件SCN可能比文件頭的啓動SCN小。這時恢復數據庫要用下面命令:recover database using Backup Controlfile或其他的恢復語句。
備份時的實例崩潰
當執行begin backup時實例崩潰:控制文件中的數據文件檢查點SCN號和數據文件頭部檢查點SCN號相同,但是每個可讀寫的在線數據文件之間檢查點SCN號不同,那麼要求介質恢復,例如發出begin backup命令後就會出現這種情況,需要通過end backup命令好纔可以打開數據庫。
參考至:《教你如何成爲10g OCP》韓思捷著
http://blog.csdn.net/daimin1983/archive/2008/12/09/3484173.aspx
http://apps.hi.baidu.com/share/detail/24548269
http://blog.csdn.net/liweiah/archive/2009/07/13/4345656.aspx
http://lanying1982.blog.163.com/blog/static/230677482009015112027385/