2019年6月关于Oracle DB_link和SCN补丁问题分析, 想说爱你不容易

最近Oracle在3月12号发布了一个严重补丁警告,最开始说是一个强制补丁,要求相关的版本在2019年4月份之前都必须打上,要不后果很严重!

 

就在上周3.17日最新的更新,把强制执行改成了强烈推荐,时间由2019年4月改成在2019年6月份之前(延缓了2个月),并更新了一些升级相关的内容,似乎没那么严重了!

 

就在昨天3.21日Oracle再次进行了更新,增加了一个对12.1.0.1.0的patch.感觉10.2.0.5也不远了!

 

那么这次要打的是什么补丁呢?为什么这么短的时间MOS更新了3次?压力山大。

 

大家应该知道了,就是关于低版本数据库在2019年6月份以后通过DBlink访问高版本数据库可能会遇到连接失败、退出、拒绝连接等问题。(高版本访问低版本没有问题)

 

 

低版本:

 

有补丁可以打:11.1.0.7和11.2.0.3,12.1.0.1(3.20号新增)

 

l 无补丁可以打,只能升级,未来防止可能的dblink问题2019年6月后不要连接高版本数据库:10.2.0.5及以下,11.2.0.2的版本

 

    Based on customer feedback, we are currentlyevaluating the need and feasibility of providing a patch for 10.2.0.5 and thisnote will be updated with that information at a later time.

   注:最新官方的显示,要根据用户的反馈决定是否为10.2.0.5提供一个patch,看大家的力量了!12.1.0.1.0已经给补丁了!团..结就是力..量,这力量是铁...

 

高版本:

 

12.2.0.1及以上,11.2.0.4和12.1.0.2的版本(不好意思,我们已经修复了,让我安静的做个美男子吧)

 

提供补丁的版本数据库列表,也就是有补丁可以打的版本

Recommended patch levels

Patch Name

Release Data  

Patch Number

12.1.0.2.0 PATCH SET FOR ORACLE DATABASESERVER  

09/01/15 

 

Patch 17694377 

12.1.0.1.0 PATCH SET FOR ORACLE DATABASE SERVER

09/01/15

Upgrade to 12.1.0.2 or above Patch 17694377 

11.2.0.4.0 PATCH SET FOR ORACLE DATABASE SERVER

08/27/13 

 

Patch 13390677 

DATABASE PATCH SET UPDATE 11.2.0.3.9 (INCLUDES CPUJAN2014)

01/14/14 

 

Patch 17540582

DATABASE PATCH SET UPDATE 11.1.0.7.20 (INCLUDES CPUJUL2014)

07/14/14 

 

Patch 18522513 

ORACLE 11G 11.2.0.3 PATCH 28 BUG FOR WINDOWS

**Patch 28 is withdrawn. Apply Patch 29 or above.

02/26/14 

 

Patch 17906982 (Win x64) | Patch 17906981 (Win 32-Bit)

 ** Patch 29 Patch 18075406 (Win x64) | Patch 18075405 (Win 32-Bit)

ORACLE 11G 11.1.0.7 PATCH 57 BUG FOR WINDOWS

07/15/14 

 

Patch 18944208 (Win x64) | Patch 18944207 (Win 32-Bit)

QUARTERLY DATABASE PATCH FOR EXADATA (JAN 2014 - 11.2.0.3.22)

01/14/14 

 

Patch 17747147 

 

没有提供补丁低版本的数据库怎么办?

 

摆在你们面前的就两条路:

l 升级到高版本

  温馨提示:最新的更新显示,只要用户反馈够多,oracle会考虑为你提供一个patch的,加油哦,不过只限10.2.0.5 。

 

l 不要使用dblink连接高版本数据库

  温馨提示:通过后面的解释,只要满足一定的条件,其实也是可以连接并没有问题的,但你最好不要冒这个风险,除非你升级打补丁对你来说很麻烦。

 

下面是oracle官方针对一些问题的解释(文档ID 2335265.1):

 

1,What is the timeline for moving to the recommended patchset/PSU/BPmentioned ?

升级的最低时间线?

 

3.12号的更新要在2019年4月份前必须都打完,

3.17的最新更新是建议在2019年6月23号前打完。

 

2,What is the change introduced by the patches listed above?

这次都更新了啥?(3月17日最新更新的说明)

 

These patchesincrease the database's current maximum SCN (system change number) limit.

Oracle增加了当前scn的最大值(Reasonable SCN Limit)和scn rate(每秒允许的增长的最大scn数)


为什么要增大呢,主要是为了满足高并发、大的事物需求,另外可用SCN值(Headroom SCN)会更大,从而减少"天花板事件"的概率。另外这个patch只增大了当前最大scn值限制,并不会影响当前scn。

