一、问题背景 Oracle RAC (Real Application Clusters) 配合 ASM (Automatic Storage Management) 是目前业界最经典的高可用数据库架构。RAC 解决了计算层的高可用与横向扩展,ASM 则在存储层提供了自动化的卷管理、条带化和镜像能力。然而,很多 DBA 在搭建 RAC 时往往将注意力集中在集群软件和数据库实例上,忽略了存储层——尤其是多路径(Multipath) ——的正确配置。
存储层配置不当会导致一系列严重问题:
磁盘路径单点故障 :HBA 卡、光纤线缆或存储控制器的任何一环出现故障,都会导致 IO 中断,RAC 节点直接被驱逐。
ASM 磁盘发现失败 :如果存储映射变更后未正确配置设备发现路径,ASM 实例将无法找到磁盘,导致磁盘组 dismount。
权限问题 :在 Linux 环境中,裸设备的 owner/group 权限不正确会导致 Oracle 无法打开磁盘,安装过程直接报错 ORA-15025、ORA-27041 等。
在生产环境中,存储阵列通常通过双控制器 向主机暴露 LUN,主机端则通过双 HBA 卡 连接存储。这就意味着同一块 LUN 在操作系统层面会看到多个 SCSI 设备(如 /dev/sdb、/dev/sdc、/dev/sdd、/dev/sde)。Multipath 的作用正是将这些底层物理路径聚合为一个逻辑设备,同时提供路径故障切换和负载均衡能力。
本文将从理论到实践,完整讲解在 RAC + ASM 架构中如何正确配置 Multipath 存储,并给出磁盘组创建和管理的完整操作指南。
二、理论分析 2.1 Linux Multipath 原理 Linux 下的多路径功能由 DM (Device Mapper) Multipath 提供,它是内核 device-mapper 框架的一部分。其架构可以简单理解为:
1 2 3 4 5 6 7 8 9 应用层 (Oracle ASM) ↓ /dev/mapper/mpathX (Multipath 逻辑设备) ↓ device-mapper 内核模块 (路径选择、故障切换) ↓ /dev/sdX (多个 SCSI 路径设备) ↓ HBA 卡 → FC 交换机 → 存储控制器
Active-Passive 模式 下,只有一条路径处于活动状态处理 IO,其余路径处于待命状态。当活动路径故障时,自动切换到备用路径。这种模式的路径切换时间较长(通常需要几秒),但实现简单、稳定性高。
Active-Active 模式 下,所有路径同时处理 IO,实现真正的负载均衡。这要求存储阵列支持 ALUA (Asymmetric Logical Unit Access) 或明确支持并发 IO。大多数中高端存储(如 EMC Unity、HDS VSP、华为 OceanStor)都支持 ALUA。
Multipath 的核心配置参数包括:
path_checker :路径健康检查方式,常用 tur(TEST UNIT READY 命令)或 readsector0
path_grouping_policy :路径分组策略,failover(主备)、multibus(多路径共享)、group_by_prio(按优先级分组)
failback :故障恢复策略,immediate(立即回切)、manual(手动)、或指定秒数
no_path_retry :所有路径不可用时的重试策略,queue 表示排队等待,数字表示重试次数
2.2 ASM 磁盘发现机制 ASM 在启动时需要发现可用的磁盘,这一过程由 ASM_DISKSTRING 参数控制。该参数支持通配符,例如:
1 2 3 ALTER SYSTEM SET asm_diskstring = '/dev/mapper/mpath*' SCOPE = SPFILE;ALTER SYSTEM SET asm_diskstring = 'AFD:*' SCOPE = SPFILE;
ASM 发现磁盘后,会读取磁盘的前两个 AU 来获取 ASM 磁盘头信息。磁盘头结构称为 kfdhdb (Kernel File Directory Header Block),其中包含:
磁盘名称、磁盘编号
所属磁盘组名称和编号
AU 大小
版本兼容性信息
分配表(AT)和空闲空间表(FST)的位置
AU (Allocation Unit) 是 ASM 的最小分配单元,默认大小为 1MB(12c 及以后支持 4MB)。ASM 的条带化分为两种粒度:
Fine-grained striping :128KB 条带,适合 OLTP 系统的小 IO 随机读写
Coarse-grained striping :AU 大小条带,适合数据仓库的大 IO 顺序读写
2.3 ASM 冗余策略 ASM 提供三种冗余策略,每种策略有不同的适用场景:
External Redundancy :不提供 ASM 级别的镜像,完全依赖底层存储的 RAID 保护。适用于已有企业级存储 RAID 保护的场景(RAID 10、RAID 5 等)。空间利用率最高,为 100%。
Normal Redundancy :提供 2-way mirror,ASM 将每个 extent 的两份副本分布在不同的故障组(Failure Group)中。至少需要两个故障组。空间利用率为 50%。适用于没有存储级镜像的场景,或对数据保护有额外要求的场景。
High Redundancy :提供 3-way mirror,三个副本分布在三个故障组中。空间利用率为 33%。适用于对数据可用性要求极高的核心业务系统。
空间计算公式:
1 可用空间 = 磁盘组原始空间 × (1 / 冗余因子) - 文件系统开销
例如,10 块 1TB 磁盘的磁盘组,Normal Redundancy 的可用空间约为 (10 × 1TB × 0.5) - 开销 ≈ 4.5TB。
2.4 ASM 权限管理 ASM 访问磁盘设备需要正确的权限配置。Linux 环境下有三种主要方案:
udev rules 方案 :通过编写 udev 规则,将 Multipath 设备的 owner 设置为 oracle:oinstall,权限设置为 0660。这是最传统也是最通用的方案,适用于所有 Oracle 版本。
**ASMFD (ASM Filter Driver)**:Oracle 12c 引入的专用驱动,在内核层拦截对 ASM 磁盘的 IO,防止意外覆写 ASM 磁盘头。ASMFD 还简化了磁盘管理,无需手动配置权限。推荐在 12c 及以后版本中使用。
1 2 3 4 $ asmcmd afd_label DATA01 / dev/ mapper/ mpathb $ asmcmd afd_scan $ asmcmd afd_lslbl
oracleasm 方案 :使用 ASMLib 工具包,通过 oracleasm createdisk 命令标记磁盘。适用于 RHEL/OEL 系统,但自 RHEL 8 起不再提供原生 ASMLib 支持,需要第三方源。配置时需注意设置 ORACLEASM_SCANORDER="dm" 以优先扫描 Multipath 设备。
三、实战操作 3.1 多路径配置 获取 SCSI 设备的 WWID 首先需要确定存储映射的 LUN 对应的 SCSI ID(WWID),以便在 multipath.conf 中进行精确配置:
1 2 3 4 5 6 7 8 9 10 /lib/udev/scsi_id -g -u -d /dev/sdb /lib/udev/scsi_id --whitelisted --device=/dev/sdb cat /sys/block/sd*/device/vendorlsscsi
完整的 multipath.conf 配置 以下是一个适用于 Oracle RAC 环境的 /etc/multipath.conf 完整配置示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 # /etc/multipath.conf - Oracle RAC 环境配置 # 适用于 EMC/DELL PowerStore、HDS VSP、华为 OceanStor 等常见存储 defaults { udev_dir /dev polling_interval 10 path_selector "round-robin 0" path_grouping_policy multibus getuid_callout "/lib/udev/scsi_id -g -u -d /dev/%n" path_checker tur rr_min_io 100 rr_min_io_rq 1 max_fds 8192 no_path_retry fail user_friendly_names yes find_multipaths yes } # 黑名单:排除本地磁盘和 USB 设备 blacklist { devnode "^(ram|raw|loop|fd|md|dm-|sr|scd|st)[0-9]*" devnode "^sd[a-b]$" # 本地系统盘,根据实际环境调整 device { vendor "Dell" product "Virtual" } device { vendor "ATA" } } # 黑名单例外:确保存储设备不被误排除 blacklist_exceptions { wwid "360060160*" # wwid "36000d310*" # 根据存储厂商的 wwid 前缀调整 } # 默认配置 multipaths { multipath { wwid 360060160f8a03800c8e6c5b7e3c3e411 alias asm_data01 path_grouping_policy group_by_prio path_selector "round-robin 0" failback immediate rr_weight priorities no_path_retry 12 prio alua } multipath { wwid 360060160f8a03800c8e6c5b7e3c3e412 alias asm_data02 path_grouping_policy group_by_prio path_selector "round-robin 0" failback immediate rr_weight priorities no_path_retry 12 prio alua } multipath { wwid 360060160f8a03800c8e6c5b7e3c3e501 alias asm_fra01 path_grouping_policy group_by_prio path_selector "round-robin 0" failback immediate rr_weight priorities no_path_retry 12 prio alua } multipath { wwid 360060160f8a03800c8e6c5b7e3c3e601 alias asm_ocr01 path_grouping_policy group_by_prio path_selector "round-robin 0" failback immediate rr_weight priorities no_path_retry queue prio alua } } devices { device { vendor "VNX" product ".*" path_grouping_policy group_by_prio path_checker tur path_selector "round-robin 0" failback immediate prio emc no_path_retry 12 hardware_handler "0" } # 华为 OceanStor 配置示例 device { vendor "HUAWEI" product "XSG1" path_grouping_policy group_by_prio path_checker tur path_selector "round-robin 0" failback immediate prio alua no_path_retry 12 } }
验证多路径配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 systemctl reload multipathd multipath -ll multipath -v3 -d dmsetup ls dmsetup status
3.2 ASM 磁盘准备 方案一:使用 udev 配置磁盘权限 在 RHEL 7/8 中,创建 udev 规则文件 /etc/udev/rules.d/99-oracle-asmdevices.rules:
1 2 3 4 5 6 7 8 9 10 ACTION=="add|change" , ENV{DM_UUID}=="mpath-360060160f8a03800c8e6c5b7e3c3e411" , OWNER="oracle" , GROUP="oinstall" , MODE="0660" ACTION=="add|change" , ENV{DM_UUID}=="mpath-360060160f8a03800c8e6c5b7e3c3e412" , OWNER="oracle" , GROUP="oinstall" , MODE="0660" ACTION=="add|change" , ENV{DM_UUID}=="mpath-360060160f8a03800c8e6c5b7e3c3e501" , OWNER="oracle" , GROUP="oinstall" , MODE="0660" ACTION=="add|change" , ENV{DM_UUID}=="mpath-360060160f8a03800c8e6c5b7e3c3e601" , OWNER="oracle" , GROUP="oinstall" , MODE="0660"
1 2 3 4 5 6 7 8 udevadm control --reload-rules udevadm trigger --type =devices --action=change ls -l /dev/mapper/asm_*
方案二:ASMFD 配置流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $ asmcmd afd_configure $ asmcmd afd_label DATA01 /dev/mapper/asm_data01 $ asmcmd afd_label DATA02 /dev/mapper/asm_data02 $ asmcmd afd_label FRA01 /dev/mapper/asm_fra01 $ asmcmd afd_label OCR01 /dev/mapper/asm_ocr01 $ asmcmd afd_scan $ asmcmd afd_lslbl $ ssh racnode2 "asmcmd afd_scan"
方案三:oracleasm createdisk 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 $ /etc/init.d/oracleasm configure ORACLEASM_SCANORDER="mpath dm" ORACLEASM_SCANEXCLUDE="sd" $ /etc/init.d/oracleasm createdisk DATA01 /dev/mapper/asm_data01 $ /etc/init.d/oracleasm createdisk DATA02 /dev/mapper/asm_data02 $ /etc/init.d/oracleasm createdisk FRA01 /dev/mapper/asm_fra01 $ /etc/init.d/oracleasm createdisk OCR01 /dev/mapper/asm_ocr01 $ /etc/init.d/oracleasm scandisks $ /etc/init.d/oracleasm listdisks
3.3 ASM 磁盘组创建 三种冗余级别的磁盘组创建语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 CREATE DISKGROUP DATA EXTERNAL REDUNDANCY DISK '/dev/mapper/asm_data01' NAME DATA_001, DISK '/dev/mapper/asm_data02' NAME DATA_002 ATTRIBUTE 'compatible.asm' = '19.0' , 'compatible.rdbms' = '19.0' , 'au_size' = '4M' ; CREATE DISKGROUP FRA NORMAL REDUNDANCY FAILGROUP FG1 DISK '/dev/mapper/asm_fra01' NAME FRA_001 FAILGROUP FG2 DISK '/dev/mapper/asm_fra02' NAME FRA_002 ATTRIBUTE 'compatible.asm' = '19.0' , 'compatible.rdbms' = '19.0' , 'au_size' = '4M' ; CREATE DISKGROUP OCR HIGH REDUNDANCY FAILGROUP FG1 DISK '/dev/mapper/asm_ocr01' NAME OCR_001 FAILGROUP FG2 DISK '/dev/mapper/asm_ocr02' NAME OCR_002 FAILGROUP FG3 DISK '/dev/mapper/asm_ocr03' NAME OCR_003 ATTRIBUTE 'compatible.asm' = '19.0' , 'compatible.rdbms' = '19.0' ;
兼容性属性说明
compatible.asm :ASM 实例的最低兼容版本。设置后不可回退,影响 ASM 集群的功能特性。
compatible.rdbms :数据库实例的最低兼容版本。如果数据库版本低于此值,将无法挂载该磁盘组。
au_size :Allocation Unit 大小。12c 起支持 4MB,对大表空间能减少 extent map 的碎片化。
条带化与性能优化 ASM 的条带化模式在 11g 以后默认使用 Coarse striping (AU 粒度)。对于 OLTP 系统,可以在文件级别设置 Fine striping:
最佳实践是将数据文件和归档日志放在不同的磁盘组(DATA vs FRA),避免 IO 竞争。
3.4 ASM 管理 asmcmd 常用命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 asmcmd lsdg asmcmd lsblk asmcmd lsinst asmcmd ASMCMD> cd +DATA ASMCMD> ls ASMCMD> find +DATA -name "*.dbf" ASMCMD> rebal -w ASMCMD> lsop
磁盘添加/删除/替换流程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ALTER DISKGROUP DATA ADD DISK '/dev/mapper/asm_data03' NAME DATA_003 REBALANCE POWER 8 ; SELECT group_number, operation, state, power, est_minutesFROM V$ASM_OPERATION;ALTER DISKGROUP DATA DROP DISK DATA_003;ALTER DISKGROUP DATA DROP DISK DATA_001 ADD DISK '/dev/mapper/asm_data04' NAME DATA_004 REBALANCE POWER 8 ; ALTER DISKGROUP ALL REBALANCE POWER 4 ;ALTER DISKGROUP DATA MOUNT;ALTER DISKGROUP DATA DISMOUNT;ALTER DISKGROUP DATA CHECK ALL ;
自动化监控脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 SELECT name, type, total_mb, free_mb, ROUND((1 - free_mb / total_mb) * 100 , 2 ) AS used_pct, ROUND(free_mb / DECODE(type, 'EXTERN' , 1 , 'NORMAL' , 2 , 'HIGH' , 3 ), 2 ) AS effective_free_mb FROM V$ASM_DISKGROUPORDER BY used_pct DESC ;SELECT name, path, header_status, mode_status, stateFROM V$ASM_DISKWHERE header_status != 'MEMBER' OR mode_status != 'ONLINE' OR state != 'NORMAL' ;
四、结果验证 完成所有配置后,需要逐层验证整个存储链路:
4.1 Multipath 层验证 1 2 3 4 5 6 7 8 9 10 11 12 13 multipath -ll | grep -E "(active|faulty|failed)" multipath -ll | grep -c "ready" echo 1 > /sys/block/sdb/device/deleteecho "- - -" > /sys/class/scsi_host/host3/scan
4.2 ASM 层验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 SELECT name, state, type, total_mb, free_mbFROM V$ASM_DISKGROUP;SELECT name, path, header_status, mode_status, state, total_mb, free_mbFROM V$ASM_DISKORDER BY group_number, disk_number;SELECT name, value FROM V$PARAMETER WHERE name IN ('asm_diskstring' , 'asm_power_limit' , 'asm_diskgroups' );
4.3 ASM Alert 日志检查 1 2 3 4 5 6 7 8 $ tail -100 $ORACLE_BASE /diag/asm/+asm/+ASM1/trace/alert_+ASM1.log
4.4 IO 性能验证 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 fio --name=asm_test \ --filename=/dev/mapper/asm_data01 \ --direct=1 \ --rw=randread \ --bs=8k \ --numjobs=4 \ --size=1G \ --runtime=60 \ --group_reporting $ orion -run advanced -testname asm_io \ -num_disks 10 -size_small 8 -size_large 1024 \ -type rand -matrix point \ -num_large 1 -num_small 8
五、经验总结 5.1 存储配置 Checklist 在每次部署 RAC + ASM 环境前,建议按以下清单逐项确认:
检查项
说明
状态
HBA 卡冗余
每个节点至少 2 块 HBA 卡
☐
存储控制器冗余
LUN 映射到双控制器
☐
Multipath 配置
所有存储 LUN 均通过 Multipath 设备访问
☐
路径状态
multipath -ll 所有路径 active
☐
设备权限
oracle:oinstall 0660
☐
ASM_DISKSTRING
指向 Multipath 设备路径
☐
SCSI ID 唯一性
每个 LUN 的 WWID 唯一
☐
udev 规则
所有节点规则一致
☐
I/O 调度器
设置为 noop 或 none
☐
大页内存
配置 HugePages
☐
5.2 ASM 磁盘组命名规范 建议采用统一的命名规范:
1 2 3 4 5 6 磁盘组前缀_用途编号 示例: +DATA01 — 第一组数据磁盘组 +FRA01 — 闪回恢复区 +OCR01 — OCR 和 Voting Disk +REDO01 — 专用 Redo 磁盘组(高 IOPS 场景)
5.3 常见存储问题快速定位 问题 1:ASM 实例无法发现磁盘
1 2 3 4 5 6 ls -l /dev/mapper/asm_*
问题 2:路径切换导致 RAC 节点驱逐
1 2 3 4 $ crsctl get css misscount
问题 3:磁盘组空间告警
1 2 3 4 5 6 ALTER DATABASE DATAFILE '+DATA/prod/users01.dbf' RESIZE 10 G;ALTER DISKGROUP DATA ADD DISK '/dev/mapper/asm_data05' NAME DATA_005;
5.4 大规模环境的 ASM 管理经验 在管理超过 50 个节点的 RAC 集群时,以下经验非常有价值:
使用 ASMFD 替代 udev + oracleasm :ASMFD 提供更好的内核级保护,减少配置不一致的风险。
磁盘组不要太大 :单个磁盘组建议不超过 20TB,避免 rebalance 时间过长。
合理设置 ASM_POWER_LIMIT :日常使用较低功率(2-4),维护窗口时提高到 8-11。
定期检查磁盘组一致性 :通过 ALTER DISKGROUP ... CHECK 定期验证。
监控 IO 延迟 :关注 V$ASM_DISK_STAT 中的读写延迟指标。
**建立标准操作流程 (SOP)**:所有存储变更必须有文档记录和回滚方案。
写在最后 :存储是数据库的根基,RAC + ASM 的高可用架构建立在正确的存储配置之上。Multipath 配置虽然看似简单,但它处于 IO 路径的最底层,一旦出问题,影响面极大。希望本文的内容能帮助大家在实际工作中少踩坑、多避雷。如果遇到复杂的存储问题,欢迎在评论区交流讨论。