ORA-19706: invalid SCN 问题分析

SQL> select sysdate from dual@dl330781;
select sysdate from dual@dl330781
*
ERROR at line 1:
ORA-19706: invalid SCN
[oracle@jbdb bdump]$ tail -f alert_orcl.log
Mon Mar 23 16:43:25 CST 2015
db_recovery_file_dest_size of 2048 MB is 0.00% used. This is a
user-specified limit on the amount of space that will be used by this
database for recovery-related files, and does not reflect the amount of
space available in the underlying filesystem or ASM diskgroup.
Mon Mar 23 16:43:25 CST 2015
Completed: alter database open
Tue Mar 24 13:48:13 CST 2015
Rejected the attempt to advance SCN over limit by 389 hours worth to  0×0d05.bcf8452b(这个是准备同步的scn目标值), by distributed transaction remote logon, remote DB: LXSB.US.ORACLE.COM.
Client info : DB logon user LWZBDB, machine jbdb, program sqlplus@jbdb (TNS V1-V3), and OS user oracle
这个错误的原因是,在两个库通过db link进行分布式事务时,假设B库的SCN值要高于A库的SCN,因此要将B库的SCN增同步到A库,但是如果B库的SCN过高,这样同步到A库之后,使得A库面临Headroom过小的风险,那么A库会拒绝同步SCN,这个时候就会报ORA-19706: Invalid SCN错误
而说起headroom则需要理解以下概念
1).SCN的内部存储方式:在Oracle内部,SCN分为两部分存储,分别称之为scn wrap和scn base。实际上SCN长度为48位,即它其实就是一个48位的整数。只不过可能是由于在早些年通常只能处理32位甚至是16位的数据,所以人为地分成了低32位(scnbase)和高16位(scn wrap)。为什么不设计成64位,这个或许是觉得48位已经足够长了并且为了节省两个字节的空间:)。那么SCN这个48位长的整数,最大就是2^48(2的48次方, 281万亿,281474976710656),很大的一个数字了。
2) Maximum Reasonable SCN:在当前时间点,SCN最大允许达到(或者说最大可能)的SCN值。也称为Reasonable SCN Limit, 简称RSL。这个值是一个限制,避免数据库的SCN无限制地增大,甚至达到了SCN的最大值。
那么SCN每秒最大可能增长速率是多少呢,这个跟Oracle版本有一定的关系,在11.2.0.2之前是16384(即16K),在11.2.0.2版本是32768(即32K)。在11.2.0.2的版本中有一个隐含参数,_max_reasonable_scn_rate,其默认值就是32768(不建议调整这个值)。如果按16K的最大值,SCN要增长到最大,要超过500年
这个值大约是这样一个公式计算出来的:(当前时间- 1988年1月1日(因为系统时间小于它oracle将不能启动))*24*3600*SCN每秒最大可能增长速率
SCN Headroom(顶部空间,可以理解为增长空间或者剩余空间): 这个是指MaximumReasonable SCN与当前数据库SCN的差值。在alert中通常是以“天”为单位,这个只是为了容易让人读而已。天数=(Maximum Reasonable SCN-Current SCN)/16384/3600/24。 这个值就的意思就是,如果按SCN的最大增长速率,多少天会到达Maximum Reasonable SCN。但实际上即使如此,也不会到达Maximum Reasonable SCN,因为到那时MaximumReasonable SCN也增大了(时间增大),要到达Maximum Reasonable SCN,得必须以SCN最大可能速率的2倍才行。
2012年1月CPU或PSU补丁的一个重要变化是增加了_external_scn_rejection_threshold_hours参数,这个参数字面意思就是就是”拒绝外部SCN“的阈值。对于数据库自身产生的SCN递增是没有影响的。
其最重要的功能就是防止dblink同步scn使得数据库SCN headroom变小,这带来的影响就是ORA-19706的错误出现的概率更高。
解决的办法将_external_scn_rejection_threshold_hours这个隐含参数设置为较小的值,推荐的值是24,即1天。
查询当前库该参数的默认值
SQL> select * from v$version;
BANNER
—————————————————————-
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 – 64bi
PL/SQL Release 10.2.0.5.0 – Production
CORE 10.2.0.5.0 Production
TNS for Linux: Version 10.2.0.5.0 – Production
NLSRTL Version 10.2.0.5.0 – Production
SQL> select a.ksppinm name, b.ksppstvl value, a.ksppdesc description from x$ksppi a, x$ksppcv b where a.indx = b.indx and a.ksppinm like ‘_external_scn_rejection_threshold_hours’;
NAME
——————————————————————————–
VALUE
——————————————————————————–
DESCRIPTION
——————————————————————————–
_external_scn_rejection_threshold_hours
744
Lag in hours between max allowed SCN and an external SCN
也就是说外部SCN想要同步到本库,则必须满足同步后本库scn即使以最快的增长速度(这里是16K)也要744个小时(31天)才能达到最大允许scn,而alert日志里面显示如果同步外部scn,则这个时间值将变成389小时,小于744,所以被拒绝,前台则提示ORA-19706: invalid SCN错误
11.2.0.2以后的版本该值默认为24,即1天,说明从这个版本开始oracle放宽了这个限制,允许scn有更大的增长空间
SQL> select timestamp_to_scn(to_timestamp(‘ 2015-03-24 13:48:13‘,’yyyy-mm-dd hh24:mi:ss’)) src,to_number(‘ 0d05bcf8452b‘,’xxxxxxxxxxxx’)tar from dual;
SRC TAR
——————– ——————–
2395460 14318296384811
SQL> select (14318296384811-2395460)/16384/3600/24 hours from dual;
HOURS
——————–
10114.80683881335788
根据alert日志显示的报错时间,计算该时间点的rsl
SQL> select (to_date(‘2015-03-24 13:48:13′,’yyyy-mm-dd hh24:mi:ss’)-to_date(‘1988-01-01′,’yyyy-mm-dd’))*24*3600*16384 rsl from dual;
RSL
——————–
14077317824512
SQL> select (
((to_number(to_char(cur_date,’YYYY’))-1988)*12*31*24*60*60) +
((to_number(to_char(cur_date,’MM’))-1)*31*24*60*60) +
(((to_number(to_char(cur_date,’DD’))-1))*24*60*60) +
(to_number(to_char(cur_date,’HH24′))*60*60) +
(to_number(to_char(cur_date,’MI’))*60) +
(to_number(to_char(cur_date,’SS’)))
) * (16*1024) rsl
from (select to_date(‘2015-03-24 13:48:13′,’yyyy-mm-dd hh24:mi:ss’) cur_date from dual);
RSL
——————–
14339199680512
两种方法获取的最大合理scn有差距,第一种是通过oracle内部计算得出,第二种以每月31天粗略估算,可以看出传递的scn值已经超过了第一种。
根据第二种方法计算的rsl继续计算其对应的headroom
SQL> select
((((
((to_number(to_char(cur_date,’YYYY’))-1988)*12*31*24*60*60) +
((to_number(to_char(cur_date,’MM’))-1)*31*24*60*60) +
(((to_number(to_char(cur_date,’DD’))-1))*24*60*60) +
(to_number(to_char(cur_date,’HH24′))*60*60) +
(to_number(to_char(cur_date,’MI’))*60) +
(to_number(to_char(cur_date,’SS’)))
) * (16*1024)) – 14318296384811)
/ (16*1024*60*60*24)
) headroom
from (select to_date(‘2015-03-24 13:48:13′,’yyyy-mm-dd hh24:mi:ss’) cur_date from dual);
HEADROOM
——————–
14.76661943576954029
由此说明如果同步scn到14318296384811,则以16k的增长速度,只需要14天即可达到rsl 14339199680512,小于_external_scn_rejection_threshold_hours参数指定的744/24=31天
SQL> select (31-14.76661943576954029)*24 from dual;
(31-14.76661943576954029)*24
—————————-
389.601133541531033
修改heardroom阈值限制为24小时.
SQL> alter system set “_external_scn_rejection_threshold_hours”=24 scope=spfile;
shutdown immediate;
startup
SQL> select b.ksppstvl value from x$ksppi a, x$ksppcv b where a.indx = b.indx and a.ksppinm like ‘_external_scn_rejection_threshold_hours’;
VALUE
——————————————————————————–
24
SQL> select current_scn from v$database;
CURRENT_SCN
——————–
2407528
SQL> conn lwzbdb/lwzbdb
Connected.
SQL> select sysdate from dual@dl330781;
SYSDATE
———
24-MAR-15
SQL> conn / as sysdba
Connected.
SQL> select current_scn from v$database;
CURRENT_SCN
——————–
14318296497701 这里可以看到scn在经过一个dblink查询之后 大幅增长
Tue Mar 24 21:55:54 CST 2015
Advanced SCN by 14565321 minutes worth to 0×0d05.bcf9fda3, by distributed transaction remote logon, remote DB: LXSB.US.ORACLE.COM.
Client info : DB logon user LWZBDB, machine jbdb, program sqlplus@jbdb (TNS V1-V3), and OS user oracle
SQL> select to_number(‘0d05bcf9fda3′,’xxxxxxxxxxxx’),14565321/60/24 from dual;
TO_NUMBER(‘0D05BCF9FDA3′,’XXXXXXXXXXXX’) 14565321/60/24
—————————————- ——————–
14318296497571 10114.80625
10114.80625表示按照每秒16k的增长速度 ,需要经过10114.80625天scn才能从2407528增长到14318296497571 ,足见增幅之大
SQL> select
((((
((to_number(to_char(cur_date,’YYYY’))-1988)*12*31*24*60*60) +
((to_number(to_char(cur_date,’MM’))-1)*31*24*60*60) +
(((to_number(to_char(cur_date,’DD’))-1))*24*60*60) +
(to_number(to_char(cur_date,’HH24′))*60*60) +
(to_number(to_char(cur_date,’MI’))*60) +
(to_number(to_char(cur_date,’SS’)))
) * (16*1024)) – 14318296497571)
/ (16*1024*60*60*24)
) headroom
from (select to_date(‘2015-03-24 21:55:54′,’yyyy-mm-dd hh24:mi:ss’) cur_date from dual);
HEADROOM
——————–
15.10520876072071217
由此说明如果同步scn到14318296384811,则以16k的增长速度,需要15天才能达到2015-03-24 21:55:54时间点的rsl,大于_external_scn_rejection_threshold_hours参数指定的24/24=1天,所以即使其增幅巨大也被oracle通过

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值