SCN headroom问题解决方案
轉(zhuǎn)載請(qǐng)注明出處,謝謝!
?---好久沒來逛ITPUB了,發(fā)一篇大家關(guān)心的問題
1.?? SCN headroom簡(jiǎn)介
SCN是Oracle內(nèi)部使用的邏輯時(shí)鐘,用于區(qū)分事務(wù)操作的先后次序以及確保事務(wù)操作的一致性。它由48位的一串單向序列數(shù)字來實(shí)現(xiàn)的,因此最大值不能超過2的48次方,為了確保這個(gè)48位的SCN能夠用足夠長(zhǎng)的時(shí)間(500年),Oracle對(duì)SCN序列做出了一個(gè)限制,即每秒鐘SCN最大增長(zhǎng)不能超過16K。為了平衡業(yè)務(wù)的高峰和低谷,Oracle使用了一個(gè)十分簡(jiǎn)單的算法來貫徹上述限制,就是以從1988年1月1日0點(diǎn)0分0秒為基準(zhǔn)時(shí)間,至當(dāng)前時(shí)間的秒鐘數(shù)乘以16K,就是當(dāng)前SCN的最大允許值,我們稱為SCN Headroom。從SCN Headroom 的算法可知,Headroom值是隨時(shí)間動(dòng)態(tài)變化的,按照oracle公司說法,如果在某個(gè)時(shí)刻SCN達(dá)到了這個(gè)最大值,那么事務(wù)就無法提交,需要等到下一秒,當(dāng)Headroom值又變大了,才能繼續(xù)進(jìn)行事務(wù)的提交;但在實(shí)際運(yùn)行時(shí),如果數(shù)據(jù)庫當(dāng)前的SCN已經(jīng)達(dá)到了Headroom的最大值時(shí),該機(jī)制有很大可能會(huì)造成數(shù)據(jù)庫保護(hù)性宕機(jī)。
當(dāng)然,在正常情況下,每秒16K的SCN增量完全可以滿足應(yīng)用的正常使用,但是在實(shí)際使用中,已經(jīng)證實(shí)一些特定的應(yīng)用模式會(huì)觸發(fā)Oracle的內(nèi)部Bug,根據(jù)經(jīng)驗(yàn)這些應(yīng)用基本都是跑報(bào)表類型的業(yè)務(wù)、采用高并發(fā)、select... for update 、執(zhí)行效率非常差的sql和相同對(duì)象的DDL語句同時(shí)執(zhí)行、大量數(shù)據(jù)處理一次性提交(大事物)等等。最終導(dǎo)致SCN在短時(shí)間內(nèi)的大幅增長(zhǎng),久而久之,SCN很快就會(huì)逼近Headroom的上限。
除了Oracle Bug引發(fā)SCN大幅增長(zhǎng)以外,Oracle數(shù)據(jù)庫固有的DBLINK運(yùn)作機(jī)制也在其中起了推波助瀾的作用。
Oracle數(shù)據(jù)庫為了實(shí)現(xiàn)分布式處理,在多個(gè)數(shù)據(jù)庫之間做DBLINK訪問的時(shí)候,會(huì)將兩個(gè)數(shù)據(jù)庫的SCN進(jìn)行同步,也就是將較高的SCN同步至參與DBLINK的另外一個(gè)庫,使兩個(gè)庫的SCN序列一致。這個(gè)機(jī)制就可能把SCN增長(zhǎng)異常傳播到其它的數(shù)據(jù)庫服務(wù)器上,并且隨著不同數(shù)據(jù)庫的業(yè)務(wù)高峰和低谷相互傳染,大大加速了SCN的增長(zhǎng),并最終造成嚴(yán)重的后果。
2.?? SCN跳變?cè)吹膶ふ曳绞?
2.1.????? 尋找跳變?cè)吹挠行Х椒?
?? 為了找到跳變?cè)?#xff0c;如果現(xiàn)網(wǎng)的dblink使用非常復(fù)雜并且headroom下降的問題涉及了幾十套甚至是上百套數(shù)據(jù)庫,這個(gè)時(shí)候查找跳變?cè)磿?huì)變得復(fù)雜。對(duì)于打了2012年1月以后的psu補(bǔ)丁的數(shù)據(jù)庫系統(tǒng)可以通過alert判斷,對(duì)于沒有打2012年1月以后的補(bǔ)丁就需要我們做好監(jiān)控。所以一般這種情況下我們會(huì)對(duì)現(xiàn)網(wǎng)的所有的數(shù)據(jù)庫進(jìn)行監(jiān)控,這樣做的好處是我們可以第一時(shí)間知道當(dāng)前所有系統(tǒng)的scn headroom的現(xiàn)狀,并且如果出現(xiàn)headroom驟降我們可以第一時(shí)間進(jìn)行相應(yīng)查找跳變?cè)?#xff0c;而不需要等到數(shù)據(jù)庫后臺(tái)報(bào)錯(cuò)了才知道headroom問題,如果后臺(tái)已經(jīng)報(bào)錯(cuò)說明headroom問題已經(jīng)非常嚴(yán)重。
1) 對(duì)于已經(jīng)打了2012 年1 月以后PSU 補(bǔ)丁的數(shù)據(jù)庫系統(tǒng),當(dāng)SCN 傳播發(fā)生時(shí),
ALERT LOG 中會(huì)有記錄,可以通過ALERT LOG 查找問題的系統(tǒng):
Advanced SCN by 13238271 minutes worth to 0x0bd6.00000f21, by distributed transaction remote logon, remote DB: ORA10G. Client info : DB logon user SCOTT, machine gc, program sqlplus@gc (TNS V1-V3), and OS user oracle
2) 而對(duì)于未安裝上述補(bǔ)丁的數(shù)據(jù)庫,則可以通過在數(shù)據(jù)庫上運(yùn)行3.1步驟中提供的腳本,列出SCN歷史的剩余天數(shù),依照SCN 序列突變的先后時(shí)間來找出源頭,或是縮小范圍便于進(jìn)一步查證。但是如果現(xiàn)網(wǎng)數(shù)據(jù)庫數(shù)量非常多的話一套一套查是非常不現(xiàn)實(shí)的,所以一般情況下我們都會(huì)做SCN的監(jiān)控。
2.2.????? SCN headroom的實(shí)時(shí)情況監(jiān)控
分鐘級(jí)監(jiān)控(時(shí)間可以自行調(diào)整):監(jiān)控主機(jī)上的部署crontab sh /u01/oracle/ljl/scn_monitor.sh? 調(diào)用存過scn_monitor生成監(jiān)控表scn_mon(最好建成分區(qū)表提升查詢效率)。
監(jiān)控腳本內(nèi)容略:
NOTE:腳本內(nèi)容可以根據(jù)需求自己控制,如果擔(dān)心監(jiān)控庫會(huì)加重庫與庫之間的scn同步并且影響我們對(duì)跳變?cè)吹呐袛?#xff0c;可以使用shell或者python直接調(diào)用,從而避免監(jiān)控庫使用dblink。近期在電力使用的python腳本監(jiān)控方式待驗(yàn)證成功后續(xù)再增加。
3.?? SCN跳變?cè)捶治?
3.1.????? SCN headroom歷史紀(jì)錄分析
查看近期的headroom歷史記錄(按分統(tǒng)計(jì))時(shí)間范圍不要選的太大,因?yàn)槲覀冞x擇的是小時(shí)為單位所以時(shí)間跨度大了以后曲線會(huì)反映不出跳變點(diǎn),定位SCN headroom下降的大概時(shí)間點(diǎn)和當(dāng)前SCN headroom總體趨勢(shì),查詢語句如下:
?select *
? from monitor.scn_mon a
?where a.date_time >= '2016/10/23'
?? order by a.date_time
定位SCN headroom下降的大概時(shí)間點(diǎn)和當(dāng)前SCN headroom總體趨勢(shì):
先把我所有系統(tǒng)的大體scn headroom的趨勢(shì)對(duì)比不同時(shí)間點(diǎn)的headroom剩余時(shí)間,如果呈現(xiàn)下降趨勢(shì)的,取其中一套headroom在下降的數(shù)據(jù)庫,進(jìn)行plsql作圖找到大致的下降時(shí)間點(diǎn)和整體的下降趨勢(shì)
?select *
? from monitor.scn_mon a
?where a.date_time >= '2016/10/23'
?? and a.host_name = ''
?? order by a.date_time
????????????????????????? 圖1-1
如果曲線如圖1-1,有明顯的垂直下降的情況,很可能是被其他數(shù)據(jù)庫通過dblink傳染的,這個(gè)時(shí)候就要定位這個(gè)斷崖的時(shí)間點(diǎn),然后執(zhí)行如下語句找到當(dāng)前時(shí)間或者前一分鐘的headroom剩余時(shí)間最小的那臺(tái)主機(jī)(也就是最先跳變的數(shù)據(jù)庫),如果確定了有一套庫在每次的垂直下降的時(shí)間點(diǎn)headroom都最先下降那么他往往就是源頭庫或者最先感染的庫。
?select *
? from monitor.scn_mon a
?where a.date_time >= '2016/10/23 21:00:00'
?and a.date_time <= '2016/10/23 21:02:00'
?? order by a.date_time
如果曲線如圖1-2,雖然headroom是一直在下降的但是下降的幅度很緩慢甚至有些時(shí)間點(diǎn)還是往上漲的,那么headroom下降的原因往往是它本身進(jìn)程異常調(diào)用而引起的問題,這個(gè)時(shí)候基本可以判定他的scnheadroom下降問題不是其他系統(tǒng)通過dblink同步而導(dǎo)致的。
???????????????????????????????? 圖1-2
?
3.2.????? 數(shù)據(jù)庫SCN自增長(zhǎng)情況分析
數(shù)據(jù)庫SCN自增長(zhǎng)查看(即call scn kcmgas的平均每秒調(diào)用值),SCN自增長(zhǎng)平均每秒超過16000需要重點(diǎn)分析(按照SCN headroom 的計(jì)算方式,平均每秒超過16000,會(huì)引起全網(wǎng)SCN headroom下降),可以通過下面語句查看SCN自增長(zhǎng):
9i數(shù)據(jù)庫(需開啟STATSPACK)
?
10g以上數(shù)據(jù)庫
單實(shí)例查詢:
? ?select to_char(b.end_interval_time,'YYYY-MM-DD HH24:MI:SS') as time,
??????? c.snap_id,
??????? trunc((lead(c.value, 1, c.value) over(order by c.snap_id) - c.value) / (select to_number(substr(replace(a.snap_interval, '+00000 ', ''), 1, 2), 99) * 3600 +
?????? to_number(substr(replace(a.snap_interval, '+00000 ', ''), 4, 2), 99) * 60 +
?????? to_number(substr(replace(a.snap_interval, '+00000 ', ''), 7, 2), 99)
? from dba_hist_wr_control a)) as per_s_value
????????? from dba_hist_sysstat c,dba_hist_snapshot b
???????? where
?????????????? b.snap_id=c.snap_id
?????????? and b.instance_number=c.instance_number
?????????? and c.instance_number = 1 ----或者2
?????????? and c.stat_name = 'calls to kcmgas'
???????? order by 1 desc;
多實(shí)例查詢:
select c.instance_number,
?????? to_char(b.end_interval_time, 'YYYY-MM-DD HH24:MI:SS') as time,
?????? c.snap_id,
?? ????trunc((lead(c.value, 1, c.value)
????????????? over(partition by c.instance_number order by c.snap_id) -
????????????? c.value) /
???????????? (select to_number(substr(replace(a.snap_interval, '+00000 ', ''),
????????????????????????????????????? 1,
????????????????????????????????????? 2),
?????????????????????????????? 99) * 3600 +
???????????????????? to_number(substr(replace(a.snap_interval, '+00000 ', ''),
????????????????????????????????????? 4,
????????????????????????????????????? 2),
?????????????????????????????? 99) * 60 +
???????????????????? to_number(substr(replace(a.snap_interval, '+00000 ', ''),
????????????????????????????????????? 7,
????????????????????????????????????? 2),
?????????????????????????????? 99)
??????????????? from dba_hist_wr_control a)) as per_s_value
? from dba_hist_sysstat c, dba_hist_snapshot b
?where b.snap_id = c.snap_id
?? and b.instance_number = c.instance_number
?? and c.stat_name = 'calls to kcmgas'
?order by 1, 2 desc;
3.3.????? Session SCN調(diào)用情況分析
如果前兩步都無法定位,則需要關(guān)注持續(xù)活動(dòng)非常久的session,并且關(guān)注session的SCN調(diào)用情況:
---建議通過value desc,last_call_et desc 排序來看,一般情況下value過千萬,甚至上億,LAST_CALL_ET超過幾個(gè)小時(shí)那么該會(huì)話可能就是引起跳變的可疑的會(huì)話。
3.4.????? 確認(rèn)感染源
?分析到了源頭庫或者是最先感染的庫,通過取下降高峰時(shí)段的AWR進(jìn)行最終確認(rèn)。
select b.end_interval_time,
?
??????? c.snap_id,
?
??????? trunc((lead(c.value, 1, c.value) over(order by c.snap_id) - c.value) / (select to_number(substr(replace(a.snap_interval, '+00000 ', ''), 1, 2), 99) * 3600 +
?
?????? to_number(substr(replace(a.snap_interval, '+00000 ', ''), 4, 2), 99) * 60 +
?
?????? to_number(substr(replace(a.snap_interval, '+00000 ', ''), 4, 2), 99)
?
? from dba_hist_wr_control a))
?
????????? from dba_hist_sysstat c,dba_hist_snapshot b
?
??????? ?where
?
?????????????? b.snap_id=c.snap_id
?
?????????? and b.instance_number=c.instance_number
?
?????????? and c.instance_number = 1 ----或者2
?
?????????? and c.stat_name = 'calls to kcmgas'
?
???????? order by 1 desc;
3.5.????? 異常session定位
?
如果已經(jīng)分析到源頭庫,緊接著來定位session,可以直接登錄該庫進(jìn)行檢查定位:
?
腳本略
當(dāng)前面的2、3、4基本初步能找出跳變?cè)?#xff0c;確定了可能的跳變?cè)磾?shù)據(jù)庫后,可以通過本語句進(jìn)行確認(rèn)相關(guān)異常會(huì)話,使用VALUE,PREVALUE,LAST_CALL_ET,event,SQL_TEXT結(jié)合起來綜合判斷。
如:value過千萬,甚至上億,LAST_CALL_ET超過幾個(gè)小時(shí),event是異常等待,且SQL_TEXT進(jìn)行了append insert操作或者語句中有parallel參數(shù)那么該會(huì)話就是引起跳變的最可疑的會(huì)話。
處理可疑會(huì)話跟業(yè)務(wù)側(cè)確認(rèn)該會(huì)話的用途是否可以停止或者后臺(tái)數(shù)據(jù)庫層直接kill,并且對(duì)這些會(huì)話進(jìn)行優(yōu)化接下來繼續(xù)觀察headroom是否回漲,如果并沒有發(fā)現(xiàn)可疑會(huì)話那就繼續(xù)重點(diǎn)監(jiān)控該數(shù)據(jù)庫觀察時(shí)候有可以會(huì)話或者后臺(tái)進(jìn)程異常調(diào)用scn,必要時(shí)可以嘗試申請(qǐng)?jiān)趕cn headroom下降的大概時(shí)間點(diǎn)窗口申請(qǐng)嘗試停數(shù)據(jù)庫,然后對(duì)比headroom曲線是否有變化,如果headroom回漲,那么可以基本定位是該數(shù)據(jù)庫,如果以上步驟對(duì)headroom沒有任何影響,則該可以跳變?cè)纯赡芫筒皇钦嬲奶冊(cè)凑?qǐng)從第一步開始分析另一個(gè)可疑的跳變?cè)础?
?
?
?
?
?
4.?? SCN問題解決方案
?
1)數(shù)據(jù)庫被外部數(shù)據(jù)庫通過DBLINK傳染,造成SCN序列異常增長(zhǎng)
如果數(shù)據(jù)庫被外部數(shù)據(jù)庫通過DBLINK傳染,而造成SCN序列異常增長(zhǎng),而應(yīng)用改造減少DBLink有無法在短期實(shí)現(xiàn),那么未防止進(jìn)一步傳染其他健康的數(shù)據(jù)庫,請(qǐng)及時(shí)將它們進(jìn)行dblink的隔離。
??? 2)數(shù)據(jù)庫本身觸發(fā)Bug,造成SCN序列的異常增長(zhǎng)
如果數(shù)據(jù)庫本身觸發(fā)Bug,造成SCN序列的異常增長(zhǎng),即3.2步驟發(fā)現(xiàn)數(shù)據(jù)庫scn自身調(diào)用異常,則可以對(duì)該庫應(yīng)用2012年一月份以后的補(bǔ)丁(該補(bǔ)丁也存在部分bu所以建議打到最新的補(bǔ)丁),并且設(shè)置:_external_scn_rejection_threshold_hours=24。這個(gè)設(shè)置降低可以SCN Headroom的頂部空間,11.2.0.2以前的版本缺省的設(shè)置容量至少為31天,降低為 24 小時(shí),可以增大SCN允許增長(zhǎng)的合理空間。如果該數(shù)據(jù)庫版本沒有對(duì)應(yīng)的補(bǔ)丁,建議升級(jí),如果升級(jí)需要跨多個(gè)版本為了降低風(fēng)險(xiǎn)可以進(jìn)行業(yè)務(wù)改造防止傳染其他健康數(shù)據(jù)庫或者直接進(jìn)行遷移。
因?yàn)闆]有對(duì)應(yīng)的補(bǔ)丁的版本數(shù)據(jù)庫往往是比較舊的,升級(jí)的可能會(huì)涉及跨多個(gè)版本,所以一般情況下我們不建議升級(jí)而是直接遷移更安全或者進(jìn)行業(yè)務(wù)改造禁用dblink。
以下版本oracle是對(duì)應(yīng)沒有補(bǔ)丁程序的:
·???????????? All versions up to and including 9.2.0.7
·???????????? Versions 10.1.0.2 to 10.1.0.4 inclusive
·???????????? Versions 10.2.0.1 and 10.2.0.2
·???????????? Version 11.1.0.6
·???????????? Version 11.2.0.1
備注:所有的解決方案都是存在風(fēng)險(xiǎn)的,所以請(qǐng)考慮周全在確定使用哪一種方式。
?
?
?
?
來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/30068249/viewspace-2130002/,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任。
轉(zhuǎn)載于:http://blog.itpub.net/30068249/viewspace-2130002/
總結(jié)
以上是生活随笔為你收集整理的SCN headroom问题解决方案的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt [GC9-13]:HUD-转向灯、
- 下一篇: 05.bean依赖注入的三种方式