关于历史天花板事件:
在两个库通过db link进行分布式事务时,假设B库的SCN值要高于A库的SCN,因此要将B库的SCN增同步到A库,但是如果B库的SCN过高,这样同步到A库之后,使得A库面临Headroom过小的风险,那么A库会拒绝同步SCN,这个时候就会报ORA-19706: Invalid SCN错误。分布式事务,或者说是通过db link的操作就会失败,即使是通过db link的查询操作


进一步分析:
这里显然有一个阈值,如果递增SCN使得Headroom过小到什么值时,就会拒绝递增(同步)SCN?目前来看是这样:如果打了2012年1月CPU或PSU补丁,11.2.0.2及以后的版本,是1天即24小时,其他版本是31天即744小时,打了补丁之后可以由隐含参数_external_scn_rejection_threshold_hours来调整。而没有打补丁的情况下,视同此参数设为0,实际最小为1小时。由于Oracle 9.2.0.8没有了最新的补丁集,显示也不会有这个参数,保持默认为1小时。注意这是一个静态参数。所以打了2012年1月CPU或PSU补丁的一个重要变化是增加了_external_scn_rejection_threshold_hours参数,同时使11.2.0.2以下版本的数据库其Headroom的阈值增得较大。这带来的影响就是ORA-19706的错误出现的概率更高。解决的办法将_external_scn_rejection_threshold_hours这个隐含参数设置为较小的值,推荐的值是24,即1天。从_external_scn_rejection_threshold_hours这个参数名的字面意思结合它的作用,可以说这个参数就是”拒绝外部SCN“的阈值。对于数据库自身产生的SCN递增是没有影响的。

打了这个补丁后,我们可以设置一个参数_external_scn_rejection_threshold_hours。这个参数的含义是,当有一个系统和我进行DBLINK操作的时候,我需要检查他的SCN HEADROOM的值,如果这个系统的SCN HEADROOM的值小于这个参数所设置的小时数,那么我就拒绝这个DBLINK访问(如果DBLINK两端的数据库都打了补丁,设置了参数,这种检查是双向的),通过拒绝DBLINK访问,来避免错误被传播。
更详细的说明参考博客:https://blog.****.net/stranger_huang/article/details/52928027

可以查看这个参数的值:
select ksppinm sp_name, ksppstvl sp_value, ksppdesc description
  from x$ksppi x, x$ksppcv y
 where (x.indx = y.indx)
   and ksppinm = '_external_scn_rejection_threshold_hours'

相关概念:

关于Scn(SystemChange Number)

Oracle的内部时钟,现在的所有数据库版本最大值是2的48次方,281,474,976,710,656(2^48),一般我们把他说成scn的硬限制。

 

关于RSL(Reasonable SCN Limit) 

到目前为止理论上可用的最大SCN值,这次升级后调整的最大值它是一个软限制,公式是:(当前时间—起始时间)*SCN_RATE

起始时间在不同兼容级别下是不一样的,可以参考下面表格。

关于Scn rate(SCN每秒最大可能增长速率),这次升级的补丁就是通过增加Scn rate变向增加了当前理论SCN最大值(RSL)。

 1)11.2.0.2之前是每秒最多支持16K的增长,按照现在硬限制scn值来计算,可以至少满足500多年增长(我真的还想在活500年,可惜我看不到那一天了),

    281474976710656/16/1024/3600/24/365=544年

 

2) 11.2.0.2之后的版本每秒最多支持32K的增长,按照现在硬限制也至少可以满足两三百年增长。

  281474976710656/32/1024/3600/24/365=272年

3) 而对于那些已经打了补丁的版本,会在2019年6月份后自动变身,scn rate将是96K,按照现在硬限制计算还至少满足90年增长(那我也看不到了)

281474976710656/96/1024/3600/24/365=90年 

这次升级增加了软限制当前理论最大值Reasonable SCN Limit(RSL),减少了硬限制值下的可用天数。

 

关于Scn Compatible

11.2.0.2之前的版本scn兼容性是1,相对应scn rate16k

11.2.0.2及之后的版本scn兼容性也是1,但可以调整到2,相对应scn rate32k

升级或已经包含补丁的版本,会在会在2019年6月23号后自动升级为3,相对应scn rate 96k

当然你也可以提前升级,低到高升级数据库在打开状态下就可以执行,如果从高降级到低则需要在mount下进行。

SQL>Alter database set scncompatibility 3;

 

关于dbms_scn 

凡是升级或包含补丁的版本均会产生这个包,他可以查看很多关于scn的信息。

SQL>setserveroutput on size 100000

SQL>DECLARE

 crsl NUMBER;

 hscnNUMBER;

 hsecNUMBER;

 csc NUMBER;

 msc NUMBER;

