深入瞭解SCN(轉)

zhouwf0726發表於2019-05-29

深入瞭解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


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756652/viewspace-242160/,如需轉載,請註明出處,否則將追究法律責任。

相關文章