深入瞭解SCN

SCN: System Change Number

SCN是順序遞增的一個數字,在Oracle 中用來標識數據庫的每一次改動,及其先後順序。SCN的最大值是0xffff.ffffffff
 

OracleSCN的管理

單節點的Instance

單節點的instance中,SCN值存在SGA區,由system commit number latch保護。任何進程要得到當前的SCN值,都要先得到這個latch

RAC/OPS環境中

Oracle通過排隊機制(Enqueue)實現SCN在各並行節點之間的順序增長。具體有兩種方法:

Lamport算法:又稱麪包房算法,先來先服務算法。跟很多銀行採用的排隊機制一樣。客戶到了銀行,先領取一個服務號。一旦某個窗口出現空閒,擁有最小服務號的客戶就可以去空閒窗口辦理業務。

Commit廣播算法:一有commit完成,最新的SCN就廣播到所有節點中。

上述兩種算法可以通過調整初始化參數max_commit_propagation_delay來切換。在多數系統 (除了Compaq Tur64 Unix)中,該參數的默認值都是700釐秒(centisecond),採用Lamport算法。如果該值小於100釐秒,Oracle就採用廣播算法,並且記錄在alert.log文件中。

幾種重要的SCN

Commit SCN

當用戶提交commit命令後,系統將當前scn賦給該transaction。這些信息都反映在redo buffer中,並馬上更新到redo log 文件裏。

Offline SCN

除了System tablespace以外的任何表空間,當我們執行SQL>alter tablespace … offline normal命令時,就會觸發一個checkpoint,將內存中的dirty buffer寫入磁盤文件中。Checkpoint完成後,數據文件頭會更新checkpoint scnoffline normal scn值。其中數據庫文件頭的checkpoint scn值可通過查詢列x$kccfe.fecps得到。

如果執行SQL>alter tablespace …offline命令時採用temporary immediate選項,而不用normal選項時,offline normal scn會被設成0。這樣當數據庫重啓後通過resetlog方式打開時,該表空間就無法再改回在線狀態。

Checkpoint SCN

當數據庫內存的髒數據塊(dirty blocks)寫到各數據文件中時,就發生一次checkpoint。數據庫的當前checkpoint scn值存在x$kccdi.discn中。Checkpoint scn在數據庫恢復中起着至關重要的作用。無論你用何種辦法恢復數據庫,只有當各個數據庫文件的checkpoint scn都相同時,數據庫才能打開。

雖然參數“_allow_resetlogs_corruption”可以在checkpoint scn不一致時強制打開數據庫,但是這樣的數據庫在open後必須馬上作全庫的export,然後重建數據庫並import數據。

Resetlog SCN

數據庫不完全恢復時,在指定時間點後的scn都無法再應用到數據庫中。Resetlog時的scn就被設成當前數據庫scnredo log也會被重新設置。

Stop SCN

Stop scn記錄在數據文件頭上。當數據庫處在打開狀態時,stop scn被設成最大值0xffff.ffffffff。在數據庫正常關閉過程中,stop scn被設置成當前系統的最大scn值。在數據庫打開過程中,Oracle會比較各文件的stop scncheckpoint scn,如果值不一致,表明數據庫先前沒有正常關閉,需要做恢復。

High and Low SCN

OracleRedo log會順序紀錄數據庫的各個變化。一組redo log文件寫滿後,會自動切換到下一組redo log文件。則上一組redo loghigh scn就是下一組redo loglow scn

在視圖v$log_history中,sequence#代表redo log的序列號,first_change#表示當前redo loglow scn,列next_change#表示當前redo loghigh scn

 SQL> col recid format 9999

SQL> col requence# format 9999

SQL> col first_change# format 9,999,999,999,999

SQL> col next_change# format 9,999,999,999,999

SQL> select recid,sequence#,first_change#,next_change# from v$log_history where rownum<6;

RECID SEQUENCE# FIRST_CHANGE# NEXT_CHANGE#

----- ---------- ------------------ ------------------

484 484 1,928,645,840,091 1,928,645,840,436

485 485 1,928,645,840,436 1,928,645,840,636

486 486 1,928,645,840,636 1,928,778,045,209

487 487 1,928,778,045,209 1,929,255,480,725

488 488 1,929,255,480,725 1,930,752,214,033

關於如何使用參數_allow_resetlogs_corruption,可參見文檔http://www.sidibe.net/allow_resetlog.html

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