前言:
近期处理了一起Oracle Exadata数据库在RMAN备份期间发生crash的案例,原因为ASM buffer cache 内存分配不合理,导致在对磁盘进行大量数据文件操作时,没有足够的ASM buffer cache来存放元数据块引发了ASM实例异常,最终导致数据库发生crash。
问题:
Oracle Exadata数据库在RMAN备份期间集群节点发生crash。
原因:
1 数据库在RMAN备份期间集群节点发生crash是因为ASM实例异常导致
2 ASM实例异常的原因为操作进程无法申请到可用的ASM buffer来缓存元数据块(ASM metadata block),导致进程ASM关键操作无法正常响应,最终引发ASM实例异常终止,数据库集群响应异常。
3 ASM实例进程无法申请到ASM buffer的原因为当前ASM buffer cache 内存分配不合理,导致在对磁盘进行大量数据文件操作时,没有足够的ASM buffer cache来存放元数据块。
建议:
调整ASM实例内存参数配置,以匹配当前ASM数据文件操作数量。
ASM实例db_cache_size参数设置为0,导致ASM buffer cache默认只分配32M内存,根据Oracle官方最佳实践建议db_cache_size参数调整为800M,确保ASM buffer cache分配足够的内存。
问题分析过程:
1 查看问题时间数据库alert日志 可以发现在14点15分实例后台出现I/O hang住问题报错,在14点32分出现ASM实例通信异常问题。
2 查看问题时间段数据库的diag错误日志,可以看到数据库后台存在大量的ASM实例操作等待问题sync asm rebalance,asm file metadata operation
从数据库的alert日志,我们可以初步确认数据库节点二异常无法响应是因为ASM实例异常导致。
3 接下来对ASM实例进行分析,查看asm实例的alert日志,从14:13开始asm实例出现问题触发了实例system dump。
4 ASM实例有大量的进程被kill,在14点57分ASM实例被异常终止。
5 分析system dump日志内容,可以发现asm实例进程存在大量的no free buffer(ASM buffer cache申请)以及disk file operation IO (磁盘文件操作)等待
注:ASM 实例的 "no free buffers" 等待指的是 ASM buffer cache (db_cache_size)不足或者过低导致无法获取到可用 buffer 来缓存 ASM metadata block。
6 查看no free buffers的会话等待函数链(short stack),可以看到调用的操作函数为kfcGetBuffer。
7 kfcGetBuffer函数的作用从Oracle官方提供的信息来看,主要用于从ASM buffer cache里面寻找free chunk来存放加载的ASM metadata block。
8 查看no free buffer等待的会话,当前都在对磁盘BACKUP_CD_***进行操作,操作与数据库期间正在进行RMAN的备份操作匹配。
9 从ASM的日志信息我们可以确认ASM实例异常的原因为ASM实例操作进程无法申请到可用的ASM buffer来缓存元数据块(ASM metadata block),导致进程ASM关键操作无法正常响应,最终引发ASM实例异常终止,数据库集群响应异常。
10 接下来分析ASM buffer cache的配置情况, 当前ASM实例的buffer cache分配为32M。
SGA有效的剩余内存为0
11 分析ASM buffer cache分配32M是否合理,根据官方文档Oracle Exadata Database Machine Automatic Storage Management Best Practices (Doc ID 2049911.1)的描述,
Exadata的ASM buffer cache size(db_cache_size)的合理设置应该为5 * (<# of disks> + <# of files>) * 4K
12 当前ASM磁盘组的disks为100,files为15299其中BACKUP目录的备份文件较多达到11102个。
根据公式计算ASM buffer cache size=5*(100+15299)*4k,ASM buffer cache size至少需要301M才能满足当前的数据文件存储元数据操作需要,而当前ASM buffer cache size只分配32M是不合理的,这将导致在对磁盘进行大量数据文件操作时,没有足够的ASM buffer cache来存放元数据块。
总结:
1 数据库在RMAN备份期间集群节点发生crash是因为ASM实例异常导致
2 ASM实例异常的原因为操作进程无法申请到可用的ASM buffer来缓存元数据块(ASM metadata block),导致进程ASM关键操作无法正常响应,最终引发ASM实例异常终止,数据库集群响应异常。
3 ASM实例进程无法申请到ASM buffer的原因为当前ASM buffer cache内存分配不合理,导致在对磁盘进行大量数据文件操作时,没有足够的ASM buffer cache来存放元数据块。
问题建议:
根据Oracle官方文档建议对db_cache_size参数进行调整
1 Oracle Exadata Database Machine Automatic Storage Management Best Practices (Doc ID 2049911.1)
2 ASM & Shared Pool (ORA-4031) (Doc ID 437924.1)
3 Oracle Exadata Initialization Parameters and Diskgroup Attributes Best Practices (Doc ID 2062068.1)
Oracle官方公式:5 * (<# of disks> + <# of files>) * 4K*1.5
按照当前磁盘组最大文件数,granule size(32M)大小,50%的安全空间以及SGA的剩余内存,建议设置db_cache_size为800M以确保ASM buffer cache分配足够的内存。
注:需要重启生效,参数可以在线设置,但ASM buffer cache大小只有重启之后才会重新分配内存,因此需要重启集群生效