SCN Headroom与时光倒流到1988年的Oracle数据库
生活随笔
收集整理的這篇文章主要介紹了
SCN Headroom与时光倒流到1988年的Oracle数据库
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
最近一陣關(guān)于scn headroom的討論很熱,? 這是由于在最新的2012 Apr的PSU中例如10.2.0.5上的PSU 13632743和 patch? 13916709: SCN: HIGH CALLS TO KCMGAS AFTER APPLYING SCN PATCHES 中引入了對scn增長過快的FIX修復(fù)。 Oracle SCN(System Change Number)也叫做系統(tǒng)變更號,Oracle中的Commit操作與SCN緊密相關(guān)。 引入SCN的最根本目的在于: 為讀一致性所用 為redolog中的記錄排序,以及恢復(fù) ? ? SCN由SCN Base和Scn Wrap組成,是一種6個字節(jié)的結(jié)構(gòu)(structure)。其中SCN Base占用4個字節(jié),而SCN wrap占用2個字節(jié)。但在實際存儲時SCN-like的stucture常會占用8個字節(jié)。 ? ub4 kscnbas
ub2 kscnwrpstruct kcvfhcrs, 8 bytes???????????????? @100????????????????????????????? Creation Checkpointed at scn
ub4 kscnbas??????????????????????? @100????? 0x000a8849????????????? www.oracledatabase12g.com
ub2 kscnwrp??????????????????????? @104????? 0x0000 ? ? 當(dāng)事務(wù)提交COMMIT時,需要完成第一個操作就是得到一個SCN值。 ? SCN是Oracle數(shù)據(jù)庫內(nèi)部的一種邏輯時間戳,通過SCN將數(shù)據(jù)庫內(nèi)的事件理清次序, 這是保證事務(wù)屬性ACID的必要信息。 ? 數(shù)據(jù)庫使用SCN來幫助實現(xiàn)查詢和跟蹤變化。舉例來說,當(dāng)一個事務(wù)更新一行數(shù)據(jù),那么數(shù)據(jù)庫就需要將該update發(fā)生時的SCN記錄下來,該事務(wù)(transaction)中的其他修改操作通常都會使用同樣的SCN。當(dāng)一個事務(wù)commit提交,數(shù)據(jù)庫又會相應(yīng)地記錄提交時的SCN。 多個事務(wù)同事commit可能會共享同一個SCN。 ? SCN總是單調(diào)遞增的序列, Oracle數(shù)據(jù)庫最大可以使用到的SCN上限值是一個天文數(shù)字,目前該上限是281萬億,即281,474,976,710,656(2的48次方)。這是對SCN的硬限制,理論上一個數(shù)據(jù)庫的SCN總是不能超過281萬億, 以每秒16K的增速計算,花費557年SCN上限才會被耗盡,作為一個hard limit ,我們很少有機會觸及。 ? 除了281萬億的hard limit外, Oracle數(shù)據(jù)庫還存在一種 soft limit 即SCN headroom, 為了保證SCN的增長速度不要過于離譜,Oracle使用了一種基于時間的限量供應(yīng)SCN的系統(tǒng)。 ? 關(guān)于headroom ,字典翻譯頭上空間, 實際你可以理解為 在一個房間內(nèi) 天花板和 頭部之間的空間, 數(shù)據(jù)庫的Current SCN就是你頭部的高度,那么(房間高度-頭部高度)=headroom, 在任何時間點上,Oracle數(shù)據(jù)庫均會計算一個當(dāng)前時間點DB 不能超過的SCN LIMIT上限, 注意這里提到了時間點 ,通俗點說這個SCN LIMIT是隨著時間流逝在增加的。 Oracle計算的算法基于從1988年到當(dāng)前時間點的秒數(shù),再乘上16,384(16k),用SQL表達就如以下語句: ? ? select
(((to_number(to_char(sysdate,'YYYY'))-1988)*12*31*24*60*60) +
((to_number(to_char(sysdate,'MM'))-1)*31*24*60*60) +
--www.oracledatabase12g.com
(((to_number(to_char(sysdate,'DD'))-1))*24*60*60) +
(to_number(to_char(sysdate,'HH24'))*60*60) +
(to_number(to_char(sysdate,'MI'))*60) +
(to_number(to_char(sysdate,'SS'))))*16384 from dual; ? ? ? 變化下公式就是 ?? (current_time-1988)?????? *?? ?16384 - (current_scn) = headroom。 1988到當(dāng)前時間的秒數(shù)?? *??? 16384 -? 當(dāng)前SCN 即SCN headroom是 當(dāng)前SCN 和(1988年到當(dāng)前時間的秒數(shù)*??? 16384)之間的差距。 ? 通過將SCN的增長率和時間流逝關(guān)聯(lián)起來,確保SCN的限量增長,保證Oracle數(shù)據(jù)庫理論上可以處理500年的數(shù)據(jù)。 ? ? 通過以上公式我們可以發(fā)現(xiàn)SCN每秒的合理增長量為16,384,然而Oracle公司在近年發(fā)現(xiàn)某些軟件層面的BUG會導(dǎo)致數(shù)據(jù)庫試圖超過或接近這個當(dāng)前時間點的SCN 最大值。 常規(guī)情況下,若數(shù)據(jù)庫嘗試超過當(dāng)前的SCN最大值,數(shù)據(jù)庫將會cancel取消掉引發(fā)該超越事件的事務(wù), 在應(yīng)用程序?qū)用鎸⒖吹揭粋€錯誤。在接下來的一秒鐘,上限值會隨著時間而增長16k,因此通常應(yīng)用程序會在短暫停頓后繼續(xù)工作。 但是在極少數(shù)情況下,數(shù)據(jù)庫可能需要為了保護自身的完整性而shutdown關(guān)閉,理論上不會造成數(shù)據(jù)丟失或corrupted。 ? 類似于計算機網(wǎng)絡(luò)中的時鐘同步,當(dāng)2個數(shù)據(jù)庫通過DBLINK相互交流訪問時,他們會選用2者中當(dāng)前Current SCN最大的一個來同步SCN, 譬如說數(shù)據(jù)庫A 的SCN 是10000,而數(shù)據(jù)庫B是20000,當(dāng)2者發(fā)生DBLINK聯(lián)系時,將會用最大的SCN (20000)來同步,數(shù)據(jù)庫A的SCN將jump跳躍到20000。 在一些環(huán)境中,往往不是本地數(shù)據(jù)庫觸發(fā)了SCN快速增長的bug,而是眾多數(shù)據(jù)庫中的某一個存在活躍的SCN BUG,而其他數(shù)據(jù)庫與該問題數(shù)據(jù)庫發(fā)生DBLINK聯(lián)系后,就會因為SCN同步而經(jīng)歷 SCN headroom的的極速減少; 換句話說就是一只老鼠壞了一鍋湯,異常高的SCN會通過DBLINK傳播給正常的數(shù)據(jù)庫,這種傳播往往呈爆炸式發(fā)展。 由于數(shù)據(jù)庫總是會拒絕SCN超過當(dāng)前的SCN上限,所以O(shè)racle官方宣稱Oracle數(shù)據(jù)庫理論運行500年的SCN預(yù)備量不會受以上問題的影響。 但是受到傳播的數(shù)據(jù)庫仍可能由于自我保護的原因而宕機。 ? Oracle官方宣布所有與SCN headroom相關(guān)的bug均已在January 2012 CPU 和相關(guān)的PSU中修復(fù)了, 同樣的修復(fù)補丁也被包含在DB Patchset Update (PSU) 以及最新的Exadata和Windows的Bundle Patch上。 ? ? 有一些客戶糾結(jié)于他們的SCN接近于當(dāng)前SCN最大值,且SCN的增長量遠大于他們處理數(shù)據(jù)庫的合理值。在所有這些cases中Oracle 發(fā)現(xiàn)均是January 2012 CPU 中已經(jīng)修復(fù)bug的現(xiàn)象,在客戶實施這些修復(fù)后SCN headroom 開始有效增長了。 ? 為了保證系統(tǒng)不出現(xiàn)潛在的問題,用戶可以運行Metalink Note"Installing, Executing and Interpreting output from the "scnhealthcheck.sql" script [ID 1393363.1]"中包含的腳本scnhealthcheck.sql來檢查特定數(shù)據(jù)庫的當(dāng)前SCN距離當(dāng)前SCN 最大值有多少差距。該腳本會警告用戶該數(shù)據(jù)庫接近于當(dāng)前SCN的最大上限,在這種情況下建議立即對受影響數(shù)據(jù)庫實施CPU/PSU補丁。實施以上補丁后的預(yù)期結(jié)果是SCN headroom有效增長,官方宣稱在所有case中都如預(yù)期一樣。 ? Oracle推薦盡可能客戶盡可能快地APPLY CPU補丁以處理最新發(fā)現(xiàn)的安全問題。 ? 從長遠來看Oracle會在今后的版本或補丁中將SCN的hard limit從281萬億 提高到一個更高數(shù)字。 ? 你肯定好奇于為什么這里要使用 1988年到當(dāng)前時間的秒數(shù),1988這個年份有什么意義? ? ? 我們來看看Oracle數(shù)據(jù)庫中的1988: ? [oracle@vrh8 ~]$ strings $ORACLE_HOME/bin/oracle > oracle.log
[oracle@vrh8 ~]$ grep 1988? oracle.log
1988
xsaggr.c:1988
Version: %d {0 = 1988 }SQL>
SQL> select? * from v$version;BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE??? 10.2.0.5.0????? Production
TNS for Linux: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - ProductionSQL> select * from global_name;GLOBAL_NAME
--------------------------------------------------------------------------------
www.oracledatabase12g.comSQL> oradebug setmypid;
Statement processed.
SQL> oradebug dump controlf 4
Statement processed.
SQL> oradebug tracefile_name;
/s01/admin/G10R25/udump/g10r25_ora_9823.trcTHREAD #1 - status:0x2 flags:0x0 dirty:252
low cache rba:(0xe.7742.0) on disk rba:(0xe.7b44.0)
on disk scn: 0x0000.002d4ac2 06/03/2012 10:03:34
resetlogs scn: 0x0000.00294b33 05/22/2012 11:33:28
heartbeat: 784994177 mount id: 2670678794
THREAD #2 - status:0x0 flags:0x0 dirty:0
low cache rba:(0x0.0.0) on disk rba:(0x0.0.0)
on disk scn: 0x0000.00000000 01/01/1988 00:00:00
resetlogs scn: 0x0000.00000000 01/01/1988 00:00:00
heartbeat: 0 mount id: 0
THREAD #3 - status:0x0 flags:0x0 dirty:0
low cache rba:(0x0.0.0) on disk rba:(0x0.0.0)
on disk scn: 0x0000.00000000 01/01/1988 00:00:00
resetlogs scn: 0x0000.00000000 01/01/1988 00:00:00
heartbeat: 0 mount id: 0
THREAD #4 - status:0x0 flags:0x0 dirty:0
low cache rba:(0x0.0.0) on disk rba:(0x0.0.0)
on disk scn: 0x0000.00000000 01/01/1988 00:00:00
resetlogs scn: 0x0000.00000000 01/01/1988 00:00:00
heartbeat: 0 mount id: 0
THREAD #5 - status:0x0 flags:0x0 dirty:0
low cache rba:(0x0.0.0) on disk rba:(0x0.0.0)
on disk scn: 0x0000.00000000 01/01/1988 00:00:00
resetlogs scn: 0x0000.00000000 01/01/1988 00:00:00
heartbeat: 0 mount id: 0
THREAD #6 - status:0x0 flags:0x0 dirty:0
low cache rba:(0x0.0.0) on disk rba:(0x0.0.0)
on disk scn: 0x0000.00000000 01/01/1988 00:00:00
resetlogs scn: 0x0000.00000000 01/01/1988 00:00:00***************************************************************************
DATA FILE RECORDS
***************************************************************************
(size = 428, compat size = 428, section max = 100, section in-use = 8,
last-recid= 421, old-recno = 0, last-recno = 0)
(extent = 1, blkno = 11, numrecs = 100)
DATA FILE #1:
(name #10) /s01/oradata/G10R25/datafile/o1_mf_system_7ch7d4mn_.dbf
creation size=0 block size=8192 status=0xe head=10 tail=10 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:418 scn: 0x0000.002d2072 06/03/2012 03:41:16
Stop scn: 0xffff.ffffffff 05/24/2012 09:51:21
Creation Checkpointed at scn:? 0x0000.00000007 04/20/2010 08:24:26 ? 1988年為什么如此重要? ? 在1988年發(fā)布了Oracle V6,首次實現(xiàn)了行級鎖定,首次實現(xiàn)了數(shù)據(jù)庫熱備份,Oracle公司從Belmont移到加利福尼亞的redwood? shores,并引入了PL/SQL。 ? 我相信目前使用版本7-11g? 仍沿用了大量的V6的代碼,V6的代碼中做了大量DEFINE的工作,這大概是一切的開始。 這就好像是"And God said, Let there be light"! ? ? Technical Data and Computer Software (October 1988) 這個所有權(quán)著名,你可以在很多Oracle的早起文檔上找到。 ? 你肯定又要問 , 我們可以在1988年之前運行Oracle V6以后的程序嗎? 假設(shè)我們獲得了時光機,拿著Oracle 10.2.0.5回到1988年前 ? [root@vrh8 ~]# date -s "1985-07-25 00:00:00"
Thu Jul 25 00:00:00 EDT 1985SQL> startup;
ORA-01513: invalid current time returned by operating system[oracle@vrh8 ~]$ strace -o startup.log? -p 9935
Process 9935 attached - interrupt to quitSQL> startup;
ORA-01513: invalid current time returned by operating system[oracle@vrh8 ~]$ oerr ora 01513
01513, 00000, "invalid current time returned by operating system"
// *Cause:? The operating system returned a time that was not between
//????????? 1988 and 2121.
// *Action: Correct the time kept by the operating system. ? ? 可以看到 Oracle數(shù)據(jù)庫可運行的時間區(qū)間其實是 1988-2121年,500年的SCN headroom其實沒什么用處, 沒有哪個凡人或者DBA等得起5個世紀(jì)!
轉(zhuǎn)載于:https://www.cnblogs.com/macleanoracle/archive/2013/03/19/2968300.html
總結(jié)
以上是生活随笔為你收集整理的SCN Headroom与时光倒流到1988年的Oracle数据库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TSO缩写
- 下一篇: Android常用代码(类似工具类吧)