关于SCN Headroom

2019-02-13  本文已影响0人  Reiko士兵

参考文献

  1. SCN警报
  2. 由oradebug poke推进scn理解scn base及scn wrap系列一
  3. SCN HeadRoom 事件分析

一、 再来谈谈SCN

上一篇文章谈到了SCN的一些种类和查询方式,这一篇再来具体看看SCN。

SCN是Oracle数据库为了确保数据和事务的一致性设计的逻辑时间戳,在Oracle数据库内部用6个字节、48位记录SCN,SCN由SCN Base和SCN Wrap组成,其中SCN Base占用4个字节,而SCN wrap占用2个字节,且有:

scn=scn wrap * power(2,32)+scn base

更多关于SCN Base和SCN Wrap的内容可看参考文献2
显然,SCN的最大值

Col SCN FOR 99999999999999999

SELECT Power(2, 48) SCN
FROM   dual;

输出结果为:

               SCN
------------------
281 4749 7671 0656

这个值是Oracle数据库设定的SCN理论上限,也就是所谓的hard limit,一旦达到这个值,SCN将无法继续增长,数据库也将变得不再可用,只能重新建库。Oracle为了确保数据库的长期可用,还设计了个soft limit,也就是headroom,将SCN的增长速度控制在每秒不超过16k,并且当前SCN不得大于1988年到当前时间点的最大SCN,在此限制下,Oracle数据库的理论最大可用年限为

SELECT Power(2, 48) / 16 / 1024 / 3600 / 24 / 365 AS years
FROM   dual;

输出结果为:

     YEARS
----------
544.770078

使用五百多年后才可能达到hard limit。当前时刻的最大SCN取值为

SET numw 20

SELECT ( ( ( 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')) ) ) * 16384 AS MAXSCN
FROM   dual;

其计算公式为:当前时刻最大SCN=1988年至当前时刻的秒数*16k
headroom的计算方式为:当前时刻最大SCN-当前实际SCN

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)

正常情况下,SCN的增长也不会大于soft limit所限制的最大SCN,但是怕就怕它不正常。

二、 SCN的BUG与DB_LINK共同引发的灾难事件

如果某一个数据库存在SCN异常增长的BUG,而其他数据库通过DB_LINK与其相互连接,DB_LINK在工作时会取两端数据库SCN值较大的一个来作为同步SCN,这意味着其他SCN正常的数据库也会发生异常,而其他原本正常的数据库也通过DB_LINK连向另外的数据库的话,则会导致SCN异常增长的问题进一步扩大另外的数据库,发生链式反应。
在2012年1月的补丁中,增加了参数external_scn_rejection_threshold_hours,这个参数设定了同步过来的SCN值计算出的headroom小于多少时拒绝DB_LINK连接的SCN同步请求。

上一篇 下一篇

猜你喜欢

热点阅读