注册
DM8 读写分离集群搭建
技术分享/ 文章详情 /

DM8 读写分离集群搭建

xixi 2026/07/31 249 0 0

1 概述

本文档基于 CentOS 7 操作系统和达梦数据库 DM8 V8(20260707)版本,搭建一套由一个主库和一个备库组成的 DM8 数据守护(DataWatch)+ 读写分离集群。其中,数据守护负责实现主备数据库之间的实时数据同步、故障监测以及主备切换,为数据库提供高可用保障;读写分离则在数据守护的基础上,将写请求统一发送至主库执行,读请求根据配置策略自动分发至备库执行,从而降低主库压力,提高数据库整体的并发处理能力和资源利用率。

本实验采用两台 KVM 虚拟机分别部署主库和备库,通过配置数据库归档、MAL 通信、Watcher、Monitor 等组件,完成数据守护环境的搭建,并在此基础上配置客户端服务文件 dm_svc.conf,开启读写分离功能。实验过程中对主备实时同步、读请求转发、SQL 日志验证、事务统计验证以及客户端连接验证等功能进行测试,验证读写分离配置是否生效,并确保数据库系统在保证数据一致性的同时,实现读写请求分离处理,提高系统的可用性、可靠性及访问性能。

2 操作环境

组件 规格/版本
虚拟化平台 KVM(Kernel-based Virtual Machine)
操作系统 CentOS Linux 7 x86_64
CPU Intel® Xeon® 6966P-C(KVM虚拟CPU)
内存 50GB
磁盘 50GB
数据库版本 DM8 V8(20260707)

3 搭建读写分离集群前准备

3.1 创建虚拟机

3.1.1 检查 KVM 嵌套虚拟化功能是否开启

# 检查嵌套虚拟化状态 cat /sys/module/kvm_intel/parameters/nested
  • 输出 N0:未开启
  • 输出 Y1:已开启
# 验证 CPU 是否支持硬件虚拟化扩展 grep -E '(vmx|svm)' /proc/cpuinfo
  • 有输出(显示 vmx):支持 Intel 虚拟化技术 (VT-x)
# 临时开启嵌套虚拟化功能 modprobe -r kvm_intel modprobe kvm_intel nested=1 # 永久开启 echo 'options kvm_intel nested=1' >> /etc/modprobe.d/kvm.conf

3.1.2 安装 KVM 及相关组件

# 安装软件包 yum install -y qemu-kvm libvirt virt-install virt-manager libvirt-client bridge-utils

各组件说明:

  • qemu-kvm:KVM 的核心用户空间组件,负责模拟 CPU、内存、磁盘等设备
  • libvirt:虚拟化 API 守护进程,提供统一接口管理不同虚拟化技术
  • virt-install:命令行工具,用于创建和安装新的虚拟机
  • bridge-utils:网络桥接工具,用于配置 Linux 网桥
  • virt-manager:图形化虚拟机管理工具(GUI)
  • libvirt-client:包含客户端库和命令行工具 virsh
# 启动并设置开机自启 libvirtd 服务 systemctl start libvirtd systemctl enable libvirtd # 检查内核模块是否加载 lsmod | grep kvm

输出应包含 kvm_intelkvm,说明环境就绪。

3.1.3 准备存储池与镜像

# 创建存储目录 mkdir -p /var/lib/libvirt/images/iso mkdir -p /var/lib/libvirt/images/vms

从宿主机传输 CentOS 镜像:

# 方法1:sftp 传输 sftp -P 5215 root@10.36.41.11 cd /var/lib/libvirt/images/iso/ put C:/study/06-iso/CentOS-7-x86_64-DVD-1804.iso # 方法2:scp 传输 scp -P 5253 C:/study/06-iso/CentOS-7-x86_64-DVD-1804.iso root@10.36.41.11:/var/lib/libvirt/images/iso/

3.1.4 创建第一台虚拟机(dm-node1)

sudo virt-install \ --name dm-node1 \ --ram 4096 \ --vcpus 2 \ --disk path=/var/lib/libvirt/images/vms/dm-node1.qcow2,size=30,format=qcow2 \ --location /var/lib/libvirt/images/iso/CentOS-7-x86_64-DVD-1804.iso \ --network network=default \ --graphics none \ --os-type linux \ --os-variant centos7.0 \ --console pty,target_type=serial \ --extra-args 'console=ttyS0,115200n8 serial'

