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不够了或者私有网络性能过差。

the Most Simple Method to Get Tracefile Name in 11g

Oracle数据库产生的跟踪文件命名规则是sid_ora_pid.trc,因此可以通过查询数据字典的方式拼出跟踪文件的名称。

Eygle提供过具体的脚本来演示如何获得跟踪文件名称

他的另一篇文章中有blue_prince提供的简化版本 – 获得跟踪文件名称的gettrcname.sql

而在最新的Oracle 11g中,这个SQL我们可以进一步简化,因为在v$process视图中oracle新增加了TRACEFILE字段。

SQL> SELECT p.TRACEFILE
  2    FROM v$session s, v$process p, v$mystat m
  3   WHERE s.paddr = p.addr
  4     AND s.SID = m.SID
  5     AND m.statistic# = 0;
 
TRACEFILE
--------------------------------------------------------------------------------
d:\oracle\diag\rdbms\orcl11g\orcl11g\trace\orcl11g_ora_5760.trc

User Default Password Check in Oracle 11g

在数据库安全性检查中有一项首先要完成的工作,就是检查数据库中的用户密码是否还仍然保留着默认值,比如sys的密码是否还是change_on_install,system的密码是否还是manager,scott的密码是否还是tiger。

在Oracle 11g之前,我们需要手工来完成这样的工作,大概步骤是:
1. 创建一张自定义的表,保存下常用的系统用户以及默认密码的HASH值。
2. 将系统中的用户密码HASH值与该表中的HASH值比较,如果相同,则表明还在使用默认值。

注意:在数据字典中存储的密码是被HASH算法加密过的,加密后的值不但跟密码本身有关还跟用户名有关,也就是,如果是不相同的用户名那么即使是完全相同的密码,加密后的HASH值也是不一样的。这样保证了每一个用户的每一个密码都有自己独一无二的HASH值。

在Oracle 11g之前,加密后的密码可以从DBA_USERS数据字典的PASSWORD字段中获得,因此可以通过这个字段中存储的值来做是否是默认值的检查。但是在11g中,PASSWORD字段却不再显示密码的内容了。

先看一下文档中对这个字段的描述:

Indicates whether the user is authenticated by OID (GLOBAL) or externally authenticated (EXTERNAL); NULL otherwise

SQL> select username,decode(password,null,'NULL',password) password from dba_users;
 
USERNAME                       PASSWORD
------------------------------ ------------------------------
MGMT_VIEW                      NULL
SYS                            NULL
SYSTEM                         NULL
DBSNMP                         NULL
SNPM                           NULL
SYSMAN                         NULL
SNPW                           NULL
SCOTT                          NULL
KAMUS                          NULL
OUTLN                          NULL
WMSYS                          NULL
DIP                            NULL
ORACLE_OCM                     NULL
TSMSYS                         NULL
 
14 rows selected

可以看到PASSWORD字段已经不再显示密码内容,全部都为空。

那么,如果再去检查这些用户是否还在使用默认的密码呢?

方法一:从SYS.USER$基表中检查,在基表的password字段中仍然可以查到HASH后的值。

SQL>  select name,password from user$ where name='SCOTT';

NAME                           PASSWORD
------------------------------ ------------------------------
SCOTT                          F894844C34402B67

方法二:这是推荐的方法,最简单的方法,11g中可以使用的方法,11g提供了新的DBA_USERS_WITH_DEFPWD视图,该视图中包含了所有还在使用默认密码的用户名。

SQL> alter user scott identified by tiger;

User altered.

SQL> select * from DBA_USERS_WITH_DEFPWD where username='SCOTT';

USERNAME
------------------------------
SCOTT

SQL> alter user scott identified by tiger1;

User altered.

SQL> select * from DBA_USERS_WITH_DEFPWD where username='SCOTT';

no rows selected

Oracle对于安全性的支持力求做到业界领先,Oracle始终在每个细节上进步着。

Abnormal result by “show sga” command in 11g

一个有趣的现象。在11.1.0.6版本的数据库中show sga的显示结果并不正确。

KAMUS@orcl11g> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
PL/SQL Release 11.1.0.6.0 - Production
CORE    11.1.0.6.0      Production
TNS for 32-bit Windows: Version 11.1.0.6.0 - Production
NLSRTL Version 11.1.0.6.0 - Production

Elapsed: 00:00:00.06
KAMUS@orcl11g> show sga

Total System Global Area  380817408 bytes
Fixed Size                  1333340 bytes
Variable Size             289408932 bytes
Database Buffers           83886080 bytes
Redo Buffers                6189056 bytes
KAMUS@orcl11g> show parameter memory_target

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
memory_target                        big integer 364M
KAMUS@orcl11g> select sum(bytes) from v$sgastat;

SUM(BYTES)
----------
 271768244

Elapsed: 00:00:00.03
KAMUS@orcl11g> select value from v$pgastat where name='total PGA allocated';

     VALUE
----------
  80623616

Elapsed: 00:00:00.01
KAMUS@orcl11g> select 380817408/1024/1024 from dual;

380817408/1024/1024
-------------------
         363.175781

Elapsed: 00:00:00.01

在show sga命令中显示Total System Global Area大小实际上是所有Memory的大小,包括了SGA+PGA,也就是memory_target参数的值。

将11g的新参数memory_target禁用,单独设置SGA和PGA,再看一下。

SYS@orcl11g> alter system set memory_target=0 scope=spfile;

System altered.
SYS@orcl11g> alter system set sga_target=271768244 scope=spfile;

System altered.
SYS@orcl11g> alter system set pga_aggregate_target=113246208 scope=spfile;

System altered.

修改完毕以后,重新启动数据库实例。再次用show sga命令显示SGA大小。

