DB Link導致SCN Headroom過低問題研究


一、     基礎概念

1、SCN(System Change Number)值是Oracle數據庫運行每次變化的一個邏輯點,相當於數據庫內部的一個時鍾,是個只增不減的數字,廣泛應用於數據庫的恢復、事務ACID、一致性讀以及分布式事務中。

2、SCN的內部存儲方式:在Oracle內部,SCN分為兩部分存儲,分別稱之為scn wrap和scn base。實際上SCN長度為48位,即它其實就是一個48位的整數。由於在早些年通常只能處理32位甚至是16位的數據,所以分成了低32位(scn base)和高16位(scn wrap)。那么SCN這個48位長的整數,最大就是2^48(281萬億,281474976710656)

3、Maximum Reasonable SCN:在當前時間點,SCN最大允許達到的SCN值。也稱為Reasonable SCN Limit,簡稱RSL。SCN Headroom即當前時間點SCN以每秒最大的增長速度達到RSL值所需時間,其計算公式為:

(當前時間-1988年1月1日00:00:00)×24×3600×SCN每秒最大的可能增長速度

  注:

  •  (當前時間-1988年1月1日)得到天數,為方便計算,每月按照31天計算。
  • SCN每秒最大的可能增長速率跟Oracle版本有一定的關系,在11.2.0.2之前是16384(即16K),在11.2.0.2及之后版本是32768(即32K)。在11.2.0.2及以上的版本中有一個隱含參數_max_reasonable_scn_rate,其默認值就是32768(不建議調整這個值)。根據對各個數據庫版本的補丁13498243中自帶的scnhealthcheck.sql研究,SCN Headroom計算公式中的最大速率均為定義為16k。
  • Alert日志中的SCN Headroom剩余天數為此刻達到RSL所需天數,並非真正耗盡數據庫SCN的時間,SCN Headroom每一秒都在增長。

二、     研究過程

1、 SCN Headroom過低問題發現

(1)  alert日志可能出現以下告警:

1、Warning - High Database SCN: Current SCN value is 0x0b7b.0008e40b, threshold SCN value is 0x0b75.055dc000
If you have not previously reported this warning on this database, please notify Oracle Support so that additional diagnosis can be performed.
2、Warning: The SCN headroom for this database is only NN days!
3、Warning: The SCN headroom for this database is only N hours!
4、WARNING: This patch can not take full effect until this RAC database has been completely shutdown and restarted again.
Oracle recommends that it is done at the earliest convenience.
5、Rejected the attempt to advance SCN over limit by 9374 hours worth to 0x0c00.00000f66, by distributed transaction remote logon, remote DB: REMDB.XX.ORACLE.COM.
Client info : DB logon user ME, machine yy, program sqlplus@yy (TNS V1-V3), and OS user uuu
6、Rejected the attempt to advance SCN over limit by 9375 hours worth to 0x0c00.000003c6, by distributed transaction logon, remote DB: REMDB.XX.ORACLE.COM.
Client info : DB logon user TC, machine xx, program oracle@xx (TNS V1-V3), and OS user xxx 
7、Rejected the attempt to advance SCN over limit by 9374 hours worth to 0x0c00.00000f66, by XXXXX
Client info : DB logon user TC, machine mmm, program sqlplus@mmm (TNS V1-V3), and OS user uuu
Where XXXXX is a string such as:
 ? PL/SQL RPC (remote)
 ? sql exec with curSCN
 ? sql exec with outSCN

(2)  腳本檢查