安装步骤:

  1. 设置语言:选择 EnglishUnited States
  2. 设置时区:AsiaShanghai
  3. 配置软件选择:选择 Minimal Install
  4. 设置磁盘:选择自动分区,使用 LVM
  5. 配置网络:启用 eth0,设置自动连接
  6. 配置主机名:dm-node1
  7. 设置 root 密码
  8. 开始安装,完成后重启
# 查看 IP 地址 ip addr show # 关闭防火墙(两台虚拟机都需要) sudo systemctl stop firewalld sudo systemctl disable firewalld

3.1.5 创建第二台虚拟机(dm-node2)

sudo virt-install \ --name dm-node2 \ --ram 4096 \ --vcpus 2 \ --disk path=/var/lib/libvirt/images/vms/dm-node2.qcow2,size=30,format=qcow2 \ --location /var/lib/libvirt/images/iso/CentOS-7-x86_64-DVD-1804.iso \ --network network=default \ --graphics none \ --os-type linux \ --os-variant centos7.0 \ --console pty,target_type=serial \ --extra-args 'console=ttyS0,115200n8 serial'

3.1.6 从宿主机连接虚拟机

# 连接 dm-node1 ssh root@192.168.122.67 # 连接 dm-node2 ssh root@192.168.122.139

3.2 安装达梦数据库

3.2.1 上传安装包

在宿主机上执行:

# 检查连通性 ping 192.168.122.67 # 传输 DM8 安装包到 dm-node1 scp /mnt/nas/dm8_20260710_x86_centos7_64.iso root@192.168.122.67:/opt/

3.2.2 数据库安装前准备

参照《达梦数据库 DM8 在 Kylin V10 SP3 上的安装部署手册》的步骤,在两台机器上都创建监控器日志保存目录:

mkdir -p /dmdata/log chown -R dmdba:dinstall /dmdata/log chmod -R 755 /dmdata/log

3.2.3 安装数据库

按照《达梦数据库 DM8 在 Kylin V10 SP3 上的安装部署手册》中的步骤进行安装。

重要提示:安装完成后需要启动 DMAP 服务,否则会影响后续的数据库备份:

cd /home/dmdba/dmdbms/bin ./DmAPService start
3.2.3.1 dm-node1(主库)实例初始化
# 实例初始化 ./dminit path=/dmdata/data INSTANCE_NAME=DMSERVER01 DB_NAME=DMDBA PORT_NUM=5234 PAGE_SIZE=32 EXTENT_SIZE=32 CASE_SENSITIVE=y CHARSET=1 LOG_SIZE=2048 SYSDBA_PWD=Dmdba123 SYSAUDITOR_PWD=Dmdba123 # 注册服务 ./dm_service_installer.sh -t dmserver -dm_ini /dmdata/data/DMDBA/dm.ini -p DMSERVER01 # 拍摄快照 virsh snapshot-create-as dm-node1 snap_dm_installed --description "进行数据守护集群搭建前" virsh snapshot-list dm-node1 # 停止服务 systemctl stop DmServiceDMSERVER01
3.2.3.2 dm-node2(备库)实例初始化
# 实例初始化(仅为了生成配置文件和目录) ./dminit path=/dmdata/data INSTANCE_NAME=DMSERVER02 DB_NAME=DMDBA PORT_NUM=5234 PAGE_SIZE=32 EXTENT_SIZE=32 CASE_SENSITIVE=y CHARSET=1 LOG_SIZE=2048 SYSDBA_PWD=Dmdba123 SYSAUDITOR_PWD=Dmdba123 # 注册服务 ./dm_service_installer.sh -t dmserver -dm_ini /dmdata/data/DMDBA/dm.ini -p DMSERVER02 # 拍摄快照 virsh snapshot-create-as dm-node2 snap_before_dm_protect --description "进行数据守护集群搭建前" # 停止服务 systemctl stop DmServiceDMSERVER02

4 搭建读写分离集群

4.1 规划端口

