1、事務開始;
2、在buffer cache中找到需要的數據塊,如果沒有找到,則從數據文件中載入buffer cache中;
3、事務修改buffer cache的數據塊,該數據被標識爲“髒數據”,並被寫入log buffer中;
4、事務提交,LGWR進程將log buffer中的“髒數據”寫入redo log file中;
5、當發生checkpoint,CKPT進程更新所有數據文件的文件頭中的信息,DBWn進程則負責將Buffer Cache中的髒數據寫入到數據文件中。
Oracle對SCN的管理,分爲單節點和RAC兩種方式。
單節點的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 TIME
---------- --------------------------------
3056178 16-MAR-12 03.32.58.000000000 PM
TIMESTAMP_TO_SCN(SYSDATE)
-------------------------
3056200
Commit SCN
在一個事務提交後(上述第四個步驟),會在redo log中存在一條redo記錄,同時,系統爲其提供一個最新的SCN(通過函數dbms_flashback.get_system_change_number可以知道當前的最新SCN),記錄在該條記錄中。
Oracle的Redo log會順序紀錄數據庫的各個變化。一組redo log文件寫滿後,會自動切換到下一組redo log文件。則上一組redo log的high scn就是下一組redo log的low scn。
在視圖v$log_history中,sequence#代表redo log的序列號,first_change#表示當前redo log的low scn,列next_change#表示當前redo log的high 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
Offline SCN
除了System tablespace以外的任何表空間,當我們執行SQL>alter tablespace…offline normal命令時,就會觸發一個checkpoint,將內存中的dirty buffer寫入磁盤文件中。Checkpoint完成後,數據文件頭會更新checkpoint scn和offline normal scn值。其中數據庫文件頭的checkpoint scn值可通過查詢列x$kccfe.fecps得到。
如果執行SQL>alter tablespace…offline命令時採用temporary或immediate選項,而不用normal選項時,offline normal scn會被設成0。這樣當數據庫重啓後通過resetlog方式打開時,該表空間就無法再改回在線狀態。(resetlogs裏面還是有很多東西要學習和理解的)
Checkpoint SCN
當數據庫內存的髒數據塊(dirty blocks)寫到各數據文件中時,就發生一次checkpoint。數據庫的當前checkpoint scn值存在x$kccdi.discn中。Checkpoint scn在數據庫恢復中起着至關重要的作用。無論你用何種辦法恢復數據庫,只有當各個數據庫文件的checkpoint scn都相同時,數據庫才能打開。
雖然參數“_allow_resetlogs_corruption”可以在checkpoint scn不一致時強制打開數據庫,但是這樣的數據庫在open後必須馬上作全庫的export,然後重建數據庫並import數據。
SCN號與oracle數據庫恢復過程有着密切的關係,只有很好地理解了這層關係,才能深刻地理解恢復的原理,從而才能很好地解決這方面的問題。
SCN與CHECKPOINT
CKPT進程在checkpoint發生時,將當時的SCN號寫入所有非只讀數據文件頭(無論redo log中的數據是否影響到該數據文件)和同時將控制文件中的System Checkpoint SCN(通過視圖v$database的字段checkpoint_change#可以查詢)、每個數據文件對應的Datafile Checkpoint(通過視圖v$datafile的字段checkpoint_change#可以查詢),同時通知DBWR進程將數據塊寫到數據文件。
CKPT進程也會在控制文件中記錄RBA(redo byte address),以標誌Recovery需要從日誌中哪個地方開始。
這四個分別是:
1.System Checkpoint SCN
當checkpoint完成後,ORACLE將System Checkpoint SCN號存放在控制文件中。我們可以通過下面SQL語句查詢:
select checkpoint_change# from v$database;
2.Datafile Checkpoint SCN
當checkpoint完成後,ORACLE將Datafile Checkpoint SCN號存放在控制文件中。我們可以通過下面SQL語句查詢所有數據文件的Datafile Checkpoinnt SCN號。
select name,checkpoint_change# from v$datafile;
3.Start SCN號
ORACLE將Start SCN號存放在數據文件頭中。
這個SCN用於檢查數據庫啓動過程是否需要做Media Recovery.
我們可以通過以下SQL語句查詢:
select name,checkpoint_change# from v$datafile_header;
4.End SCN (Stop SCN)號
ORACLE將End SCN號存放在控制文件中。
這個SCN號用於檢查數據庫啓動過程是否需要做Instance Recovery.
我們可以通過以下SQL語句查詢:
select name,last_change# from v$datafile;
在數據庫正常運行的情況下,對可讀寫的,online的數據文件,該SCN號爲NULL.
我們作個小的試驗,內容如下:
在執行檢查點進程之前SCN號如下:
System Checkpoint scn:
CHECKPOINT_CHANGE#
------------------
3053495
Datafile Checkpoint scn:
NAME CHECKPOINT_CHANGE#
------------------------------------------------------ ---------------------------------
/opt/app/oracle/oradata/orcl/system01.dbf 3053495
/opt/app/oracle/oradata/orcl/sysaux01.dbf 3053495
/opt/app/oracle/oradata/orcl/users01.dbf 3053495
/home/oracle/dpump/part1.dbf 3031971
Start SCN:
------------------------------------------------------ ---------------------------------
/opt/app/oracle/oradata/orcl/system01.dbf 3053495
/opt/app/oracle/oradata/orcl/sysaux01.dbf 3053495
/opt/app/oracle/oradata/orcl/users01.dbf 3053495
/home/oracle/dpump/part1.dbf 3031971
SQL>select name,last_change# from v$datafile;
------------------------------------------------------ ---------------------------------
/opt/app/oracle/oradata/orcl/system01.dbf
/opt/app/oracle/oradata/orcl/sysaux01.dbf
/opt/app/oracle/oradata/orcl/users01.dbf
/home/oracle/dpump/part1.dbf 3031971
執行alter system checkpoint。後的SCN號如下:
System Checkpoint SCN:
CHECKPOINT_CHANGE#
------------------
3055942
Datafile Checkpoint SCN :
NAME CHECKPOINT_CHANGE#
/opt/app/oracle/oradata/orcl/system01.dbf 3055942
/opt/app/oracle/oradata/orcl/sysaux01.dbf 3055942
Start SCN:
SQL>select name,checkpoint_change# from v$datafile_header;
/opt/app/oracle/oradata/orcl/system01.dbf 3055942
/opt/app/oracle/oradata/orcl/sysaux01.dbf 3055942
End SCN :
------------------------------------------------------ ---------------------------------
/opt/app/oracle/oradata/orcl/system01.dbf
/opt/app/oracle/oradata/orcl/sysaux01.dbf
/opt/app/oracle/oradata/orcl/users01.dbf
/home/oracle/dpump/part1.dbf 3031971
這三個SCN在表空間處於只讀期間都將被凍結。
SCN不連續原因可能如下:
1.當發生日誌組切換的時候
2.當符合LOG_CHECKPOINT_TIMEOUT,LOG_CHECKPOINT_INTERVAL,fast_start_io_target,fast_start_mttr_target參數設置的時候
3.當運行ALTER SYSTEM SWITCH LOGFILE的時候
4.當運行ALTER SYSTEM CHECKPOINT的時候
5.當運行alter tablespace XXX begin backup,end backup的時候
6.當運行alter tablespace ,datafile offline的時候;
6.SCN號與數據庫啓動
第一步:在數據庫啓動過程中,檢查System Checkpoint SCN、Datafile Checkpoint SCN和Start SCN號都相同時,如果相同數據庫可以正常啓動,不需要做media recovery.三者當中有一個不同時,則需要做media recovery。
7.SCN號與數據庫關閉
數據庫在正常關閉(shutdown immediate/normal)時,會先做一次checkpoint,將log file中的數據寫入數據文件中,將控制文件、數據文件中的SCN(包括控制文件中的Stop SCN)都更新爲最新的SCN。數據庫異常/意外關閉不會或者只更新部分Stop SCN。
在理解和學習resetlog的時候,SCN還是會用到的!!