Oracle SCN詳解

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/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章