BEGIN

  dbms_scn.getCurrentSCNParams(crsl,hscn, hsec, csc, msc);

  dbms_output.put_line('Current RSL:'||TO_CHAR(crsl));

  dbms_output.put_line('HeadroomSCN:'||TO_CHAR(hscn));

  dbms_output.put_line('HeadroomSec:'||TO_CHAR(hsec));

  dbms_output.put_line('CurrntSCOMP:'||TO_CHAR(csc));

  dbms_output.put_line('Max_SCN_COMP:'||TO_CHAR(msc));

END;

/

 

---------------------下面是输出内容------------------------

Current RSL:20769265647616        ---当前理论最大scn限制

HeadroomSCN:20769261950431          ---当前可用SCN数

HeadroomSec:633827574           ---当前可用秒数

CurrntSCOMP: 3                   ---当前兼容级别

Max_SCN_COMP:3                   ---最大兼容级别


关于Headroom SCN:

是当前还可用的SCN数量,它是当前最大scn值与数据库当前scn的差值,

公式是:Reasonable SCN Limit-current_scn


关于Headroom Sec

当前可用秒数,需要说明的是这个不能作为真正判断的依据,因为RSL一直也在变化,

公式为:(Headroom SCN /SCNRATE)单位是秒,

关于Headroom day

当前SCN可用天数

按照天计算的公式为:(Headroom SCN /SCN RATE)/3600(秒)/24(小时)

这个值的意思就是,如果按SCN的每大增长速率,多少天会到达 Reasonable SCN Limit。同理不能作为真正可用时间判断的依据,因为实际上即使如此,也不会到达Reasonable SCN Limit,因为到那时Reasonable SCNLimit也增大了(时间越长值应该会变大),如果要到达Reasonable SCN Limit,scn rate要增大一倍才有可能。

 

关于Current_scn(当前SCN)

可用通过试图或包进行查看

selectcurrent_scn from v$database;

 

Compatible

起始时间

 RSL(Reasonable SCN Limit )

Current_scn

Headroom SCN 

Headroom Sec

Headroom day

SCN RATE

1

1988/01/01

15913374941184

3718203

15913371222981

971275099

11241

16K(16384)

2

1998/07/01

20769265647616

3697185

20769261950431

633827574

7335

32K(32768)

3

2008/03/30

31513855688704

3675924

31513852012780

320575480

3710

96K(98304)

 

关于Auto Rollover

对于升级或包含补丁的版本在2019年6月23号会自动触发将scn Compatible升级为3.

升级后scn rate将会增加到96k,另外会增加当前scn的最大值。

经过测试手工调整时间至2019年6月也是可以触发兼容级别变化。

当然如果你不打算在2019年6月份自动调整级别到3,那么可以禁用该功能

 过DBMS_SCN包来实现

SQL>execute dbms_scn.disableautorollover;

想要开启的话 

SQL>execute dbms_scn.enableautorollover;

为什么前面要引入那么多的概念,当你把上面的概念名称都理解后,那么就会很快明白这次dblink补丁更新会在哪些情况下对我们有影响,哪些情况下即使是低版本连接高版本也不会有问题!

 

在排除BUG等异常的情况下,记住这个公式,就不会触发dblink低版本连接高版本的问题。

公式:1,高版本SCN<低版本RSL(Reasonable SCN Limit)
          2,高版本每秒事物量所需的SCN值<=低版本SCN RATE

只要你能放慢脚步,我们就可以并肩前行!

官方解释:

Please note that the patches only increase the max limit but the currentSCN is not impacted. So, if all your databases don’t have any major change intransaction rate, the current SCN would still remain below the current maximumSCN limit and database links between newer (or patched) and unpatched databaseswould continue to work. The patches provide the safety measure to ensure thatyou don’t have any issue with dblinks independent of any possible future changein your transaction rate

 

只要低版本通过DBlink连接高版本数据库操作,没有特别大的事物率变化 高版本每秒产生的事物量所需的SCN数量(大事物,高并发事物)不会超过低版本scn rate的值,或高版本的SCN低于低版本当前最大SCN限制(RSL),也可以理解成B库同步到A库的差值没有超过A的Headroom SCN,那么就不会有问题,一直可以保存连接工作。

但是在不能确保未来业务是否会突曾,SCN是否会突然增大的情况下,建议还是打了吧,本身那些低版本的数据库就已经到了延保期了,除非升级对你来说升级是很困难的事情,否则不要给自己找没必要的麻烦,另外这个补丁也是Oracle的一个进步升级,建议还是打上吧。对于我们这些服务于银行的客户是一定会建议打上的。

这就是oracle突然又转变,不强制打补丁的原因! 

