简介面向Oracle DBA及架构师的跨数据中心高可用部署参考文档针对RAC依赖共享存储、ADG偏重容灾无法双活的短板梳理存储双活配置的完整思路与操作步骤。文档覆盖磁盘规划AA/BB机房OCR与数据盘、ZC仲裁盘、Grid Infrastructure安装、创建Normal冗余磁盘组、OCR与votedisk迁移、ASM SPFILE迁移及性能测试等关键环节。内容以docx格式呈现压缩包共1个文件大小约104KB适合已有Oracle RAC基础、正在规划双活方案的运维与架构人员查阅。目前已有150人学习下载。文档中不仅给出CREATE DISKGROUP、ocrconfig、crsctl等命令示例还包含跨机房Interconnect时延与IO性能测试要点可帮助读者评估双活架构风险并快速搭建验证环境。1. 存储双活不是炫技先说清楚它到底解决 Oracle 的什么问题我见过太多采购了双活存储却只在存储层做演练的项目存储工程师把阵列切换玩得很熟练真到数据库切换时应用连不上、ASM 磁盘组起不来最后只能灰溜溜做传统恢复。存储双活的本质是让两台存储同时承载生产 IO任何一台故障时另一台无缝接管而 Oracle 这层能不能跟上才是双活配置真正要解决的核心问题。这篇笔记只讨论一件事Oracle 数据库在双活存储架构下的配置路径、关键参数和落地验证方法。适合正在选型或已经拿到双活存储、准备把核心库迁上去的 DBA、存储工程师和架构师。读完你能得到的不是一个存储双活的概念而是一套从多路径到 ASM 再到集群层面可抄作业的配置方法。2. 给 Oracle 选一条双活路径存储镜像、Data Guard 还是集群2.1 双活存储加 ASM 的组合是主流为什么不是文件系统双活存储也叫存储镜像双活的核心是把同一份数据在两台存储阵列上各写一份主机看到的是一套逻辑卷写 IO 由存储阵列负责同步复制到对端。对 Oracle 来说无论底层的盘是文件系统还是裸设备最终数据库进程只感知到一块盘。为什么主流方案都选择 ASM自动存储管理来管理这块盘因为 ASM 天生就是为共享存储设计的它自己管理数据文件的分布和冗余支持在线加盘、删除盘还提供 rebalance 机制。双活存储本身已经做了数据冗余ASM 这边不需要再开 normal redundancy 做镜像用 external redundancy 反而更简单、性能损耗更小。文件系统方案也不是不行但当你面对 RAC 多节点共享、动态扩容这些场景时ASM 的运维成本明显更低。ASM 和双活存储的配合还有一个关键点ASM 以磁盘组为单位管理盘双活存储的 LUN 映射到主机后以多路径设备形式存在。ASM 眼里只有路径并不关心路径背后是单台存储还是双活架构。这意味着你把 LUN 从单存储迁到双活存储数据库层几乎不用改结构只需要重新识别磁盘、重建磁盘组或者做数据迁移。这也是我倾向于推荐双活存储 ASM RAC组合的根本原因每个层面只负责自己最擅长的事故障域清晰切换逻辑简单。2.2 三种方案边界对比存储镜像双活、Data Guard、Oracle Real Application Clusters如果把双活理解成广义的高可用行业内其实有三条路线存储镜像双活、Data Guard 物理备库、Oracle Real Application Clusters简称 RAC。这三者解决的问题不一样经常被混淆。对比维度存储镜像双活Data GuardOracle Real Application Clusters数据同步粒度存储块级日志级缓存融合实例级切换单位存储/主机数据库实例/节点RPO零丢失取决于链路质量零丢失最大保护模式/可配置零丢失RTO分钟级取决于切换脚本秒到分钟级需手动或依赖额外工具秒级自动应用透明性完全透明需要切换连接串完全透明适用场景存储单点故障防御容灾、迁移、报表分流计算层高可用 横向扩展实际生产中最常见的组合是存储镜像双活打底解决存储层单点故障RAC 解决实例层故障Data Guard 再做跨机房容灾。三者不是互斥关系。如果你的预算只够做一项优先考虑什么我的看法是如果数据库业务连续性要求是机房断电 5 分钟内恢复存储双活 RAC 是可靠组合如果只接受恢复时间目标半小时以内单独的 Data Guard 也能覆盖。2.3 以某公司核心库为例的选型思路延迟、距离和预算曾经帮某公司做过一个选型评估他们有一套 7×24 小时生产库计划把两套存储放在同城两个机房机房间专线延迟约 0.8 毫秒。A 方案是纯 Data GuardB 方案是存储双活 RAC。从成本看 A 方案少买一套存储但从切换复杂度看Data Guard 需要应用层配合修改连接串核心业务方强烈反对任何登录跳变。最终选择存储双活 RAC理由有三延迟低于 1 毫秒双活存储的同步复制可以承受RAC 切换对应用完全透明无需改造两机房带宽足够承载同步复制流量。如果你的机房距离超过 50 公里或者延迟超过 2 毫秒我不建议硬上存储双活。同步复制对延迟极其敏感延迟高了不仅影响业务 IO 性能还可能导致复制链路频繁超时。这个阈值不是玄学是双活存储厂商普遍承认的工程边界。选型时还要注意一个细节存储双活本身不解决任何数据库层的问题比如坏块、逻辑损坏、误删除。这些必须靠备份或 Data Guard 兜底不要以为有了双活就不需要备份。3. 配置前的两项基础工作多路径一致性与存储认盘3.1 存储双活环境下的 Linux 多路径绑定关键参数与配置示例双活存储最常见的翻车点不在存储而在操作系统层的多路径配置。双活架构下每台主机会从两台阵列各看到一条路径访问同一个 LUN多路径软件负责把这两条路径聚合成一个设备。如果多路径策略不对切换时数据库 IO 可能卡死甚至出现脑裂后双写冲突。我一般用 device-mapper-multipath配置前先确认三件事两端的 LUN WWID 一致、链路速率一致、多路径版本一致。# /etc/multipath.conf 核心配置片段 defaults { user_friendly_names no # 用 WWID 命名不用 dm-0 这种 find_multipaths yes path_grouping_policy multibus # 所有路径在一个组故障组内均衡 path_selector round-robin 0 # 轮询分发 IO failback immediate # 路径恢复后立即回切 rr_min_io 100 # 切换 IO 数量阈值 polling_interval 5 # 路径检测间隔秒 } multipaths { multipath { wwid 3600a098038303044452b466d44376b43 alias asm_disk1 path_grouping_policy failover # 按阵列分组主备模式 path_selector round-robin 0 failback 10 } }注意path_grouping_policy这里我写了两处不同值这是刻意的。双活存储有两种主流 IO 路径策略multibus表示所有路径平等轮询failover表示按存储端分组组内轮询、组间主备。选哪种取决于你的双活存储是否支持双活同时读写。大多数双活阵列支持两端同时读写multibus能提高链路利用率但如果你使用某款存储的主备模式同一时刻只有一端承担生产 IO就必须用failover分组否则故障切换时会出现 IO 抖动。这块配置没有通用答案要跟存储工程师确认阵列的实际工作模式。配置完成后重启 multipathd 服务或者直接systemctl reload multipathd让配置生效。验证是否认到了正确的盘multipath -ll # 输出里应该有 2 条 active 路径且 WWID 相同 # 例如3600a098038303044452b466d44376b43 dm-2 某存储,VRAID # size2.0T features0 hwhandler0 wprw # -- policyround-robin 0 prio1 statusactive3.2 udev 规则与磁盘权限为什么 ASM 总是扫不到盘多路径设备认出来了但 Oracle 装 ASM 时经常报找不到候选磁盘十有八九是权限问题。ASM 要求磁盘属主是oracle:asmadmin权限是0660。Linux 在重启后设备节点会重新分配/dev/mapper/asm_disk1这个设备文件默认属主是root:disk必须用 udev 规则固定。# /etc/udev/rules.d/99-oracle-asm.rules # 按 WWID 匹配多路径设备固定属主和权限 KERNELdm-*, ENV{DM_UUID}mpath-3600a098038303044452b466d44376b43, OWNERoracle, GROUPasmadmin, MODE0660 KERNELdm-*, ENV{DM_UUID}mpath-3600a098038303044452b466d44376b44, OWNERoracle, GROUPasmadmin, MODE0660这里有个容易被忽略的坑DM_UUID的值必须以mpath-开头后面跟 LUN 的 WWID。multipath -ll输出里能直接看到。如果你用user_friendly_names yes把设备命名成了mpatha这种别名udev 规则里匹配DM_UUID依然有效但要注意dm-*的KERNEL名称每次重启可能变化所以规则只认DM_UUID不认设备名。写完 udev 规则后执行udevadm trigger重载设备节点然后用ls -l /dev/mapper/asm_disk1确认属主已经变成oracle:asmadmin。我见过有人在规则里写对了但没触发重载重启十几台机器后发现 ASM 还是扫不到盘原因就是这个。3.3 存储侧映射清单与多路径核对确认两端路数一致配置前的最后一项工作是核对清单不要跳过这一步。双活存储最常见的交付问题是A 端阵列映射了 LUNB 端阵列漏映射了主机上只能看到一条路径。表面上看数据库能正常跑但实际上双活已经降级成了单活你还不知道。# 查看每条路径对应的 HBA 端口和控制器 # 在 Linux 上可以通过 sysfs 查看路径详情 cat /sys/class/fc_transport/target*/port_name # 用 scsi_id 查看每个 scsi 设备的 WWID /usr/lib/udev/scsi_id -g -u /dev/sdb拿到的 WWID 和存储管理界面上的 LUN 做比对确保每个 LUN 在两台阵列上都有映射。同时还要查路径数正常情况下每个 LUN 在主机上至少应该有 4 条路径两台阵列各 2 个控制器。如果只有 2 条要么是存储控制器配置问题要么是光纤交换机 zone 没放通。不要急着进下一步路径数量不对就继续排查否则后面 ASM 磁盘组建得再漂亮切换一发作全盘皆输。4. ASM 双活配置的完整动作从磁盘组到集群相关参数4.1 创建 ASM 磁盘组external redundancy 与兼容性参数完成多路径认盘后进入 ASM 配置阶段。双活存储下我一般选择EXTERNAL REDUNDANCY原因前面说过存储层已经做了镜像ASM 层再做镜像属于重复投资浪费容量还增加 rebalance 开销。但这里有一个例外如果你的双活存储没有开启同步复制而只是异步复制那存储层实际上没有实时镜像ASM 内部仍然需要故障组来保护数据。配置前跟存储团队确认复制模式是同步还是异步这直接影响 ASM 的冗余级别选择。-- 用 sqlplus 或 asmcmd 执行创建磁盘组 CREATE DISKGROUP DATA EXTERNAL REDUNDANCY DISK /dev/mapper/asm_disk1 NAME data_disk1, /dev/mapper/asm_disk2 NAME data_disk2 ATTRIBUTE compatible.asm 19.0.0, compatible.rdbms 19.0.0, disk_repair_time 8h;compatible.asm和compatible.rdbms不是随便填的它们决定了这组磁盘能不能享受新版本特性同时也决定了旧版本集群能不能挂载这个磁盘组。升级场景中常见报错是磁盘组compatible.asm高于集群版本导致无法挂载所以配置前先确认集群版本。disk_repair_time这个参数在双活架构里尤其重要它控制了 ASM 在磁盘离线后等多久才把它从磁盘组里驱逐。双活存储切换时可能出现一端存储短暂不可达ASM 会标记对应磁盘离线如果disk_repair_time太短ASM 可能直接把盘踢出去触发 rebalance白白消耗 IO。我习惯设成 8 小时以上给存储故障恢复留足窗口。4.2 跨阵列的故障组设计避免 ASM 把副本放在同一台存储上刚才提到的存储异步复制用 ASM 冗余场景以及未来可能存在的一台存储完全损坏容灾需求都要靠 ASM 故障组failure group来隔离数据副本的物理位置。故障组的意义是告诉 ASM这些盘在物理上是同一个故障域ASM 在写入镜像时会把两个副本放在不同故障组避免单点故障同时损坏所有副本。-- 两个故障组分别对应两台存储阵列 CREATE DISKGROUP DATA NORMAL REDUNDANCY FAILGROUP fg_storeA DISK /dev/mapper/asm_disk1 NAME storeA_disk1, DISK /dev/mapper/asm_disk2 NAME storeA_disk2 FAILGROUP fg_storeB DISK /dev/mapper/asm_disk3 NAME storeB_disk1, DISK /dev/mapper/asm_disk4 NAME storeB_disk2 ATTRIBUTE compatible.asm 19.0.0, compatible.rdbms 19.0.0;这里最关键的坑是故障组必须按真实物理故障域划分不是按主机名或随意分组。你的映射清单上记录了每个 LUN 来自哪台存储的哪个控制器故障组就要按存储阵列分组。如果两台存储各自只有 2 个 LUN 以上每个故障组至少有 2 块盘才能保证某个故障组里一块盘坏掉时还有同组盘可以继续承载。只有 1 块盘一个故障组的用法可以但重建时间很长因为必须从另一个故障组全量复制。4.3 RAC 场景下的双活配置注意点OCR、表决盘与缓存策略存储双活加 RAC 的组合下OCROracle 集群注册表和表决盘voting disk通常放在 ASM 磁盘组里。这两个文件的 IO 量不大但对延迟和一致性要求极高恰好戳中双活存储的软肋。双活存储的同步复制会增加写延迟如果专线质量不好会有概率触发集群件的心跳超时导致节点被驱逐。建议把 OCR 和表决盘单独建一个NORMAL REDUNDANCY的小磁盘组比如 3 块盘三副本与数据文件磁盘组分隔管理即使数据磁盘组出问题也不影响集群件判断。还有一个容易被忽视的参数是存储阵列的写缓存策略。双活存储下两端阵列必须保持一致的写缓存策略——要么都用 write-back要么都用 write-through。我曾经遇到过一次存储工程师调整了 A 端缓存策略没同步 B 端导致某一时间窗口内 A 端性能正常、B 端写入极慢数据库出现周期性 IO 尖刺。这类问题排查起来极痛苦因为数据库层的 AWR 报告看不出任何明显异常。因此配置清单里应当明确记录两端阵列的缓存策略并在变更后主动核对。检查项建议值说明ASM 冗余级别EXTERNAL同步复制时/ NORMAL异步复制时以存储复制模式为准disk_repair_time8h给存储切换留恢复窗口OCR/表决盘磁盘组NORMAL REDUNDANCY 独立建组避免与数据争用和相互影响多路径策略multibus 或按存储分组 failover以阵列工作模式为准存储写缓存两端一致不一致会导致性能尖刺专线延迟小于 1ms超过则不建议同步双活5. 双活配置避坑我见过的 5 个翻车现场5.1 路径权重不一致切换后 IO 全部挤到同一条劣化链路现象存储切换演练时业务系统没有中断但数据库等待事件里出现大量db file sequential read的异常增长IOPS 明显下降。原因配置多路径时用了multibus模式但两端阵列到主机的链路速率不一致。A 端 16Gbps 光纤B 端 8Gbps 光纤多路径轮询分发了相同比例 IO8G 链路成了瓶颈性能反而比单链路还差。解决路径速率不一致时改用按阵列分组的主备模式或者把rr_min_io调大让 IO 更倾向于高性能链路。更彻底的做法是统一两端 HBA 速率。这个坑的核心教训是双活链路之间的性能对称性比路径数量更重要。5.2 ASM 磁盘头覆盖导致磁盘组无法挂载现象某公司把 LUN 从单存储迁移到双活存储后ASM 磁盘组挂载时报无法验证磁盘头所有磁盘都不可用。原因迁移过程中存储工程师把双活 LUN 的映射顺序调换了ASM 按 WWID 识别磁盘但磁盘头里的 ASM 磁盘名和实际预期的名称对不上。更糟的是有人在没确认外部冗余的情况下重新初始化了磁盘把原磁盘头覆盖了。解决迁移前先用kfed read /dev/mapper/asm_disk1备份所有磁盘的磁盘头信息迁移后用kfed逐一比对。如果已经被覆盖用kfed repair从备份恢复。这类问题没有快捷修复路径磁盘组一旦起不来只能重新建组导入数据。所以任何涉及盘符顺序、映射关系的变更第一件事就是把kfed read的结果保存下来。5.3 一端存储离线触发 ASM 重新平衡风暴现象正常运维时拔掉一台存储的控制器存储双活自动切换但数据库紧接着出现大量ASM rebalance后台任务IO 长时间处于高负载。原因disk_repair_time设置太短默认 3.6 小时存储切换还没完成ASM 就已经判定磁盘离线并触发 rebalance。双活存储的控制器切换通常只需要几分钟但因为存储链路抖动被 ASM 误判为磁盘损坏导致它启动了数据重分布。解决把disk_repair_time调大一般建议 8 小时以上。另外要在存储侧配合配置链路抖动抑制让存储切换时不产生长时间 IO 超时。ASM 的 rebalance 可以通过ALTER DISKGROUP DATA REBALANCE POWER 1降低优先级但这个只是事后补救真正要做的是避免触发。5.4 测试只做存储切换没有做数据库层验证现象存储团队报告双活切换演练成功但隔了一个月真实故障时数据库磁盘组直接 DISMOUNT应用全部中断。原因演练流程只验证了存储管理界面的切换没有验证操作系统多路径能否感知、ASM 能否保持磁盘组在线、数据库会话是否持续可用。存储层切换和数据库层可用是两回事。解决把验证脚本做成三层第一层multipath -ll确认路径切换第二层asmcmd ls -l确认磁盘组 ONLINE第三层跑一个持续查询的 SQL比如SELECT COUNT(*) FROM dual CONNECT BY LEVEL 100000在存储切换过程中观察 SQL 是否中断。三层全过了才算真双活。5.5 忽视时钟同步双活存储的日志时间戳错乱现象存储双活链路正常数据库无忧但查看存储复制日志时发现两端写入事件的时间差越来越大偶尔还出现过去时间修改的告警。原因两机房 NTP 服务器不一致时钟漂移导致存储复制引擎判断同步进度异常。某些双活存储依赖时间戳做冲突仲裁时钟偏移会导致错误的冲突判定。解决两机房统一使用同一 NTP 时间源并配置存储管理用户权限受控避免人工调整时间。配置后通过存储管理界面的时间同步状态确认两端时间差小于 100 毫秒。这个问题平时看不出来一出事就是灾难级别的数据不一致值得在配置清单里单独列一行。6. 验证与进阶用故障演练把双活变成可信承诺配置完成不等于双活可用真正让团队放心的是反复演练后得出的结论。我习惯在每次双活配置变更后做一套三层验证流程耗时约 30 分钟能覆盖九成以上风险场景。# 演练脚本核心逻辑模拟存储控制器切换观察数据库连续性 # 步骤1记录当前多路径状态 multipath -ll /tmp/mp_before.txt # 步骤2在存储管理界面触发一端控制器故障切换 # 步骤3持续监控多路径状态等待路径切换完成 # 步骤4验证 ASM 磁盘组状态 asmcmd ls -l DATA # 步骤5验证数据库会话连续性在另一终端执行 sqlplus -S / as sysdba EOF SET PAGESIZE 0 SELECT COUNT(*) FROM dual CONNECT BY LEVEL 50000; EOF这套脚本最好的价值不是自动化而是让每个参与者都亲眼看到切换过程。演练时记录三个时间点切换开始时间、多路径恢复时间、数据库会话恢复时间。如果第二个时间点超过 10 秒先查存储链路如果第三个时间点超过 5 秒查 ASM 的I/O路径和磁盘组状态。把每次演练结果存档形成历史基线下次配置变更后对比基线就能快速发现性能劣化。进阶技巧方面双活存储下值得深入研究的是 ASM 的优先读取prefer-read设置。如果你的数据库实例都在机房 A可以把 ASM 配置成优先读取机房 A 对应故障组的磁盘副本避免跨机房读延迟。在支持该特性的 ASM 版本中通过ALTER DISKGROUP DATA SET PREFERRED READ FAILGROUP fg_storeA即可设置。这个动作能显著降低正常情况下的读延迟但对于没有开启 ASM 层冗余的 EXTERNAL 磁盘组不适用。最后说一个我自己的教训第一次给某公司配置双活存储时我觉得配置完成、存储管理界面显示同步正常就算大功告成结果一个月后真实切换时数据库直接不可用。从那时起我养成了一个习惯——任何高可用架构交付后的两周内至少做一次完整的故障演练并把演练记录发到项目群让所有人知道这套系统在故障面前的真实表现。存储双活配置到最后拼的不是参数调得多漂亮而是你敢于主动制造故障并且能从故障中恢复。希望这篇笔记对你有用。本文还有配套的精品资源点击获取