注册
达梦DM8两节点读写分离集群搭建完整实战
专栏/技术分享/ 文章详情 /

达梦DM8两节点读写分离集群搭建完整实战

何处惹尘埃 2026/07/17 266 3 0
摘要

达梦DM8两节点读写分离集群搭建完整实战

前言

达梦读写分离集群是DM8提供的一个用于提升并发事务处理性能的集群组件,它通过创新的架构设计实现了事务级别的读写操作自动分离。读写分离集群底层依赖数据守护机制——主库包揽所有的写入和修改操作,备库在实时同步主库数据的同时,帮主库分担查询的压力。

本文完整记录在CentOS 7虚拟机上搭建达梦DM8两节点读写分离集群的全过程,包括部署、同步测试、读写分发比例配置,以及与主备集群的差异对比。

适用场景:最适合“读多写少”的业务模型。例如,管理员发布通知(写入操作只有1次并发),但成千上万的用户查看通知(读取操作可能有上万次并发),所有查询压力被分流到备库,主库在海量并发下依然能稳如泰山

一、环境准备

1.1 集群规划

本实验环境为一台虚拟机配置双网卡,主备库运行在同一物理机上,通过不同网卡和端口隔离:

角色 IP地址 实例名 数据库端口 MAL端口 守护端口 实例监听守护端口
主库 192.168.200.18 GRP1_RT_01 5236 6236 7236 8236
备库 192.168.201.90 GRP1_RT_02 5237 6237 7237 8237
确认监视器 192.168.200.18

端口说明
数据库端口(5236/5237)供业务连接;
MAL端口(6236/6237)用于集群内部日志传输;
守护端口(7236/7237)供守护进程通信;
实例监听守护端口(8236/8237)供监视器连接。

1.2 前置条件

  • 操作系统:CentOS 7
  • 达梦版本:DM8
  • 安装目录:/home/dmdba/dmdbms
  • 主库数据目录:/data/dmdata1/DAMENG/
  • 备库数据目录:/data/dmdata2/DAMENG/
  • 数据库密码:Admin2026

1.3 确认网络互通

在主库终端执行:

# 确认两个IP都能ping通(本机双网卡) ping -c 3 192.168.200.18 ping -c 3 192.168.201.90

1.4 确认实例已关闭

# 切换到dmdba用户 su - dmdba # 检查主库进程 ps -ef | grep dmserver | grep 5236 # 检查备库进程 ps -ef | grep dmserver | grep 5237 # 如有进程,先停止(使用DmService脚本或kill)

注意:由于之前有别的技术操作,如果之前已启动过实例,务必先正常关闭,避免端口冲突。

二、任务一:部署读写分离集群并测试同步

2.1 配置主库(GRP1_RT_01)

步骤1:修改主库 dm.ini

su - dmdba vi /data/dmdata1/DAMENG/dm.ini

找到以下四个参数,修改为指定值(如不存在则手动添加):

ALTER_MODE_STATUS = 0 ENABLE_OFFLINE_TS = 2 MAL_INI = 1 ARCH_INI = 1

保存退出(:wq)。

注意ALTER_MODE_STATUS=0 表示禁止手动修改数据库模式,由守护进程统一管理。MAL_INI=1ARCH_INI=1 分别开启MAL系统和归档功能。

步骤2:创建主库 dmmal.ini

MAL(Message Access Layer)是集群节点间的通信机制,通过 dmmal.ini 配置实现日志传输和状态同步。主库和备库的 dmmal.ini 内容必须完全一致

vi /data/dmdata1/DAMENG/dmmal.ini

写入以下内容:

MAL_CHECK_INTERVAL = 5 MAL_CONN_FAIL_INTERVAL = 5 [MAL_INST1] MAL_INST_NAME = GRP1_RT_01 MAL_HOST = 192.168.200.18 MAL_PORT = 6236 MAL_INST_HOST = 192.168.200.18 MAL_INST_PORT = 5236 MAL_DW_PORT = 7236 MAL_INST_DW_PORT = 8236 [MAL_INST2] MAL_INST_NAME = GRP1_RT_02 MAL_HOST = 192.168.201.90 MAL_PORT = 6237 MAL_INST_HOST = 192.168.201.90 MAL_INST_PORT = 5237 MAL_DW_PORT = 7237 MAL_INST_DW_PORT = 8237

