Oracle安全:SCN可能最大值與耗盡問題Oracle安全:SCN可能最大值與耗盡問題
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.
--------------------------------------
這個問題已經出現在客戶環境中,需要引起大家的足夠重視。
在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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Oracle的SCN顯示問題Oracle
- 如何修復Apple AirPods Max電池耗盡問題?APPAI
- Oracle:SCNOracle
- 【SCN】Oracle SCN 詳細介紹Oracle
- ora-19706 scn問題
- 【SCN】Oracle推薦scn命令參考Oracle
- 【SCN】Oracle檢查scn值指令碼Oracle指令碼
- Oracle SCN詳解Oracle
- ORACLE -詳解SCNOracle
- oracle的scn及sequenceOracle
- Linux下php-fpm程式過多導致記憶體耗盡問題解決LinuxPHP記憶體
- 股票問題-求收益最大值
- 全球 IPv4 地址正式耗盡
- ORACLE RAC TO RAC DG搭建過程中可能遇到的問題Oracle
- Oracle 檢查點涉及的SCNOracle
- ordebug 手動修改Oracle sga scnOracle
- oracle基於SCN增量恢復Oracle
- Oracle SCN健康狀態檢查Oracle
- 解決線上Oracle連線耗時過長的問題現象RPYBOracle
- 滑動視窗最大值問題
- Oracle的DBMS_SCN修正以及SCN的auto-rollover新特性Oracle
- 單例模式中可能存在的一些問題(執行緒安全問題)單例模式執行緒
- 淺談 ABAP 程式執行時出現『記憶體耗盡』錯誤的問題試讀版記憶體
- Oracle SCN機制詳細解讀Oracle
- 滑動視窗的最大值問題
- 全球 43 億 IPv4 地址宣告耗盡!
- kubernetes排程之資源耗盡處理配置
- oracle 推進scn(poke、gdb、event、bbed)方法Oracle
- Oracle修改字符集前如何找出可能出現問題的資料?Oracle
- Oracle 19C上線後可能出現的問題彙總(全)Oracle
- 關於Gfx.WaitForPresent的耗時問題AI
- Oracle trigger問題Oracle
- 前端的安全問題與防禦策略前端
- 全球IPv4地址已正式耗盡!
- oracle 11.2.0.4 DataGuard Broker配置過程中可能遇到的問題及解決方法Oracle
- 分割槽使用與Oracle許可證問題XSOracle
- Oracle常用傻瓜問題1000問Oracle
- 執行SQL查詢導致磁碟耗盡故障演示SQL
- 記憶體耗盡後Redis會發生什麼記憶體Redis