除此之外就会有问题:

1,高版本SCN>=低版本RSL(Reasonable SCN Limit)
2,高版本每秒事物量所需的SCN值>低版本SCN RATE

 

如A(低版本)库通过DBlink连接到B(高版本)库,B库的SCN值要高于A库的SCN,因此要将B库的SCN同步到A库,但是如果B库的SCN过高,超过了A库的RSL,也可以理解成B库同步到A库的差值,超过了A的Headroom SCN,那么A库会拒绝同步SCN,因为你都超过了我的当前理论最大值,超过了我当前可用值,我无法分配这么多的SCN,连接将别拒绝。或高版本每秒产生的事物量所需的SCN数量(大事物,高并发事物)超过过低版本scn rate的值,低版本的scn rate根本分配不了,连接拒绝。


 为了方便理解,我自己画了一个图,如下:

2019年6月关于Oracle DB_link和SCN补丁问题分析, 想说爱你不容易


如果你没有打补丁会怎么样?

1) 你的最大当前scn限制将会比较低,你的scn rate也别想到96k 

2)  2019年6月份后未打补丁的低版本数据库通过dblink和高版本数据库连接时,低版本数据库要同步高版本数据库scn的时候发现超出低版本当前scn最大值,或超过了scn rate时 dblink将不能建立连接。

 

4. What about databases that are 10.2 or older, which are not listedin the table?

对于那些10.2或更低版本,以及没有在patch列表里的版本会怎样?

 

你应该意识到要不升级到新版本,要不不要通过dblink连接高版本或已经打了补丁的数据库,如果2019你6月分以后你还继续连接的话,在你操作的过程中可能会报错,这个时候你需要断开dblink连接。

 

5.How can I check the details regarding the dblinks to and froma database?

如何查看dblink

select* from dba_db_links;

12.1及以上:

select* from dba_db_link_sources;

 

6. Will there be any issues with the db links connecting twounpatched databases ? Or databases of older versions?

两个低版本的或未安装补丁数据库的通过dblink可以连接吗? 

可以,不会有影响。

 

8. Will the dblinks involving a patched and an unpatcheddatabase, stop working immediately after June 2019? 

2019年后对于一个没有打补丁和已经打了补丁的数据库通过dblink连接会马上停止工作吗?

不会马上不可用,但是可能会发生错误,前面已经提过了。


7.  What should I do, if the dblink connection from an olderversion database to a latest (or patched) version database fails, after June2019?

2019年6月之后,如果低版本连接新版本或已经打了补丁的数据库连接失败,我该怎么办?

 

低版本没有提供pach的版本,升级到patch list包含的版本,然后在打补丁,或者直接升级到不需要打补丁的版本 

低版本提供patch的版本,可以直接打补丁或升级到更高的不需要打补丁的版本

 

8.What do we need to do for 11.2.0.4, 12.1.0.2 and 12.2.0.1database releases?

我们这些版本该怎么办?

 

啥都不用干!  安安静静做个美男子吧!(等着2019年6月变成超级美男)

 

如果在技术上还不是很清楚,我推荐几篇文章:

http://blog.****.net/stranger_huang/article/details/52928027

http://blog.****.net/songyundong1993/article/details/52514865 

都是早些年处理类似DBlink连接问题的博客,感谢他们。

 

关于这次DBlink可谓满城风雨,记录大事件:

3.15日:Oracle ACS小组给出了第一版的补丁严重警告建议

3.16日:恩墨第一反映并根据官方说明给了第一版建议:预警解密,倒计时炸弹11.2.0.4前版本DB LINK必须升级在2019年4月升级真想

3.17日:Oracle MOS更新了第二版补丁升级建议,把补丁级别从强制改成了建议。

3.19日:Oracle  ACS小组再次通过邮件给出了官方解释。

3.19日:恩墨马上针对Oracle的第二版也做了说明 :Oracle全面修正关于DBlink和SCN补丁的公告。

3.19日:海量数据也发布了自己针对这次DBlink时间的建议:Oracle关于SCN(影响严重)的警告

3.20日:中亦安图也同样发布了自己针对这次DBlink时间的建议:无需恐慌,从容应对Oracle对于DB link的预警,解析为何Oracle将补丁属性从“强制”改成了“推荐”

3.20日:Oracle MOS再次更新了第三版,加上了对12.1.0.1.0的补丁

同样感谢这么多有诚意,有技术,有资质的公司所提供的方案和建议。

另外感谢Oracle ACS负责人宏伟兄的支持。

 

官方文档参考:Recommended patching andactions  for Oracle databaseversions 12.1.0.1, 11.2.0.3 and earlier -  before June 2019 (文档 ID 2335265.1)