编写原则
- 结构按”结论 → 冲突裁决 → 操作 → 原文依据 → 错例 → 选型“推进,先给能用的,再给证据,最后给免责边界。
- 凡口径冲突,一律以 Oracle 官方表述为准;官方文档之间互相冲突时,按 §2.0 的证据优先级裁决。
- 正文不保留任何不可落地的示例值(错误写法的讨论集中在 §五,只做定性描述,不给出可被复制的配置行)。
资料来源
| 编号 | 资料 | 性质 |
|---|---|---|
| A | 《多路径下使用ASMLIB创建ASM磁盘》(博客园 · 我是DBA,2018-05-04) https://www.cnblogs.com/automng/p/8990250.html | 博客:中文操作笔记 + 转载官方英文文档 |
| B | 《Why ASMLIB and why not?(ZT)》(博客园 · dbblog,2011-07-19) https://www.cnblogs.com/ebs-blog/archive/2011/07/19/2167234.html | 博客:选型观点(转自 oracledatabase12g.com) |
| C | 《Configuring Oracle ASMLib on Multipath Disks》(Oracle 官网,Oracle Database 10g) https://www.oracle.com/linux/technologies/multipath-disks.html | 官方:10g 代际技术说明,A 的后半段即其转载 |
| D | 《How To Setup ASM & ASMLIB On Native Linux Multipath Mapper disks?》(MOS/Metalink 602952.1) https://blog.51cto.com/jonsen/1671071 | 官方:10.1.0.2~12.1.0.2 操作 Note,B 文中引用的就是它 |
| E | Oracle 12.2《Grid Infrastructure Installation and Upgrade Guide for Linux — Configuring Disk Scan Ordering》 见文末链接 | 官方:当前代际安装指南(本次核到原文) |
一、结论速览
- 问题的本质:多路径下同一块盘有三个”面孔”(路径 1、路径 2、聚合点),而 ASM 不能看到同一块盘两次。ASMLib 默认只取”最先找到”的那条,很可能就是单路径
sd。 - 要做两件事:
ORACLEASM_SCANORDER把聚合设备排前面;ORACLEASM_SCANEXCLUDE="sd"把单路径整片排除。后者是硬闸,前者只定”先扫谁”。 - 前缀取值:官方给了两个合法值 ——
"dm"或"mpath dm"(MOS 602952.1)。RHEL/OEL 4 时代按内核名dm-XX枚举(写dm),RHEL/OL 5 及以后按/dev/mapper条目枚举(写mpath或mapper/mpath)。不确定版本时写"mpath dm",是唯一同时不与两份官方表述冲突的取值。带*的写法官方不支持,见 §2.6。 - 三条写法”都好像对”的原因:未命中不报错 +
SCANORDER只排序不白名单 +SCANEXCLUDE兜底。要判断哪个前缀真命中,做 §3.6 的对照诊断。 - 建盘对象:
createdisk建在 mapper 设备的分区上(如/dev/mapper/mpath0p1),官方建议每块盘一个分区(MOS 602952.1)。 - ASM 侧:必须
ASM_DISKSTRING='ORCL:*',否则 ASM 看不到ORCL:前缀的盘。 - 验收:
/dev/oracleasm/disks/下每个盘的major,minor应是dm的(如252,x),不能是sd的(8,x);重启后必须再验一次。 - 选型:能用 udev 就别用 ASMLib(§六)。
二、冲突与裁决(以 Oracle 官方表述为准)
2.0 证据优先级
资料之间打架时,按下表取上层为准;博客只提供经验与案例,不作为口径来源。
| 优先级 | 来源 | 效力 | 适用范围 |
|---|---|---|---|
| ① | MOS 602952.1(D) | 针对”多路径 mapper 上配 ASM+ASMLIB”这一具体议题的操作 Note,明确给出 SCANORDER 两个取值 | 10.1.0.2~12.1.0.2(2013-10-08 核过相关性) |
| ② | Oracle 12.2 安装指南(E) | 当前代际官方安装指南,说明前缀对应 /etc/multipath.conf 的 alias | 12.x(19c 同系列文档按此口径;本次仅核到 12.2 原文) |
| ③ | Oracle 10g 技术页(C) | 旧代际技术说明,只适用于”按内核设备名枚举”的实现 | 10g / ASMLib 2.x |
| ④ | 博客 A、B | 经验、案例、历史观点 | 仅作旁证 |
2.1 冲突一:SCANORDER 到底写 dm、mpath 还是 mpath dm
| 来源 | 表述 | 适用面 |
|---|---|---|
| C(10g 技术页) | “必须使用 dm 前缀“(NOTE 原文:Any configuration … must use the dm prefix);内核看到的是 /dev/dm-XX | 按内核设备名枚举的实现 |
| Oracle 11.2 官方文档(多份转述一致) | “For Oracle Linux and RHEL 5, when scanning, the kernel sees the devices as /dev/mapper/XXX entries… should use the /dev/mapper/XXX entries” | RHEL / OL 5 |
| 一份 2012 年的官方文档转载 | 明确指出 RHEL/OEL 4 用 /dev/dm-XX,RHEL/OEL 5 用 /dev/mapper/XXX | 把分界线讲得最清楚的一份 |
| E(12.2 安装指南) | 按 /dev/mapper 的别名匹配,默认别名即 /dev/mapper/mpath* | 12.x |
| D(MOS 602952.1) | 直接列出两个并列取值:"dm" 或 "mpath dm" | 10.1~12.1 |
裁决:这不是”谁对谁错”,而是发行版 + ASMLib 版本决定的枚举层差异:
- 老实现(RHEL/OEL 4 时代)枚举内核名
dm-XX→ 写dm; - RHEL/OL 5 及以后的实现枚举
/dev/mapper条目 → 写mpath(或写带目录段的mapper/mpath,见 §2.6); - 最高优先级的 D 已把
"dm"与"mpath dm"同时列为合法值,所以"mpath dm"是唯一同时覆盖两种枚举层的取值 → 默认推荐。
补充三点:
- 自定义 alias 写该 alias 的前缀(如
asm);user_friendly_names no时别名是 WWID,mpath失效。 - 未命中的前缀不报错、不影响结果——这也是三种写法”看起来都对”的直接原因,机制见 §2.7。
- 因此”某写法在我这儿能用”不能证明该前缀真的命中,必须做 §3.6 的诊断才能区分。
关于 "dm" 的两个常见误解(按 §2.6 的匹配语义推导,非官方原文,供谨慎参考):
- 写
dm命中的是**”所有 device-mapper 设备”**,而不只是多路径盘 —— LVM 逻辑卷的内核名同样是dm-N,会被一起排到扫描队首(SCANEXCLUDE="sd"排不掉它们,因为它们的名字不叫sd)。 - 所谓”多路径设备稳定映射为
dm-*的环境”实际不存在:dm-N的编号在重启、增删盘、multipath 重建后都会变。所以dm的价值只在”覆盖面”,不在”稳定性”;把dm理解成”精确指定多路径盘”是错的。
2.2 冲突二:10g 页面自身”NOTE 与示例”矛盾
同一页 C 中,NOTE 要求”必须用 dm 前缀”,紧接着的示例却用了另一个前缀。
裁决:示例里的那个词是 C 开头自述的占位名——原文说把多路径磁盘统称 multipatha 以做到”存储厂商无关”。占位名不是设备名,不得作为配置值;硬约束(”must”)优先于示例。这也是为什么 A 的作者正文实际落地用的是 dm,而不是页面示例里的写法。
2.3 冲突三:内核看到的是 dm-XX 还是 /dev/mapper/XXX
| 来源 | 表述 |
|---|---|
| C(10g) | 内核只看到 /dev/dm-XX;/dev/mapper/XXX 是 udev 为可读性创建的,内核不认识 |
| E(12.2) | 前缀对应 /dev/mapper 的别名 |
裁决:按代际分治(同 §2.1)。实操上不做纯理论判断,以实测为准:先看 multipath -ll 与 ls -l /dev/mapper 得到真实名字,再写前缀,最后用 scandisks + 设备号验证是否命中。
2.4 冲突四:排除单路径用”前缀”还是”具体盘符”
| 来源 | 表述 |
|---|---|
| C(10g)前缀定义 | 变量是”以空白分隔的前缀列表”,”not globs”,且不含 /dev/ |
| C(10g)排除示例 | 给出把具体盘符写死的示例,并称其”更为精确(more specific)” |
裁决:以前缀定义为准(这是变量的语义约束,且与 NOTE 同属硬性描述),具体盘符示例只当”演示”,不作生产写法。原因见 §5.2 第 2 条:盘符是瞬态拓扑。
2.5 冲突五(流派差异,非官方互斥):整盘建 ASMLib 盘 vs 每盘一分区
| 来源 | 表述 |
|---|---|
| D(MOS 602952.1) | 先 kpartx -a 在 mapper 设备上建分区,再 createdisk 到该分区;建议每块盘一个分区 |
| 社区常见做法 | 直接对整盘 createdisk |
裁决:两者都可用,同一环境内不得混用(否则 ASM 侧盘数与容量口径会乱)。有官方倾向时按官方——每盘一分区。
2.6 冲突六:前缀是”纯字符串前缀”还是”glob 模式”(mapper/mpath* 这类写法)
这是三种写法里争议最大的一种,也是最容易被判错的一种。
| 来源 | 表述 |
|---|---|
| C(10g 技术页) | “These are not globs. They do not use wildcards. They are simple prefixes.”;且”the /dev/ path is not part of the prefix“ |
| Oracle 11.2 文档 | RHEL/OL 5 上”the kernel sees the devices as /dev/mapper/XXX entries”,配置应使用这些条目 —— 意味着可以带目录段 |
| 社区实测(ITPUB,2011) | 直接写带 * 的形式,并说明”* 是一个表达式,匹配 mapper 目录下所有 mpatha、mpathb 这类设备” |
| 社区实测(另一例) | 写成两段前缀(mapper 与 mpath 并列),按目录段前缀 + 别名前缀配合命中 |
裁决(分两层,不要混为一谈)
- “能不能带目录段”——官方是支持的。11.2 文档明确说 RHEL/OL 5 要用
/dev/mapper/XXX条目,去掉/dev/后就是mapper/mpath0这种形态。也就是说mapper/mpath这一层前缀有官方依据。 - “
*能不能当通配符”——官方文本是否定的(”not globs, do not use wildcards”)。它在某些环境的实测中有效,只能说明该版本的实现按模式串处理,属于版本相关行为,不是文档承诺的语义。
结论:mapper/mpath* 在”按 /dev/mapper 枚举 + 该版本支持模式匹配”的环境里确实能命中,所以你说它”也对”是有道理的——但它的正确性建立在实现细节上,而不是文档保证上。稳妥做法是去掉 *,写确切前缀(mpath 或 mapper/mpath),两种枚举层写作 "mpath dm"。这样既不违反官方文本,又能实际命中。
我在上一版文档里把带
*的写法直接判成”零匹配、纯静默失效”,是过硬的判断——现已按上述证据改为”版本相关、不作推荐”。这是本版修正的第一处结论。
2.7 裁决总表,以及”为什么三种写法看起来都对”
| 议题 | 冲突点 | 裁决(依据) |
|---|---|---|
SCANORDER 取值 | dm vs mpath vs mpath dm | "mpath dm" 为默认(D 明列);按发行版/版本可简化为单前缀 |
| 前缀能否带目录段 | mpath vs mapper/mpath | 可以带(11.2 文档:RHEL/OL 5 用 /dev/mapper/XXX 条目) |
前缀是否支持 * | 纯前缀 vs glob | 官方文本不支持通配(C:”not globs”);实测有效者属版本相关,不做推荐 |
| 10g 示例前缀 | NOTE vs 示例 | 占位名不落地,以 NOTE 为准(C 自述 + D) |
| 排除写法 | 具体盘符 vs 前缀 | 前缀 sd(C 的变量语义 + §5.2 瞬态拓扑) |
| 建盘对象 | 整盘 vs 分区 | 官方倾向每盘一分区,同环境不混用(D) |
| 验证设备名 | 看配置还是看设备号 | 看 major,minor 是否 dm 号(C 的内核名口径 + 实测) |
为什么三种写法”看起来都对”?三件事叠加的结果:
- 未命中的前缀不出错。ASMLib 只是”没提前扫到”,不报错、不告警,所以写错了没有任何反馈。
SCANORDER不是白名单,只是排序。官方原文说得很明确:前缀匹配完之后,ASMLib 还会继续扫描其余所有不匹配的磁盘。所以即使三个前缀全都没命中,dm/mapper设备照样会被扫到、照样会被绑定。- 真正把单路径踢掉的是
SCANEXCLUDE="sd"。它才决定”哪些盘绝对不扫”。
→ 三者最终绑定的设备相同,因为兜底机制相同,而不是因为三个前缀各自都命中。这也解释了为什么”我这套配置能用”无法反推”前缀写对了”。
要区分”哪个前缀真的命中”,必须做 §3.6 的诊断(把 SCANORDER 换成无意义前缀看结果是否变化)。
三、可落地配置(唯一推荐版本)
3.1 第 0 步:勘察命名(决定前缀写什么)
multipath -ll | egrep 'mpath|dm-' # 别名 ↔ 内核名
ls -l /dev/mapper/ # 别名清单
grep -E 'user_friendly_names|^ *alias' /etc/multipath.conf
3.2 第 1 步:填 SCANORDER
| 你的环境 | ORACLEASM_SCANORDER |
|---|---|
| 不确定版本 / 想一版通吃 | "mpath dm"(官方明列的取值) |
别名是默认 mpathXX(user_friendly_names yes) | "mpath" |
multipath.conf 里自定义了 alias(如生成 /dev/asm-ocr1) | "asm dm"(见下方专段) |
确认按 /dev/mapper 条目枚举、要显式带目录段 | "mapper/mpath"(不要带 *,理由见 §2.6) |
| 旧代际按内核名枚举(RHEL/OL 4 时代 / ASMLib 2.x) | "dm" |
| 厂商自有多路径驱动(PowerPath / UltraPath) | 按 emcpower / upath 等实际前缀 |
别名叫 /dev/asm* 这类时怎么填(关键)
先明确一件事:alias 改了以后,设备就不叫 mpathXX 了。
multipath.conf 的 alias 决定生成 /dev/<别名> 这一层名字(例如 /dev/asm-ocr1),而默认的 mpathXX 来自 user_friendly_names。两者是互斥的两条命名路线。所以:
- 一旦用了自定义 alias,
mpath前缀必然不命中;"mpath dm"里的mpath段彻底空转,只剩dm在干活 —— 又是 §2.7 那种”看起来能用、其实只有一个前缀在工作”的情形。 - 也别写
mapper/asm...:自定义 alias 的设备在/dev/下(/dev/asm-ocr1),不在/dev/mapper/下,mapper/前缀不命中。
推荐写法(三选一,按精度递进):
# 写法 1:别名同族(都是 asm- 开头)——最常用
ORACLEASM_SCANORDER="asm dm"
ORACLEASM_SCANEXCLUDE="sd"
# 写法 2:只靠别名族,不要兜底(确认是现代 /dev/mapper 枚举层时)
ORACLEASM_SCANORDER="asm"
# 写法 3:要绝对精确时,把完整别名逐个列出来(完整名本身就是合法前缀)
ORACLEASM_SCANORDER="asm-ocr1 asm-vote1 asm-data1 dm"
dm 那一段留着有两个作用:① 老版本按内核名 dm-N 枚举时照样命中(见 §2.1);② 万一某块盘的 alias 写漏了,仍能被兜住,不至于漏扫。代价是顺带把 LVM 的 dm-N 也排到前面(见 §2.1 的两个误解),所以生产上更稳的是写法 3。
三条落地注意事项:
- RAC 双节点 alias 必须完全一致。alias 是按
wwid在multipath.conf里绑定的,两节点配置不一致会导致同一 LUN 在两个节点叫不同名字,ASMLib 标签随之错位——这类问题改SCANORDER是修不好的。 - 改完先验命名,再验绑定:
multipath -ll | egrep 'asm|dm-' # alias 与 dm-N 的对应关系 ls -l /dev/asm* # 应是指向 /dev/dm-N 的块设备 /etc/init.d/oracleasm scandisks ls -l /dev/oracleasm/disks/ # major,minor 必须是 dm 号,不能是 8,x - 建盘时用别名路径,不要用
dm-N:createdisk建议指向/dev/asm-ocr1p1这类稳定名字;/dev/dm-N的编号重启就变,写进建盘命令(或脚本)里等于埋雷(§5.2 的第二类根因)。
一句话:别名是什么,前缀就写什么(去掉
/dev/后的开头部分)。mpath只在你还用默认mpathXX命名时才有意义。
能不能干脆写一串兜底("mpath asm dm")?
能跑,结果也对——前缀不命中不出错、SCANORDER 又不是白名单,所以它天然是个安全的”超集”。它甚至多覆盖了一种情况:user_friendly_names no 时别名变成 WWID(3600…),mpath 和 asm 双双不命中,这时只有 dm 在兜底。
但代价有三条,值得知道再决定:
| 维度 | 精确写法(如 "asm-ocr1 asm-data1 dm") | 兜底写法("mpath asm dm") |
|---|---|---|
| 能否达到目的(绑到聚合设备) | 能 | 能(但成功率同样只取决于 SCANEXCLUDE="sd") |
| 可诊断性 | 某个前缀失效时,§3.6 的对照实验能定位到”是哪一层变了” | 几乎无法定位——结果永远是”能用”,无从判断哪个前缀真的命中 |
| 隐蔽故障 | alias 拼错、alias 被改成 WWID,会在验收时暴露 | 被 dm 兜住,故障被掩盖,直到某次重启或换盘才爆 |
还有一处它其实没覆盖全:如果该实现比较的是去掉 /dev/ 后的整条相对路径(mapper/mpath0),那么 mpath 这个前缀不命中(字符串以 mapper/ 开头)。要真做到形态全覆盖,得写成 "mapper/mpath mpath asm dm" 四段。当然,这种情况下 dm 依然会兜底,所以最终结果不受影响——这也正说明多写前缀并不能提高成功率,只影响排序的确定性。
建议:
- 标准化模板、多套异构环境复用:可以用兜底写法,但按
"mapper/mpath mpath asm dm"补齐,并明确注释”这是兜底模板,不是精确配置”; - 单套已知环境:用精确写法(写法 3),把
dm留在最后。理由不是”更正确”,而是让配置出错时能被发现。
3.3 第 2 步:填 SCANEXCLUDE
ORACLEASM_SCANEXCLUDE="sd"
只写前缀,不写具体盘符(理由见 §2.4、§5.2)。
3.4 第 3 步:完整配置文件示例
# /etc/sysconfig/oracleasm(或它指向的 /etc/sysconfig/oracleasm-_dev_oracleasm)
ORACLEASM_ENABLED=true
ORACLEASM_UID=grid
ORACLEASM_GID=asmadmin
ORACLEASM_SCANBOOT=true
ORACLEASM_SCANORDER="mapper/mpath mpath asm dm"
ORACLEASM_SCANEXCLUDE="sd"
ORACLEASM_USE_LOGICAL_BLOCK_SIZE=false # 4K 原生扇区存储按需改 true
SCANORDER 四段的分工(这是兜底模板,不是精确配置):
| 段 | 覆盖的形态 | 何时命中 |
|---|---|---|
mapper/mpath | 按 /dev/mapper 相对路径枚举(mapper/mpath0) | RHEL/OL 5 及以后的实现 |
mpath | 按设备名/别名枚举(mpath0、mpathX) | user_friendly_names yes 的默认命名 |
asm | 自定义 alias(asm-ocr1) | multipath.conf 里写了 alias asm-* |
dm | 内核名(dm-N) | 老实现(RHEL/OEL 4 时代);也是 WWID 命名、alias 写漏时的总兜底 |
两个注意点:
①ORACLEASM_UID/GID按你的环境取(grid/asmadmin或oracle/dba,取决于是否用 GI 用户建盘)。
② 手工编辑时必须保证/etc/sysconfig/oracleasm指向oracleasm-_dev_oracleasm的软链完好,否则改了等于没改。
③ 这套多段写法降低的是配置漂移的风险,不是提高成功率——成功与否仍由SCANEXCLUDE="sd"与”未命中继续扫其余磁盘”的兜底决定;代价是配置写错时更难被发现,所以必须配 §3.6 的诊断与 §3.7 的验收。
3.5 第 4 步:建盘与让 ASM 看见(MOS 602952.1 原流程)
# 1) 在 mapper 设备上建分区并刷新分区表
kpartx -a /dev/mapper/mpath#
/sbin/partprobe
# 2) 在 mapper 分区上创建 ASMLIB 磁盘(每盘一个分区,官方建议)
/etc/init.d/oracleasm createdisk ASMDISK1 /dev/mapper/mpath0p1
# 3) RAC 环境在每个节点执行(扫描并使磁盘对 ASMLIB 可用)
/etc/init.d/oracleasm scandisks
/etc/init.d/oracleasm listdisks
-- 4) ASM 侧:设置发现字符串
SQL> alter system set ASM_DISKSTRING = 'ORCL:*' scope=BOTH;
-- 5) 验证 ASMLIB 盘已被 ASM 发现(RAC 每节点查)
SQL> select path from v$asm_disk;
-- 6) 建磁盘组
SQL> create diskgroup DATA external redundancy disk 'ORCL:DISK1';
版本提示:该流程出自 10.1~12.1 时代的 Note;19c/OL8 上更常见的是直接用 udev 按 WWID 固定别名(§六),本篇步骤作”思路参照”。
3.6 第 5 步:诊断 SCANORDER 是否真的生效(关键,别跳过)
因为未命中的前缀静默无反馈,光看”最后能用”证明不了前缀写对了。用”对照组”就能分清:
# 对照组:把 SCANORDER 换成一个绝不可能命中的前缀
ORACLEASM_SCANORDER="zzz" # 临时改,SCANEXCLUDE 保持 "sd" 不动
/etc/init.d/oracleasm scandisks
ls -l /dev/oracleasm/disks/ # 看 major,minor
| 结果 | 含义 |
|---|---|
仍是 dm 号(如 252,x) | SCANORDER 根本没起决定作用 —— 实际是 SCANEXCLUDE="sd" + “未命中就继续扫其余磁盘”的兜底在干活。此时你写 dm/mpath/mapper/mpath* 都一样,无法证明哪个命中 |
变成 sd 号(8,x) | SCANORDER 确实在起决定作用,取值有效;换回正确前缀即可 |
更严格的测法(仅在测试环境做):把 SCANEXCLUDE 临时置空,三个候选前缀各测一次,用 oracleasm querydisk -d <label> 看首次绑定的到底是哪条设备。这样能直接判定该版本枚举的是 dm-N 还是 mapper/mpathN。
3.7 第 6 步:验收清单
# 1. 命名两层对照
multipath -ll | egrep 'mpath|dm-'
ls -l /dev/mapper/
# 2. 触发扫描
/etc/init.d/oracleasm scandisks # 或 oracleasm scandisks
# 3. 关键判据:major,minor 必须是 dm 的主次设备号(如 252,x),不能是 sd 的(8,x)
ls -l /dev/oracleasm/disks/
cat /proc/partitions | egrep 'sd[a-z]|dm-'
# 4. 单个标签解析到哪条设备
oracleasm querydisk -d OCRVOTE
# 5. 重启后重复 1~4(这一步最容易翻车)
通过判据:/dev/oracleasm/disks/ 下每块盘只出现一次、属组 asmadmin(或 dba)、属主 grid/oracle、权限 660;设备号是 dm 的;跨节点名称与底层 WWID 一一对应。
3.8 按 OS 版本 / 存储驱动速查(实配对照)
| 环境 / 驱动 | 设备名形态 | SCANORDER | SCANEXCLUDE | 关键点 |
|---|---|---|---|---|
| 通用兜底模板(本笔记) | mapper/mpath0 / mpathX / asm-* / dm-N | "mapper/mpath mpath asm dm" | "sd" | 四段覆盖四种枚举形态;价值在抗配置漂移,不在提高成功率 |
| 原生 dm-multipath(EL7 默认) | /dev/mapper/mpathX(/dev/mpath/ 软链在 EL6 后已废弃) | 下列三种任一:"mapper/mpath*" / "mapper/mpath" / "mpath" | "sd" | 三者指向同一设备,都”能用”;差异只在哪一段真命中,见下方说明 |
| 日立 HDLM | /dev/sddlmX(HDLM 专属伪设备) | "sddlm" | ""(空) | HDLM 独占接管设备,原生 sd 路径对 OS 不可见,没有要排的盘 |
| EMC PowerPath | /dev/emcpowerX | "emcpower" | "sd" | PowerPath 不隐藏原生 sd 设备,不排就会双路径重复 |
这几条实配的判读要点:
EXCLUDE空不空,取决于厂商驱动是否隐藏了原生sd路径——这是唯一的判据,不是风格差异。- 判据动作:
ls /dev/sd*是否还列出真实的共享盘。HDLM 接管后通常只剩本地盘/系统盘,所以""是”有依据的空”,不是图省事。 - 空
EXCLUDE的真实风险:一旦 HDLM 驱动未加载/接管失效(升级内核、驱动异常),原生sd会重新暴露,ASMLib 立刻绑到单路径——而且这种状态往往只在重启后才出现。所以 HDLM 环境验收必须包含”重启后ls /dev/sd*+ 复核/dev/oracleasm/disks/设备号”。
- 判据动作:
- EL7 那三种写法是”等价但不都命中”。
mapper/mpath*依赖该版本按模式串处理(§2.6);mapper/mpath依赖按相对路径枚举;mpath依赖按设备名枚举。三种都能跑出正确结果,但只有一个真命中——这正是 §3.6 要诊断的东西。推荐用"mapper/mpath"(不带*,官方文本可支撑)。 - 厂商前缀不要混着写。
sddlm环境里写mpath/mapper/mpath无害但纯噪音,一旦哪天 HDLM 没接管,这些无效前缀会让你误判”配置已经覆盖了多路径”。 - 厂商伪设备同样遵循”前缀 = 去掉
/dev/的开头”:sddlm、emcpower、upath、mpath都是这个逻辑,没有例外。
四、官方原文(翻译)
4.1 C:Oracle 10g《Configuring Oracle ASMLib on Multipath Disks》
《在多路径磁盘上配置 Oracle ASMLib》
ASMLib 是 Oracle Database 10g 自动存储管理(ASM)特性的支撑库,Oracle 提供了它的 Linux 专用实现。本文档是一组配置技巧,用于让 ASMLib 能够访问多路径设备;完整安装指南见 Oracle Database 10g 官方文档。
本文描述的是:在存储侧已经用厂商工具配好多路径盘的前提下,如何配置 Oracle 提供的 Linux 版 ASMLib 去访问这些多路径磁盘。文中把多路径磁盘统称为 “multipatha”,以做到与具体存储厂商无关。
涉及多路径磁盘的问题
在 ASM 中使用多路径磁盘有两个问题。第一,ASM 无法容忍”看到同一块盘两次”,一旦重复就会报错。而在多路径配置下,同一块盘可能以三种形式出现:① 该盘的第一条路径;② 该盘的第二条路径;③ 多路径访问点(聚合设备)。
举例:某系统有一块本地盘 /dev/sda,还有一块通过外部存储接入的盘,主机到外部存储有两条连接(两条路径),Linux SCSI 驱动会同时看到两条路径,表现为 /dev/sdb 和 /dev/sdc。访问 sdb 或 sdc 最终都落到同一处。若启用了多路径,会多出一个多路径磁盘(例如 /dev/multipatha),它可以走任意一条路径:如果系统正走 sdb 而该线缆被拔掉,会出错;但多路径磁盘知道自动切到 sdc。
大多数系统软件并不感知多路径的存在,它用 sdb、sdc 还是聚合设备都无所谓,也分不出差别。ASMLib 同样如此——默认配置并不关心用哪条路径。
ASMLib 只会选其中一条路径,因为 ASM 不能重复看到同一块盘。这解决了第一个问题:ASM 只看到一条路径。但第二个问题随之而来:ASM 看到的是哪条路径? 默认配置下,ASMLib 选择它最先找到的那条,也就是 Linux 最先报告的那条;具体是哪条取决于存储驱动行为,可能是多路径设备,也可能是某条单路径。
系统管理员希望 ASMLib 始终使用多路径磁盘——不然配多路径有什么意义?但 ASMLib 无法自己识别”什么是多路径”,必须通过配置告诉它。
磁盘扫描顺序
磁盘通过 ASMLib 安装流程中描述的方式标记给 ASMLib。ASMLib 在一个叫”磁盘扫描”的过程中得知哪些盘被标记,它每次启动都会执行扫描,管理员也可以 /etc/init.d/oracleasm scandisks 强制触发。
ASMLib 逐个检查系统中的每块盘,看它是否被标记为 ASMLib 磁盘,凡已标记的都对 ASMLib 可用。正常情况下,ASMLib 严格按操作系统列出磁盘的顺序检查,这对多数系统足够。
上一节描述了一种”操作系统顺序不够好”的情形:管理员希望 ASMLib 先看到多路径盘、后看到单路径盘,从而选中多路径盘提供给 Oracle。ASMLib 提供两种顺序调整手段:一是排除某些磁盘(彻底忽略);二是指定优先扫描的磁盘(这批盘排在其他盘之前扫)。
两者任选其一即可:可以排除掉所有单路径盘,只扫多路径盘;也可以声明多路径盘优先扫描,ASMLib 先看到它们,就会优先选用。
配置扫描顺序
Oracle ASMLib 的配置文件是 /etc/sysconfig/oracleasm,它是指向 /etc/sysconfig/oracleasm-_dev_oracleasm 的链接,工具实际读的是后者。文件里保存着管理员通过 /etc/init.d/oracleasm configure 设定的全部启动配置——但该命令无法配置扫描顺序。
配置文件包含多个变量,其中 ORACLEASM_SCANORDER 指定优先扫描的磁盘,ORACLEASM_SCANEXCLUDE 指定要忽略的磁盘。
这两个变量的取值是以空白分隔的前缀字符串列表。磁盘名只要以其中任一前缀开头就算匹配。例如前缀 sd 会匹配所有 SCSI 设备,因为 sda 以 sd 开头。注意:这些不是 glob 通配符,不支持 * 之类;它们是纯前缀,且不含 /dev/ 路径部分。
原文硬约束(本节最重要的一条)
扫描时只会扫内核所知道的设备名。使用 device-mapper 时,内核看到的是/dev/dm-XX;/dev/mapper/XXX这些名字是 udev 为了可读性创建的。因此ORACLEASM_SCANORDER或ORACLEASM_SCANEXCLUDE的任何配置都必须使用dm前缀。
(原文此处紧接着给了”多路径优先”和”排除单路径”两个示例配置。前者使用了占位名,后者把具体盘符写死,两者均按 §2.2、§2.4 裁决不落地,正确写法见 §3.2、§3.3。)
另注:如果手工编辑 /etc/sysconfig/oracleasm,要确保它指向 /etc/sysconfig/oracleasm-_dev_oracleasm 的链接没有被弄断。
EMC PowerPath 与 ASMLib
很多管理员想用 EMC PowerPath 做多路径、用 ASMLib 做磁盘访问。但 PowerPath 与 2.4 内核(如 RHEL 3、SLES 8)的组合不被 EMC 支持;Linux 2.6 内核(如 RHEL 4、SLES 9)配 ASMLib 2.0 内核驱动是受支持的,具体请查 EMC Support Matrix 确认互操作要求。若在 2.4 内核系统上遇到任何 ASMLib + PowerPath 的支持问题,请联系 EMC。
4.2 D:MOS 602952.1《How To Setup ASM & ASMLIB On Native Linux Multipath Mapper disks?》
适用版本:Oracle Database Enterprise Edition 10.1.0.2 ~ 12.1.0.2,平台 Linux x86 / x86-64 / Itanium;文档标注 “Checked for relevance on 08-Oct-2013″。
目标:给出一个示例,说明如何用 Mapper Multipath 磁盘来搭建 ASM 与 ASMLIB 磁盘。
解决方案
1)安装 ASMLIB API(RAC 环境需在每个节点安装),并按以下文档配置:Oracle ASMLib、Tips on Installing and Using the Software、Configuring Oracle ASMLib on Multipath Disk。
2)在 /dev/mapper/mpath* 的 mapper 设备上创建一个分区:
# kpartx -a /dev/mapper/mpath#
其中 # 是多路径组编号。注:kpartx 会创建多路径分区,例如 mpath0 上的分区会显示为 /dev/mapper/mpath0p1、/dev/mapper/mpath0p2 等。Oracle 建议每块盘创建一个分区。
3)用 partprobe 更新内核分区表:
# /sbin/partprobe
4)在这个新的 mapper 分区上创建 ASMLIB 磁盘:
# /etc/init.d/oracleasm createdisk <ASMLIB 磁盘名> /dev/mapper/mpath<#>
示例:
# /etc/init.d/oracleasm createdisk ASMDISK1 /dev/mapper/mpath0p1
5)每创建完一个 ASMLIB 磁盘后,需要配置 ASMLIB 使用多路径磁盘(RAC 环境在每个节点都要做)。需要把 /etc/sysconfig/oracleasm 中 ORACLEASM_SCANORDER 参数改成下面两个值之一:
ORACLEASM_SCANORDER="dm"
或
ORACLEASM_SCANORDER="mpath dm"
6)如果是 RAC 配置,则在每个节点用 root 执行以下命令(用于扫描多路径磁盘并使其对 ASMLIB 可用):
# /etc/init.d/oracleasm scandisks
# /etc/init.d/oracleasm listdisks
7)然后连到 ASM 实例,把 ASM_DISKSTRING(磁盘发现字符串)设为 'ORCL:*':
SQL> alter system set ASM_DISKSTRING = 'ORCL:*' scope=BOTH;
8)验证 ASMLIB 磁盘(ORCL:<磁盘名>)已被 ASM 发现(RAC 环境在每个节点验证):
SQL> select path from v$asm_disk;
9)最后在新 ASMLIB 磁盘上创建磁盘组,例如:
SQL> create diskgroup DATA external redundancy disk 'ORCL:DISK1';
相关文档:NOTE:1594584.1(ASMLIB 在多路径 Mapper 设备上的安装与配置白皮书,含 RAC/单机分步演示);NOTE:580153.1(如何用 ASMLIB 磁盘、裸设备、块设备或 UDEV 设备搭建 ASM)。
4.3 B:《为什么要用 ASMLIB,又为什么不用》
ASMLIB 是一种基于 Linux 模块、专为 Oracle 自动存储管理(ASM)特性设计的内核支撑库。长久以来我们对 ASMLIB 的认识并不全面,这里具体梳理一下它的优缺点。
理论上,可以从 ASMLIB API 获得以下好处:
- 始终使用 direct、async I/O;
- 解决了持久化设备名问题——即便重启后设备名已经改变(
/dev/sdX漂移); - 解决了文件权限、属主问题(不必每次开机重做 chown / chmod);
- 减少 I/O 期间从用户态到内核态的上下文切换,从而可能降低 CPU 使用率;
- 减少文件句柄的使用量;
- ASMLIB API 提供了把 I/O 优先级等元信息传递到存储设备的可能。
但是:虽然理论上能获得性能收益,实践中这种优势几乎可以忽略。没有任何性能报告显示 ASMLIB 相对 Linux 原生 udev 设备管理有任何性能优势。 Oracle 官方论坛关于此事的帖子《ASMLib and Linux block devices》有这样的评论:”ASMLIB 未必能给你带来多少 I/O 性能提升,它主要是为了方便管理——它能帮你找到/发现正确的设备;ASMLIB 的 I/O 效果和在裸设备上做异步 I/O 大体相同。”也就是说,用 ASMLIB 与直接用裸设备,性能上没什么差别。
ASMLIB 可能带来的缺点:
- 对多路径设备,需要在
/etc/sysconfig/oracleasm-_dev_oracleasm中设置ORACLEASM_SCANORDER与ORACLEASM_SCANEXCLUDE,ASMLIB 才能找到正确的设备文件(详见 Metalink Note 602952.1,即本文 §4.2)。 - 因为 ASM 实例是通过 ASMLIB 提供的 asm disk 来使用的,所以多了一层(ASMLib 内核模块 + 用户态库)。
- 每次 Linux 内核更新,都需要替换新的 ASMLIB 包(内核模块与内核版本强绑定)。
- 增加了因人为错误造成宕机(downtime)的可能性。
- 使用 ASMLIB 意味着要花更多时间去创建和维护。
- 因为 ASMLIB 的存在,可能引入更多 bug——这是最不想看到的。
- 用 ASMLIB 创建的 disk,其 disk header 与普通 ASM disk header 并无不同,仅多出 ASMLIB 的属性空间。
结论(作者观点):尽可能不要使用 ASMLIB,当然这不是 DBA 个人能决定的事;另一方面也取决于习惯。RHEL 4 早期发行版没有 udev 这类设备管理服务,导致 RHEL 4 时代大量 ASM + RAC 组合使用 ASMLIB。如果是在 RHEL/OEL 5(及以后)中,你完全有理由利用 udev 而放弃 ASMLIB。
五、常见错误写法与后果
本章只做定性描述,不给出可直接复制的配置行——因为这些错误写法与正确写法外形几乎一样,一旦出现在文档里就会被误抄。
5.1 剔除清单
| # | 写法性质 | 错在哪 | 照抄的后果 | 正确做法 |
|---|---|---|---|---|
| 1 | 10g 页”多路径优先”示例中用占位名 multipath 作前缀 | 该名是文档为”厂商无关”虚构的占位名;且与同页硬约束(必须用 dm 前缀)冲突 | 前缀匹配 0 个设备,配置看似改过,实际靠单路径兜底 → ASMLib 绑到 sd,链路维护即丢盘 | §3.2 |
| 2 | A 的”说明性配置”块里的同一处 | 同上,该段抄自页面示例,非作者实际使用值 | 同上(空跑) | §3.2 |
| 3 | 10g 页”排除单路径”示例中把具体盘符写死(原文还称其”更为精确”) | 把瞬态拓扑固化进配置:盘符随加减 LUN、重启、换 HBA、改 zoning 漂移 | 漂移后要么漏排(同盘被看两次,ASM 报错),要么误排(漏扫 ASM 盘 / 开机找不到盘) | §3.3 |
| 4 | 带通配符 * 的前缀写法(二手博客常见) | 官方文本明说”not globs”,* 不应作为通配符;实测有效者属该版本按模式串处理,无文档保证 | 多数环境零匹配;即便”看起来能用”,也无法证明是该前缀命中(可能只是 §2.7 的兜底机制) | 去掉 * 写确切前缀:mpath / mapper/mpath / mpath dm |
| 5 | 把 mapper/ 目录段拼进前缀 | 混用两代口径:10g 是”去掉 /dev/ 后的路径”,12.2 是”直接匹配别名(不含目录段)” | 跨版本必翻车 | 按 ls /dev/mapper + 实测确定 |
5.2 三类根因(可迁移到其他场景)
- 占位名当真名:官方文档为讲原理而虚构的设备名被当成配置值。凡示例里出现语义化的”示例名”,先问”这是真名还是占位”。
- 瞬态拓扑写死:把会漂移的盘符固化进配置。配置里只应出现”前缀 / 别名 / WWID”这类稳定标识。
- 通配符思维误入前缀语义:把 shell/glob 习惯带进一个只做”前缀比较”的变量。
文档层面的教训:官方页面自身也会”NOTE 说必须用 X,紧接着示例却用 Y”。示例与硬约束(must/必须)冲突时,一律以硬约束为准;同页示例若使用占位名,则整段作废,只留方法论。
5.3 反面案例(为什么这不是”配置洁癖”)
- 重启后绑回单路径(实测记录):配好之前,重启后 ASMLib 绑的是
sd(8,x设备号);配好SCANORDER/SCANEXCLUDE再重启才回到dm(252,x)。根因是dm-*依赖sd-*,内核永远先建sd后建dm—— “重启前正常 ≠ 重启后正常”是结构性陷阱。
https://www.ergemp.org/post/configuring-asmlib-on-multipath-devices - 生产事故:某 RAC 双机
ORACLEASM_SCANORDER为空,ASMLib 把单路径sd也当 ASM 盘;一次 SAN 链路维护拔掉的正是被选中的那条链路,ASM 丢盘、两节点实例全关。
https://blog.csdn.net/m0_37723088/article/details/129368294
六、选型建议:ASMLib 还是 udev
6.1 取舍(数据来自 §4.3)
| 维度 | 结论 |
|---|---|
| 定位 | Linux 内核模块 + 用户态库,为 ASM 提供”持久设备名 + 权限 + direct async I/O” |
| 真实收益 | 主要是管理便利(设备发现、名称/权限持久化),不是性能 |
| 性能 | 与 udev、与裸设备 async I/O 基本无差别;无任何性能报告支撑优势 |
| 主要代价 | 多一层;绑内核版本(升级内核必须重装机包);多路径要额外配 SCANORDER/SCANEXCLUDE;维护成本与人为误操作风险;潜在 bug |
| 磁盘头差异 | 仅多出 ASMLIB 属性空间,其余与普通 ASM 磁盘头相同 |
6.2 按代际给建议
| 环境 | 建议 | 理由 |
|---|---|---|
| RHEL 4 早期(无 udev) | ASMLib 是历史必然 | 当时没有更好的持久化手段 |
| RHEL / OEL 5、6 | 优先 udev | udev 已成熟,可替代 ASMLib 的核心收益 |
| OL 7 / 8、19c(当前生产主流) | 默认 udev:按 WWID(scsi_id / lsblk / /dev/disk/by-id)固定别名与属组 asmadmin、权限 660 | 免内核模块依赖、免升级重装、免多路径前缀调优 |
| 已有历史 ASMLib 环境(VMware/rac 虚拟机等) | 可继续用,但必须守住 §三 那套:"mpath dm" + SCANEXCLUDE="sd" + 重启后复核 | 改造收益 vs 风险,通常先稳后改 |
6.3 若继续用 ASMLib,最小合规清单
SCANORDER用"mpath dm"或按实测的单前缀(§3.2)SCANEXCLUDE="sd"只写前缀(§3.3)- 软链
/etc/sysconfig/oracleasm→oracleasm-_dev_oracleasm完好 ASM_DISKSTRING='ORCL:*'已设ls -l /dev/oracleasm/disks/设备号为dm号且每盘只出现一次- 重启后复验上述全部
附:来源与延伸
| 资料 | 链接 |
|---|---|
| A 《多路径下使用ASMLIB创建ASM磁盘》 | https://www.cnblogs.com/automng/p/8990250.html |
| B 《Why ASMLIB and why not?(ZT)》 | https://www.cnblogs.com/ebs-blog/archive/2011/07/19/2167234.html |
| C Oracle 10g《Configuring Oracle ASMLib on Multipath Disks》 | https://www.oracle.com/linux/technologies/multipath-disks.html |
| D MOS 602952.1《How To Setup ASM & ASMLIB On Native Linux Multipath Mapper disks?》 | https://blog.51cto.com/jonsen/1671071 |
| E Oracle 12.2《Configuring Disk Scan Ordering to Select Multipath Disks》 | https://docs.public.oneportal.content.oci.oraclecloud.com/en/database/oracle/oracle-database/12.2/cwlin/configuring-disk-scan-ordering-to-select-multipath-disks.html |
| B 标注的原始出处 | http://www.oracledatabase12g.com/archives/why-asmlib-and-why-not.html |
| 重启后绑回单路径的实测记录 | https://www.ergemp.org/post/configuring-asmlib-on-multipath-devices |
| SAN 链路维护导致 RAC 双节点宕机 | https://blog.csdn.net/m0_37723088/article/details/129368294 |

徐万新之路

