SCN Headroom与时光倒流到1988年的Oracle数据库
生活随笔
收集整理的這篇文章主要介紹了
SCN Headroom与时光倒流到1988年的Oracle数据库
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近一陣關于scn headroom的討論很熱,? 這是由于在最新的2012 Apr的PSU中例如10.2.0.5上的PSU 13632743和 patch? 13916709: SCN: HIGH CALLS TO KCMGAS AFTER APPLYING SCN PATCHES 中引入了對scn增長過快的FIX修復。 Oracle SCN(System Change Number)也叫做系統變更號,Oracle中的Commit操作與SCN緊密相關。 引入SCN的最根本目的在于: 為讀一致性所用 為redolog中的記錄排序,以及恢復 ? ? SCN由SCN Base和Scn Wrap組成,是一種6個字節的結構(structure)。其中SCN Base占用4個字節,而SCN wrap占用2個字節。但在實際存儲時SCN-like的stucture常會占用8個字節。 ? ub4 kscnbas
ub2 kscnwrpstruct kcvfhcrs, 8 bytes???????????????? @100????????????????????????????? Creation Checkpointed at scn
ub4 kscnbas??????????????????????? @100????? 0x000a8849????????????? www.oracledatabase12g.com
ub2 kscnwrp??????????????????????? @104????? 0x0000 ? ? 當事務提交COMMIT時,需要完成第一個操作就是得到一個SCN值。 ? SCN是Oracle數據庫內部的一種邏輯時間戳,通過SCN將數據庫內的事件理清次序, 這是保證事務屬性ACID的必要信息。 ? 數據庫使用SCN來幫助實現查詢和跟蹤變化。舉例來說,當一個事務更新一行數據,那么數據庫就需要將該update發生時的SCN記錄下來,該事務(transaction)中的其他修改操作通常都會使用同樣的SCN。當一個事務commit提交,數據庫又會相應地記錄提交時的SCN。 多個事務同事commit可能會共享同一個SCN。 ? SCN總是單調遞增的序列, Oracle數據庫最大可以使用到的SCN上限值是一個天文數字,目前該上限是281萬億,即281,474,976,710,656(2的48次方)。這是對SCN的硬限制,理論上一個數據庫的SCN總是不能超過281萬億, 以每秒16K的增速計算,花費557年SCN上限才會被耗盡,作為一個hard limit ,我們很少有機會觸及。 ? 除了281萬億的hard limit外, Oracle數據庫還存在一種 soft limit 即SCN headroom, 為了保證SCN的增長速度不要過于離譜,Oracle使用了一種基于時間的限量供應SCN的系統。 ? 關于headroom ,字典翻譯頭上空間, 實際你可以理解為 在一個房間內 天花板和 頭部之間的空間, 數據庫的Current SCN就是你頭部的高度,那么(房間高度-頭部高度)=headroom, 在任何時間點上,Oracle數據庫均會計算一個當前時間點DB 不能超過的SCN LIMIT上限, 注意這里提到了時間點 ,通俗點說這個SCN LIMIT是隨著時間流逝在增加的。 Oracle計算的算法基于從1988年到當前時間點的秒數,再乘上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到當前時間的秒數?? *??? 16384 -? 當前SCN 即SCN headroom是 當前SCN 和(1988年到當前時間的秒數*??? 16384)之間的差距。 ? 通過將SCN的增長率和時間流逝關聯起來,確保SCN的限量增長,保證Oracle數據庫理論上可以處理500年的數據。 ? ? 通過以上公式我們可以發現SCN每秒的合理增長量為16,384,然而Oracle公司在近年發現某些軟件層面的BUG會導致數據庫試圖超過或接近這個當前時間點的SCN 最大值。 常規情況下,若數據庫嘗試超過當前的SCN最大值,數據庫將會cancel取消掉引發該超越事件的事務, 在應用程序層面將看到一個錯誤。在接下來的一秒鐘,上限值會隨著時間而增長16k,因此通常應用程序會在短暫停頓后繼續工作。 但是在極少數情況下,數據庫可能需要為了保護自身的完整性而shutdown關閉,理論上不會造成數據丟失或corrupted。 ? 類似于計算機網絡中的時鐘同步,當2個數據庫通過DBLINK相互交流訪問時,他們會選用2者中當前Current SCN最大的一個來同步SCN, 譬如說數據庫A 的SCN 是10000,而數據庫B是20000,當2者發生DBLINK聯系時,將會用最大的SCN (20000)來同步,數據庫A的SCN將jump跳躍到20000。 在一些環境中,往往不是本地數據庫觸發了SCN快速增長的bug,而是眾多數據庫中的某一個存在活躍的SCN BUG,而其他數據庫與該問題數據庫發生DBLINK聯系后,就會因為SCN同步而經歷 SCN headroom的的極速減少; 換句話說就是一只老鼠壞了一鍋湯,異常高的SCN會通過DBLINK傳播給正常的數據庫,這種傳播往往呈爆炸式發展。 由于數據庫總是會拒絕SCN超過當前的SCN上限,所以Oracle官方宣稱Oracle數據庫理論運行500年的SCN預備量不會受以上問題的影響。 但是受到傳播的數據庫仍可能由于自我保護的原因而宕機。 ? Oracle官方宣布所有與SCN headroom相關的bug均已在January 2012 CPU 和相關的PSU中修復了, 同樣的修復補丁也被包含在DB Patchset Update (PSU) 以及最新的Exadata和Windows的Bundle Patch上。 ? ? 有一些客戶糾結于他們的SCN接近于當前SCN最大值,且SCN的增長量遠大于他們處理數據庫的合理值。在所有這些cases中Oracle 發現均是January 2012 CPU 中已經修復bug的現象,在客戶實施這些修復后SCN headroom 開始有效增長了。 ? 為了保證系統不出現潛在的問題,用戶可以運行Metalink Note"Installing, Executing and Interpreting output from the "scnhealthcheck.sql" script [ID 1393363.1]"中包含的腳本scnhealthcheck.sql來檢查特定數據庫的當前SCN距離當前SCN 最大值有多少差距。該腳本會警告用戶該數據庫接近于當前SCN的最大上限,在這種情況下建議立即對受影響數據庫實施CPU/PSU補丁。實施以上補丁后的預期結果是SCN headroom有效增長,官方宣稱在所有case中都如預期一樣。 ? Oracle推薦盡可能客戶盡可能快地APPLY CPU補丁以處理最新發現的安全問題。 ? 從長遠來看Oracle會在今后的版本或補丁中將SCN的hard limit從281萬億 提高到一個更高數字。 ? 你肯定好奇于為什么這里要使用 1988年到當前時間的秒數,1988這個年份有什么意義? ? ? 我們來看看Oracle數據庫中的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年發布了Oracle V6,首次實現了行級鎖定,首次實現了數據庫熱備份,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) 這個所有權著名,你可以在很多Oracle的早起文檔上找到。 ? 你肯定又要問 , 我們可以在1988年之前運行Oracle V6以后的程序嗎? 假設我們獲得了時光機,拿著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數據庫可運行的時間區間其實是 1988-2121年,500年的SCN headroom其實沒什么用處, 沒有哪個凡人或者DBA等得起5個世紀!
轉載于:https://www.cnblogs.com/macleanoracle/archive/2013/03/19/2968300.html
總結
以上是生活随笔為你收集整理的SCN Headroom与时光倒流到1988年的Oracle数据库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TSO缩写
- 下一篇: linux cmake编译源码,linu