参数 dm-node1 (主) dm-node2 (备)
IP 192.168.122.67 192.168.122.139
实例端口 (PORT_NUM) 5234 5234
MAL 监听端口 (MAL_PORT) 5235 5235
守护进程端口 (MAL_DW_PORT) 5236 5236
实例监听守护进程 TCP 连接的端口 (MAL_INST_DW_PORT) 5237 5237
OGUID 45331 45331

4.2 dm-node1(主库)配置

4.2.1 修改 dm.ini

vi /dmdata/data/DMDBA/dm.ini

修改以下参数:

INSTANCE_NAME = DMSERVER01
PORT_NUM = 5234                    # 数据库实例监听端口
DW_INACTIVE_INTERVAL = 60          # 接收守护进程消息超时时间
ALTER_MODE_STATUS = 0              # 不允许手工方式修改实例模式/状态/OGUID
ENABLE_OFFLINE_TS = 2              # 不允许备库 OFFLINE 表空间
MAL_INI = 1                        # 打开 MAL 系统
ARCH_INI = 1                       # 打开归档配置
RLOG_SEND_APPLY_MON = 64           # 统计最近 64 次的日志发送信息

4.2.2 修改 dmmal.ini

vi /dmdata/data/DMDBA/dmmal.ini

配置内容:

MAL_CHECK_INTERVAL = 5 MAL_CONN_FAIL_INTERVAL = 5 [MAL_INST1] MAL_INST_NAME = DMSERVER01 MAL_HOST = 192.168.122.67 MAL_PORT = 5235 MAL_INST_HOST = 192.168.122.67 MAL_INST_PORT = 5234 MAL_DW_PORT = 5236 MAL_INST_DW_PORT = 5237 [MAL_INST2] MAL_INST_NAME = DMSERVER02 MAL_HOST = 192.168.122.139 MAL_PORT = 5235 MAL_INST_HOST = 192.168.122.139 MAL_INST_PORT = 5234 MAL_DW_PORT = 5236 MAL_INST_DW_PORT = 5237

4.2.3 修改 dmarch.ini

vi /dmdata/data/DMDBA/dmarch.ini

配置内容:

[ARCHIVE_TIMELY] ARCH_TYPE = TIMELY ARCH_DEST = DMSERVER02 # 指向备库实例名 ARCH_WAIT_APPLY = 0 [ARCHIVE_LOCAL1] ARCH_TYPE = LOCAL ARCH_DEST = /dmdata/arch ARCH_FILE_SIZE = 128 ARCH_SPACE_LIMIT = 0

4.2.4 启动主库并开启归档

# 启动数据库 ./DmServiceDMSERVER01 start # 连接数据库 ./disql SYSDBA/Dmdba123@localhost:5234 # 查看归档状态 SELECT * FROM V$ARCH_STATUS;

4.2.5 主库全备

# 执行完全备份 BACKUP DATABASE FULL BACKUPSET '/dmdata/dmbak/db_full_bak_01'; # 查看备份结果 ls -lh /dmdata/dmbak/db_full_bak_01 # 复制备份到备库 scp -r /dmdata/dmbak/db_full_bak_01 dmdba@192.168.122.139:/dmdata/dmbak/

4.3 dm-node2(备库)配置

4.3.1 确认无 DMSERVER02 进程

ps -ef | grep dmserver

4.3.2 校验备份集

cd /home/dmdba/dmdbms/bin ./dmrman CTLSTMT="CHECK BACKUPSET '/dmdata/dmbak/db_full_bak_01';"

4.3.3 执行数据库还原

./dmrman CTLSTMT="RESTORE DATABASE '/dmdata/data/DMDBA/dm.ini' FROM BACKUPSET '/dmdata/dmbak/db_full_bak_01';"

4.3.4 执行数据库恢复

./dmrman CTLSTMT="RECOVER DATABASE '/dmdata/data/DMDBA/dm.ini' FOR STANDBY FROM BACKUPSET '/dmdata/dmbak/db_full_bak_01';"

4.3.5 更新 DB_MAGIC

4.3.6 修改备库配置

# 修改 dm.ini(只需修改实例名) vi /dmdata/data/DMDBA/dm.ini # INSTANCE_NAME = DMSERVER02 # 修改 dmmal.ini(与主库一致) vi /dmdata/data/DMDBA/dmmal.ini # 修改 dmarch.ini(只需修改归档目标) vi /dmdata/data/DMDBA/dmarch.ini # ARCH_DEST = DMSERVER01 # 指向主库实例名

