ORA-19706:invalid SCN

  某客户上个月刚迁移升级的业务系统在今天执行某条sql查询报ORA-19706:invalid SCN,导致无法正常显示查询结果。经了解,具体报错的基本情况是:

192.168.2.85上的用户通过db_link去访问192.168.2.45下面的数据,报:

<img src="http://s1.sinaimg.cn/mw690/0037BKKwgy6R04eYdrOf0&690" real_src="http://s1.sinaimg.cn/mw690/0037BKKwgy6R04eYdrOf0&690" height="55" width="304" name="image_operate_10551427354914625" alt="Oracle  db_link引发的ORA-19706:invalid SCN错误" title="Oracle  db_link引发的ORA-19706:invalid SCN错误" action-data="http%3A%2F%2Fs1.sinaimg.cn%2Fmw690%2F0037BKKwgy6R04eYdrOf0%26690" action-type="show-slide" style="margin:0px;padding:0px;list-style:none;" />

我们统计了下午3点多到晚上10点多的SCN的增长速度

 

下午3点多的SCN值

晚上10点多的SCN

相差

192.168.2.45(B库)

14246110914784

14245785946041

324968734

192.168.2.85(A库)

14238384967631

14238383909345

1058286

看一下ORA-19706错误的解释:可以看到too large是产生该问题的原因之一

$oerr ora 19706

19706, 00000, "invalid SCN"

// *Cause:  The input SCN is either not a positive integer or too large.

// *Action: Check the input SCN and make sure it is a valid SCN.

我们先来了解下SCN

1: SCN



SCN是当Oracle数据库更新后,由DBMS自动维护去累积递增的一个数字。

在Oracle内部,SCN分为两部分存储,分别称之为scn wrap和scn base。SCN长度为48位,即它其实就是一个48位的整数。那么SCN这个48位长的整数,最大就是 2^48(2的48次方, 281万亿,281474976710656),这是很大的一个数字了。 据推算这个值可以保证Oracle数据库理论上可以处理500年的数据。
   


      Maximum Reasonable SCN:在当前时间点,SCN最大允许达到的SCN值被称为" Maximum Reasonable SCN“(最大合理SCN),也称为Reasonable SCN Limit,简称RSL。这个值是一个限制,避免数据库的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 Headroom这个是指Maximum Reasonable SCN与当前数据库SCN的差值。在alert中通常是以“天”为单位,这个只是为了容易让人读而已。天数=(Maximum Reasonable SCN-Current SCN)/16384/3600/24。这个值就的意思就是,如果按SCN的每大增长速率,多少天会到达Maximum Reasonable SCN。但实际上即使如此,也不会到达Maximum Reasonable SCN,因为到那时Maximum Reasonable SCN也增大了(越时间增大),要到达Maximum Reasonable SCN,得必须以SCN最大可能速率的2倍才行。


关于SCN Headroom, Oracle提供了一个脚本 scnhealthcheck.sql 用于检查数据库当前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=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;
/


<img src="http://s16.sinaimg.cn/mw690/0037BKKwgy6R073DYrd1f&690" real_src="http://s16.sinaimg.cn/mw690/0037BKKwgy6R073DYrd1f&690" height="113" width="535" name="image_operate_55391427360206167" alt="Oracle  db_link引发的ORA-19706:invalid SCN错误" title="Oracle  db_link引发的ORA-19706:invalid SCN错误" action-data="http%3A%2F%2Fs16.sinaimg.cn%2Fmw690%2F0037BKKwgy6R073DYrd1f%26690" action-type="show-slide" style="margin:0px;padding:0px;list-style:none;" />

以下是客户实际环境检查输出结果:

<img src="http://s14.sinaimg.cn/mw690/0037BKKwgy6R07sTEVn2d&690" real_src="http://s14.sinaimg.cn/mw690/0037BKKwgy6R07sTEVn2d&690" height="232" width="552" name="image_operate_76991427360206217" alt="Oracle  db_link引发的ORA-19706:invalid SCN错误" title="Oracle  db_link引发的ORA-19706:invalid SCN错误" action-data="http%3A%2F%2Fs14.sinaimg.cn%2Fmw690%2F0037BKKwgy6R07sTEVn2d%26690" action-type="show-slide" style="margin:0px;padding:0px;list-style:none;" />


SCN的异常增长几种类型

1: 数据库内部BUG触发,

2:人为调整导致SCN异常增长过大,比如数据库通过特殊手段强制打开,手工把SCN递增得很大。

3 : 通过db link传播。如果A库通过db link连接到B库,如果A库的SCN高于B库的SCN,那么B库就会递增SCN到跟A库一样,反之如果A库的SCN低于B库的SCN,那么A库的SCN 会递增到跟B库的SCN一样。也就是说,涉及到db link进行操作的多个库,它们会将SCN同步到这些库中的最大的SCN。

客户场景的实际情况来看,属于第3种类型导致SCN异常增长。B库的SCN值要高于A库的SCN,因此要将B库的SCN增同步到A库,但是如果B库的SCN过高,这样同步到A库之后, 使得A库面临Headroom过小的风险,那么A库会拒绝同步SCN,这个时候就会报ORA-19706: Invalid SCN错误。




解决方法:

  1: 由于B库数据库版本为10.2.0.4. Oracle推荐解决SCN增长异常的最佳办法就是给B库打上相应的补丁或者直接升级到10205并打上最新的PSU .但由于B库和A库不是同一个中心管辖的系统,而且B库也不允许升级带来的风险和停机时间。

 2: 只能委曲求全从A库下手,由于A库是最新升级的oracle 11203版本,通过隐含参数_external_scn_rejection_threshold_hours来处理这个问题,

在11203版本中,该值默认为24,单位小时。从_external_scn_rejection_threshold_hours这个参数名的字面意思结合它的作用,可以说这个参数就是”拒绝外部SCN“的阈值。极端情况下可以设置为1。

在本案例中,减少该隐含参数的值,我们将该值设置为1,重启数据库后,ORA-19706报错得以解决。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25462274/viewspace-1980848/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/25462274/viewspace-1980848/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值