熊军(老熊)
云和恩墨西区总经理
Oracle ACED,ACOUG核心会员
Oracle数据库在安装了2012年1月发布的CPU或PSU补丁之后,经常出现下面一些现象:
1、应用出现ORA-19706: invalid SCN错误。
2、在alert日志中出现类似如下警告:
3、在alert日志中出现类似如下错误:
4、在alert日志中出现类似如下信息:
5、在MOS文档《ORA-19706 and Related Alert Log Messages [ID 1393360.1]》中还提到其他会出现在alert中的一些警告信息:
如果说以上的现象只是警告或应用级报错,影响范围有限,那么不幸的是如果遇到RECO进程在恢复分布式事务时遇到SCN问题,则可能使数据库宕掉,例如:
那么2012年1月发布的CPU或PSU补丁到底使数据库在SCN处理方面产生了什么样的变化?这种变化对数据库有什么危害吗?甚至于说,以上提示的信息是由于这个补丁的BUG引起的吗?
要回答这些问题,得先从SCN讲起。SCN可以说是Oracle中的很基础,但同时也是很重要的东西,它是一个单向增长的“时钟”,广泛应用于数据库的恢复、事务ACID、一致性读还有分布式事务中。那么除了这些,SCN还有以下一些知识点:
现在是时候来回答以下几个问题了:
增加了_external_scn_rejection_threshold_hours参数,11.2.0.2及以上版本的这个参数默认值是24,其他版本默认值是744。这样使11.2.0.2以下版本的数据库其Headroom的阈值增得较大。
在一个具有很多系统的大型企业环境里面,db link使用很多,甚至有一些不容易管控到的数据库也在跟关键系统通过 db link进行连接,在这样的环境中,过高的SCN扩散到关键系统,而系统如果打了这个补丁,其Headroom阈值变大,那么就更容易出现ORA-19706错误,对db link依赖很严重的系统可能会导致业务系统问题,严重情况下甚至会宕库。不过通过设置隐含参数_external_scn_rejection_threshold_hours可解决这样的问题。所以,如果你安装了2012年1月的CPU或PSU补丁,请尽快设置此参数为建议的值24,极端情况下你可以设置为1。。
这些提示或警告不是BUG引起的。它只是提醒你注意SCN过高增长,或者是你的Headroom较小(在Headroom小于62天时可能会提醒),引起你的重视。实际上根据MOS文档《System Change Number (SCN), Headroom, Security and Patch Information[ID 1376995.1]》的说法,这个补丁修复了SCN相关的一些BUG。如果非要说BUG,可以勉强认为补丁安装后新增的参数_external_scn_rejection_threshold_hours其默认值过大。Bug13554409 - Fix for bug 13554409 [ID 13554409.8]就是说的这个问题。不过这个问题已经在2012年4月的CPU或PSU补丁中得到修复。
在最后我们来解读一下alert日志中的一些信息:
这里是说,SCN向前(跳跃)递增了68098分钟,其递增后的SCN是0x0ba9.4111a520。注意这里的分钟的计算就是根据SCN每秒最大可能增长速率为16K来的。我们计算一下: 0x0ba94111a520转换成10进制12821569053984。
在alert日志中,这个信息是刚打开数据库的时候,所以 crash recovery完成时的scn可以做为近似的当前SCN,其值为12754630269552: (12821569053984-12754630269552)/16384/60=68093.65278320313 这里16384值的是SCN每秒最大可能增长速率,可以看到计算结果极为接近。
我们再来计算一下这个SCN的headroom是多少:
可以看到结果为24天,由于这个时候_external_scn_rejection_threshold_hours参数值为24,即1天,所以虽然有这么大的跳跃,但SCN仍然增长成功。
在这个信息中,拒绝了db link引起的SCN增加。计算一下这个SCN的headroom: 0x0ba93caec689转换成10进制是12821495465609 当前时间是2012-05-30 12:02:00,
由于这个时候_external_scn_rejection_threshold_hours参数值为744,即31天,计算出的headroom在这个阈值之内,因此拒绝增加SCN。 (31-24.0710752)*24=166.2941952,正好是166小时。
-update on 2012/6/2--
实际上2012年1月的CPU或PSU补丁之后还会有下面的变化:
1、_minimum_giga_scn这个隐含没有了,可惜了这个手工增加SCN的利器。
2、11.2.0.2及之后的版本,从原来的32K SCN最大速率调整回了16K速率。可以用下面的SQL来得到结果:
上面的SQL的结果只有在11.2.0.2及以上版本才有意义,结果为Y,表示使用的是16K的速率,否则是使用32K速率。
本文涉及的一些参数,和SCN的一些算法,可能会随着版本或补丁的变化而产生较大的变化。
important update: 实际上在Jan 2012的PSU/CPU补丁中存在较大的SCN BUG,目前已经不建议打这个补丁集,而是打到更高的PSU补丁集上。
本期趣味竞答答案:BC
A: 这行数据在PLCH_student_courses表中是student_id为1, 课程为PHYSICS。所以外键允许你插入这个数据。
B: PLCH_student_courses表中有一行student_id为2, 也有一行课程为PHYSICS。但是在不同的行。所以你不能插入这些值。
C: student_id为3和课程为ENGLISH在父表中都不存在。所以这会报 ORA-02291 异常。
D: 外键允许子表中有NULL值。所以你可以插入这行而不报错。
E: PLCH_student_courses没有student_id为3的数据。但是正如文档所言:如果一个复合外键的任意列为空,则该键的非空部分不必和父键的相应部分匹配。因为course_code为空,Oracle就不再校验student_id = 3 是否在父表中存在。所以你可以在子表中保存不匹配父值的数据!
F:正如文档中所言:外键允许所有键值为空,即使不存在匹配的主键或者唯一键。
所有外键列的值为空,所以ORACLE允许你插入这一行。