Oracle Database 11gR2 (11.2) New Features in Oracle RAC

Oracle宣布在2009年9月29日将正式发布Oracle Database 11g Release 2,无论是从功能还是从稳定性的潜意识忧患上来说,众多还在使用Oracle9i的客户有理由直接从9i升级到11g了。

Oracle11gR2

之前也有略略提过11gR2的新功能,那么对于企业级用户比较关心的RAC选件上来说,11gR2又有哪些具体的增强呢?

Oracle在这个新版本中给我们的一个最主要印象是,Oracle Clusterware、ASM、RAC这三者泾渭分明的进化为三个独立的产品,在今后Oracle Clusterware就是一个全功能性的集群软件,将跟IBM的HACMP和HP的Service Guard分庭抗礼,ASM或者说ACFS将是一个全功能性的集群文件系统,跟IBM的GPFS和Veritas的VxFS直接竞争,RAC则是构筑在集群环境中的数据库解决方案。至此,Oracle对于企业级集群环境的一揽子解决方案(Total Solution)基本上已经成型。

1. Grid Plug and Play
即插即玩,冏。。。好吧,让我们跳过语意上的幻想,实际上Oracle一直在致力于提高整个Grid环境搭建配置的简便性,不可否认确实一直在进步,但是可惜的是,至少从文档中还看不出11gR2的Plug and Play比11gR1中就已经提供的Clusterware、ASM、RAC的clone功能有何种进步。
打包已经安装的程序文件,分发到其他节点上,然后运行clone.pl脚本,再运行root.sh完成增加节点的工作,目前看来还是这样的Play体验。

2. Role-separated management
前面说过,Oracle Clusterware已经独立为一个全功能性的集群软件,那么很明显在一个集群环境中将允许运行多个数据库应用,通过角色的控制提高了安全性的需求,每个DBA将只可以管理属于自己的那个数据库。

3. OCR performance enhancements
当集群环境中某些节点出现问题的时候,存取OCR的速度大幅提高,现在OCR可以存储在ASM中了,并且最多允许5份备份(之前是2份)。

4. SRVCTL support for single-instance database
仍然是再次提醒大家Oracle Clusterware将是独立的集群软件了,在11gR2中即使是单实例数据库也可以加入到集群环境中让Oracle Clusterware来监控数据库实例的状态,在必要的时候通过Oracle Restart来重新启动数据库实例。

5. Zero downtime for patching Oracle RAC
无论是给Clusterware还是给RAC打patch都不需要将整个集群环境全部关闭了。

6. ODVM and ACFS
Oracle Dynamic Volume Manager和Oracle Automatic Storage Management Cluster File System是11gR2的重头戏,并不是三言两语可以概述的,总而言之,Oracle现在有自己的集群文件系统了,允许存储除了Oracle Datafile之外的所有其它企业应用程序文件。ACFS同样是跟RAC无关的,无论是选用RAC数据库还是单实例数据库都可以使用ACFS文件系统。

Adaptive Cursor Sharing in Oracle Database 11g

还记得2007年时候遭遇过一次由于cursor_sharing = similar导致的系统问题,大量游标无法共享,产生巨大的version count,最终让整个系统崩溃。

在这个案例中我提到有4个条件导致了问题的发生:
1. cursor_sharing = similar
2. 收集了列上的histogram
3. SQL中使用到了此列作为条件,并且条件是“等于”
4. 这个SQL是没有绑定变量的

在最近Optimizer Development GroupWhy do I have hundreds of child cursors when cursor_sharing set to similar in 10g文章中又再次提到这个现象。

This is in fact the expected behavior when
1. CURSOR_SHARING is set to similar
2. Bind peeking is in use
3. And a histogram is present on the column used in the where clause predicate of query

在Oracle10g中这是正常的现象,如果在某列上收集了histograms信息,那么就等于告诉CBO这一列上的数据是不平衡的,如果都使用同一个执行计划那么就可能产生问题,因此对于每一个distinct值,CBO都会产生一个child cursor,这一点无法避免。当然,由于这是child cursor,因此比cursor_sharing = exact时候产生的parent cursor还是要节省内存空间,至少SQL语句本身不需要重复存储了。

在Oracle10g中解决方法是:
1. 去掉这列上的histograms统计信息,或者
2. 将CURSOR_SHARING = FORCE

虽然源于对Oracle Database的热爱,我们无条件接受了10g中这个方式,并且不认为这是bug,但是实际上心里一定暗暗骂过,傻啊,收集了histogram就要每个值产生1个cursor吗?如果是一样的执行计划何必要用不同的cursor空间呢?

我想Oracle自己也一定意识到了这点,于是在Oracle11g中这一切有了变化,Oracle推出了称为Adaptive Cursor Sharing(自适应游标共享)的游标共享机制,可以阅读这几篇相关文章。

Optimizer Development Group:Adaptive Cursor Sharing
Optimizer Development Group:Update on Adaptive Cursor Sharing
Arup Nanda:Adaptive Cursors and SQL Plan Management
Tim Hall:Adaptive Cursor Sharing in Oracle Database 11g Release 1

什么是Adaptive Cursor Sharing就不重复叙述了,上面的几篇文章说的非常清楚,那么ACS机制对于之前在10g中碰到的child cursor过多的情况有何种改善呢?

