一次ORACLE ASM磁盘故障处理

客户给 ASM 磁盘组加了一块新盘,rebalance power 设了 8,跑了 3 小时后 ASM 实例突然重启,重启后磁盘组状态变成 MOUNTED,但数据文件打不开,报 ORA-15042。查了下,ASM 的 Partnership Status Table(PST)有块损坏,部分 extent 的冗余信息丢了。这要是恢复不了,整个磁盘组的数据都得从备份还原。

1 ASM 的 Rebalance 不是简单的拷贝

很多人以为 ASM rebalance 就是 rsync,把数据从旧盘拷到新盘。实际上它是个精细的在线重分布过程:ASM 把每个 AU(Allocation Unit,默认 1MB)当成最小迁移单位,迁移时先在新位置写副本,更新 PST 里的 partnership 记录,确认 PST 写成功后,再标记旧位置的 AU 为可回收。整个过程中,数据库的 I/O 不能中断,所以 ASM 用了类似 Copy-on-Write 的机制:迁移期间如果数据库写了某个 AU,ASM 会把这个写操作同时落到新旧两个位置,保证一致性。

故障发生在 PST 更新阶段。PST 存在每个磁盘的头几个 AU 里(通常是 AU 0-3),记录了该磁盘与哪些其他磁盘互为镜像伙伴。rebalance 过程中,PST 需要频繁更新,如果此时 ASM 实例崩溃,PST 可能处于半写状态——新 partnership 信息写了一半,旧信息被覆盖了。重启后 ASM 读取 PST,发现 checksum 不对,就报 ORA-15042。

2 实验:用 kfed 读取 PST 并修复

-- 查看磁盘组状态
SELECT name, state, type, total_mb, free_mb
FROM v$asm_diskgroup WHERE name = 'DATADG';
-- DATADG 状态 MOUNTED,但无法 OPEN

-- 查看磁盘头信息
SELECT path, name, mount_status, header_status, mode_status
FROM v$asm_disk WHERE group_number = 1;
-- 发现 DISK_04 的 header_status = PROVISIONED(PST 损坏)

-- 用 kfed 读取磁盘头(在 ASM 实例上执行)
kfed read /dev/oracleasm/disks/DATA04 | grep -i pst
-- kfbh.type: 1 (KFBTYP_DISKHEAD)
-- kfdhdb.partner: 0x00000000  -- partnership 信息全 0,明显损坏

-- 从镜像伙伴磁盘恢复 PST
-- 先找到 DATA04 的伙伴磁盘(假设是 DATA02)
kfed read /dev/oracleasm/disks/DATA02 | grep -i partner
-- 记录 DATA02 的 partnership 表

-- 手动修复 DATA04 的 PST(极端应急,生产环境建议找 Oracle SR)
kfed write /dev/oracleasm/disks/DATA04     aus=4194304 blkn=1     'kfdhdb.partner[0]: 2'     'kfdhdb.partner[1]: 3'
-- 然后重新 mount 磁盘组
ALTER DISKGROUP DATADG MOUNT;

-- 更稳妥的做法:把 DATA04 drop 掉,让 ASM 用剩余磁盘重建冗余
ALTER DISKGROUP DATADG DROP DISK DATA04 FORCE;
-- 然后 rebalance
ALTER DISKGROUP DATADG REBALANCE POWER 4;

我们那次用了稳妥做法:FORCE DROP 损坏盘,然后 rebalance。虽然丢了一些 extent(因为损坏盘上的副本没来得及同步完),但 ASM 的 triple mirror(HIGH 冗余)还有另外两个副本,数据没丢。rebalance 跑了 6 小时,磁盘组恢复正常。如果用的是 NORMAL 冗余(双副本),而当时损坏盘上有些 extent 只写了一半,那就可能丢数据,必须从 RMAN 恢复。

事后总结:第一,rebalance 的 power 别设太高,尤其是磁盘组里有大量小文件时。power 8 意味着同时迁移 8 个 AU,CPU 和 I/O 压力都大,我们后来改成 power 2,虽然慢点,但稳;第二,加盘前先做 ALTER DISKGROUP ... CHECK ALL,确保现有磁盘没有隐藏的坏块;第三,ASM 的 PST 损坏虽然罕见,但一旦发生就是灾难级,建议定期用 kfed 做磁盘头备份,脚本化执行:for disk in /dev/oracleasm/disks/DATA*; do kfed read $disk > /backup/asm/$(basename $disk).hdr; done别等灾难来了才想起来没备份。


请使用浏览器的分享功能分享到微信等