Oracle数据库管理-低版本数据库SCN问题分析

OracleSCN机制更新与数据库版本管理
Oracle从2019年6月开始启用SCN(Autorollover)的新机制,SCN增长率提升至96K,旧版本数据库需打补丁或升级以避免与新版本通过DBLink连接时的问题。SCN是系统改变号,用于数据库一致性与恢复操作。若SCN接近极限,数据库可能出错,需关注数据库版本和SCN健康状况。Oracle提供了scnhealthcheck.sql脚本检查SCN剩余空间。

1 SCN内容概述

在早些一段时间Oracle更新了一篇文章(ANNOUNCEMENT: Recommended patches and actions for Oracle databases versions 12.1.0.1, 11.2.0.3 and earlier – before June 2019 (Doc ID 2361478.1))

简单的说,Oracle将在2019年6月份自动启动SCN的新机制(auto rollover),即SCN rate 最大增长可达96K(每秒增加的SCN不超过 96K),远超之前的32kb(在 Oracle 11.2.0.2 之前这个限制是 16K)。

高版本最大值增加96K,而低版本数据库无法增加96K?????

那么哪些版本的数据库会自动启用这个机制,查看如下:

 也就是说11.2.0.4和12.1.0.2以及12.2.0.1以上已经包含了必要的修复,已天然豁免。11.1.0.7和11.2.0.3版本需要打相对应补丁。 其他版本无补丁,需要升级,否则低版本和新版本的其他库通过 DB Link 连接时可能遇到问题。

2 哪些版本的数据库需要处理

如果你的所有Oracle数据库都是11.2.0.4或12.2等新版本,那么无需做任何处理;
如果你的所有数据库中,有部分低版本(如10205、11.1)需要通过dblink访问高版本的库(如11.2.0.4,12.2),那么可能有风险,建议将低版本的库进行升级或者安装上面推荐的Patch;
如果你的数据库都是低版本的库,那么不受任何影响;
如果你的数据库之间,没有dblink相互访问,你也可以高枕无忧!

3 科普一下SCN机制


1、SCN(System Change Number) ,也就是通常我们所说的系统改变号,是数据库中非常重要的一个数据结构。它定义数据库在某个确切时刻提交的版本。在事物提交时,它被赋予一个唯一的标示事物的 SCN 。 SCN 提供 Oracle 的内部时钟机制,可被看作逻辑时钟,这对于恢复操作是至关重要的 ( Oracle 仅根据 SCN 执行恢复)。

2、Oracle 通过 SCN 来维护数据库的一致性,并通过SCN 实施 Oracle 至关重要的恢复机制。

3、SCN 是Oracle数据库的内部时钟,单调递增,不可逆转。

4 SCN接近极限值的风险


SCN 在很多情况下会增长,比如Commit,Oracle对这个增长进行控制。如果通过 DB Link 进行跨数据库访问,基于分布式一致性原理,Oracle会将两个数据库的SCN时钟同步;通过DB Link,SCN低的被拉高,一旦超过数据库的允许限制,就会出错。如果数据库的 SCN 接近极限,则数据库就可能频繁出错,最坏的情况是事务都执行不了,数据库停顿。由于SCN不可以重置,严重情况甚至要重建数据库。

查看下scn使用的最大位数
Oracle 使用了 6 Bytes 记录SCN,也就是48位,不能无限增长。6 Bytes 的最大值是:

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

如果在6月份使用最新的scn机制schema 3,也就是Oracle在内部控制每秒增加的SCN不超过 96K,按照这样计算,那么在 96K 的约束之下,SCN 的存储空间,可以使用 90 年。

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

当然,在新的算法中,Oracle改变了 SCN 算法的起点值,在最新96K的增长率下,起点分别近似调整为:
3: ~ 2008/03/30
所以经过调整最大支持到大约 2097年。

我们需要做哪些
梳理所有Oracle数据库,确认版本信息,将数据库升级到11.2.0.4、12.1.0.2以上版本或者包含补丁程序的低版本打补丁。

以下是11.2.0.4的数据库,检查是否启用SCN的新机制(auto rollover)

set serveroutput on

declare

v_autorollover_date date;

v_target_compat number;

v_is_enabled boolean;

begin

dbms_scn.getscnautorolloverparams(v_autorollover_date,v_target_compat,v_is_enabled);

dbms_output.put_line('auto rollover date :'||to_char(v_autorollover_date,'YYYY-MM-DD'));

dbms_output.put_line('target scheme : '||v_target_compat);
dbms_output.put_line('rollover enabled (1=yes): '||sys.diutil.bool_to_int(v_is_enabled));

end;

/

auto rollover date      : 2019-06-23
target scheme           : 3
rollover enabled (1=yes): 1

PL/SQL procedure successfully completed.

大家可以在sqlplus中执行如上脚本,

如有上述结果输出,证明这个数据库会自动启用新的SCN机制。

---------------------------文章2 ----------------------

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.

--------------------------------------

这个问题已经出现在客户环境中,需要引起大家的足够重视。

在SCN告警阈值达到时,数据库中可能出现以下错误信息:

Advanced SCN by 8381 minutes worth to Ox0bad.4ab15e1,by distributed transaction remote logon,remote DB:ORCL.

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.

Warning: The SCN headroom for this database is only NN days!

Warning: The SCN headroom for this database is only N hours!

Rejected the attempt to advance SCN over limit by 984 hours worth to 0x0c00.0000ff66, by distributed transaction remote logon, remote DB: DB.ORCL.ORACLE.COM.

Client info : DB logon user SYS, machine sun, program sqlplus@orcl (TNS V1-V3), and OS user oracle

Rejected the attempt to advance SCN over limit by 9875 hours worth to 0x0c00.000003e6, by distributed transaction logon, remote DB: DB.ORCL.ORACLE.COM.MOS参考文档:

NOTE:1376995.1 - Information on the System Change Number (SCN) and how it is used in the Oracle Database

NOTE:1393363.1 - Installing, Executing and Interpreting output from the "SCNhealthcheck.sql" script

NOTE:1388639.1 - Evidence to collect when reporting "high SCN rate" issues to Oracle Support

NOTE:1393360.1 - ORA-19706 and Related Alert Log Messages

By eygle on 2012-05-17 23:38 |

Comments (0) |

Advanced |

Internal | 3003 |
 

————————————————
版权声明:本文为优快云博主「iverycd」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/kiral07/article/details/90202774

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值