简单地说,在Oracle11g中我们可以保留cursor_sharing=similar并且也保留列上的histograms统计信息 [参考ADS with cursor_sharing] 应该设置cursor_sharing=force并收集倾斜列上的histograms统计信息,ACS机制将不会对每一个distinct值都产生一个child cursor,而是对每一个不同的执行计划产生一个child cursor,这大大减少了子游标的数量。这种处理方式无疑是合理的,只有在执行计划确实需要不相同的时候才产生额外的child cursor,当然,在bind peeking之后,CBO是否确实能够选择一个最优的执行计划那另当别论,是另外的话题。

注意,实际上产生的child cursor数量仍然是会大于execution plan数量的,也就是假如对于一个绑定变量的SQL一共有2种执行计划,那么child cursor数量会大于2,因为CBO始终在监控SQL的执行效率,如果认为变量的某一个真实值跟其它值的分布情况有很大的不同,那么CBO就会让这个SQL再做一次hard parse,这样就会产生出来一个新的child cursor,即使最终这个cursor的执行计划还是跟之前的相同。但是我们不用担心这些多余的cursor,因为这些cursor被标志为无法共享(可以通过v$sql.is_shareable字段得知),在需要的时候将会被age out出去。

About SCN propagation in Oracle RAC

关于昨天被客户问到Oracle RAC在节点间的同步问题,今天稍微整理一下。

由于Oracle RAC多节点共用一份数据库Datafile,因此在磁盘存储方面不存在同步问题。那么实际上所谓各节点同步指的是每个节点间SGA的同步,更专业一些的术语其实就是SCN propagation的算法。

在Oracle9i和Oracle10gR1中,SCN propagation默认使用Lamport方案,受到初始化参数MAX_COMMIT_PROPAGATION_DELAY影响,默认的同步间隔是7秒,也就是在极限情况下,一个节点上的更新在7秒后另外的节点才能知道。将该参数值设置为0,则表示要求任何一个事务在commit之后就立刻通知其他节点SCN变更了,这种方式就被称为BOC(Broadcast On Commit)。

在Oracle10gR2和Oracle11g中,BOC被作为了SCN propagation的默认方案,初始化参数MAX_COMMIT_PROPAGATION_DELAY被废弃,转换成了隐含参数_IMMEDIATE_COMMIT_PROPAGATION,默认值为TRUE。

SQL> @hidden
Enter value for par: propagation
old  14: x.ksppinm like '%_&par%'
new  14: x.ksppinm like '%_propagation%'

NAME                                     VALUE                     ISDEFAULT ISMOD      ISADJ
---------------------------------------- ------------------------- --------- ---------- -----
_evt_system_event_propagation            TRUE                      TRUE      FALSE      FALSE
_immediate_commit_propagation            TRUE                      TRUE      FALSE      FALSE
max_commit_propagation_delay             0                         TRUE      FALSE      FALSE

在Oracle11g RAC中,BOC有了更进一步的改善。包括:

o The number of outstanding broadcasts increased from 3 to 8.
This improves throughput but does not affect latency.

o LGWR can now issue direct and indirect sends.
This frees up the local LMS processes and improves latency.

o Processing is not limited to LMS0. The SCN is hashed to determine which LMS process will send the message (indirect send) or process the broadcast and send the ACK back to the broadcasting node.
This improves general performance by reducing the load on the local (indirect sends) and remote LMS0 processes.

o Broadcast and acknowledgement messages are no longer blocked by DRM events.
This improves BOC latency by eliminating the up to 0.5-second delay introduced by Dynamic Remastering.

o All Cache Fusion messages can now carry the broadcast SCN.
This reduces the need for explicit broadcasts thereby reducing the number of messages on the private interconnect and possibly reducing latency.

在indirect send方式中,LGWR在本地事务提交时会根据SCN号计算出的HASH值选择一个本地LMS进程(之前始终是LMS0),然后本地LMS进程又根据这个HASH值选择一个其它节点的远程LMS进程来通知,这样就均衡负载了各节点LMS进程的工作量。

为了更进一步降低本地LMS进程的工作量,现在有了direct send方式,在这种方式中,传递BOC到其它节点LMS进程的操作将由LGWR进程自己来完成,当然,其它节点LMS进程对于BOC消息的回馈(ACK)仍然还是发送回本地LMS进程的,再由LMS进程通知LGWR进程。

从事务提交post LGWR进程开始写日志,一直到LGWR写完日志,并且收到了本地LMS进程的通知,所有的其他节点都给了BOC ACK消息,这才算是完成了Log file sync等待。因此很明显,在RAC环境中,LMS进程的效率、BOC的传递效率都会影响到Log file sync等待的多少,也意味着会影响到系统响应时间。这也是为什么Oracle一直强调在操作系统级别的进程CPU需求中,LGWR进程和LMS进程都应该置于Real Time scheduling策略中,同时要保证RAc节点Interconnect的畅通,高吞吐量,低延迟。

如果LGWR进程写本地redo文件在收到所有其他节点的BOC ACK之前完成了,那么这通常意味着CPU不够了或者私有网络性能过差。