Oracle安全:SCN可能最大值與耗盡問題Oracle安全:SCN可能最大值與耗盡問題

jinqibingl發表於2015-02-13
SCN的問題一旦出現,使得資料庫的一切事務停止,由於SCN不能後退,所以資料庫必須重建,才能夠重用。
在2012年第一季度的CPU補丁中,包含了一個關於SCN修正的重要變更,這個補丁提示,在異常情況下,Oracle的SCN可能出現異常增長,使得資料庫的一切事務停止,由於SCN不能後退,所以資料庫必須重建,才能夠重用。


我曾經在以下連結中描述過這個問題:





Oracle使用6 Bytes記錄SCN,也就是48位,其最大值是:


SQL> col scn for 999,999,999,999,999,999  
SQL> select power(2,48) scn from dual;  
SCN  
------------------------  
281,474,976,710,656 


Oracle在內部控制每秒增減的SCN不超過 16K,按照這樣計算,這個數值可以使用大約544年:


SQL> select power(2,48) / 16 / 1024 / 3600 / 24 / 365 from dual;  
POWER(2,48)/16/1024/3600/24/365  
-------------------------------  
544.770078 


然而在出現異常時,尤其是當使用DB Link跨資料庫查詢時,SCN會被同步,在以下連結中,我曾經描述過此問題:





一個資料庫當前最大的可能SCN被稱為"最大合理SCN",該值可以透過如下方式計算:


col scn for 999,999,999,999,999,999  
select 
(  
(  
 (  
(  
(  
(  
to_char(sysdate,'YYYY')-1988  
)*12+  
to_char(sysdate,'mm')-1  
)*31+to_char(sysdate,'dd')-1  
)*24+to_char(sysdate,'hh24')  
)*60+to_char(sysdate,'mi')  
)*60+to_char(sysdate,'ss')  
) * to_number('ffff','XXXXXXXX')/4 scn  
from dual  

這個演算法即SCN演算法,以1988年1月1日 00點00時00分開始,每秒計算1個點數,最大SCN為16K。


這個內容可以參考如下連結:





在CPU補丁中,Oracle提供了一個指令碼 scnhealthcheck.sql 用於檢查資料庫當前SCN的剩餘情況。


該指令碼的演算法和以上描述相同,最終將最大合理SCN 減去當前資料庫SCN,計算得出一個指標:HeadRoom。也就是SCN尚餘的頂部空間,這個頂部空間最後摺合成天數:


以下是這個指令碼的內容:


Rem  
Rem $Header: rdbms/admin/scnhealthcheck.sql st_server_tbhukya_bug-13498243/8 2012/01/17 03:37:18 tbhukya Exp $  
Rem  
Rem scnhealthcheck.sql  
Rem  
Rem Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.  
Rem  
Rem NAME 
Rem scnhealthcheck.sql - Scn Health check 
Rem  
Rem DESCRIPTION  
Rem Checks scn health of a DB  
Rem  
Rem NOTES  
Rem .  
Rem  
Rem MODIFIED (MM/DD/YY)  
Rem tbhukya 01/11/12 - Created  
Rem  
Rem  
define LOWTHRESHOLD=10  
define MIDTHRESHOLD=62  
define VERBOSE=FALSE 
set veri off;  
set feedback off;  
set serverout on 
DECLARE 
verbose boolean:=&&VERBOSE;  
BEGIN 
For C in (  
select 
version,  
date_time,  
 dbms_flashback.get_system_change_number current_scn,  
indicator  
from 
(  
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  
from v$instance  
)  
) LOOP  
dbms_output.put_line( '-----------------------------------------------------' 
|| '---------' );  
dbms_output.put_line( 'ScnHealthCheck' );  
dbms_output.put_line( '-----------------------------------------------------' 
|| '---------' );  
dbms_output.put_line( 'Current Date: '||C.date_time );  
dbms_output.put_line( 'Current SCN: '||C.current_scn );  
if (verbose) then 
dbms_output.put_line( 'SCN Headroom: '||round(C.indicator,2) );  
end if;  
dbms_output.put_line( 'Version: '||C.version );  
dbms_output.put_line( '-----------------------------------------------------' 
|| '---------' );  
IF C.version > '10.2.0.5.0' and 
C.version NOT LIKE '9.2%' THEN 
IF C.indicator>&MIDTHRESHOLD THEN 
dbms_output.put_line('Result: A - SCN Headroom is good');  
dbms_output.put_line('Apply the latest recommended patches');  
dbms_output.put_line('based on your maintenance schedule');  
IF (C.version < '11.2.0.2') THEN 
dbms_output.put_line('AND set _external_scn_rejection_threshold_hours=' 
|| '24 after apply.');  
END IF;  
ELSIF C.indicator<=&LOWTHRESHOLD THEN 
dbms_output.put_line('Result: C - SCN Headroom is low');  
dbms_output.put_line('If you have not already done so apply' );  
dbms_output.put_line('the latest recommended patches right now' );  
IF (C.version < '11.2.0.2') THEN 
dbms_output.put_line('set _external_scn_rejection_threshold_hours=24 ' 
|| 'after apply');  
END IF;  
dbms_output.put_line('AND contact Oracle support immediately.' );  
 ELSE 
