前阵子做国产化数据库替换时,被问得最多的一套环境就是“基于DMASM的DMDSC安装部署”。DMDSC是达梦的共享存储集群方案,DMASM则是达梦自研的自动存储管理组件,两者搭配起来,相当于国产数据库里的“Oracle RAC + ASM”组合。这篇文章我就以一套双节点DMDSC集群为例,把从环境规划、存储划分、DMASM磁盘组创建,到DMDSC集群建库的全过程完整拆一遍,包括最后我在实测中遇到的几个典型故障和排查思路。如果你正在做达梦的集群交付,或者准备从单机往共享存储集群迁移,这篇可以直接当参考手册用。
开始之前先说明一下:达梦不同小版本之间,个别配置文件命名和初始化参数会有一点差异,但整体思路和架构是稳定的。我会以通用部署路径为主线,遇到版本敏感的地方,会提醒你以手上版本的手册为准。
1. 整体方案选型:为什么用DMASM托管DMDSC
1.1 DMDSC到底是一套什么架构
DMDSC(DaMeng Data Shared Cluster),核心就是“多个数据库实例同时挂载同一份共享数据”。你可以把它想象成一个公司里有多个前台窗口(实例),后面所有人都共用同一个档案库(共享存储)。任何一个窗口挂了,其他窗口可以继续接待,客户无感知。
这套架构里,最核心的三个角色是:
- DMCSS:集群控制服务,负责节点成员管理、故障发现、实例自动拉起,相当于集群里的调度中心。
- DMASM:自动存储管理服务,负责把共享磁盘池统一管理起来,给数据库提供卷,相当于存储管理员。
- DMServer:真正干活的数据库实例,用户连接、SQL执行都发生在这一层。
三个角色之间有专门的通信链路,默认走MAL(Multi-Address Link)协议。集群内不同节点之间通过心跳网络互相感知状态,一旦某个节点失联,DMCSS会在规定时间内触发故障处理流程,由存活节点接管服务和锁资源。
对比Oracle RAC的话:DMCSS承担了CSS和CRS的部分功能,DMASM对应Oracle ASM,DMServer对应Oracle DB Instance。架构对应关系非常清晰,做过RAC的人上手会很快。
1.2 没有DMASM行不行,为什么一定要引入存储管理层
很多刚接触DMDSC的人会问:我直接把数据文件放到共享盘上,让两个实例去读写,是不是也可以?理论上可以,这就是“裸设备模式”。但真到生产环境你会发现裸设备方案有几道坎:
第一,设备权限管理很痛苦。共享盘在节点A上叫/dev/sdb,到节点B上可能是/dev/sdc,如果两边绑定的名称不一致,实例启动时连磁盘都找不到。裸设备模式下,所有节点必须对同一磁盘保持完全一致的视图,一旦udev规则没写好、多路径识别顺序不同,就是故障。
第二,文件管理不透明。数据文件是直接落在分区上的,你想要扩容,得先找空闲分区,再扩文件,过程非常僵硬。DBA没法像管理普通文件一样管理裸设备,表空间路径、大小、状态一多就乱。
第三,没有冗余保护。裸设备模式下,单块磁盘损坏直接影响对应数据文件,除非你靠存储层做RAID,否则数据库层没有任何自愈手段。
DMASM把这些问题统一解决掉了。它在所有节点上提供同一条路径规则,磁盘组、卷、自动均衡都是平台能力。你在ASM上创建一个卷,它会在所有节点上以相同名称、相同路径出现,数据库只认卷名,不关心底层物理盘是哪一块。加上DMASM支持不同冗余级别,相当于在数据库层也加了存储冗余保护。
所以我的建议很直接:生产环境的DMDSC,老老实实走DMASM这条路。虽然多一个组件就多一份学习成本,但这些成本换来的是一致性、可管理性和故障自愈能力。
1.3 哪些场景其实不适合这套方案
不是所有情况都该上DMDSC。我见过不少项目,业务并发量并不高,却为了“有集群”这个面子硬上共享存储。DMDSC最大的价值是高可用和负载分担,但代价是架构复杂度显著上升,还引入了共享存储这个单点。
如果你面临的是以下场景,建议先冷静评估:
- 单实例就能扛住业务压力,只是担心机器故障,这时候更应该看达梦数据守护(DMDataWatch),主备切换方案成本和运维难度都低得多。
- 两个机房距离远,网络延迟超过3毫秒以上,DMDSC的心跳和缓存融合对网络要求很高,跨机房部署综合收益不大。
- 没有真正的共享存储硬件,只想用普通服务器本地盘搭集群,这就放弃了DMDSC的本质,不如不做。
我遇到过一次非常典型的案例:客户为了用DMDSC,拿两台服务器加一个低端NAS柜做共享存储,结果存储IO成为整个集群的瓶颈,双节点的性能还不如单机。最后换成了数据守护,问题立刻消失。
2. 环境规划与前置准备:这步做不好后面全是坑
2.1 集群拓扑和网络规划,两个网段必须分开
DMDSC对网络规划的基本要求是:业务网络和心跳网络物理隔离。严格来说,心跳网络应该走独立的网卡、独立的交换机,带宽建议万兆起步。
我给你的规划表格模版,照着填就能用:
| 节点角色 | 主机名 | 业务IP | 心跳IP | 操作系统 | 数据库版本 |
|---|---|---|---|---|---|
| 节点1 | dmdb01 | 192.168.10.11 | 10.10.10.11 | 麒麟V10 SP1 | DM8 DMASM+DMDSC |
| 节点2 | dmdb02 | 192.168.10.12 | 10.10.10.12 | 麒麟V10 SP1 | DM8 DMASM+DMDSC |
这里有一个很容易被忽略的点:心跳IP和业务IP如果在同一个广播域,万一交换机出现环路或异常流量,心跳包会被冲垮,集群会误判节点故障,进而触发脑裂保护。设计阶段就把两个网段彻底分开,后续少很多麻烦。
主机名规划也一样,不要用一堆无规律的名字,我习惯用dmdb01、dmdb02这种带序号的命名,后面写配置文件、排查日志都能省心不少。两个节点的/etc/hosts必须写清楚两套IP的主机名映射,包括心跳IP那份,否则MAL通信会解析出错。
2.2 共享存储划分,磁盘怎么分、LUN怎么规划
在DMASM模式下,整个存储池由若干共享LUN组成。规划原则是:先划分一组基础盘,后面再按需扩容。
我通常把LUN分成两类:
- OCR/VOTE盘:用于存放DMCSS的集群配置和表决信息,相当于Oracle RAC里的OCR和Voting Disk。容量不需要太大,1GB到2GB即可,但一定要做冗余。
- 数据盘:给DMASM磁盘组用,所有数据文件、控制文件、日志文件都落在这些盘上。具体大小看你业务数据量预估,建议在预估量基础上再放30%余量。
生产环境共享存储建议走光纤SAN,次选万兆iSCSI。不管是哪种,两个节点都必须装好多路径软件,我这边比较多的是用系统自带的device-mapper-multipath。多路径配置完成后,先在两个节点上分别执行multipath -ll,确认各自看到的dm设备名是一致的。
这里强烈建议再用udev把磁盘名固定住。一个通用的udev规则示例:
KERNEL=="dm-*", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$parent", RESULT=="3600508b400105f3900030000670000000", SYMLINK+="asm_ocr", OWNER="dmdba", GROUP="dinstall", MODE="0660"规则写好后,执行udevadm trigger让规则生效。为什么要这么折腾?因为如果节点A看到的是/dev/mapper/asmdata1,节点B看到的是/dev/mapper/asmdata1_1,后面创建磁盘组的时候就会一头雾水,这属于部署阶段最典型的坑,后面第6节我会专门讲一次。
2.3 操作系统基础调整,不做好这些DMCSS永远起不来
操作系统层面的准备,我按优先级排个序:
第一,时间同步。两个节点之间的时间偏差控制在秒级以内,超过这个范围,MAL消息的时序判断就会出问题。强烈建议配置NTP或chrony,指向同一个时间源。
第二,关闭防火墙和SELinux。DMDSC的MAL通信端口很多,靠逐条放行策略很容易漏,内网环境直接关防火墙最省事。当然,如果安全策略强制要求开防火墙,那就要把所有节点之间的业务IP端口和心跳IP端口研究清楚,逐条放行,工作量大很多。
第三,资源和内核参数。达梦官方要求的dmdba用户资源限制、文件句柄数、进程数这些,直接用ulimit改掉,然后写入/etc/security/limits.conf确保重启后仍然生效。内核参数里,vm.swappiness建议调整为10以下,透明大页建议关闭,这些对数据库类的负载都是基本要求。
第四,安装达梦软件。两个节点都需要安装相同版本、相同目录的DM软件,建议装在本地磁盘上,不要装在共享存储上。安装用户统一用dmdba,安装目录统一为/dm/dmdbms这样的固定路径,可以避免很多环境差异。装完之后用disql先起来一个单机实例验证安装没问题,再进入集群部署,这样能区分软件问题和集群问题。
3. DMASM存储管理核心步骤:磁盘组与卷的创建
3.1 初始化DMASM实例,别忽略独立实例目录
DMASM不是数据库实例,它是独立的一套服务进程,有自己的实例目录、配置文件和日志。我的习惯是在数据库软件目录之外,单独规划一套ASM实例目录,例如:
/dm/dmdbms/data/dmasm_01这个目录用于存放DMASM实例的初始化配置和运行日志。两个节点各建各的,不要共享。
接着要准备DMASM实例的配置文件,常见的是dmasvrmal.ini和dmasm.ini。其中dmasvrmal.ini描述了ASM实例之间以及ASM与DMCSS之间的MAL通信配置,包括MAL端口、MAL心跳端口等;dmasm.ini则记录实例名、ASM磁盘发现路径等基础信息。需要注意的是,这部分配置在不同版本里细节差异较大,建议安装完成后直接参考达梦自带的模板文件修改,而不是自己从零写。
我在部署时有个习惯:先把两个节点的dmasvrmal.ini填好,再互相核对一遍节点名、IP、端口是否完全对应。MAL配置不对,后面DMASM起来也找不到对方,排查起来整个链路都是乱的。
3.2 使用dmasmcmd创建磁盘组
DMASM启动后,管理操作主要靠dmasmcmd工具完成。进入工具后,第一件事就是查看当前已发现的磁盘组:
dmasmcmd lsdg如果磁盘组为空,说明还需要继续创建。创建一个外部冗余磁盘组的典型命令是:
create diskgroup 'DMDATA' with '/dev/mapper/asmdata1', '/dev/mapper/asmdata2';这里DMDATA是磁盘组名称,后面跟的是共享LUN在本地节点上的设备路径。创建完成后,再次用lsdg确认磁盘组状态正常。
关于冗余模式的选择,我的建议是:
- 外部冗余:适合底层存储已经做了RAID10/RAID5的场景,磁盘利用率最高。
- 正常冗余:DMASM层做双镜像,写入性能会降一截,但能抵御单块磁盘故障。
- 高冗余:三副本,一般业务用不上,存储成本太大。
绝大多数生产环境,底层SAN都已经做了硬件RAID,所以我在DMDSC部署里用外部冗余是最多的。如果你的项目预算充足、又担心存储单点风险,可以选正常冗余,但一定要在压测阶段就把写入性能的损耗测出来。
3.3 在磁盘组上创建数据卷
磁盘组相当于一个“空仓库”,真正给数据库用的是“卷(Volume)”。在DMASM里,卷是一个逻辑存储单元,数据库初始化时会把表空间文件直接建在卷上。
创建卷的命令和磁盘组相似,大致是:
create volume 'DMDATA' size 2048;上面这个命令会在DMDATA磁盘组上分配一个2048MB的卷。卷创建完成后,在所有节点上应该能看到完全一致的路径。DMASM通常会在约定的卷路径下生成对应的卷文件,例如/dm/dmdbms/data/asm_vol/DMDATA/...这样的目录结构。
我踩过的一个教训:卷数量不要一开始就拆得非常细。比如把系统表空间、用户表空间、回滚日志、在线日志各建一个卷,看似合理,实际操作中扩容和管理会非常繁琐。更省心的做法是,按业务模块建大卷,比如一个数据总卷,一个日志卷,初始化数据库时把文件分散放在卷上,后续扩容直接扩卷大小即可。
创建完卷之后,我习惯用达梦自带的磁盘读写工具或者dd简单做一轮读写验证,确保所有节点都能正常访问同一个卷:
dd if=/dev/zero of=/dm/dmdbms/data/asm_vol/DMDATA/testfile bs=1M count=1024 oflag=direct验证完记得把测试文件删掉。这一步虽然简单,但能提前暴露节点间卷路径不一致、权限不对等问题,不要跳过。
4. DMDSC集群安装与建库完整流程
4.1 配置DMCSS集群控制服务,节点信息的“总台账”
DMCSS是集群里最先启动的服务,它的配置文件dmdcs_cfg.ini保存了集群内所有节点(CSS、ASM、DB)的基础信息。你可以理解为集群的总台账。
典型的配置内容会包括:
- CSS节点信息:CSS节点数量、投票磁盘路径。
- ASM节点信息:ASM实例名、MAL通信IP和端口、ASM投票磁盘路径。
- DB节点信息:数据库实例名、MAL端口、数据库节点对应使用的ASM实例名和ASM端口。
配置的关键点是所有节点上的dmdcs_cfg.ini内容保持一致,特别是节点数量、IP、端口这些,任何一个节点写错,集群都无法正常组建。
我这里给一个简化的配置示意,实际部署时需以安装包模板为准:
[CSS] CSS_COUNT = 2 CSS_VOTE_DISK = /dev/mapper/asm_ocr [ASM] ASM_COUNT = 2 ASM_ID = 1 ASM_NAME = DMASM ASM_MAL_HOST = 10.10.10.11 ASM_MAL_PORT = 7235 ASM_VOTE_DISK = /dev/mapper/asm_ocr [DB] DB_COUNT = 2 DB_ID = 1 DB_NAME = DMDSC DB_INST_NAME = DMSERVER01 DB_MAL_HOST = 10.10.10.11 DB_MAL_PORT = 7237 DB_ASM_NAME = DMASM DB_ASM_PORT = 7235这里我只是列了一个轮廓,实际配置项比这多,而且不同版本之间命名不同。放这段的目的,是让你理解配置文件里每个区块的职责和它们之间的引用关系。节点2的配置除了ID、IP、实例名不同,结构完全一样。
配置完成后,先不要启动数据库,先启动DMCSS服务,观察它是否能把ASM实例拉起来。DMCSS启动后会监控配置中的ASM和DB节点,并尝试自动拉起,这一点和Oracle RAC的CRS行为很像。我第一次部署时直接跳过了观察DMCSS,结果后面数据库起不来,回头看日志发现ASM都没起来,白白浪费半天。
4.2 配置DMDSC数据库实例,dmdsc_cfg.ini的作用
DMCSS把集群框架搭起来之后,数据库实例本身还需要一套集群版配置。达梦在这里提供的核心文件是dmdsc_cfg.ini,它的作用类似于单机版的dm.ini,但增加了集群相关的参数。
需要重点核对的内容包括:
- 数据库实例的名称和ID,每个节点唯一。
- 各实例的MAL配置,用于实例间缓存融合和消息通信。
- ASM连接方式,数据库实例启动时需要连接到对应的DMASM实例,读取卷信息。
- 集群故障处理相关参数,比如节点故障后的踢出判定时间、实例恢复窗口等。
两个节点上的dmdsc_cfg.ini最好别再手动改来改去,用同一份再按节点微调最稳妥。我见过有人在节点2上忘记改实例名,结果两个节点用了同一个实例名,DMCSS那边怎么都起不来第二个数据库,日志报实例冲突错误。
4.3 初始化集群数据库,把库建到DMASM卷上
配置做完,进入建库阶段。DMDSC建库和单机库最大的区别在于,数据文件的路径必须是DMASM卷路径,而不是普通文件系统路径。这也是整篇文章的主线:先有DMASM卷,然后才有DMDSC数据库。
使用dminit初始化集群数据库时,要显式指定路径到ASM卷上,同时声明这是一套集群数据库。不同版本参数有差异,但方向一致。我的操作步骤如下:
第一,确认DMASM状态正常,卷已经存在,卷路径在节点间一致可见。 第二,在两个节点上都准备好初始化数据库所需的配置,尤其是节点各自的实例参数。 第三,在其中一个节点执行dminit,指定数据库名、实例名、ASM卷路径等信息,初始化完成后,其他节点复用同一套环境,不需要重复建库。
这里有一个重要提醒:DMDSC的数据库文件是共享的,所以建库动作本质上只能做一次,文件一旦生成,所有节点访问的是同一份数据。不要在两个节点上分别执行建库命令,否则相当于格式化了两遍,产生冲突。
建库完成后,先别急着启动数据库实例,先在ASM管理工具里确认卷空间占用情况,看看系统表空间、日志文件是否已经在卷上正确生成。如果这里发现文件散落在单机磁盘上,那就是建库参数不对,返回去修正,别继续往下走。
4.4 服务注册与启停顺序,先CSS后DB
达梦安装目录下提供了服务注册脚本,可以在系统服务管理器中注册DMCSS和DMServer服务。我的启动顺序是:
- 启动两个节点的DMCSS服务。
- DMCSS启动后自动拉起本节点和远端节点的DMASM实例。
- DMASM就绪后,DMCSS继续拉起数据库实例。
- 数据库实例由DMCSS统一管理,不建议手动单独起停。
之所以不建议手动单独启动数据库实例,是因为DMCSS有完整的集群状态机。你手动拉起的实例,如果状态和DMCSS记录不一致,会被误判为异常节点然后被强制踢出。最典型的就是手动启动节点2的数据库,结果节点2在DMCSS那边还标记为“故障中”,启动即被要求退出。
首次启动时,我建议用前台方式观察日志:
/dm/dmdbms/bin/dmserver /dm/dmdbms/data/dmdcs/dmdcs.ini日志输出正常后,再退回用系统服务托管。这一步能让你第一时间看到MAL通信、ASM挂载、数据库恢复的完整过程,比事后翻日志高效得多。
集群启动完成后,用disql登录任意一个实例,执行:
SELECT * FROM V$DSC_EP;查看集群节点状态。如果看到两个节点的EP_STATUS都是正常值,且节点能互相看到对方,DMDSC集群就算基本建立成功了。
5. 高频故障与排错经验实录
5.1 节点磁盘路径不一致,ASM发现不了磁盘
这个故障我遇到过不止一次,现象是:节点1dmasmcmd里能看到完好的磁盘组,节点2 执行lsdg却提示磁盘不存在或者磁盘组不可用。
排查步骤:
- 先在两个节点分别执行
lsblk,对比共享盘的设备名和大小是否一致。 - 再执行
multipath -ll,看多路径设备命名。 - 最后检查udev规则是否在两边生效,生成的符号链接是否一致。
解决办法就是把两边的udev规则尽量做得完全一致,用同一个规则文件,重新加载后同步触发。设备名统一后,重启DMASM实例再查看磁盘组。
这类问题的根源在于:底层存储已经做成一个共享LUN,但操作系统层因为扫描顺序、多路径配置差异,把它识别成了不同名字。DMDSC本身不知道这些盘其实是同一块,它只认路径。所以路径不一致,集群就认为磁盘丢了。
5.2 实例启动后反复退出,日志报MAL通信超时
有次测试集群,节点2的数据库起来之后,过一会就自动退出,DMCSS尝试拉起几次,又退几次,陷入重启循环。日志里反复出现MAL通信超时或对端不可达。
我排查的顺序是:
- 先 ping 心跳IP,确认网络通不通。
- 再 telnet 对端的心跳端口,确认MAL端口能不能通。
- 检查两边防火墙状态,确认没有过滤规则。
- 最后核对
dmdsc_cfg.ini里的MAL配置,有没有IP写错、端口写反的情况。
那次问题的原因很朴素:心跳网卡虽然配了IP,但交换机上没有放通对应VLAN。网络层不通,MAL消息全部丢了,DMCSS判断节点失联,于是触发踢出流程。
这类问题排查的核心思路是:先看网络,再看配置,最后看日志,不要上来就改参数。
5.3 初始化数据库时报ASM卷空间不足
DMDSC建库和单机库一样,需要分配系统表空间、回滚表空间、重做日志等。如果ASM卷本身只建了很小的容量,初始化到一半就会报空间不足。
我当时遇到的情况是:卷只建了2GB,结果系统表空间加回滚段初始化就要接近1.5GB,加上日志文件,直接超了。
处理办法:
- 先删除创建多余的卷释放空间。
- 再对原来的卷进行扩容操作,或者重新创建一个大容量卷。
- 确保卷容量在预估数据量的基础上,留出至少20%的余量和后续表空间扩展空间。
我后来形成的一个习惯是:数据卷初始容量直接按“计划数据量的1.3倍”创建,回滚日志卷按数据卷的20%到30%创建,在线日志卷按日志文件的增长速率单独评估。宁可一次性给足,也不要频繁在线扩容。
5.4 故障切换测试里,三个时间参数最容易忽略
集群建好后,一定要做故障切换测试。我的标准测试是:在节点1上正常执行业务SQL,然后直接拔掉节点1的心跳网线或者kill -9节点1的数据库进程,观察节点2能否在设定时间内接管。
这个测试最容易暴露的问题是:切换时间过长,或者节点2一直没有触发接管。背后的关键参数是DMDSC故障处理相关的几个时间设置,比如:
- 心跳超时时间:多久没收到对端心跳就判定失联。
- 故障确认时间:发现失联后,等待多久确认节点确实故障。
- 实例拉起等待时间:故障恢复后,允许节点多长时间内自动加入集群。
如果心跳超时默认是10秒,那么业务中断至少就是10秒起步。想要更快的切换,可以在压测验证后适当调小心跳超时时间,但也不能太小,否则网络抖动会造成误切换。我的习惯是把心跳超时设置在5秒左右,故障确认时间控制在10秒左右,兼顾稳定性和切换速度。
这里有一个非常重要的经验:故障节点恢复后,不要第一时间手动拉起实例。要先看DMCSS日志确认故障清理流程已经结束,旧节点残留的锁资源和会话已经被回收。过早拉起很容易造成两个节点同时操作同一资源,日志里会报出各种奇怪的锁冲突。等服务自己拉起来,比手动干预更安全。
最后补一个实战心得
整套环境我在测试环境反复搭建过多个轮次,最深的体会是:DMDSC和DMASM真正难的点不在于命令怎么敲,而在于你对“集群如何感知节点状态、ASM如何统一卷视图、DMCSS如何控制启动顺序”这三件事的理解是否到位。配置写错可以改,架构理解错了,出了问题都不知道该查哪个日志。
个人建议,新项目上线之前,至少要在测试环境做三轮完整演练:第一轮按文档正常部署,第二轮模拟单节点故障切换,第三轮演练存储链路中断。每轮都要记录切换时间、日志报错、恢复步骤。等这三轮跑完,这套DMDSC环境才算真正有交付的底气。