Automatic Statistics Gathering

在Oracle10g中引入的优化器统计信息(Optimizer Statistics)自动收集,是一个看上去很不错的功能,但是在实际应用中却往往没有起到相应的效果,甚至在某些系统中我们会建议禁用这个功能。

阐述一些该功能的相关知识点。

1. Automatic Statistics Gathering是由Scheduler调度GATHER_STATS_JOB作业来完成的,在GATHER_STATS_JOB作业中则调用DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC存储过程。

2. 该作业在创建数据库的自动创建,并且设置为每天晚上10点到第二天早上6点和周六周日的全天为运行窗口期。在运行窗口期内,该作业都会运行,根据stop_on_window_close属性来决定,如在窗口期结束以后,该作业如果还没有运行完毕,是继续运行还是结束运行。

3. GATHER_DATABASE_STATS_JOB_PROC是内部的存储过程,基本上跟DBMS_STATS.GATHER_DATABASE_STATS的功能一样,但是有内部的优先顺序考虑,更新越多的表将会越优先收集统计信息。

4. 收集统计信息的表对象是,之前从来没有收集过的或者是更新的(包括insert,update,delete,truncate)记录数超过当前总记录数10%的表。记录数的更改量由Oracle数据库自动监控,在初始化参数statistics_level设置为TYPICAL或者ALL时,自动监控即会生效。

5. 在USER_TAB_MODIFICATIONS表中记录了所有被监控的表的数据量更改信息。该信息的更新将会稍微滞后于真实的修改,可以通过DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO存储过程来立刻将更改的信息更新到USER_TAB_MODIFICATIONS表中。对于更新之后再rollback的记录,仍然算为已经受影响的记录,Oracle不会在rollback之后再去更新USER_TAB_MODIFICATIONS表。

SQL> select * from user_tab_modifications where table_name=’EMP’;

no rows selected

SQL> select count(*) from emp;

COUNT(*)
———-
14

SQL> update emp set sal=sal+100;

14 rows updated.

SQL> select * from user_tab_modifications where table_name=’EMP’;

no rows selected

SQL> exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO();

PL/SQL procedure successfully completed.

SQL> select inserts,updates,deletes from user_tab_modifications where table_name
=’EMP’;

INSERTS UPDATES DELETES
———- ———- ———-
0 14 0

SQL> rollback;

Rollback complete.

SQL> exec DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO();

PL/SQL procedure successfully completed.

SQL> select inserts,updates,deletes from user_tab_modifications where table_name
=’EMP’;

INSERTS UPDATES DELETES
———- ———- ———-
0 14 0

SQL>

6. 在Oracle10g版本(包括最新的10.2.0.4)中没有已知的修改10%这个阀值的方法。但是在Oracle11g中则提供了SET_TABLE_PREFS等函数。

以下命令将指定表的STALE默认值从10%改为5%,该值可以从新的dba_tab_stat_prefs数据字典中查询获得。

–仅限于Oracle11g版本
BEGIN
DBMS_STATS.SET_TABLE_PREFS ( ownname =>’KAMUS’, tabname =>’T1′, pname =>’STALE_PERCENT’, pvalue =>’5′);
END;
/

SQL> select * from dba_tab_stat_prefs;

OWNER TABLE_NAME PREFERENCE_NAME PREFE
———- ———- ——————– —–
KAMUS T1 STALE_PERCENT 5

7. 在Oracle10g中运行以下命令,可以禁用统计信息自动收集功能。
BEGIN
DBMS_SCHEDULER.DISABLE(‘GATHER_STATS_JOB’);
END;
/

How to install 10.2.0.3 CRS BUNDLE #1

安装完Oracle RAC 10.2.0.3之后,可以选择打上CRS BUNDLE #1 Patch(PatchID:6160398),这是一系列Patch的集合,不能简单地用“opatch apply”来完成。当然,其中的README文件详细描述了每一步应该怎么做。

这里只是说两件需要注意的事情。

1. 要打CRS BUNDLE #1 ,必须要先升级OPatch实用程序,至少要升级到10.2.0.3.3,因为Oracle 10.2.0.3自带的OPatch版本中没有napply这个命令。升级OPatch实用程序很简单,去Metalink上下载Patch 4898608,然后解压覆盖原先的OPatch目录就可以。

2. 仍然是OPatch的问题。必须将CRS_HOME和ORACLE_HOME中的OPatch目录都升级到10.2.0.3.3或者之后的版本,否则在Patch过程中给ORACLE_HOME打补丁的时候报如下错误。

UtilSession failed: Patch 6160398 requires component(s) that are not installed in OracleHome. These not-installed components are oracle.crs:10.2.0.3.0,

OPatch failed with error code 73

虽然是作为Oracle的员工,还是得说,Oracle的Patch管理实在是有些不方便,大部分Patch都得靠眼睛去Metalink上找,找来以后还可能跟别的Patch冲突,然后还要去申请Merge Label Patch,总之是一个糟糕的体验。

Oracle9i upgrade to Oracle10g RAC

从昨天开始,正式全程参与某客户的数据库系统升级工作。工作内容是将客户的关键应用从原先的Oracle9.2.0.6单实例升级为Oracle 10.2.0.3 双实例RAC。

更加详细的工作内容包括:
1. 将原先存储在JFS2文件系统上的文件转移到GPFS中
2. 将原先单实例模式的Shareplex转换为RAC模式的Shareplex
3. 将原先的高级复制转换为简单的物化视图刷新
4. 使用Oracle Clusterware替代HACMP负责Shareplex资源的切换

总的来说,是一个很大的工程,数据库大小在800G左右,升级使用DBUA,单实例转换为RAC则使用rconfig实用程序。

工作的几个难点在于:
1. DBUA是否能顺利将Oracle 9.2.0.6升级为Oracle 10.2.0.3?
2. rconfig是否能顺利将单实例数据库转换为RAC数据库?
3. 能否正常在Oracle Clusterware中添加Shareplex资源并且保证在各种异常情况下顺利切换到另外一台主机上?

之前已经做过多次测试,希望这两天的正式升级会一帆风顺。

Update@2008-4-3
升级工作圆满结束,有惊无险。

1. 本来一直到rconfig转换单实例到RAC之前,整个进度都是提前了4个小时左右的,敲完rconfig的命令之后大家欢欣鼓舞地去开会,结果开完会回来发现rconfig失败了,一直处于悬停状态,整个主机没有任何负载,数据库实例也完全无法登录。根据回退方案将数据库重新转换为之前的单实例模式,成功启动完数据库以后,开始检查转换为RAC失败的原因。最后发现是ntp服务配置有问题,RAC两个节点的时间差异在1小时。重新调整ntp服务,然后再次转换,成功结束。此时,落后进度计划大概1个小时。

2. 后续的工作一帆风顺,应用上的几个问题也相继迅速地修改了,上线当天上午观察了一下主机情况,一切正常。于是中午就离开客户处了,没过2小时,客户电话说,机房忽然断电,所有设备全部意外down机 。。。我问UPS呢?客户说,就是一台UPS短路导致机房断电的。我FT。再赶回客户处,等着加电,幻想着加电以后GPFS文件系统全部损坏,然后再从带库恢复数据的凄惨景象。幸运的是,加电以后全部设备都安然启动,数据库也正常。Shareplex丢失了一部分数据,也都成功恢复。

3. 到今天为止没有更点儿背的事情发生,应用完全正常,宣告这次升级工作圆满结束。