首页 > 数据库 > Oracle > 第70期 检查大名鼎鼎的SCN 急速增长漏洞的脚本
define LOWTHRESHOLD=10
define MIDTHRESHOLD=62
define VERBOSE=TRUE
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;
/
文件归属:Oracle TFA/ORACH K 内置巡检脚本(
orach k 是 Oracle 官方数据库健康检查工具)
核心背景:大名鼎鼎 SCN 急速增长漏洞(MOS 1393363.1)
Oracle 旧版本存在缺陷:外部工具(Data Pump、GoldenGate、dblink、外部客户端)可推送超大 SCN,快速耗尽数据库可用 SCN 空间;SCN 存在理论上限,一旦耗尽数据库直接宕机无法写入,属于致命故障。该脚本用来提前测算 剩余可用 SCN 余量(SCN Headroom,SCN 剩余可用天数),分级预警风险。define LOWTHRESHOLD=10 -- 剩余≤10天:高危C级,立刻打补丁+联系Oracle支持 define MIDTHRESHOLD=62 -- 10<剩余≤62天:中危B级,尽快补丁-- >62天:安全A级 define VERBOSE=FALSE -- 是否打印详细Headroom数值
4.隐藏参数
_external_scn_rejection_threshold_hours=24补丁配套参数:拦截外部传入超过 24 小时的超大 SCN,防止外部工具恶意 / 异常推高 SCN。
define LOWTHRESHOLD=10 define MIDTHRESHOLD=62 define VERBOSE=FALSE set veri off; set feedback off; set serverout on
关闭校验、执行反馈,开启输出打印巡检结果;
可执行时传参修改阈值:
define VERBOSE=TRUE 输出精确剩余天数。
indicator = ( ( (基准时间换算总秒数)*16*1024 - 当前系统SCN(dbms_flashback.get_system_change_number) ) / (16*1024*60*60*24) )
公式逻辑:
Oracle 标准 SCN 速率: 每 1 秒最大消耗 16*1024 = 16384 个 SCN
用固定时间基准算出理论最大允许 SCN;
减去当前已使用 SCN,得到剩余 SCN 总量;
除以一天总秒数 × 每秒最大 SCN,换算为 剩余可用天数。
select version, -- 数据库版本 to_char(SYSDATE,'YYYY/MM/DD HH24:MI:SS') DATE_TIME, -- 当前时间 dbms_flashback.get_system_change_number current_scn, -- 当前实时SCN indicator -- 计算出的剩余可用天数 from v$instance
indicator >62 → A 安全:按计划定期打补丁
10<indicator ≤62 → B 中危:立刻打最新补丁
indicator ≤10 → C 高危:紧急补丁 + 立刻联系 Oracle 技术支持
11.2.0.2 以下版本打完补丁必须配置_external_scn_rejection_threshold_hours=24
10g 区间打完补丁强制配置拦截参数
当前时间、实时 SCN、数据库版本
可选输出精确剩余天数(VERBOSE=TRUE)
风险等级 A/B/C + 补丁操作指引
关联 MOS 文档:1393363.1(SCN 耗尽故障官方说明)
| 等级 | 剩余 SCN 天数 (indicator) | 风险 | 处置要求 |
|---|---|---|---|
| A 安全 | >62 天 | 低 | 日常维护周期打补丁 |
| B 预警 | 10~62 天 | 中 | 立即安排停机打 SCN 修复补丁 |
| C 紧急 | ≤10 天 | 极高 | 立刻停机维护、打补丁、联系 Oracle Support |
Current Date: 2026/07/09 15:30:22 Current SCN: 14289654721 Version: 11.2.0.1.0 Result: C - SCN Headroom is low If you have not already done so apply the latest recommended patches right now set _external_scn_rejection_threshold_hours=24 after apply AND contact Oracle support immediately.
_external_scn_rejection_threshold_hours=24;3)重启数据库,拦截外部超大 SCN,Headroom 恢复至 300 + 天。环境:19c 新版本数据库,官方已内置 SCN 防护机制;
脚本输出 A 安全,仅提示按季度更新补丁,无紧急操作。
数据库 10g,无补丁,脚本显示剩余 5 天;
若未及时处理,5 天后数据库所有 DML、DDL 直接报错,业务完全中断;
临时应急:断开所有 dblink、OGG 同步减缓 SCN 上涨,连夜停机打补丁。
sqlplus / as sysdba @scnhealthcheck.sql
define VERBOSE=TRUE@scnhealthcheck.sql
SCN Headroom: 126.35 代表剩余 126.35 天。_external_scn_rejection_threshold_hours=24 防护参数,无法完全拦截外部异常 SCN;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/12798004/viewspace-3175501/ ,如需转载,请注明出处,否则将追究法律责任。