大片播放網(wǎng)站seo百度發(fā)包工具
SCN可以說是Oracle中一個很基礎的部分,但同時它也是一個很重要的。它是系統(tǒng)中維持數(shù)據(jù)的一致性和順序恢復的重要標志,是數(shù)據(jù)庫非常重要的一種數(shù)據(jù)結構。
轉載:深入剖析 - Oracle SCN機制詳細解讀 - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/31446957
SCN介紹
SCN即系統(tǒng)改變號(System Change Number),是在某個時間點定義數(shù)據(jù)庫已提交版本的時間戳標記。 Oracle為每個已提交的事務分配一個唯一的SCN。 SCN的值是對數(shù)據(jù)庫進行更改的邏輯時間點。 Oracle使用此編號記錄對數(shù)據(jù)庫所做的更改。在數(shù)據(jù)庫中,SCN也可以說是無處不在,數(shù)據(jù)文件頭,控制文件,數(shù)據(jù)塊頭,日志文件等等都標記著SCN。也正是這樣,數(shù)據(jù)庫的一致性維護和SCN密切相關。不管是數(shù)據(jù)的備份,恢復都是離不開SCN的。
SCN是一個6字節(jié)(48bit)的數(shù)字,其值為281,474,976,710,656(2^48),分為2個部分:
SCN_BASE是一個4字節(jié)(32bit)的數(shù)字
SCN_WRAP是一個2字節(jié)(16bit)的數(shù)字
每當SCN_BASE達到其最大值(2^32 = 4294967296)時,SCN_WRAP增加1,SCN_BASE將被重置為0,一直持續(xù)到SCN_WRAP達到其最大值,即2^16 = 65536。
SCN?=(SCN_WRAP * 4294967296)+ SCN_BASE
SCN隨著每個事務的完成而增加。提交不會寫入數(shù)據(jù)文件,也不更新控制文件。當發(fā)生checkpoint時,控制文件更新,SCN被寫入到控制文件。
當前的SCN可以通過以下查詢獲得:
select dbms_flashback.get_system_change_number scn from dual;
select current_scn from v$database;
四種重要的SCN
在理解這幾種SCN之前,我們先看下oracle事務中的數(shù)據(jù)變化是如何寫入數(shù)據(jù)文件的:
第一步:事務開始;
第二步:在buffer cache中找到需要的數(shù)據(jù)塊,如果沒找到,從數(shù)據(jù)文件中載入buffer cache中;
第三步:事務修改buffer cache的數(shù)據(jù)塊,該數(shù)據(jù)被標識為“臟數(shù)據(jù)”,并被寫入log buffer中;
第四步:事務提交,LGWR進程將log buffer中的“臟數(shù)據(jù)”的日志條目寫入redo log file中;
第五步:當發(fā)生checkpoint,CKPT進程更新所有數(shù)據(jù)文件的文件頭中的信息,DBWn進程則負責將Buffer Cache中的臟數(shù)據(jù)寫入到數(shù)據(jù)文件中。
經過上述5個步驟,事務中的數(shù)據(jù)變化最終被寫入到數(shù)據(jù)文件中。但是,一旦在上述中間環(huán)節(jié)數(shù)據(jù)庫意外宕機了,在重新啟動時如何知道哪些數(shù)據(jù)已經寫入數(shù)據(jù)文件、哪些沒有寫呢?(同樣,在DG、streams中也存在類似疑問:redolog中哪些是上一次同步已經復制過的數(shù)據(jù)、哪些沒有)
SCN機制就能比較完善的解決上述問題。 SCN是一個數(shù)字,確切的說是一個只會增加、不會減少的數(shù)字。正是它這種只會增加的特性確保了 Oracle知道哪些應該被恢復、哪些應該被復制。
總共有4種SCN:
系統(tǒng)檢查點(System Checkpoint)SCN
數(shù)據(jù)文件檢查點(Datafile Checkpoint)SCN
結束SCN(Stop SCN)
開始SCN(Start SCN)
(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語句查詢所有數(shù)據(jù)文件的Datafile Checkpoinnt SCN。
select name,checkpoint_change# from v$datafile;
(3)Start SCN
Oracle將StartSCN存放在數(shù)據(jù)文件頭中。這個SCN用于檢查數(shù)據(jù)庫啟動過程是否需要做media recovery。我們可以通過以下SQL語句查詢:
select name,checkpoint_change# from v$datafile_header;
(4)Stop SCN
ORACLE將StopSCN存放在控制文件中。這個SCN號用于檢查數(shù)據(jù)庫啟動過程是否需要做instance recovery。我們可以通過以下SQL語句查詢:
select name,last_change# from v$datafile;
在數(shù)據(jù)庫正常運行的情況下,對可讀寫的online數(shù)據(jù)文件,該SCN號為NULL。
SCN與數(shù)據(jù)庫啟動:
在數(shù)據(jù)庫啟動過程中,當System Checkpoint SCN、Datafile Checkpoint SCN和Start SCN都相同時,數(shù)據(jù)庫可以正常啟動,不需要做media recovery。三者當中有一個不同時,則需要做media recovery.如果在啟動的過程中,End SCN為NULL,則需要做instance recovery。Oracle在啟動過程中首先檢查是否需要media recovery,然后再檢查是否需要instance recovery。
SCN與數(shù)據(jù)庫關閉:
如果數(shù)據(jù)庫的正常關閉的話,將會觸發(fā)一個checkpoint,同時將數(shù)據(jù)文件的END SCN設置為相應數(shù)據(jù)文件的Start SCN。當數(shù)據(jù)庫啟動時,發(fā)現(xiàn)它們是一致的,則不需要做instance recovery。在數(shù)據(jù)庫正常啟動后,ORACLE會將END SCN設置為NULL.如果數(shù)據(jù)庫異常關閉的話,則END SCN將為NULL。
Q&A
Q
為什么ORACLE在控制文件中記錄System checkpoint SCN 號的同時,還需要為每個數(shù)據(jù)文件記錄DatafileCheckpoint SCN?
A
如果有表空間read only,那么該表空間的所有datafile的start SCN和stop SCN將被凍結,這個時候就跟System Checkpoint SCN不一致,但在庫open的時候是不需要做media recovery的,如果沒有DatafileCheckpoint SCN就無法判斷這些datafile是否是最新的。
可能遇到的SCN問題
首選我們看幾個跟SCN有關的概念:
Reasonable SCNLimit(RSL)
RSL = (當前時間 - 1988年1月1日)*24*3600*SCN每秒最大可能增長速率
也就是從1988年1月1日開始,假如SCN按最大速率增長,當天理論上的最大值。
最大增長速率:在11.2.0.2之前是16384,在11.2.0.2及之后版本是32768
在11.2.0.2版本之后由_max_reasonable_scn_rate參數(shù)控制
該參數(shù)不建議修改。
SCN Headroom
Headroom(天) = (Reasonable SCN Limit -CurrentSCN)/ SCN每秒最大可能增長速率/3600/24
也就是如果SCN按最大速率增長,達到當前理論最大值需要的天數(shù)。這個值可以用來判斷SCN增長速率是否過快。
那么,SCN Headroom如果獲取呢?
參考MOS: Bug 13498243 -"scnhealthcheck.sql" script (文檔 ID 13498243.8),打上該BUG的patch之后,將在$ORACLE_HOME/rdbms/admin中增加scnhealthcheck.sql文件,該文件就是用來檢查SCN是否正常。
另外還有一篇MOS文檔,專門對該腳本的輸出做了解釋。即Installing, Executing and Interpreting output from the"scnhealthcheck.sql" script (文檔 ID 1393363.1)。
執(zhí)行該腳本,結果如下:
這個結果我們仍然無法得到該數(shù)據(jù)庫的具體SCN Headroom,下面這個SQL是從scnhealthcheck.sql中找到的,可以直接查到SCN Headroom的值(indicator字段)。
Q&A
Q
針對上面的查詢結果,是不是意味著過1647天之后,SCN就將達到最大值?
A
不會,因為1647天之后,Current SCN會變大,Reasonable SCN Limit同樣也會變大,正常情況下,SCNHeadroon只會變大不會變小。
SCN headroom過小的問題
如果SCN正常增長,達到最大值大約可以用500年,SCN headroom的值也會隨著時間的推移慢慢變大,但是可能由于BUG、用特殊手段人為調整、dblink傳播導致SCN增長出現(xiàn)異常。但如果出現(xiàn)SCN headroom過小,alert log會出現(xiàn)警告:Warning: The SCN headroom for this database is only NN days!
原因定位:
1. 通過下面這篇文檔里提供的腳本,該腳本類似于創(chuàng)建AWR,可以按snap_id對dba_hist_sysstat里的某個stat_name做統(tǒng)計,我們這里的Stat_name選擇calls to kcmgas。
How to Extract the Historical Values of aStatistic from the AWR Repository (文檔 ID 948272.1)
2. 通過查詢V$ARCHIVED_LOG單位時間內scn變化
3. 通過上面兩個方式得出的結果分析,如果是非持續(xù)突發(fā)增長,認為很可能是通過dblink引起;
4. 同時比較awr報告中“callsto kcmgas” 和“user commits”,如果user commits也是高速增長,很可能是自身引起;
kcmgas是Oracle分配scn的函數(shù),在一個空庫上做測試,可以看出每分配一次scn,calls to kcmgas的統(tǒng)計增加1,所以calls to kcmgas的量可以作為scn的增長量來分析。
ORA-19706: Invalid SCN錯誤
[1376995.1]里的介紹,在2012年1月CPU或PSU里增加_external_scn_rejection_threshold_hours參數(shù),11.2.0.2及以后的版本,默認為1天即24小時,其他版本默認為31天即744小時,相當于把拒絕外部SCN連接的閾值調大了,因而更加容易引發(fā)ORA-19706錯誤。該參數(shù)對數(shù)據(jù)庫自身產生的SCN遞增沒有影響。Bug 13554409 - Fix for bug13554409 [ID 13554409.8]的里對該問題也有介紹。
ORA-19706錯誤:最常見的就是拒絕dblink連接的時候,如A庫跟B庫通過dblink連接,A的SCN有通過人為調整增大許多,連接B庫的時候,Oracle會判斷該SCN傳播過來之后,如果會導致SCN headroom小于_external_scn_rejection_threshold_hours設置的閾值,則拒絕連接
相關參考:SCN、ORA-19706錯誤和_external_scn_rejection_threshold_hours參數(shù)
如果打完2012年1月CPU或PSU后遇到ORA-19706錯誤,對于以下這些版本的數(shù)據(jù)庫:
Oracle 10.2.0.5
Oracle 11.1.0.7
Oracle 11.2.0.2
Oracle 11.2.0.3
oracle建議給數(shù)據(jù)庫安裝2012年4月發(fā)布的PSU,并在安裝該PSU的基礎上,安裝補丁13916709。如果是集群架構,同時給集群軟件最新安裝PSU。參數(shù)_external_scn_rejection_threshold_hours在2012年4月(包含2012年4月)以后發(fā)布的PSU/CPU中,11.2.0.2及以后的版本,是1天即24小時,其他版本是31天即744小時。其他版本:先升級到高版本,再按照上面的方法處理。
總結
如果發(fā)現(xiàn)SCN有異常,需要及時通過上述方法來打上最新的PSU,同時盡量少用DBLINK,從系統(tǒng)設計角度來講也是不推薦這種系統(tǒng)間強耦合的設計。