dbms_output.put_line('Result: B - SCN Headroom is low');  
dbms_output.put_line('If you have not already done so apply' );  
dbms_output.put_line('the latest recommended patches right now');  
IF (C.version < '11.2.0.2') THEN 
dbms_output.put_line('AND set _external_scn_rejection_threshold_hours=' 
||'24 after apply.');  
END IF;  
END IF;  
ELSE 
IF C.indicator<=&MIDTHRESHOLD THEN 
dbms_output.put_line('Result: C - SCN Headroom is low');  
dbms_output.put_line('If you have not already done so apply' );  
dbms_output.put_line('the latest recommended patches right now' );  
IF (C.version >= '10.1.0.5.0' and 
C.version <= '10.2.0.5.0' and 
C.version NOT LIKE '9.2%') THEN 
dbms_output.put_line(', set _external_scn_rejection_threshold_hours=24' 
|| ' after apply');  
END IF;  
dbms_output.put_line('AND contact Oracle support immediately.' );  
ELSE 
dbms_output.put_line('Result: A - SCN Headroom is good');  
dbms_output.put_line('Apply the latest recommended patches');  
dbms_output.put_line('based on your maintenance schedule ');  
IF (C.version >= '10.1.0.5.0' and 
C.version <= '10.2.0.5.0' and 
C.version NOT LIKE '9.2%') THEN 
dbms_output.put_line('AND set _external_scn_rejection_threshold_hours=24' 
|| ' after apply.');  
END IF;  
END IF;  
END IF;  
dbms_output.put_line(  
'For further information review MOS document id 1393363.1');  
dbms_output.put_line( '-----------------------------------------------------' 
|| '---------' );  
END LOOP;  
end;  

在應用補丁之後,一個新的隱含引數 _external_scn_rejection_threshold_hours 引入,通常設定該引數為 24 小時:


_external_scn_rejection_threshold_hours=24


這個設定降低了SCN Headroom的頂部空間,以前預設的設定容量至少為31天,降低為 24 小時,可以增大SCN允許增長的合理空間。


但是如果不加控制,SCN仍然可能會超過最大的合理範圍,導致資料庫問題。


這個問題的影響會極其嚴重,我們建議使用者檢驗當前資料庫的SCN使用情況,以下是檢查指令碼的輸出範例:


--------------------------------------  
ScnHealthCheck  
--------------------------------------  
Current Date: 2012/01/15 14:17:49  
 Current SCN: 13194140054241  
Version: 11.2.0.2.0  
--------------------------------------  
Result: C - SCN Headroom is low  
If you have not already done so apply  
the latest recommended patches right now  
AND contact Oracle support immediately.  
For further information review MOS document id 1393363.  
-------------------------------------- 
這個問題已經出現在客戶環境中,需要引起大家的足夠重視。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/9606200/viewspace-1435660/,如需轉載,請註明出處,否則將追究法律責任。

相關文章