10g RAC培训 – 1

今天在上地6号参加RAC Pack的培训,讲师是来自RAC Pack核心Team的roy.rossebo和su.tang以及北京的paulo.qiu。

第一天仅限于在Redhat上安装CRS+ASM+DB,基本上没有太多技术问题,整个下午的讨论似乎有些偏离这次Training的主题,都聚焦在Oracle的Patch机制上。

为什么会有Merge Label Patch,为什么又有Bundle Patchset,怎么通过内部的Wiki站点查询已经发布的和即将发布的Merge Label Patch,对于不是RAC的系统在哪儿可以查到推荐的Patchset,对于是RAC的系统又在哪儿查询。

更Detail的技术问题应该在后面几天会涉及到吧。

最后培训结束以后,跟ACS的几位同事聊天,得到了一堆稍显粗糙但是又颇为贴切的对于Oracle售后几个部门的比喻。

我问他们,ACS和GCS有什么不同,他们说:
OSS中的ACS就好比小姐出台,因为是到客人处上班的短期行为。
OSS中的GCS就好比小姐坐台,因为是在公司处理热线的长期行为。

于是我恍然大悟,跟他们说:
那这样,OCS就好比二奶,因为是在客人处上班的长期行为。

那,老婆是什么呢,是集成商啊。。。

哈哈,大家一笑。

5 node RAC 10g completed

昨天又干了一件大工程,搭建5节点的Oracle10g RAC,仍然是AIX 5L操作系统,盘阵是HP比较老些的XP128,不过也属于高端盘阵了,210块盘做ASM中的datagroup(用于存储数据文件),10块盘中ASM的flashgroup(用于flash recovery area),一块盘做OCR Disk,一块盘做Voting Disk。

总体安装过程简直可以用“完美”来形容,一个错误也没有发生,恩,我的意思是说实际上还是碰到了一个问题。:)

这个问题发生在10.2.0.3版本的racgvip脚本中,如果操作系统没有设置默认网关(Gateway),那么在安装完10.2.0.3补丁以后,vip资源将无法正常启动,而在之前的10.2.0.1中一切都是正常的。

老实说,实际上耗费了不少时间去找这个问题的原因,甚至修改了racgvip脚本来echo我自己需要的调试信息,这样才一步步追踪到错误信息输出之前的那步操作,是检查系统的default gateway,并且返回的变量值是null,然后询问系统管理员,得知系统确实没有设置网关。这时候,才发现原来在racgvip脚本的最开始有一个变量可以控制当系统没有默认网关时整个脚本是否还继续进行。

vi /oracle/crs/bin/racgvip

默认有一行
FAIL_WHEN_DEFAULTGW_NO_FOUND=1

需要将1修改为0
FAIL_WHEN_DEFAULTGW_NO_FOUND=0

然后再次启动crs,一切正常了。再之后就一帆风顺,平安到港。

下面最简单的描述一下在AIX 5L安装Oracle10g RAC的步骤。

1. 安装操作系统所需补丁
2. 设置存储,其中创建两个裸设备,一个给ocr disk,一个给vote disk
3. 修改所有节点中的/etc/hosts,/etc/hosts.equiv,~root/.rhosts,~oracle/.rhosts,这是给rsh用的
4. 修改所有节点中的~oracle/.profile,这是设置环境变量
5. 安装CRS
6. 安装Oracle 10.2.0.1 软件
7. 升级CRS和Oracle Software到10.2.0.3
8. 创建ASM实例,创建diskgroup
9. 创建数据库

Oracle 10.2.0.3 Bind Peeked Parallel Bug

昨晚11:30,客户电话,报告数据库服务器CPU负载陡然上升到95%以上,并且报ORA-4031错误。12:00赶到现场。

查看故障发生期间的AWR报告。

1. 最高的等待事件是“latch: library cache lock”和“latch: library cache”
2. Shared Pool Memory Usage 达到了98% (Shared Pool Size: 4,096M)
3. SQL ordered by Elapsed Time部分显示一条SQL占用了91.9%的总时间
4. SQL ordered by CPU Time 部分显示同样这条SQL占用了91.9%的CPU时间
5. SQL ordered by Sharable Memory部分,大批Executions=N/A的SQL,并且最高的一条SQL已经消耗了将近2G的Sharable Memory
6. SQL ordered by Version Count部分,刚才那句占用了将近2G缓存的SQL有高达77,237的Version Count

至此,大概可以猜测整个问题的发生原因了。因为过度的Version Count导致Shared Pool消耗殆尽,在Library Cache中开始频繁获取空闲空间以parse新进的SQL,于是产生大量的library cache latch,最终Shared Pool中再也无法找到足够解析一个SQL的空闲空间,于是报ORA-4031。整个系统全线崩溃。

那么现在问题就在于为什么会有如此巨大的Version Count?

查询v$sql_shared_cursor视图,对于每句SQL,如果由于某种原因不能被共享而被重新parse生成一个cursor的话,就会在这个视图中多一条记录,同时记录了不能被共享的原因。

通过AWR报告中的sql_id,发现产生巨大Version Count的原因是BIND_PEEKED_PQ_MISMATCH,简单解释一下,就是说对于并行操作在有Bind_Peek时,Oracle认为整体条件不符合cursor共享的原则,于是便重新解析了。

应用里面的SQL是比较规范的,使用了绑定变量,但是巧就巧在:
1. 在Table级别,客户设置了parallel属性,导致对于该表的select操作,即使是白天的OLTP阶段也仍然使用了大量的并行进程
2. 因为绑定变量,所以Oracle决定在生成执行计划之前要Bind_Peek一下

这两个条件的合作触发了Oracle10g的一个BUG 4367986,本来不应该实际上却产生了这么多Version Count。

解决这个BUG的Patch目前只有Linux,Solaris和HP-UX平台的,而客户现在的AIX平台只有等待Oracle开发团队的Backport,希望在明天可以收到release的Patch。

权宜之计是:
1. 去除Table级别的Parallel设定(其实早就应该去除,因为在OLTP系统中设置表的并行值并不值得推荐)
2. 或者,禁用Bind_Peek,初始化参数中设置”_optim_peek_user_binds”=FALSE

客户选择了前者,目前整个系统功能正常。

屡次熬夜并且屡次早上睡了几个小时又被叫起来的经历之后,一个感想:

AWR报告,ADDM报告,ASH报告,这些10g的新利器需要DBA彻底地去熟悉,仔细再仔细,任何问题你都会找到蛛丝马迹的,然后串在一起,就会豁然开朗,柳暗花明。