注意MAL_HOST 必须绑定具体的网卡IP,不能写 0.0.0.0 或主机名,防止解析错误。

步骤3:创建主库 dmarch.ini

读写分离集群通常采用即时归档(TIMELY),即日志写入联机日志文件后发送给备库。

vi /data/dmdata1/DAMENG/dmarch.ini

写入:

[ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = /data/dmdata1/DAMENG/arch ARCH_FILE_SIZE = 512 ARCH_SPACE_LIMIT = 51200 [ARCHIVE_TIMELY1] ARCH_TYPE = TIMELY ARCH_DEST = GRP1_RT_02

注意ARCH_DEST 指向备库的实例名 GRP1_RT_02,确保与 dmmal.ini 中的实例名一致。

步骤4:创建主库 dmwatcher.ini

守护进程(dmwatcher)运行在各节点,负责监控数据库状态,触发故障切换。

vi /data/dmdata1/DAMENG/dmwatcher.ini

写入:

[GRP1] DW_TYPE = GLOBAL DW_MODE = MANUAL DW_ERROR_TIME = 10 INST_RECOVER_TIME = 60 INST_ERROR_TIME = 10 INST_OGUID = 45331 INST_INI = /data/dmdata1/DAMENG/dm.ini INST_AUTO_RESTART = 1 RLOG_SEND_THRESHOLD = 0 RLOG_APPLY_THRESHOLD = 0

注意

  • DW_TYPE=GLOBAL 表示全局守护类型,主备库均使用此类型。
  • DW_MODE=MANUAL 为手动切换模式,便于学习验证;生产环境可改为 AUTO 实现自动故障切换。
  • INST_OGUID 是集群唯一标识,主备库必须一致。

2.2 配置备库(GRP1_RT_02)

步骤5:修改备库 dm.ini

su - dmdba vi /data/dmdata2/DAMENG/dm.ini

修改同样的四个参数:

ALTER_MODE_STATUS = 0 ENABLE_OFFLINE_TS = 2 MAL_INI = 1 ARCH_INI = 1

步骤6:复制 dmmal.ini

直接复制主库的 dmmal.ini

cp /data/dmdata1/DAMENG/dmmal.ini /data/dmdata2/DAMENG/dmmal.ini

步骤7:创建备库 dmarch.ini

备库只需配置本地归档:

vi /data/dmdata2/DAMENG/dmarch.ini

写入:

[ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = /data/dmdata2/DAMENG/arch ARCH_FILE_SIZE = 512 ARCH_SPACE_LIMIT = 51200

关键:备库的 dmarch.ini 必须额外添加 TIMELY 归档指向主库,否则GLOBAL类型的守护进程启动时会报错。

修改如下:

vi /data/dmdata2/DAMENG/dmarch.ini

追加:

[ARCHIVE_TIMELY1] ARCH_TYPE = TIMELY ARCH_DEST = GRP1_RT_01

最终备库 dmarch.ini 完整内容为:

[ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = /data/dmdata2/DAMENG/arch ARCH_FILE_SIZE = 512 ARCH_SPACE_LIMIT = 51200 [ARCHIVE_TIMELY1] ARCH_TYPE = TIMELY ARCH_DEST = GRP1_RT_01

步骤8:创建备库 dmwatcher.ini

vi /data/dmdata2/DAMENG/dmwatcher.ini

写入(注意 INST_INI 指向备库路径):

[GRP1] DW_TYPE = GLOBAL DW_MODE = MANUAL DW_ERROR_TIME = 10 INST_RECOVER_TIME = 60 INST_ERROR_TIME = 10 INST_OGUID = 45331 INST_INI = /data/dmdata2/DAMENG/dm.ini INST_AUTO_RESTART = 1 RLOG_SEND_THRESHOLD = 0 RLOG_APPLY_THRESHOLD = 0

2.3 配置确认监视器

监视器(dmmonitor)负责监控集群状态和协调故障切换。

mkdir -p /data/dmdata1/monitor vi /data/dmdata1/monitor/dmmonitor.ini

写入:

MON_DW_CONFIRM = 1 MON_LOG_PATH = /data/dmdata1/monitor/log MON_LOG_INTERVAL = 60 [GRP1] MON_INST_OGUID = 45331 MON_DW_IP = 192.168.200.18:7236 MON_DW_IP = 192.168.201.90:7237

注意MON_DW_CONFIRM=1 表示确认监视器,用于自动故障切换场景。

2.4 设置环境变量

为避免每次输入完整路径,设置环境变量:

echo 'export DM_HOME=/home/dmdba/dmdbms' >> ~/.bash_profile echo 'export PATH=$DM_HOME/bin:$PATH' >> ~/.bash_profile source ~/.bash_profile

2.5 启动集群

关键顺序:必须先以Mount方式启动主备库 → 设置OGUID和模式 → 启动守护进程 → 启动监视器。

终端1:以Mount方式启动主库

su - dmdba dmserver /data/dmdata1/DAMENG/dm.ini mount

看到 SYSTEM IS READY 表示启动成功,保持此终端运行

终端2:以Mount方式启动备库

新开终端:

su - dmdba dmserver /data/dmdata2/DAMENG/dm.ini mount

保持此终端运行

终端3:设置主库OGUID和模式

新开终端,连接主库:

disql SYSDBA/Admin2026@192.168.200.18:5236

执行:

SP_SET_OGUID(45331); ALTER DATABASE PRIMARY;

验证:

SELECT DB_MAGIC, MODE$ FROM V$DATABASE;

确认 MODE$ 显示为 PRIMARY,输入 exit 退出。

终端4:设置备库OGUID和模式

新开终端,连接备库:

disql SYSDBA/Admin2026@192.168.201.90:5237

执行:

SP_SET_OGUID(45331); ALTER DATABASE STANDBY;

验证:

SELECT DB_MAGIC, MODE$ FROM V$DATABASE;

确认 MODE$ 显示为 STANDBY,输入 exit 退出。

终端5:启动主库守护进程

dmwatcher /data/dmdata1/DAMENG/dmwatcher.ini

看到 DMWATCHER[4.0] IS READY 表示成功,保持运行

终端6:启动备库守护进程

dmwatcher /data/dmdata2/DAMENG/dmwatcher.ini

保持运行

终端7:启动确认监视器

dmmonitor /data/dmdata1/monitor/dmmonitor.ini

在监视器命令行输入:

show

应看到类似输出:

INSTANCE            STATUS   MODE
GRP1_RT_01          OPEN     PRIMARY
GRP1_RT_02          OPEN     STANDBY

如果两个实例均为 OPEN 状态,说明集群搭建成功。

2.6 验证数据同步

主库建表插入数据

disql SYSDBA/Admin2026@192.168.200.18:5236

执行:

CREATE TABLE TEST_RW (ID INT, NAME VARCHAR(50)); INSERT INTO TEST_RW VALUES (1, 'PRIMARY_INSERT'); COMMIT; SELECT * FROM TEST_RW;

备库查询验证

disql SYSDBA/Admin2026@192.168.201.90:5237

执行:

SELECT * FROM TEST_RW;

如果能立即看到 (1, 'PRIMARY_INSERT'),说明数据同步正常,任务一完成

运行结果如下:
截屏20260714 13.59.37.png

三、任务二:配置读写事务分发比例

3.1 编辑 dm_svc.conf

达梦的读写分离通过客户端配置文件 dm_svc.conf 实现,应用通过服务名连接集群,客户端接口根据参数自动完成读写分流。

vi /etc/dm_svc.conf

添加以下内容:

# 定义服务名,包含主备节点 DMRWC=(192.168.200.18:5236,192.168.201.90:5237) # 开启读写分离 DMRWC_RWSEPARATE=(1) # 分发比例:主库25%,备库75% DMRWC_RWSEPARATE_PERCENT=(25,75)

参数说明

  • RWSEPARATE=1:开启读写分离功能。
  • RWSEPARATE_PERCENT=(25,75):表示 25% 的读请求发往主库,75% 发往备库。该值表示分发到主库的事务占主备库总事务的百分比,取值范围0~100。

3.2 验证读写分离配置

通过服务名连接:

disql SYSDBA/Admin2026@DMRWC

执行查询:

SELECT * FROM TEST_RW;

连接输出会显示实际连接的服务器地址。多次执行观察连接IP的变化,验证分发比例是否生效。

运行结果如下:

截屏20260714 13.38.22.png

任务二完成

四、任务三:理解与主备集群的差异

4.1 核心差异对比

对比维度 实时主备集群 读写分离集群(本文搭建)
核心目标 高可用(HA)——保障业务连续性 高性能(HP)+ 高可用——提升吞吐量
备库角色 冷备/温备,一般不对外服务 热备,承担读查询负载
归档类型 实时归档(REALTIME 即时归档(TIMELY
MAL配置 不需要 必须配置 dmmal.ini
客户端路由 手动指定或依赖IP漂移 通过 dm_svc.conf 自动分流
备库状态 通常为 MOUNT 必须为 OPEN 才能提供读服务
数据一致性 强一致(同步/半同步) 允许毫秒级延迟(最终一致性)
故障切换 支持手动/自动切换 同样支持,切换后需更新路由

4.2 关键技术差异详解

归档模式差异:读写分离集群与主备集群最核心的区别在于归档模式的设置。主备集群通常采用 REALTIME(实时归档),日志在写入联机日志文件之前发送给备库;读写分离集群采用 TIMELY(即时归档),日志在写入联机日志文件之后发送给备库。

客户端分流差异:读写分离集群中,应用通过服务名连接集群,客户端接口先连接主库,主库根据归档配置返回可用备库信息,客户端接口建立备库影子连接,只读事务在备库执行,写事务转回主库执行。

一致性处理差异:读写分离集群存在“写后读”不一致的风险。达梦通过 ARCH_WAIT_APPLY 参数控制:设为1(事务一致模式)时主库等待备库确认重演完成后才提交;设为0(高性能模式,默认)时主库不等待备库重演。

五、常见问题与排查

5.1 启动守护进程时报错“Dmwatcher is active”

现象:执行 SP_SET_OGUIDALTER DATABASE 时报错 [-720]:Dmwatcher is active

原因ALTER_MODE_STATUS 是静态参数,修改后必须重启实例才能生效。

解决方法

  1. 停止主备库实例(Ctrl+C)。
  2. 将主备库 dm.iniALTER_MODE_STATUS 临时改为 1
  3. 重新以mount启动,执行设置命令。
  4. 设置完成后停止实例,改回 ALTER_MODE_STATUS=0,重启。

5.2 备库守护进程报错“not configured REALTIME or TIMELY archive”

现象Dmwatcher is GLOBAL type, but has not configured REALTIME or TIMELY archive in dmarch.ini

解决方法:在备库 dmarch.ini 中添加 TIMELY 归档指向主库(参考2.2步骤7)。

5.3 备库处于MOUNT状态无法查询

现象:备库查询报错 System in mount status

解决方法:启动备库守护进程后,守护进程会自动将备库切换为 OPEN 状态。或在监视器中执行 open standby GRP1.GRP1_RT_02

六、总结

本文完整记录了达梦DM8两节点读写分离集群的搭建过程:

  1. 部署集群:配置主备库的 dm.inidmmal.inidmarch.inidmwatcher.ini,启动集群并验证数据同步。
  2. 配置分发比例:通过 dm_svc.conf 配置 RWSEPARATE_PERCENT 参数控制读写分流比例。
  3. 理解差异:从归档模式、客户端路由、一致性处理等维度理解读写分离与主备集群的本质区别。

读写分离集群是在数据守护基础上进一步利用备库资源:主库承担写操作,备库承担部分只读操作。它最适合“读多写少”的业务场景,能在保障高可用的同时显著提升系统吞吐量。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服