Oracle SCN機制解析

SCNSystem Chang Number)做爲oracle中的一個重要機制,在數據恢復、Data GuardStreams複製、RAC節點間的同步等各個功能中起着重要做用。理解SCN的運做機制,能夠幫助你更加深刻地瞭解上述功能。數據庫

在理解SCN以前,咱們先看下oracle事務中的數據變化是如何寫入數據文件的:oracle

1、事務開始;ide

2、在buffer cache中找到須要的數據塊,若是沒有找到,則從數據文件中載入buffer cache中;函數

3、事務修改buffer cache的數據塊,該數據被標識爲髒數據,並被寫入log buffer中;spa

4、事務提交,LGWR進程將log buffer中的髒數據寫入redo log file中;日誌

5、當發生checkpointCKPT進程更新全部數據文件的文件頭中的信息,DBWn進程則負責將Buffer Cache中的髒數據寫入到數據文件中。orm

通過上述5個步驟,事務中的數據變化最終被寫入到數據文件中。可是,一旦在上述中間環節時,數據庫意外宕機了,在從新啓動時如何知道哪些數據已經寫入數據文件、哪些沒有寫呢(一樣,在DGstreams中也存在相似疑問:redo log中哪些是上一次同步已經複製過的數據、哪些沒有)?SCN機制就能比較完善的解決上述問題。htm

SCN是一個數字,確切的說是一個只會增長、不會減小的數字。正是它這種只會增長的特性確保了Oracle知道哪些應該被恢復、哪些應該被複制。進程

總共有4SCN:系統檢查點(System CheckpointSCN、數據文件檢查點(Datafile CheckpointSCN、結束SCNStop SCN)、開始SCNStart SCN)。其中其面3SCN存在於控制文件中,最後一種則存在於數據文件的文件頭中。事務

在控制文件中,System Checkpoint SCN是針對整個數據庫全局的,於是之存在一個,而Datafile Checkpoint SCNStop SCN是針對每一個數據文件的,於是一個數據文件就對應在控制文件中存在一份Datafile Checkpoint SCNStop SCN。在數據庫正常運行期間,Stop SCN(經過視圖v$datafile的字段last_change#能夠查詢)是一個無窮大的數字或者說是NULL

在一個事務提交後(上述第四個步驟),會在redo log中存在一條redo記錄,同時,系統爲其提供一個最新的SCN(經過函數dbms_flashback.get_system_change_number能夠知道當前的最新SCN),記錄在該條記錄中。若是該條記錄是在redo log被清空(日誌滿作切換時或發生checkpoint時,全部變化日誌已經被寫入數據文件中),則其SCN被記錄爲redo loglow SCN。之後在日誌再次被清空前寫入的redo記錄中SCN則成爲Next SCN

當日志切換或發生checkpoint(上述第五個步驟)時,從Low SCNNext 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都不會被更新。

那系統是如何產生一個最新的SCN的?實際上,這個數字是由當時的timestamp轉換過來的。每當須要產生一個最新的SCNredo記錄時,系統獲取當時的timestamp,將其轉換爲數字做爲SCN。咱們能夠經過函數SCN_TO_TIMESTAMP10g之後)將其轉換回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


也能夠用函數timestamp_to_scn將一個timestamp轉換爲SCN

SQL> select timestamp_to_scn(SYSTIMESTAMP) as scn from dual;

      SCN

----------

2877078439


最後,SCN除了做爲反映事務數據變化並保持同步外,它還起到系統的心跳做用——每隔3秒左右系統會刷新一次系統SCN

下面,在簡單介紹一下SCN如何在數據庫恢復中起做用。

數據庫在正常關閉(shutdown immediate/normal)時,會先作一次checkpoint,將log file中的數據寫入數據文件中,將控制文件、數據文件中的SCN(包括控制文件中的Stop SCN)都更新爲最新的SCN

數據庫異常/意外關閉不會或者只更新部分Stop SCN

當數據庫啓動時,Oracle先檢查控制文件中的每一個Datafile Checkpoint SCN和數據文件中的Start SCN是否相同,再檢查每一個Datafile Checkpoint SCNStop SCN是否相同。若是發現有不一樣,就從Redo Log中找到丟失的SCN,從新寫入數據文件中進行恢復。具體的數據恢復過程這裏就再也不贅述。

SCN做爲Oracle中的一個重要機制,在多個重要功能中起着控制器的做用。瞭解SCN的產生和實現方式,幫助DBA理解和處理恢復、DGStreams複製的問題。

最後提一句,利用SCN機制,在Oracle10g11g中又增長了一些很實用的功能——數據庫閃回、數據庫負載重現等。


原文地址 http://www.hellodba.com/Doc/Oracle_SCN.htm
相關文章
相關標籤/搜索