select
  version,
  to_char(SYSDATE,'YYYY/MM/DD HH24:MI:SS') DATE_TIME,
  ((((
   ((to_number(to_char(sysdate,'YYYY'))-1988)*12*31*24*60*60) +
   ((to_number(to_char(sysdate,'MM'))-1)*31*24*60*60) +
   (((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')))
   ) * (16*1024)) - dbms_flashback.get_system_change_number)
  / (16*1024*60*60*24) 
  ) indicator    --day
from v$instance;

注:根據scnhealthcheck.sql定義:

  • 當SCN Headroom > 62天則健康狀態為A,系統無SCN問題;
  • 當10 < SCN Headroom <= 62天則健康狀態為B,系統存在SCN問題,尚不致命;
  • 當SCN Headroom <=10天則健康狀態為C,系統存在致命的SCN問題,需立即處理。

(3)  問題發生可能原因:

  • 本地數據庫自身業務問題導致SCN激增
  • DB Link傳染

數據庫之間可以通過dblink來進行數據訪問,當通過dblink進行業務提交的時候,由於數據庫之間存在不同的SCN,因此,為了讓事務一致,Oracle將會以兩者之間較大的SCN來進行同步,更新dblink兩端的數據庫SCN。但是,如果源數據庫出現SCN生成率過高的問題,隨着業務的不斷運行,SCN的異常就會通過dblink傳染到其他相關的數據庫,而dblink使用的頻率越大,這種傳染的速度也就越快。如果企業內部存在網狀的dblink結構,那么這將很容易將SCN的問題擴大到全網,極端情況下會引起大范圍的宕機。

通過以下腳得到數據庫的scn headroom變化趨勢圖,如果 SCN Headroom 的剩余天數的歷史變化很突然,那么就說明數據庫主要被外部通過DBLINK 傳染,導致SCN異常增長。

#查看scn headroom變化趨勢(前提是數據庫開啟歸檔模式)
set numwidth 17
set pages 1000
alter session set nls_date_format='DD/Mon/YYYY HH24:MI:SS';
SELECT tim, gscn,
  round(rate_per_sec),
  round((chk16kscn - gscn)/24/3600/16/1024,1) "Headroom"
FROM
(
 select tim, gscn, rate_per_sec,
  ((
  ((to_number(to_char(tim,'YYYY'))-1988)*12*31*24*60*60) +
  ((to_number(to_char(tim,'MM'))-1)*31*24*60*60) +
  (((to_number(to_char(tim,'DD'))-1))*24*60*60) +
  (to_number(to_char(tim,'HH24'))*60*60) +
  (to_number(to_char(tim,'MI'))*60) +
  (to_number(to_char(tim,'SS')))
  ) * (16*1024)) chk16kscn
 from
 (
   select FIRST_TIME tim , FIRST_CHANGE# gscn,
          ((NEXT_CHANGE#-FIRST_CHANGE#)/
           ((NEXT_TIME-FIRST_TIME)*24*60*60)) rate_per_sec
     from v$archived_log
    where (next_time > first_time)
 )
)
order by 1,2

對於非歸檔模式的數據庫可以通過以下腳本查詢SCN增長速度,通過了解SCN的走勢診斷SCN Headroom問題,發現系統中存在的跳變情況則可確認為DB Link傳染導致SCN異常。

with t1 as(
select time_dp , 24*60*60*(time_dp - lag(time_dp) over (order by time_dp)) timediff,
  scn - lag(scn) over(order by time_dp) scndiff
from smon_scn_time
)
select time_dp , timediff, scndiff,
       trunc(scndiff/timediff) rate_per_sec
from t1
order by 1
/

2、 建議解決方式

(1)  應用ORACLE官方推薦的補丁13498243,調整隱含參數:_external_scn_rejection_threshold_hour(11.2.0.2及以上版本的這個參數默認值是24,其他版本默認值是744,官方建議調整為24小時,以避出現過多的ORA-19706)、

_external_scn_logging_threshold_second(建議為86400,相關的信息會記錄到Alert log中。通過這些記錄的信息,日后可以查找導致SCN跳變的源頭。)、_external_scn_rejection_delta_threshold_minute

這三個參數最大限度保障業務系統正常運行需安裝到所有db link操作相關的數據庫上,同是將SCN Headroom加入監控指標進行規律監控。

(2)  查找SCN傳染源數據庫並進行隔離通過其他手段使用數據,如使用OGG同步相關數據,減少DB Link使用,避免數據庫之間通過DB Link傳染高SCN值,傳染源數據庫打完13498243補丁,可直接在alert日志中找到傳染源數據庫的相關信息:

Advanced SCN by 2280 minutes worth to 0x0e26.e74b94ff, by distributed transaction end, remote DB: ORCL.
 Client info: DB logon user DB_CX, machine HDDS-FXGLDB, program ORACLE.EXE, and OS user SYSTEM

另外,12cr2可利用新特性監視數據庫鏈接,可確認SCN暴增原因,主要通過這3個視圖:DBA_DB_LINKS,DBA_EXTERNAL_SCN_ACTIVITY、DBA_DB_LINK_SOURCES。

通過dbms_tns包的函數resolve_tnsname可以分析判斷數據庫鏈接目標主機是否可用,dba_db_link_sources可以獲取到存在的數據庫鏈接信息,DBA_EXTERNAL_SCN_ACTIVITY可以記錄分布式事務和分布式讀在分布式數據庫環境中的一致性即來判斷SCN是否高速率增長。

執行以下腳本,如無結果,則數據庫無SCN高生成率活動,否則,會返回造成SCN高生成率相關信息。

(SELECT RESULT, OPERATION_TIMESTAMP, EXTERNAL_SCN, SCN_ADJUSTMENT, HOST_NAME, DB_NAME, 
SESSION_ID, SESSION_SERIAL#   
    FROM DBA_EXTERNAL_SCN_ACTIVITY a, DBA_DB_LINK_SOURCES s   
    WHERE a.INBOUND_DB_LINK_SOURCE_ID = s.SOURCE_ID) --返回通過DB Link導致SCN增長的遠程數據庫信息
UNION 
(SELECT RESULT, OPERATION_TIMESTAMP, EXTERNAL_SCN, SCN_ADJUSTMENT, 
dbms_tns.resolve_tnsname(HOST) HOST_NAME, NULL DB_NAME, SESSION_ID, 
SESSION_SERIAL#   
    FROM DBA_EXTERNAL_SCN_ACTIVITY a, DBA_DB_LINKS o, DBA_DB_LINK_SOURCES s 
    WHERE a.OUTBOUND_DB_LINK_NAME = s.SOURCE_ID AND  
OUTBOUND_DB_LINK_OWNER = o.OWNER) --返回通過DB Link導致SCN增長的遠程數據庫信息
UNION 
(SELECT RESULT, OPERATION_TIMESTAMP, EXTERNAL_SCN,   SCN_ADJUSTMENT,  
s.MACHINE HOST_NAME, NULL DB_NAME, SESSION_ID, SESSION_SERIAL#   
    FROM DBA_EXTERNAL_SCN_ACTIVITY a, V$SESSION s
    WHERE a.SESSION_ID = s.SID AND           
        a.SESSION_SERIAL#=s.SERIAL# AND
        INBOUND_DB_LINK_SOURCE_ID IS NULL AND
        OUTBOUND_DB_LINK_NAME IS NULL AND
        OUTBOUND_DB_LINK_OWNER IS NULL); --返回通過用戶連接導致SCN增長的相關信息
--腳本源自《Oracle® Database Administrator’s Guide 12c Release 2 (12.2)》32.5.5 Determining the Source of High SCN Activity for Incoming Database Links
--《Oracle® Database Administrator’s Guide 12c Release 2 (12.2)》4.242 DBA_EXTERNAL_SCN_ACTIVITY
--尚未進行相關驗證

 

三、     總結

1. 在全系統內做SCN生成率的普查,看看各系統的SCN生成情況是否牽涉生成率過高的現象;

2. 發現SCN生成率過高的相關數據庫,及時進行修正處理;

3. 形成日常檢查機制,每半月或者每月運行scnhealthcheck.sql,例行檢查SCN的生成率情況;

4. 根據相關數據庫的dblink使用情況,形成dblink跟蹤列表,便於日后檢查SCN狀態。列表內容包括源數據庫名稱、目標數據庫名稱、dblink名稱、dblink用途,甚至包括關聯對象等信息,

5. 目前的Oracle官方並沒有給出完全解決SCN headroom過低問題,只能通過設置相關隱含參數最大限度保障業務系統的正常運行,隔離高SCN值數據庫通過DB link傳染,極端情況下還需關閉數據庫等待SCN headroom增長。

四、     相關SQL腳本附錄

#隱含參數查詢

select name
    ,value
    ,decode(isdefault, 'TRUE','Y','N') as "Default"
    ,decode(ISEM,'TRUE','Y','N') as SesMod
    ,decode(ISYM,'IMMEDIATE', 'I','DEFERRED', 'D','FALSE', 'N') as SysMod
    ,decode(IMOD,'MODIFIED','U','SYS_MODIFIED','S','N') as Modified
    ,decode(IADJ,'TRUE','Y','N') as Adjusted
    ,description
    from ( --GV$SYSTEM_PARAMETER
        select x.inst_id as instance           
            ,x.indx+1
            ,ksppinm as name
            ,ksppity
            ,ksppstvl as value
            ,ksppstdf as isdefault
            ,decode(bitand(ksppiflg/256,1),1,'TRUE','FALSE') as ISEM
            ,decode(bitand(ksppiflg/65536,3),1,'IMMEDIATE',2,'DEFERRED','FALSE') as ISYM
            ,decode(bitand(ksppstvf,7),1,'MODIFIED','FALSE') as IMOD
            ,decode(bitand(ksppstvf,2),2,'TRUE','FALSE') as IADJ
            ,ksppdesc as description
        from x$ksppi x,x$ksppsv y
    where x.indx = y.indx
    and substr(ksppinm,1,1) = '_'
    and x.inst_id = USERENV('Instance')
)
where name like '%&par%'
order by name
/

五、     參考資料

System Change Number (SCN), Headroom, Security and Patch Information (文檔 ID 1376995.1)

Installing, Executing and Interpreting output from the "scnhealthcheck.sql" script (文檔 ID 1393363.1)

ORA-19706 and Related Alert Log Messages (文檔 ID 1393360.1)

How to Extract the Historical Values of a Statistic from the AWR Repository (文檔 ID 948272.1)

關於Oracle DB SCN 生成率過高的預警及處理建議

SCN、ORA-19706錯誤和_external_scn_rejection_threshold_hours參數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM