1. 先弄清DSC的定位共享存储和主备、读写分离有什么不同1.1 为什么最终选了DSC双节点而不是继续用数据守护主备在动手搭这套达梦数据库共享存储集群之前我先把需求捋了一遍业务侧要求两个数据库节点都能对外提供读写服务任何一个节点宕机都不能影响应用接续而且不能接受主备切换后“备库追日志”的那几秒延迟。摆到桌面上有两个方案一是达梦的数据守护主备二是直接上DSC共享存储集群。主备方案的架构大家都很熟一台主库提供读写一台备库实时接收归档和重做日志主库出故障后执行切换。它的问题在于备库本质上是一份“物理拷贝”同一时刻只有主库在写备库要么处于Standby状态要么只能开只读资源利用率和扩展性都受限。而DSC让两个实例共享同一份物理数据文件所有节点都能读写任何一个节点故障后剩下的节点仍然持有完整的存储和最新的数据业务无需等待日志追平体验上更接近负载均衡而非故障切换。所以要回答“为什么要上DSC”一句话就是业务要的是多节点并发读写与故障状态下无感接管这单靠主备达不到。如果你只需要容灾和读写分离那主备完全够用DSC反而把存储层面和集群组件复杂度全拉上来了选型要根据业务负载模型来定。1.2 DSC的四个核心组件各管哪一段达梦DSC不是安装完数据库就自动具备集群能力它由四个角色协同工作我把它们对应到实际进程读者排查问题时才好定位DMCSS集群同步服务。它负责节点心跳、投票表决和故障判定。两个节点的CSS互相通信结合表决盘来判断谁是活节点、谁是故障节点。CSS挂了整个集群就失去了仲裁能力。DMCRS集群注册服务。它负责统一管理集群内的资源包括DMASM实例和DMSERVER实例的注册、启动、监控、自动拉起。你可以把它理解成“调度中心”的常驻代理。DMASM自动存储管理服务。它负责将共享存储上的裸设备格式化成磁盘组并在磁盘组里管理数据文件的分配与映射。节点读写数据走的是DMASM。DMSERVER数据库实例服务。这就是数据库本体两个节点各一个实例共享DMASM磁盘组中的数据。画个简单的运行关系DMCSS负责裁定谁活着DMCRS负责拉起和守护资源DMASM负责管理存储DMSERVER负责对外提供SQL服务。任何一个环节的配置错位都会表现为“进程起来了但集群不正常”。1.3 用Openfiler做IP SAN是学习和压测的可行方案但生产别照搬原本计划用一台物理盘阵接FC SAN但测试环境没有这个条件最终用Openfiler虚拟机承载iSCSI Target走IP SAN。选择的原因很现实Openfiler能把一块普通磁盘划分成多个Block Volume然后通过iSCSI协议发布成LUN两个数据库节点通过以太网就能挂载不需要独立的HBA卡。测试环境里换LUN大小、删除重建都非常方便适合反复演练初始化流程。IP SAN本身的网络吞吐受网卡限制但对验证集群机制、测试故障切换和练手已经足够。必须提醒的是Openfiler这类软件存储没有双控制器缓存镜像也没有断电保护机制它适合实验室模拟。生产环境建议用带双控制器、BBU和写缓存保护的硬件SAN否则存储单点就是整个集群最大的风险点。2. 动手前必须先定的三件事网络、LUN清单和节点基线2.1 三网分离心跳流量绝不能混在业务网里DSC最忌讳的就是心跳和业务流量混用一张网卡。两个节点之间需要高频交换心跳报文如果业务突发流量占满带宽心跳报文被延迟或丢弃CSS就会判定对方失联触发故障踢出动作造成无谓的节点驱逐。这比“真的宕机”还要坑因为业务侧会看到明明两个节点都活着其中一个却被强制隔离。我的网络规划如下网络用途节点1节点2存储设备说明业务网192.0.2.11192.0.2.12不涉及应用连接、客户端访问私网心跳10.10.10.1110.10.10.12不涉及两节点CSS心跳建议直连存储网192.168.100.11192.168.100.12192.168.100.30iSCSI存储流量注意心跳网段我这里用了独立网段和独立网卡有条件时两个节点之间用一根交叉线直连减少交换机故障对心跳的影响。存储网也要单独走物理网卡如果条件实在有限至少要用VLAN隔离不要让存储流量和业务流量在同一个广播域里横冲直撞。2.2 LUN按用途拆分不把日志、数据和表决盘塞进同一块DSC对共享存储的要求是“所有节点看到的物理盘一致”但盘的数量和用途有讲究。我按官方文档的常见做法划分了四块LUN其中表决盘是DMCSS用来投票仲裁的空间很小但必须存在LUN名称大小用途VOTE_LUN1GBDMCSS表决盘DATA_LUN100GB系统表空间、用户数据LOG_LUN20GB重做日志ARCH_LUN50GB归档日志为什么日志要单独拆出来因为重做日志写入频率远高于普通数据文件如果和数据盘混在一起日志写操作会跟随机读操作争抢磁盘I/O直接影响集群整体TPS。表决盘单独1GB就够它只存CSS仲裁写入的少量状态信息但是它的可靠性关系到整个集群能不能做脑裂判定不能省。2.3 两个节点的基线必须一致否则后面排查会疯掉双节点集群最怕的就是“左边能跑右边报错”之类的问题多数情况都源于基线不一致。我在这里花了比较多时间做基线整理核心几项操作系统用户和组一致创建dmdba用户主组dinstallUID/GID在两个节点上设置成一致。环境变量一致DM_HOME、PATH、LD_LIBRARY_PATH这些变量在节点1和节点2必须指向相同的安装路径。内核参数一致共享内存、信号量和文件句柄限制统一我按达梦安装文档把/etc/sysctl.conf配成一致并sysctl -p生效。时间同步两个节点加入同一chrony源节点间时间差尽量控制在秒级以内否则CSS超时判断会被时间偏差严重干扰。/etc/hosts里面同时配置两个节点的业务IP和心跳IP后续安装和连接都用主机名避免因IP写错导致节点间通信失败。这些工作重复且琐碎但它们是后面每一条报错排查的基础。我在实际操作中见过有人节点2漏开了防火墙端口结果CSS一直处于“抖动-超时-重连”循环查了大半天才找到根因所以节点基线检查这一遍真不能省。3. Openfiler存储端配置从卷组到iSCSI Target的完整操作3.1 创建Volume Group和Block VolumeOpenfiler部署好之后通过HTTPS访问管理界面。我用的版本是2.4.x界面虽然老旧但功能逻辑还是比较清楚的。它的操作链路是先建分区和物理卷再做卷组最后在卷组上创建块设备。具体操作分三步在Volumes标签页选择物理磁盘添加为物理卷。基于这些物理卷建立Volume Group。这里我建议几个LUN都建在同一个卷组里方便统一管理空间配额。在卷组下创建Volumes类型选iSCSI/FC Block不要选Network File System那种共享文件系统类型。我们给数据库节点的必须是裸块设备不能有文件系统层。创建Volume时有一个“Extent Size”选项它决定卷组内空间分配的块粒度。默认值就好不必特别调。每创建一个Volume就对应一个LUN我依次创建了VOTE、DATA、LOG、ARCH四块容量按照上一节规划来填。3.2 iSCSI Target的添加、映射与ACL放行Volume创建完还不等于节点能用必须发布成iSCSI Target在Services标签页启用iSCSI Target服务Openfiler会启动对应的后台服务。进入SAN标签页在iSCSI Target模块添加一个新的Target。在Target的LUN映射里把刚才创建的四个Volume逐个添加进去。设置Network ACL只放行两个数据节点的存储网IP192.168.100.11和192.168.100.12。这里最容易漏掉的就是ACL。默认情况下Openfiler的Target创建后没有放行任何客户端IP两个节点login时要么卡在Discovery阶段要么login超时但存储端日志里又看不到明显报错。生产环境建议在Target上加CHAP认证测试环境至少把客户端IP限定住别把一个裸设备发布到整个内网。3.3 存储端完成后我建议做的三项自检存储端配置做完先别急着去节点上装数据库先做一轮自检在节点1和节点2分别执行iscsiadm -m discovery -t sendtargets -p 192.168.100.30两个节点应该都能看到同一个Target和四块LUN。检查LUN大小四块LUN在两个节点上的容量必须完全一致大小不一致说明映射错乱。在Openfiler界面确认Target状态是Active同时确认两个节点都建立了连接会话。自检通过再继续如果在这里发现ACL或者Target映射问题修复成本最低等到了达梦初始化阶段再回来改存储中间会多出很多无谓的排查。4. 数据节点连盘iSCSI登录与多路径固化4.1 Linux端的iSCSI登录与自动挂载配置两个节点都需要安装open-iscsi客户端并配置自动挂载。以某发行版为例yum install -y iscsi-initiator-utils systemctl enable --now iscsid发现Target并登录iscsiadm -m discovery -t sendtargets -p 192.168.100.30 iscsiadm -m node --loginall iscsiadm -m node -o update -n node.startup -v automatic其中第三条命令的作用是把所有已登录Target的启动项设为automatic保证节点重启后不需要手工login。这一步很容易漏漏掉的直接后果就是存储设备重启后数据库起不来。另外我建议修改一下/etc/iscsi/iscsid.conf里的超时参数node.session.timeo.replacement_timeout 20 node.session.err_timeo.abort_timeout 30理由很实际达梦DSC的会话检测有自己的心跳机制如果iSCSI层因为网络抖动立即把命令置为失败数据库可能还没反应过来就被CSS判定为节点故障。适当放宽iSCSI层的命令超时让存储层“钝感”一些反而能帮忙过滤掉短时网络毛刺。4.2 多路径配置重点在“黑名单”和固定别名如果存储只有一个IP入口不配置多路径也能用但真正生产环境建议至少两条存储链路。我在测试环境模拟了双链路所以用device-mapper-multipath把多个路径聚合为一个逻辑设备参考配置如下yum install -y device-mapper-multipath mpathconf --enable在/etc/multipath.conf中defaults { user_friendly_names yes path_grouping_policy multibus } blacklist { wwid SATA____VMware_Virtual_I_000000000000000 } multipaths { multipath { wwid 36001405fabcdef123456 alias asm-vote } }这里最关键的坑是黑名单。多路径一旦开启会把系统本地盘也纳入管理弄不好重启后根文件系统路径变化系统直接进不去。我先把本地系统盘的wwid确认出来写进黑名单只让iSCSI盘走multipath再为每块共享盘设置alias别名。配置完成后执行multipath -r multipath -ll此时看到的dm-*设备会有对应的alias比如asm-vote、asm-data。后续达梦初始化和CSS配置里都用alias路径不要用/dev/sdb这种不稳定名字。4.3 共享盘权限与udev绑定DSC要求所有节点对共享设备有相同的访问权限而且最好固化设备名。我的做法是通过udev把multipath别名设备绑定成固定符号链接并设置属主为dmdbaKERNELdm-*, ENV{DM_UUID}mpath-VOTE_UUID, SYMLINKasm-vote, OWNERdmdba, GROUPdinstall, MODE660写进/etc/udev/rules.d/60-dsc.rules后执行udevadm trigger。这一条规则的作用远不止“好看”它解决了DSC最典型的身份识别问题节点1看到共享盘是/dev/sdb节点2看到的可能是/dev/sde如果直接拿设备名去初始化磁盘组两个节点的ASM元数据对不上数据库起不起来。而通过固定符号链接两个节点引用的路径完全一致ASM磁盘识别就稳定了。5. 达梦软件层安装磁盘组、CSS/CRS服务与启动顺序5.1 安装软件与准备实例目录达梦数据库软件安装本身不复杂重点在于两个节点路径一致。我的做法是先在节点1安装到/dm8然后拷贝到节点2保持完全相同的目录结构避免一个节点用/dm8另一个节点用/opt/dmdbms这类差异。之后设置环境变量export DM_HOME/dm8 export PATH$DM_HOME/bin:$PATH export LD_LIBRARY_PATH$DM_HOME/bin:$LD_LIBRARY_PATH安装完成后按照集群规划为每个节点准备独立实例目录例如/dm8/data/DSC1、/dm8/data/DSC2但注意存储相关路径在两个节点必须指向同一套共享设备路径。实例目录里需要放dminit工具初始化出来的初始化参数文件以及后续手动创建的dmcss.ini和dmcrs.ini。5.2 dmasmtool创建ASM磁盘组进入共享存储初始化阶段使用dmasmtool工具创建磁盘组。以我之前操作的方式为参考cd /dm8/bin ./dmasmtool进入交互界面后依次创建三个磁盘组create diskgroup VOTE with disk /dev/mapper/asm-vote; create diskgroup DMA with disk /dev/mapper/asm-data; create diskgroup DMLOG with disk /dev/mapper/asm-log;创建磁盘组是DSC安装中很关键的步骤它把物理裸盘“格式化”成达梦ASM能识别的结构。需要留意的是创建动作只需要在一个节点执行结果会同时被两个节点读取。完成后退出工具后续DMSERVER的dm.ini里都要引用对应磁盘组名称。5.3 DMCSS与DMCRS的配置和启动顺序DMCSS的配置文件dmcss.ini核心参数大约是这样CSS_VOTE_DISK /dev/mapper/asm-vote CSS_PORT 7233 CSS_HEARTBEAT_TIMEOUT 15 CSS_DB_HEARTBEAT_TIMEOUT 30DMCRS的配置文件dmcrs.ini里需要把两个节点的DMASM实例和DMSERVER实例都注册进去。这一步我踩过比较久的坑一开始只注册了本节点资源启动后CRS能拉起本节点实例但无法感知另一节点状态集群始终处于不完整状态。最终把两个节点的实例配置路径都写进资源清单问题才解决。启动顺序上必须严格遵循节点1启动DMCSS节点2启动DMCSS节点1启动DMCRS节点2启动DMCRSDMCRS按注册资源拉起本节点的DMASM和DMSERVER这个顺序不是随便定的。CSS是所有集群决策的基础必须先形成仲裁CRS依赖CSS的裁决结果去做资源调度DMASM和DMSERVER又依赖CRS守护。倒过来启动或者跳步都会在日志里看到“CSS服务不可用”或者“资源注册失败”之类的问题。5.4 DMSERVER的双实例参数差异只有小处两个节点的dm.ini大部分参数可以保持一致只有少数需要区分开。我这里整理了一份对照参数节点1节点2instance_nameDMSERVER1DMSERVER2asm_nameDMASM1DMASM2port_num52365236或独立端口dcr_ini/dm8/data/DSC1/dmcrs.ini/dm8/data/DSC2/dmcrs.inicss_ini/dm8/data/DSC1/dmcss.ini/dm8/data/DSC2/dmcss.ini注意与共享存储相关的路径比如数据库文件目录、归档目录、控制文件路径两个节点必须完全一致因为它们操作的是同一份物理文件。只有实例名和节点标识不同。配置完成后我先把两个节点都停止再按上一小节顺序启动日志里确认“集群初始化成功”再继续验证。6. 集群上线后的验证与三个典型故障复盘6.1 双节点一致性检查集群启动后我做了一套比较完整的验证流程在两节点执行进程检查确认dmcss、dmcrs、dmasm、dmserver四类进程都存在。在节点1用disql连接数据库创建一张测试表并插入一条记录然后切到节点2连接同样的数据库服务能立即查到这条记录说明共享存储读写链路正常。检查CSS日志确认两个节点的心跳状态为在线没有反复出现超时断开记录。这一步测的是“多实例同时读写同一份存储”的基本能力。如果节点2查询不到节点1刚插入的数据很大概率是ASM磁盘组路径不一致或者缓存融合机制未正常建立要回头检查磁盘组配置。6.2 存储链路故障模拟达梦DSC的价值主要在故障场景下体现。我在测试环境做了一次破坏性演练在Openfiler的Network ACL中临时移除节点2的存储网IP模拟节点2与存储失联。观察到的现象是节点2的SQL操作开始阻塞持续约20秒后DMCSS判定节点2心跳异常并触发故障处理。节点2被标记为故障节点后节点1上的业务不受影响继续对外提供服务。我在有维护窗口的前提下恢复ACL节点2重新连回存储然后重新加入集群。这个演练建议大家在测试环境一定要做一遍它能帮你直观理解“共享存储链路断开”和“节点宕机”在DSC中的处理差异。需要反复强调的是破坏性演练前必须先备份数据并安排维护窗口不要在生产环境随手做。6.3 三个真实故障复盘最后分享我实际遇到过的三个故障希望给大家排查路径提供一些参考故障现象根因解决办法节点2 iSCSI login失败但节点1正常Openfiler Network ACL未放行节点2存储网IP在ACL中添加192.168.100.12dmasmtool创建磁盘组时两个节点看到的设备名不一致直接使用/dev/sd*不稳定盘符改用multipath alias配合udev固定设备名集群运行期间节点频繁被踢出心跳与业务共用网卡流量拥塞导致心跳超时心跳走独立直连网卡并调整CSS心跳超时参数第一个故障属于配置遗漏排查最快。第二个故障是DSC新手最容易踩的经典坑凡是出现“ASM元数据读取失败”之类报错优先检查共享设备名在两个节点是否一致。第三个故障则是网络设计问题在虚拟机环境尤其容易出现因为默认只有一块网卡时人们图省事不想加网卡结果把心跳和业务混在一起最终花在排查上的时间远大于配一块网卡的时间。从我实际使用的体会来说DSC双节点的核心不是“多装一遍数据库”而是理解共享存储、仲裁服务、资源管理这三者之间的相互约束。整套环境搭下来我最深的感觉是规划阶段多花半小时比排障阶段熬两小时更值得。尤其是固定设备名和网络隔离这两步一定不要偷懒省掉。