Oracle System Change Number (SCN) Number 完全筆記
SCN是當Oracle資料更新後,由DBMS自動維護去累積遞增的一個數字。 當一個交易commit時,LGWR會將log buffer寫入redo log file,同時也會將該筆交易的 SCN同步寫入到redo log file內(wait-until-completed)。因此當你commit transaction時, 在交易成功的訊息返回之前,LGWR必須先完整的完成上述行為之後,否則你是看不到提交成功的回應訊息。 |
我們可以查詢目前系統最新的SCN select dbms_flashback.get_system_change_number from dual; 可以理解的,這裡返回的SCN,也是目前redo log file最新的SCN紀錄。 因為commit後的交易才會有SCN,而一旦commit就會立刻寫入redo log file中。 CHECKPOINT 和 SCN 的關連 checkpoint發生的目的就是要把儲存在buffer內的已提交交易寫回disk,否則一旦發生crash,需要 進行recovery時,你就必須花很多的時間從redo log file內最後的SCN交易開始進行recovery,這樣 在商業應用上是很浪費時間和沒有效率的。 重點在於當commit一個交易時,只會立刻將redo buffer寫入redo log file內,但是並不會馬上將 該update後的block(dirty block)同步寫回disk datafile中,這是為了減少過多disk IO的考量,所以採取batch的方式寫入。 When a checkpoint occurs, Oracle must update the headers of all datafiles to record the details of the checkpoint. This is done by the CKPT process. The CKPT process does not write blocks to disk; DBWn always performs that work. 在shutdown normal or shutdown immediate下,也就是所謂的clean shutdown,checkpoint也會自動觸發,並且把SCN紀錄寫回。 當發生checkpoint時,會把SCN寫到四個地方去。三個地方於control file內,一個在datafile header。 Control file三個地方為 1.System checkpoint SCN ===========> (SYSTEM CHECKPOINT SCN in control file) SQL> select checkpoint_change# from v$database; CHECKPOINT_CHANGE# 2.Datafile checkpoint SCN ===============> (DATAFILE CHECKPOINT SCN in control file) SQL> select name,checkpoint_change# NAME CHECKPOINT_CHANGE# 3.Stop SCN ======================> (STOP SCN in control file) SQL> select name,last_change# NAME LAST_CHANGE# 正常datafile在read-write mode咦饗攏琇ast_change#一定是NULL 另外一個地方在datafile header內 4.Start SCN ================================> (DATAFILE HEADER) SQL> select name,checkpoint_change# NAME CHECKPOINT_CHANGE# 為什麼儲存在CONTROL FILE中要分為兩個地方(SYSTEM CHECKPOINT SCN,DATAFILE CHECKPOINT SCN ?) 當你把一個tbs設為read-only時,他的SCN會凍結停止,此時DATAFILE CHECKPOINT SCN是不會再遞增改變的, 但是整體的SYSTEM CHECKPOINT SCN卻仍然會不斷遞增前進。 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 正常shutdown database後,SCN會發生什麼變化? 我們可以把資料庫開在mount mode select checkpoint_change# from v$database; CHECKPOINT_CHANGE# select name,checkpoint_change#,last_change# from v$datafile where name like '%user%'; NAME CHECKPOINT_CHANGE# LAST_CHANGE# 可以看到儲存在control file中的三個SCN位置都是相同,注意此時的stop scn不會是NULL,而是等於start scn 我們也來查詢datafile header SCN: select name,checkpoint_change# from v$datafile_header where name like '%users01%'; NAME CHECKPOINT_CHANGE# 當clean shutdown 時,checkpoint會進行,並且此時datafile的stop scn和start scn會相同。 等到我門開啟資料庫時,Oracle檢查datafile header中的start scn和存於control file中的datafile的scn是否相同, 如果相同,接著檢查start scn和stop scn是否相同,如果仍然相同,資料庫就會正常開啟,否則就需要recovery... 等到資料庫開啟後,儲存在control file中的stop scn就會恢復為NULL值,此時表示datafile是open在正常模式下了。 如果不正常SHUTDOWN (shutdown abort),則mount資料庫後,你會發現stop scn並不是等於其他位置的scn, 而是等於NULL,這表示Oracle在shutdown時沒有進行checkpoint,下次開機必須進行crash recovery。 crash recovery 必須先進行roll forward(從redo log file中從目前的start SCN開始,重做後面的已提交之交易) 檢驗controlfile中的SCN會等於datafile header的SCN select 'controlfile' "SCN location",name,checkpoint_change# SCN location NAME CHECKPOINT_CHANGE#
crash recovery vs media recovery 啟動資料庫時,如果發現STOP SCN = NULL,表示需要進行crash recovery;啟動資料庫時,如果發現有datafile header的START SCN 不等於儲存於CONTROLFILE的DATAFILE SCN,表示需要進行Media recovery STOP SCN equal NULL ==> NEED CRASH RECOVERY RECOVERY DATABASE 兩種常見問題 1) RECOVER DATABASE UNTIL CANCEL ==> OPEN DATABASE RESETLOG ==> DATAFILE HEADER SCN一定會小於CONTROLFILE的DATAFILE SCN 如果你有進行RESTORE DATAFILE,則該RESTORE的DATAFILE HEADER SCN一定會小於目前CONTROLFILE的DATAFILE SCN,此時會無法 restore datafile後,可以mount database然後去檢查controlfile and datafile header的SCN select 'controlfile' "SCN location",name,checkpoint_change# SCN location NAME CHECKPOINT_CHANGE# 2) RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE; ===> OPEN DATABASE RESETLOG ==> DATAFILE HEADER SCN一定會大於CONTROLFILE的DATAFILE SCN 如果只是某TABLE被DROP掉,沒有破壞資料庫整體資料結構,還可以用INCOMPLETE RECOVERY解決 如果是某個TABLESPACE OR DATAFILE被DROP掉,因為檔案結構已經破壞,目前的CONTROL FILE內已經沒有 該DATAFILE的資訊,就算你只RESTORE DATAFILE然後進行INCOMPLETE RECOVERY也無法救回被DROP的DATA FILE。 只好RESOTRE 之前備份的CONTROL FILE(裡頭被DROP DATAFILE Metadata此時還存在),不過RESTOREC CONTROL FILE後 此時Oracle會發現CONTROL FILE內的SYSTEM SCN會小於目前的DATAFILE HEADER SCN,也不等於目前儲存於LOG FILE內的SCN, 此時就必須使用RECOVER DATABASE UNTIL CANCEL USING BACKUP CONTROLFILE到DROP DATAFILE OR DROP TABLESPACE之前的SCN。
|
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-84849/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- LeetCode - 解題筆記 - 8 - Palindrome NumberLeetCode筆記
- leetcode學習筆記09 palindrome-numberLeetCode筆記
- ORACLE NUMBER資料型別Oracle資料型別
- How Oracle Store Number internal(zt)Oracle
- 解決 Error: ENOSPC: System limit for number of file watchers reachedErrorMIT
- Oracle實驗(03):number的使用Oracle
- Oracle的number資料型別Oracle資料型別
- Oracle中rownum和row_number()Oracle
- 【NUMBER】Oracle資料庫最佳化之理解NUMBER儲存機制Oracle資料庫
- mysql 啟動錯誤(InnoDB: Operating system error number 13 )MySqlError
- 10_深入解析Oracle number資料型別及os層number解析工具分享Oracle資料型別
- JavaScript Number()JavaScript
- 【Oracle】ORA-23421: job number XXXX is not a job in the job queueOracle
- Kata:Hamming number
- JavaScript Number toLocaleString()JavaScript
- JavaScript Number toString()JavaScript
- Number.NaNNaN
- JavaScript Number 物件JavaScript物件
- Leetcode Number of islandsLeetCode
- [20190930]oracle raw型別轉化number指令碼.txtOracle型別指令碼
- Python3學習筆記1,基本資料型別-Number、strPython筆記資料型別
- Oracle:SCNOracle
- Perfect Number 完美數
- [LeetCode] Third Maximum NumberLeetCode
- [LeetCode] Find the Duplicate NumberLeetCode
- Leetcode 9 Palindrome NumberLeetCode
- Number.parseInt() 方法
- Number.parseFloat()方法
- Number.isSafeInteger()方法
- Number.isNaN()方法NaN
- Number.isFinite()方法
- Js中的NumberJS
- Number.POSITIVE_INFINITY
- Number.ATIVE_INFINITY
- Big Number hd 1212
- 7.104 ITERATION_NUMBER
- Leetcode 447 Number of BoomerangsLeetCodeOOM
- react input[type='number']React
- number(p,s)(轉)