KAMUS@orcl11g> show sga

Total System Global Area  272011264 bytes
Fixed Size                  1332612 bytes
Variable Size             180357756 bytes
Database Buffers           88080384 bytes
Redo Buffers                2240512 bytes
KAMUS@orcl11g> select sum(bytes) from v$sgastat;

SUM(BYTES)
----------
 272013276

Elapsed: 00:00:00.10

这次show sga的显示结果正确了(有一些细微的误差,可以忽略不计)。

Oracle 11gR2 New Features Highlight

基本成型的Oracle 11gR2文档已经可以看到了,通览一下New Features部分,列举看上去很美妙的一些亮点。

以下仅仅是通过阅读文档得到的信息,在11gR2正式发布之前,一切都可能是会变化的。

1. RMAN Web-Services Backup

现在Oracle允许通过RMAN将数据库直接备份到Amazon S3或者其它的云计算存储解决方案中,虽然还没有明确的报价,但是可以预见一定会比自己购买带库要便宜。这里需要解决的一个是备份的效率问题,另外一个是备份集的安全性。

2. Edition-Based Redefinition
一直以来都知道在产品环境中,我们不能随便地去重定义包,函数,存储过程,视图,否则可能产生严重的锁等待,现在Edition-Based Redefinition的引入有助于在繁忙的产品环境中通过版本的控制来顺利地升级或者修改应用程序。

3. Cluster Time Service
代替NTP的东东,也许是因为NTP导致了一系列RAC的bug,所以Oracle干脆自己做一个时间同步服务,似乎这是在11gR2中安装RAC的前提条件了。

4. Columnar Compression
列式压缩,全新的压缩方式,消耗更多的CPU能力来获得更小的存储消耗,列式压缩对于应用是透明的,数据仓库系统值得去尝试一下这个新功能。

5. Data Pump Legacy Mode
在11gR2中原先的exp已经不再被支持,imp仍然允许使用。因此11gR2提供了兼容模式,允许在Data Pump中使用之前的exp和imp脚本,使客户获得更加平滑的升级体验。

6. Significant Performance Improvement of On-Commit Fast Refresh
对于物化视图刷新的改善,鼓励更多的数据仓库用户使用物化视图重写来改善应用性能。

最后也是最重量级的震撼新功能,那就是ASM全面升级,脱胎换骨。

7. Automatic Storage Management for All Data,是的,所有的数据都可以存储在ASM中,因为在11gR2中ACFS, ADVM闪亮登场了。

ASM Dynamic Volume Manager (DVM)是Oracle的卷管理软件,ASM Cluster File System (ACFS)是Oracle的集群文件系统,在这里不但可以存储以前ASM可以容纳的Oracle Datafile,同样也可以存储Oracle Binary, log file, trace file以及其它应用的程序文件,包括Oracle Clusterware需要的OCR Disk和Voting Disk现在也可以放置在ASM中了(11gR2之前必须放置在裸设备或者第三方集群文件系统中)。

期待11gR2的早日发布。

CBO need more human brains?

从Oracle8中引入的CBO和统计信息收集功能在8i,9i,10g,11g中一直在发展,CBO的设计理想是美好的,但是一直以来也受到用户的质疑,CBO的不够智能,或者说某些时候过于笨,有些时候又过于自作聪明,引发了很多问题。

11g推出之后,Oracle在完善CBO自身功能的同时,又添加了很多允许用户参与的功能,也许言下之意是,CBO的完善还有很长的路要走,但是面对各种现实问题,还是先允许更加聪明的人类用户来参与影响SQL的执行计划吧。

看看新提供的DBMS_STATS.COPY_TABLE_STATS功能,该功能可以改善对于使用range方式来分区的大分区表的统计信息生成方式,这种表往往统计信息更新赶不上数据更新。通过copy statistics可以将一个已经存在的分区统计信息复制到新生成的分区中,该方法基于的理念是每个业务分区的统计信息在数据条数,数据分布,NDV值等等方面都是基本相同的。

再加上之前介绍的SPM功能,也同样是允许用户来决定最终使用哪个执行计划的举措。

数据库管理越来越智能,并不意味着数据库管理员的工作越来越少了。

How to resolve ORA-13541

在尝试调整AWR报告的保留时限时,出现ORA-13541错误。

SQL> exec DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(4320,60);
BEGIN DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(4320,60); END;

*
ERROR at line 1:
ORA-13541: system moving window baseline size (691200) greater than retention
(259200)
ORA-06512: at "SYS.DBMS_WORKLOAD_REPOSITORY", line 89
ORA-06512: at "SYS.DBMS_WORKLOAD_REPOSITORY", line 137
ORA-06512: at line 1

试图查询ORA-13541的具体含义,但是发现oerr ora 13541并没有任何输出,同时在metalink上也查询不到任何一篇提及ORA-13541错误的文章。

只有从错误信息本身进行解读,我们的SQL动作是将AWR报告的保留时限从默认的8天改为3天。语句中的参数4320是retention,以分钟为单位,4320分钟等于3天。错误信息中的259200也是retention,但是却是以秒为单位,4320分钟=259200秒。那么691200也同样是秒,换算为天数是8天。此时再去检查AWR Baseline中的定义。

SQL> select moving_window_size from dba_hist_baseline;

MOVING_WINDOW_SIZE
------------------
                 8

那么重新解读一下错误信息,就是AWR Baseline中的MOVING_WINDOW_SIZE是8天,大于了想要修改的AWR Retention的3天。

尝试先将AWR Baseline的MOVING_WINDOW_SIZE修改为3天。可以在OEM的AWR Baselines链接里直接修改。

然后再次修改AWR Retention,成功。

SQL> exec DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(4320,60);

PL/SQL procedure successfully completed.