ORA-600 [2252] & Know more about SCN
前段时间有个朋友遇到的问题,让我协助分析,现象是一个地市的数据库与省级数据库通过DBLINK连接时提示ORA-600 2252, 但是其它地市与省级的DBLINK正常。错误如下:
SQL> select sysdate from dual@ANBOB_RMT ORA-00600: 内部错误代码, 参数: [2252], [3985], [1364216517], [], [], [], [], []
ORA-600 [2252] [A] [B] [] [] []
Cause:
————
Oracle compares the given SCN value with the reasonable upper limit value calculated based on the
system date. If Oracle detects the provided scn is too large, ORA-600[2252] would be raised.
ARGS:
————
arguments A: SCN WRAP
arguments B: SCN BASE
Fix:
————
symptom: System date differs between the two machines
symptom: Query that uses a database link between two machines fails
cause: Argument [2252] for the ORA-00600 indicates that the System Change Number (SCN) Oracle is calculating for a transaction is an unreasonable number.
The SCN is calculated based in part on the host system date.
If the system date is a LONG way off, the maximum possible value calculated for the SCN may be impossibly large which would result in an ORA-600[2252].
简而言之:数据库当前的请求SCN大于当前最大允许SCN时会提示ORA-600[2252], 最大允许SCN是有本地系统时间决定。一个可能性是本地库主机时间向前调了,还有个可能性是通过DBLINK 分布式事务同步SCN时,远程库 SCN大于本地允许的最大scn.
SQL@ANBOB> select 3985*power(2,32)+1364216517 from dual; 3985*POWER(2,32)+1364216517 --------------------------- 17116808891077 SQL@ANBOB> select dbms_flashback.get_system_change_number scn from dual; SCN ---------- 15756464714 sys@ANBOB>select current_scn,dbms_flashback.get_system_change_number scn from v$database; CURRENT_SCN SCN -------------------- -------------------- 15756464716 15756464716 -- 确认时间,时区 select CURRENT_TIMESTAMP, LOCALTIMESTAMP FROM DUAL; -- 现场的人整理了本地(DBa)、远程(DBb)库的系统时间和SCN. DBa DBb -------- ---------- OS date: 20171204 15:50 20171204 15:48 sysdate: 20171204 .. 20171204 .. scn: 15756464722 17117005290806 DB ver: 11.2.0.1 11.2.0.3 OS Plat: Windows Aix
Note:
本地库和远程库的SCN不在一个数量级,相差1000倍,其实我们可以根据当前的时间计算一下SCN 的最大允许值,远程库的SCN 远大于本地库的最大允许SCN(简称RSL,下面会补充相关知识)。 关于SCN可以查阅 MOS note <<System Change Number (SCN), Headroom, Security and Patch Information (文档 ID 1376995.1)>>
— 查询远程库的SCN Headroom
SQL> select
2 version,
3 to_char(SYSDATE, 'YYYY/MM/DD HH24:MI:SS') DATE_TIME,
4 ((((
5 ((to_number(to_char(sysdate, 'YYYY')) - 1988) * 12 * 31 * 24 * 60 * 60) +
6 ((to_number(to_char(sysdate, 'MM')) - 1) * 31 * 24 * 60 * 60) +
7 (((to_number(to_char(sysdate, 'DD')) - 1)) * 24 * 60 * 60) +
8 (to_number(to_char(sysdate, 'HH24')) * 60 * 60) +
9 (to_number(to_char(sysdate, 'MI')) * 60) +
10 (to_number(to_char(sysdate, 'SS')))
11 ) * (16 * 1024)) - dbms_flashback.get_system_change_number)
12 / (16 * 1024 * 60 * 60 * 24)
13 ) indicator
14 from v$instance
15 ;
VERSION DATE_TIME INDICATOR
----------------- ------------------- ----------
11.2.0.3.0 2017/12/04 17:15:26 -959.18726
Note:
Oops!!! 上面的脚本也较常见来自官方的scnhealthcheck.sql, INDICATOR是距离SCN Headroom(天花板)的天数,是负数说明已经超过天花板上天了。当然scn限制是决定不会也不允许超过天花板的。 那会不会是远程库有问题?为什么其它地市的库可以跟这个远程库查询?负数的原因是什么?
基实上面的脚本对于11.2.0.2以后的数据库还需要确认另一处,就是每秒16K的限制从11G R2(11.2.0.2)起已经改变为32K(我查了11.2.0.3 11.2.0.4 12.2.0.1默认都是32K), 有隐藏参数”_max_reasonable_scn_rate”控制,同时需要使用下面的SQL语句实际确认是16K还是32K(只对11.2.0.2以后的版本有意义),因为我发现有些11.2的数据库仍然使用的是16K(也许是低版本直接升级原因,也许是某个PSU临时回归了16K的增速):
sys@ANBOB_RMT>@pd _max_reasonable_scn_rate Show all parameters and session values from x$ksppi/x$ksppcv... INDX I_HEX NAME VALUE DESCRIPTION -------------------- ----- ---------------------------- ---------- --------------------------- 978 3D2 _max_reasonable_scn_rate 32768 Max reasonable SCN rate sys@ANBOB_RMT>select decode(bitand(DI2FLAG,65536),65536,'Y','N') using16 from x$kccdi2; U - N sys@ANBOB_RMT>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'))) ) * (32 * 1024)) - dbms_flashback.get_system_change_number) / (32 * 1024 * 60 * 60 * 24) ) indicator from v$instance; VERSION DATE_TIME INDICATOR ----------------- ------------------- ---------- 11.2.0.3.0 2017/12/04 17:35:26 5087.41908
现在总结一下这个问题:
1,本地库是11.2.0.1 scn 的频率限制还是16K
2, 远程库是11.2.0.3,并且从x$kccdi2确认了当前使用的频率限制是32K
3, 远程库当前的SCN已经超过了本地库16K允许的上限所以使用DBLINK 同步SCN 会出现ora-600 [2252]
4, 远程库查询天花板需要修改脚本中16为32
5,其它地市能访问远程库是因为他们的数据库也是11.2.0.2版本以后,且同样使用的是32K的限制。
SCN增长速率加快了,如果32k的速度使用6bytes的scn总上限也就不是过去说的可用500年了,所以从12.2又引入了big scn加到了8bytes.且在12.2版本中对于SCN传播跳跃, 增加了2个视图可以定位源头, 使用DBA_EXTERNAL_SCN_ACTIVITY DBA_DB_LINK_SOURCES and DBA_DB_LINK关连就可以,2012年1月以后的PSU起或在11G的部份版本中提供了控制SCN相关参数:
A.1) SCN rejected due to request for high SCN increment (controlled by _external_scn_rejection_threshold_hours) 限制最多用到多少,保留时间
A.2) SCN rejected due to request in certain DELTA of changes (controlled by _external_scn_rejection_delta_threshold_minutes) 限制一次最多变化多少,如果请求超过会失败,提示ORA-19706。
A.3) SCN accepted but with a warning (controlled by _external_scn_logging_threshold_seconds) 增长超过一定阀值时,写ALERT LOG。
SCN相关知识点:
1, SCN 是Oracle数据库单向增长的”时钟”,广泛用于数据库一致性恢复和分布式事务(如dblink)
2, SCN 有两部分组成 wrap.base, 在数据库中占用8bytes, 在12c r2前预留2bytes, 是一个6bytes(48bit)的Integer类型的数字,[16bit SCN Wrap].[32bit SCN Base], 在12c R2起引入big scn, 启用了原来预留的2bytes, 总长限有原来的2^48增长到2^64。
3, 为了限制SCN无限增长,在程序的代码级设计了一个当前时间点的允许的最大SCN(Maximum Reasonable SCN)的软限制, Reasonable SCN Limit简称RSL, 这个值是有一个工式计算出来的RSL=(从1988年1月1日起到当前时间) * 24 * 3600 * 每秒允许的最大增长率, 需要注意的是并不是简单的当前时间和1988-1-1两个时间点相减,可能是出于计算的简单,每个月是按31天计算的,从上面MOS中提供的脚本也可以看出。 每秒允许的最大增长率在11.2.0.2之前是16384(16K)11.2.0.2及以后的版本是32768(32K),有隐藏参数_max_reasonable_scn_rate控制。
4, SCN Headroom是一个最重要的检查项,值是当前时间点的允许的最大SCN与当前数据库SCN的差值,为了方便阅读以”天“为单位,SCN Headroom 天数=(Maximum Reasonable SCN-Current SCN) / (每秒允许的最大增长率) /3600/24
5, SCN异常增长通常是有DBLINK、人为前推SCN、oracle bug。SCN的历史变化可以从V$ARCHIVED_LOG得到, 最近5天的SCN也可以尝试从smon_scn_time得到。 数据库自身的增长可以从从dba_hist_sysstat得到’calls to kcmgas’的变化, SCN通过DBLINK 的传播可以通过上面提到的参数控制,和12c 中提供的新视图。
6, 数据库11.2.0.2及以后的版本默认是允许32K的增长速率,所以就会像本案例以上产生较大的SCN, 这就意味着11.2.0.2可能不能再与低版本的数据库或是使用16K增长速率的数据库通过DBLINK。
更多可以参考我的另外两篇BLOG
预警:2019年ORACLE SCN 兼容性特性( Compatibility)自动改变的影响
案例: 修复Oracle 11.2.0.1 dblink 访问ORA-600 [2252]
如果您遇到了该问题解决不了,可以联系 www.anbob.com 首页上的联系方式找到我。
对不起,这篇文章暂时关闭评论。