4.4 修改主备角色

4.4.1 主库配置

# 停止数据库后以 MOUNT 状态启动 ./dmserver /dmdata/data/DMDBA/dm.ini mount

新开终端窗口,登录数据库执行:

-- 允许修改模式状态 SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1); -- 修改数据库模式为主库 ALTER DATABASE PRIMARY; -- 设置 OGUID(需与 dmwatcher.ini 中一致) SP_SET_OGUID(45331); -- 恢复模式状态保护 SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);

4.4.2 备库配置

同样以 MOUNT 状态启动:

./dmserver /dmdata/data/DMDBA/dm.ini mount

登录数据库执行:

-- 允许修改模式状态 SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1); -- 修改数据库模式为备库 ALTER DATABASE STANDBY; -- 设置 OGUID SP_SET_OGUID(45331); -- 恢复模式状态保护 SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);

配置结束后关闭 MOUNT 前台进程。

4.5 配置 Watcher

4.5.1 创建 dmwatcher.ini

两台机器都创建:

vi /dmdata/data/DMDBA/dmwatcher.ini

配置内容:

[GRP1] DW_TYPE = GLOBAL DW_MODE = AUTO DW_ERROR_TIME = 10 INST_RECOVER_TIME = 60 INST_ERROR_TIME = 10 INST_OGUID = 45331 INST_INI = /dmdata/data/DMDBA/dm.ini INST_AUTO_RESTART = 1 INST_STARTUP_CMD=/home/dmdba/dmdbms/bin/DmServiceDMSERVER01 start RLOG_SEND_THRESHOLD = 0 RLOG_APPLY_THRESHOLD = 0

注意:dm-node2 中的 INST_STARTUP_CMD 需要修改为:

INST_STARTUP_CMD=/home/dmdba/dmdbms/bin/DmServiceDMSERVER02 start

4.5.2 注册 Watcher 服务

以 root 用户执行:

cd /home/dmdba/dmdbms/script/root # 在 dm-node1 注册 ./dm_service_installer.sh -t dmwatcher -watcher_ini /dmdata/data/DMDBA/dmwatcher.ini -p DMSERVER01_WATCHER # 在 dm-node2 注册 ./dm_service_installer.sh -t dmwatcher -watcher_ini /dmdata/data/DMDBA/dmwatcher.ini -p DMSERVER02_WATCHER # 查看服务是否注册成功 systemctl list-unit-files | grep WATCHER

4.6 配置 Monitor

监视器可以部署在任意一台节点上,或者单独的第三台机器。这里部署在 dm-node1 上。

vi /dmdata/data/DMDBA/dmmonitor.ini

配置内容:

MON_DW_CONFIRM = 1 MON_LOG_PATH = /dmdata/log MON_LOG_INTERVAL = 60 MON_LOG_FILE_SIZE = 32 MON_LOG_SPACE_LIMIT = 0 [GRP1] MON_INST_OGUID = 45331 MON_DW_IP = 192.168.122.67:5236 MON_DW_IP = 192.168.122.139:5236

4.7 启动集群

在 DM8 数据守护(DataWatch)中,启动顺序非常重要:先启动数据库实例,再启动 Watcher,最后启动 Monitor

4.7.1 启动主库(dm-node1)

# 启动数据库实例 systemctl start DmServiceDMSERVER01 # 检查服务状态 systemctl status DmServiceDMSERVER01

4.7.2 启动备库(dm-node2)

# 启动数据库实例 systemctl start DmServiceDMSERVER02 # 检查服务状态 systemctl status DmServiceDMSERVER02

4.7.3 启动 Watcher

注意:如果角色没有正确设置,不要启动 Watcher。因为 Watcher 启动后会认为数据库状态异常。

# 在 dm-node1 启动 Watcher systemctl start DmWatcherServiceDMSERVER01_WATCHER # 在 dm-node2 启动 Watcher systemctl start DmWatcherServiceDMSERVER02_WATCHER # 检查 Watcher 状态 systemctl status DmWatcherServiceDMSERVER01_WATCHER systemctl status DmWatcherServiceDMSERVER02_WATCHER

