必须修改\_asm\_hbeatiowait参数,因其默认15秒不足以应对存储切换(如主控掉电、双控切换、FC链路重路由等20–90秒场景),不调整将导致ASM磁盘组标记MISSING并触发RAC节点驱逐。
必须改 _asm_hbeatiowait,默认15秒在存储切换场景下根本不够用——主控掉电、双控切换、fc链路重路由都可能耗时20–90秒,不调这个参数,asm磁盘组直接标记为missing,rac节点大概率被驱逐。
为什么默认15秒会挂住整个RAC
ASM磁盘心跳(disk heartbeat)不是靠轮询,而是依赖底层存储返回响应。当SAN交换机故障、阵列控制器接管或HBA驱动异常时,IOCTL调用会卡在内核态,超时由_asm_hbeatiowait控制。一旦超时,ASM立即把磁盘标为MISSING,触发快速镜像同步;若同步窗口(_asm_disk_repair_time,默认3.6秒)内仍未恢复,就走彻底删除+重平衡流程——而重平衡本身又加重IO压力,形成恶性循环。
常见现象包括:
-
SELECT name, state, repair_timer FROM v$asm_disk中大量磁盘状态为MISSING,repair_timer为 0 - 告警日志出现
ORA-15040: diskgroup is incomplete或ORA-15042: ASM disk "X" is missing - 伴随
cssd日志里反复出现missed disk heartbeat,但网络心跳正常
怎么安全修改 _asm_hbeatiowait
该参数是隐藏参数,只对ASM实例生效,必须写入SPFILE并重启ASM。注意:不是数据库实例,也不是CRS服务。
操作步骤如下:
- 用
grid用户登录任意节点,执行:sqlplus "/as sysasm"<br>SELECT ksppinm, ksppstvl FROM x$ksppi x, x$ksppcv y WHERE x.indx = y.indx AND ksppinm = '_asm_hbeatiowait';
- 确认当前值(通常为15),然后执行:
ALTER SYSTEM SET "_asm_hbeatiowait"=120 SCOPE=SPFILE SID='*';
- 关闭ASM(不是数据库):
srvctl stop asm -n(每个节点单独执行) - 再启动ASM:
srvctl start asm -n
⚠️ 注意:SID='*' 表示所有ASM实例;不能只改一个节点;修改后无需重启数据库实例,但ASM进程必须重启才生效。
改完还挂?检查这三处硬性依赖
参数调大只是争取时间,不代表问题消失。以下任一条件不满足,照样触发MISSING和驱逐:
-
voting disk所在磁盘组的IO延迟过高:iostat -x 1查看await > 50ms或%util > 95,说明磁盘心跳包发不出去,_asm_hbeatiowait再大也白搭 - UDEV规则未同步更新:如果用了UDEV绑定ASM磁盘路径(如
/dev/asm-data01),规则中MODE="0660"、OWNER="grid"、GROUP="asmadmin"必须与ls -l /dev/oracleasm/disks/输出完全一致,否则ASM读磁盘头失败,心跳根本发不出 -
SELinux处于Enforcing模式:它会拦截grid对设备节点的open()调用,现象是oracleasm scandisks能列出盘,但asmcmd lsdg连不上,getenforce返回Enforcing就必须关
别忘了配套调 _asm_disk_repair_time
_asm_hbeatiowait 控制“单次IO心跳超时”,而 _asm_disk_repair_time 控制“MISSING状态容忍窗口”。二者要匹配:
- 若把
_asm_hbeatiowait改成120,_asm_disk_repair_time至少设为 300(5分钟),否则刚等完心跳超时,还没来得及恢复,磁盘就被删了 - 设置方式相同:
ALTER SYSTEM SET "_asm_disk_repair_time"=300 SCOPE=SPFILE SID='*';
- 注意:该值单位是秒,且必须小于磁盘组
DISK_REPAIR_TIME属性(可通过ALTER DISKGROUP ... SET ATTRIBUTE 'disk_repair_time'='300s'调整)
真正容易被忽略的是:这两个参数改完后,必须验证v$asm_disk里的repair_timer是否真能跑起来——不是看值变大,而是拔一次线缆模拟瞬断,观察它是否从非零开始倒计时,而不是直接跳到0变成OFFLINE。











