前 言
ENTER TITLE
近日,Oracle的官方技术支持网站MOS上发布了两篇与DB Link(数据库链接)相关的预警文章,它们分别是:
Mandatory Patching Requirement for DatabaseVersions 11.2.0.3 or Earlier, Using DB Links (文档 ID2335265.1)
Oracle Databases Need to be Patched to aMinimum Patchset/PSU/RU level before April 2019 (文档 ID2361478.1)
这两篇文章引起了很多用户的担心,对此,中亦科技经过分析后给出的建议是:这个补丁并不会引发问题。这个补丁只是对ORACLE功能的一种增强,提供了更大的SCN增长能力,如果你的系统确实需要每秒16K以上的SCN增长(系统繁忙,事务数巨大),不管有没有DBLINK,这个补丁都是建议打上的;而即使无法在2019年6月23日前打上该补丁,对于正常系统来说影响的概率也是极低的;即使在使用过程中出现了DB LINK因SCN问题无法访问的情况,及时打上补丁即可修复问题。所以面对这个问题,我们无需恐慌,按照生产需求来管理维护我们的系统即可。

我们关心的问题都在这里
本次预警提及的版本有哪些?
答:在本次预警涉及的变化,在11.1.0.7.20+ 11.2.0.3.9+ 11.2.0.4+ 版本已经包含对应的补丁,实现了关于SCN的新特性,默认将会在2019年6月23日之后改变SCN的一些特征;
该补丁实现了什么功能?
答:补丁本身并不针对某个具体bug进行修复,该补丁的作用旨在调整SCN的上限计算策略,尽量地规避SCN增长过快的系统可能遇到的“SCN Headroom(SCN天花板)”问题;所以,这个补丁并不改变系统中SCN本身的变化的速率,只是让系统对SCN本身变化的“容忍度”变大了,可允许的系统中SCN的变化率相较于之前更大。
该补丁与DBLINK有什么关系?
答:该补丁本身并不对DBLINK做出调整;但是,ORACLE数据库间通过DBLINK互访需要同步SCN;如果两库在同步SCN时,因低SCN库同步成高SCN,ORACLE在计算SCN变化率结果大于原来的“容忍度”时,将会导致DBLink访问失败,严重时导致宕机的情况;这个补丁的作用在于将“容忍度”扩大,尽量规避这种情况的出现。
这个补丁是怎么影响到DBLink的?
答:上述补丁在试图规避“SCN Headroom”的过程中,也带来了新系统(打了补丁的系统)与旧系统(未打补丁的系统)间容忍SCN增长的上限不一致的问题,新系统允许SCN增长更快,而旧系统SCN增长上限不变,这样在新旧系统间通过DB Link同步SCN后,可能导致旧系统出现SCN增长率超过其原“容忍度”而出现问题;但是,上述问题出现的前提是:新系统运行确实非常繁忙,SCN增长速度确实足够快,这与补丁本身无关。
不升级/不打补丁我的DB Link就不能用/数据库就必然会CRASH吗?
答:不是!系统SCN的变化是基于系统的繁忙情况,事务的多少等;在打上该补丁后,系统SCN的变化速度并不改变,只是允许系统上存在更多事务/允许系统增长更多的SCN,这样在通过DBLINK同步到其他低SCN又未打补丁的系统上时,才会有可能造成DB link访问拒绝或数据库crash;
升级/打补丁之后我的DB Link就可以高枕无忧地使用了吗?
答:不是。如前所述,该补丁本质只是增大了SCN增长速度的“容忍度”,如果某系统上依然存在bug或其他原因导致SCN的异常增长,计算出的SCN增长速度超过了SCN增长的“容忍度”,即使是所有系统都打上了该补丁,DB Link间的SCN同步依然会发生,同样会将SCN的异常传播到整个DB Link网络;
我应该优先关注/处理什么样的系统?
综上,我们应该优先注意环境中目前是否存在SCN增长过快的系统;
建议检查目前环境中的所有数据库的SCN值,是否接近15.9万亿(15907472244736)。
select to_char(current_scn) fromv$database ;
如果存在SCN值较大的库,需要查看其SCN增长值,抓取业务高峰期间AWR报告,搜索关键字“kcmgas”,
nstance ActivityStats
Statistic | Total | per Second | per Trans |
calls to kcmgas | 9,433,023 | 5,188.09 | 4.69 |
如果该值超过16K,我们应该进一步检查该系统是否存在DB Link关系与其他系统关联;
数据库是否存在数据库链接可以通过下面的查询获得数据库链接的详细信息
SQL>select * from dba_db_links;
如果您的数据库版本为12.1.0.1 或者更新,还可以用下面的查询了解哪些数据库链接是指向自己的。
SQL>select * fromdba_db_link_sources;
如果,存在业务高峰期SCN增长速率超过16K,而且存在与其他系统的DB Link关系,则建议优先将该系统和对应的DB Link关联系统升级/打补丁;否则对于该问题暂时可以从容应对,不需特别关注。
如果我想升级/打补丁,我需要怎么做?
对于老版本的数据库,建议升级,升级列表汇总如下:
数据库版本 | 解决方案 |
10.2.0.<X> | 请升级到11.2.0.4 或者更高的版本 |
10.1.0.<X> | 请升级到11.2.0.4 或者更高的版本 |
9i | 请升级到11.2.0.4 或者更高的版本 |
11.2.0.1, 11.2.0.2 | 请升级到11.2.0.4 或者更高的版本 |
11.2.0.3 | 应用PSU补丁11.2.0.3.9(补丁编号17540582)或者更高的PSU补丁 |
11.2.0.3(windows 平台) | 应用增量补丁29, 补丁编号18075406 (64位) ,补丁编号18075405 (32位)或者更高的增量补丁 |
11.1.0.7 | 应用PSU补丁11.1.0.7.20(补丁编号18522513 )或者更高的PSU补丁 |
11.1.0.7(windows平台) | 增量补丁57,补丁编号18944208 (64位) , 补丁编号18944207 (32位) 或者更高的增量补丁 |
Exadata系统,而且数据库版本为11.2.0.3 | 应用Exadata PSU 补丁 11.2.0.3.22 (补丁编号17747147 )或者更高的PSU补丁 |
首先我们回顾下,前几年出现较多的SCNReject问题,部分Oracle数据库在安装2012年1月份发布的CPU或SPU补丁后Alert日志经常出现下列信息或者报错。
ORA-19706: invalid SCN
Advanced SCN by 68093 minutes worth to …
Rejected the attempt to advance SCN over limit by 166 hours worth …
普及下相关知识点:
SCN存在2种限制:硬限制为固定值约281万亿(2的48次方);软限制从1988年到当前时间点的秒数,再乘上16,384(16k)即Headroom=(current_time-1988)*16384-(current_scn)。
SCN Headroom指的是当前数据库SCN与当前时间的SCN软限制的差距。
正常情况下SCN的设计是没有问题的,但是由于BUG或者强制开库等原因,导致部分数据库SCN增长异常。DBLink交互数据需要同步源端和目标端的SCN值,如果递增SCN使其SCN Headroom过小,DB Link将会被拒绝连接,万一RECO进程遇到SCN增长被拒绝并且没更新SCNhardening补丁可能导致数据库实例Crash。
2012年1月份的补丁中,包含了SCNhardening补丁,将允许同步的SCN Headroom Reject Threshold由原来的1小时调整成了1天(11.2.0.2)或31天(其他版本),导致DB Link连接更容易被拒绝连接。
我的数据库距离Headroom还有多远?
我们在高版本的数据库中,发现和此次SCN Compatible升级有关的包——DBMS_SCN,其中存在一个函数”GETSCNPARAMSBYCOMPAT”用于预先判断当前数据库升级到目标SCN Compatibility版本,还有Headroom时间。
SQL> DESC DBMS_SCN
FUNCTION GETSCNPARAMSBYCOMPAT RETURNS BOOLEAN
Argument Name Type In/Out Default?
----------------------------------------------------- ------ --------
COMPAT NUMBER IN
RSL NUMBER OUT
HEADROOM_IN_SCN NUMBER OUT
HEADROOM_IN_SEC NUMBER OUT
从$ORACLE_HOME/rdbms/admin/dbmsscnc.sql这个脚本中可以看到这几个参数的具体含义。
-- compat -- SCN compatibility value
-- rsl -- Reasonable SCN Limit
-- headroom_in_scn -- Difference between current SCN and RSL
-- headroom_in_sec -- number of seconds it would take to reachRSL
-- assuminga constant SCN consumption rate associated
-- withspecified database SCN compatibility
测试该函数,其中COMPAT为输入参数,代表SCNCompatible的版本。
declare
compat number := 1;
rsl number;
headroom_in_scn number;
headroom_in_sec number;
var boolean;
begin
var:=dbms_scn.GetSCNParamsByCompat(compat,rsl,headroom_in_scn,headroom_in_sec);
dbms_output.put_line('compat=' ||compat);
dbms_output.put_line('rsl=' ||rsl);
dbms_output.put_line('headroom_in_scn=' || headroom_in_scn);
dbms_output.put_line('headroom_in_sec=' || headroom_in_sec);
end;
/
Current SCNCompatibility=1
Reasonable SCNlimit=15907519004672
hrt =970917777
hrs=15907516861870
Max Compatibility=3
测试下SCN Compatible的几种可能值,估算出其每秒钟最大的SCN数。当SCN Compatible版本不同,那么当前数据库距离Headroom的时间也越短。
虽然在SCN Compatible版本为3的情况下Headroom时间最短,但是其每秒钟允许真正的SCN数目也越大,一般的业务较难达到每秒98304个SCN,且Headroom随着时间的流逝,每秒钟都在增加,完全不需要担心升级到SCN Compatible 3 后SCN不够用。
新版本在19年6月份会做什么?
通过AUTO ROLLOVER机制,在2019年6月23日数据库会自动调整SCN Compatibility为3。
set serveroutput on;
declare
auto_rollover_ts date;
target_compat number;
is_enabled boolean;
begin
dbms_scn.getscnautorolloverparams(auto_rollover_ts,target_compat,is_enabled);
dbms_output.put_line('auto_rollover_ts='||to_char(auto_rollover_ts,'YYYY-MM-DD'));
dbms_output.put_line('target_compat=' ||target_compat);
end;
/
effective_auto_rollover_ts=2019-06-23
target_compat=3
那么我们能够控制这个特性吗。
如何不让系统自动调整SCN Compatibility
可以看到DBMS_SCN里面还包含了2个存储过程,可能和Auto Rollover有关。
SQL> desc dbms_scn
PROCEDUREDISABLEAUTOROLLOVER
PROCEDUREENABLEAUTOROLLOVER
这边进行模拟测试,首先找套SCN正常11.2.0.4版本的数据库,其SCN Compatibility为1。
Current SCNCompatibility=1
Reasonable SCNlimit=15907519004672
hrt =970917777
hrs=15907516861870
Max Compatibility=3
禁用Auto Rollover
SQL> EXECDBMS_SCN.DISABLEAUTOROLLOVER;
PL/SQL proceduresuccessfully completed.
关闭数据库
SQL> shutodwnimmediate
修改时间到2019年6月23日之后。
[root@lnx11204s1 ~]#date -s 2019-08-01
Thu Aug 1 00:00:00 CST 2019
启动数据库,检查SCN Compatibility版本,还是为1。
Current SCNCompatibility=1
Reasonable SCNlimit=16631622025216
hrt =1015113518
hrs=16631619881494
Max Compatibility=3
说明Auto Rollover特性被禁用了。
这时候再次启用Auto Rollover
SQL> EXECDBMS_SCN.ENABLEAUTOROLLOVER;
PL/SQL proceduresuccessfully completed.
重启数据库,检查SCN Compatibility版本,已经升级为3。
Current SCNCompatibility=3
Reasonable SCNlimit=35820837437440
hrt =364388379
hrs=35820835293133
Max Compatibility=3
如何手动调整SCN Compatibility
如果不启用Auto Rollover,我们怎么手工控制SCNCompatibility?
在较新版本数据库中存在相关语法如下:
ALTER DATABASE SETSCN COMPATIBILITY X;
-- X可以为1,2或者3。
经过测试,低往高可以在线调整,高往低调整需要重启数据库MOUNT状态 后,再执行。
Auto Rollover特性涉及到哪些版本
以MOS文档 ID2335265.1提到的版本作为风水岭,划分为高低两个版本,“高版本”的数据库软件中能够修改SCN Compatibility为3。
6,7,8,9,10 | 低版本 |
11.1.0.6 | 低版本 |
11.1.0.7.20- | 低版本 |
11.1.0.7.20+ | 高版本(默认将在2019年6月23日修改为3) |
11.2.0.1/11.2.0.2 | 低版本 |
11.2.0.3.9- | 低版本 |
11.2.0.3.9+ | 高版本(默认将在2019年6月23日修改为3) |
11.2.0.4 | 高版本(默认将在2019年6月23日修改为3) |
12cR1/12cR2/18c | 高版本(默认将在2019年6月23日修改为3) |
不同SCN Compatibility的区别
以2018年3月份为例,我们可以算出每个级别的软限制大小:
SCN Compatibility为1的数据库软限制为15.9万亿。
SCN Compatibility为2的数据库软限制为20.7万亿。
SCN Compatibility为3的数据库软限制为31.4万亿。
Auto Rollover有什么后果
分析3种可能的场景,DB LINK连接后可能发生什么现象。
场景1:
假设源端和目标端SCN Compatibility都是1,并且不会进行AutoRollover,两端SCN每秒钟增速限制相等,不会因为该SCN特性导致问题。
场景2:
这边考虑正常SCN增长场景:
A库版本为10.2.0.5,B库版本为11.2.0.4
A库和B库的SCN Compatibility 都是1
A库和B库的当前SCN都是15.9万亿
在2019年6月23日,B库触发了AutoRollover,将SCN Compatibility自动调整为3,这时候如果B库的SCN像脱缰了的野马,飞速增长到了16万亿以上。
A库与B库进行DB Link连接,需要进行SCN同步,发现B库的SCN值超过了A库的SCN Headroom,这时候DB Link将会被拒绝连接。
场景3:
假设源端和目标端SCN Compatibility都是3,不受影响。
可能的场景汇总如下:
SCN Compatibility | 现象 |
两端都是1 | 和SCN异常数据库交互时候可能被拒绝同步SCN |
1和2/3 | 高版本SCN超过15.9万亿时候,低版本数据库可能拒绝同步SCN |
2和3 | 高版本SCN超过20.7万亿时候,低版本数据库可能拒绝同步SCN |
两端都是2 | 正常 |
两端都是3 | 正常 |
场景4:
假设源端和目标端SCN Compatibility都是3,但是某一个库SCN增长速度还是涨的飞快,马上要超过31.4万亿了,那么数据库还是会遇到天花板问题。
建议检查目前环境中的所有数据库的SCN值,是否接近15.9万亿。如果存在SCN值较大的库,需要查看其SCN增长值,抓取业务高峰期间AWR报告,搜索关键字“kcmgas”,查看每秒钟平均SCN增量是否超过16384,这时候可以考虑暂时禁用AutoRollover。
Instance ActivityStats
Statistic | Total | per Second | per Trans |
calls to kcmgas | 9,433,023 | 5,188.09 | 4.69 |
等到和该数据库存在DBLINK交互的都升级到支持SCN Compatibility 为3版本上后,按照SCN增长速度,优先调整SCN增长速度每秒小于16384的数据库,最后调整SCN增速较快的数据库。
对于老版本的数据库,建议升级,升级列表汇总如下。
总结
总的来说,这只是ORACLE在尝试规避SCN Headroom的一个补丁,理解了原理后我们发现,它并不会带来问题,只是它还存一定的局限性(无法帮助DB Link的另一端来同样做到进一步规避SCN Headroom而已),所以,对于这个问题,我们完全可以从容面对。
END