4.7.4 启动 Monitor(只在 dm-node1)

# 切换到 dmdba 用户 su - dmdba # 启动 Monitor cd /home/dmdba/dmdbms/bin ./dmmonitor /dmdata/data/DMDBA/dmmonitor.ini

进入 Monitor 控制台后,可以查看集群状态:

-- 查看集群状态 show;

image.png

正常输出应显示两个实例均为 OPEN 状态,且主备关系正确。

4.8 创建读写分离配置

# 切换到 root 用户 su - root # 编辑配置文件 vi /etc/dm_svc.conf

添加以下配置内容:

# 定义服务名,指向主库和备库 RWW_SVC=(192.168.122.67:5234,192.168.122.139:5234) # 全局设置(可选) TIME_ZONE=(480) LANGUAGE=(CN) # 读写分离专用配置 [RWW_SVC] RW_SEPARATE=(1) # 启用读写分离 RW_PERCENT=(0) # 主库承担 0% 的读事务 LOGIN_MODE=(1) # 优先连接主库 SWITCH_TIMES=(60) SWITCH_INTERVAL=(1000)

保存退出(:wq),并确保 dmdba 用户可读:

chmod 644 /etc/dm_svc.conf

5 验证读写分离

5.1 查看备库 SQL 日志

方法的原理是:读写分离生效时,备库会收到从主库转发来的查询请求,并记录在自身的 SQL 日志中。

5.1.1 备库节点(dm-node2)配置

# 切换到 dmdba 用户 su - dmdba # 连接备库 cd /home/dmdba/dmdbms/bin ./disql SYSDBA/Dmdba123@localhost:5234

在 SQL 命令行中执行:

-- 开启 SQL 日志 SP_SET_PARA_VALUE(1, 'SVR_LOG', 1); -- 查看日志参数是否生效 SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME='SVR_LOG';

image.png

5.1.2 主库节点(dm-node1)操作

# 切换到 dmdba 用户 su - dmdba # 连接主库 cd /home/dmdba/dmdbms/bin ./disql SYSDBA/Dmdba123@localhost:5234

在 SQL 命令行中执行:

-- 在主库上创建表(写操作会在主库执行) CREATE TABLE TEST_RW(ID INT, NAME VARCHAR(50)); INSERT INTO TEST_RW VALUES(1, '主库写入'); COMMIT; -- 查询操作会根据 RW_PERCENT 决定是否发往备库 SELECT * FROM TEST_RW;

5.1.3 查看备库 SQL 日志

在备库节点(dm-node2)上查看 SQL 日志:

# 查看最新的 SQL 日志文件 ls -lt /home/dmdba/dmdbms/log/dmsql_*.log | head -1 # 实时查看日志(替换为实际文件名) tail -f /home/dmdba/dmdbms/log/dmsql_DMSERVER02_20260715_131657.log

image.png
如果读写分离配置生效,应该能看到类似以下内容:

2026-07-15 13:16:57.123 [INFO] SELECT * FROM TEST_RW;
客户端 IP: ::ffff:192.168.122.67

这表明查询是通过读写分离机制从主库自动转发到备库执行的,而非手动连接备库执行。

5.2 计算备库上处理的事务数

5.2.1 查看主库上的会话数

# 连接主库(直连或服务名均可) ./disql SYSDBA/Dmdba123@192.168.122.67:5234 # 查询当前总会话数 select * from v$sysstat where name like 'transaction commit count' or name like 'transaction rollback count';

5.2.2 查看备库上的会话数

# 连接备库 ./disql SYSDBA/Dmdba123@192.168.122.139:5234 # 查询当前总会话数 SELECT COUNT(*) FROM V$SESSIONS;

image.png
只要读写分离生效,主库和备库上都会同时存在同一个客户端的连接会话。

5.2.3 查看备库事务统计

# 连接备库 ./disql SYSDBA/Dmdba123@192.168.122.139:5234 # 查看事务统计信息 SELECT * FROM V$SYSSTAT WHERE NAME LIKE 'transaction commit count' OR NAME LIKE 'transaction rollback count';

主库执行select前:
image.png
主库执行select后:
image.png

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服