首页 > 数据库 > 国内数据库 > 达梦DM9自治容灾集群DMAFC安装与测试
自治容灾集群(DM Autonomous Failover Cluster),简称DMAFC。
DMAFC是一套基于Raft一致性协议构建的高可用数据库解决方案,专门为满足两地三中心、高并发、高可靠等业务场景而设计。
主打自动化的主库选举、故障检测与恢复机制,消除单点故障风险,确保数据零丢失与业务连续性。无论是金融交易系统、实时数据分析平台,还是需要强一致性保障的物联网应用,它都能提供7x24小时不间断稳定服务。
简单来说,DMAFC把分布式数据库里那套成熟的“自动选举”机制,搬到了集中式数据库的容灾里。
上述描述的参考链接:
https://mp.weixin.qq.com/s/LbRWv_nvsnnVBoJG0U8krg


操作系统:

3个节点,分别安装DM9,注意实例名不同
跳过创建用户、目录 …等操作,和DM8没什么区别。
本次采用图形化安装,主要想看看DM9的图形界面有哪些优化:

图形化安装完DM9以后,自动启动达梦实例和DMAP服务,脱机备份前需要先关闭实例,3个节点,依次执行:
shutdown immediate;
节点1:脱机备份
dmrman CTLSTMT="BACKUP DATABASE '/dm9/data/CJC/dm.ini' FULL TO BACKUP_FILE1 BACKUPSET '/dm9/bak/tmp/BACKUP_FILE_01'"

备份文件通过scp工具上传到节点2、节点3:
节点2,节点3:执行恢复
dmrman CTLSTMT="restore database '/dm9/data/CJC/dm.ini' from backupset '/dm9/bak/tmp/BACKUP_FILE_01'" dmrman CTLSTMT="recover database '/dm9/data/CJC/dm.ini' from backupset '/dm9/bak/tmp/BACKUP_FILE_01'" dmrman CTLSTMT="recover database '/dm9/data/CJC/dm.ini' update DB_MAGIC "

3个节点分别修改dm.ini配置文件:
[dmdba@cjc-db-19 ~]$ vi /dm9/data/CJC/dm.ini ARCH_INI = 1 ALTER_MODE_STATUS = 0
节点1:
[root@cjc-db-19 ~]# cat /dm9/data/CJC/dmarch.ini XMAL_HB_INTERVAL = 5 RAFT_HB_INTERVAL = 150 RAFT_VOTE_INTERVAL = 3000 XMAL_IP = 192.168.244.159 XMAL_PORT = 61101 RAFT_SELF_ID = 1 [ARCHIVE_RAFT1] ARCH_TYPE = RAFT ARCH_DEST = CJC01 ARCH_DEST_IP = 192.168.244.158 ARCH_DEST_PORT = 61101 ARCH_DEST_ID = 2 [ARCHIVE_RAFT2] ARCH_TYPE = RAFT ARCH_DEST = CJC02 ARCH_DEST_IP = 192.168.244.170 ARCH_DEST_PORT = 61101 ARCH_DEST_ID = 3 [ARCHIVE_LOCAL] ARCH_TYPE = LOCAL ARCH_DEST = /dm9/arch ARCH_FILE_SIZE = 64 ARCH_SPACE_LIMIT = 0

节点2:
[root@cjc-db-18 ~]# cat /dm9/data/CJC/dmarch.ini XMAL_HB_INTERVAL = 5 RAFT_HB_INTERVAL = 150 RAFT_VOTE_INTERVAL = 4000 XMAL_IP = 192.168.244.158 XMAL_PORT = 61101 RAFT_SELF_ID = 2 [ARCHIVE_RAFT1] ARCH_TYPE = RAFT ARCH_DEST = CJC ARCH_DEST_IP = 192.168.244.159 ARCH_DEST_PORT = 61101 ARCH_DEST_ID = 1 [ARCHIVE_RAFT2] ARCH_TYPE = RAFT ARCH_DEST = CJC02 ARCH_DEST_IP = 192.168.244.170 ARCH_DEST_PORT = 61101 ARCH_DEST_ID = 3 [ARCHIVE_LOCAL] ARCH_TYPE = LOCAL ARCH_DEST = /dm9/arch ARCH_FILE_SIZE = 64 ARCH_SPACE_LIMIT = 0

节点3:
[root@cjc-db-20 ~]# cat /dm9/data/CJC/dmarch.ini XMAL_HB_INTERVAL = 5 RAFT_HB_INTERVAL = 150 RAFT_VOTE_INTERVAL = 5000 XMAL_IP = 192.168.244.170 XMAL_PORT = 61101 RAFT_SELF_ID = 3 [ARCHIVE_RAFT1] ARCH_TYPE = RAFT ARCH_DEST = CJC ARCH_DEST_IP = 192.168.244.159 ARCH_DEST_PORT = 61101 ARCH_DEST_ID = 1 [ARCHIVE_RAFT2] ARCH_TYPE = RAFT ARCH_DEST = CJC01 ARCH_DEST_IP = 192.168.244.158 ARCH_DEST_PORT = 61101 ARCH_DEST_ID = 2 [ARCHIVE_LOCAL] ARCH_TYPE = LOCAL ARCH_DEST = /dm9/arch ARCH_FILE_SIZE = 64 ARCH_SPACE_LIMIT = 0

3个节点分别启动数据库,启动到mount:
[dmdba@cjc-db-19 ~]$ dmserver /dm9/data/CJC/dm.ini mount [dmdba@cjc-db-18 ~]$ dmserver /dm9/data/CJC/dm.ini mount [dmdba@cjc-db-20 ~]$ dmserver /dm9/data/CJC/dm.ini mount
节点1是 PRIMARY ,节点2、节点3 是STANDBY 。
SQL> SELECT INSTANCE_NAME, RAFT_STAT, SYS_MODE, SYS_STATUS FROM V$GLOBAL_RAFT_INFO; 行号 INSTANCE_NAME RAFT_STAT SYS_MODE SYS_STATUS ---------- ------------- --------- -------- ---------- 1 CJC LEADER PRIMARY OPEN 2 CJC01 FOLLOWER STANDBY OPEN 3 CJC02 FOLLOWER STANDBY OPEN 已用时间: 4.795(毫秒). 执行号:601.

select * from V$RAFT_SWITCH_INFO;

select * from V$GLOBAL_RAFT_INSTANCE;


节点1:新增数据
SQL> create table cjc.t3(id int); 操作已执行 已用时间: 13.848(毫秒). 执行号:905. SQL> SQL> insert into cjc.t3 values(1); 影响行数 1 已用时间: 2.032(毫秒). 执行号:906. SQL> commit; 操作已执行 已用时间: 3.774(毫秒). 执行号:907.
节点2、节点3:只读库,数据正常同步
SQL> create table t1(id int); create table t1(id int); [-710]:试图在STANDBY模式下,修改用户库. 已用时间: 1.487(毫秒). 执行号:0. SQL> select * from cjc.t3; 行号 id ---------- ----------- 1 1 已用时间: 2.076(毫秒). 执行号:1.
关闭主库
shutdown immediate

节点2:自动变成主库
SQL> SELECT INSTANCE_NAME, RAFT_STAT, SYS_MODE, SYS_STATUS FROM V$GLOBAL_RAFT_INFO; 行号 INSTANCE_NAME RAFT_STAT SYS_MODE SYS_STATUS ---------- ------------- --------- -------- ---------- 1 CJC01 LEADER PRIMARY OPEN 2 CJC02 FOLLOWER STANDBY OPEN 已用时间: 4.585(毫秒). 执行号:801.

新主库,插入数据

启动节点1数据库,变成STANDBY自动加入集群,数据自动同步

关闭所有STANDBY节点,主无法写入数据

Ctrl+c 后,再次执行

对应切换日志如下:
2026-08-24 20:17:35.753 [INFO] database P0000027760 T0000000000000027893 rraft_elect_schedule_thread follower elect_start! 2026-08-24 20:17:35.753 [INFO] database P0000027760 T0000000000000027893 [rraft] l_term_id: 6 -> 7. 2026-08-24 20:17:35.754 [INFO] database P0000027760 T0000000000000027893 [rraft] raft_stat: FOLLOWER -> CANDIDATE. 2026-08-24 20:17:35.754 [INFO] database P0000027760 T0000000000000027893 rraft election-start[self elect timeout] term[6->7] state[FOLLOWER->CANDIDATE] leader[CJC->UNKNOWN]. 2026-08-24 20:17:38.757 [INFO] database P0000027760 T0000000000000029607 [rraft] l_term_id: 7 -> 8. 2026-08-24 20:17:38.757 [INFO] database P0000027760 T0000000000000029607 [rraft] raft_stat: CANDIDATE -> FOLLOWER. 2026-08-24 20:17:38.757 [INFO] database P0000027760 T0000000000000029607 [rraft] [vote] received g_seq is larger, received[log_term:6, g_seq:3397, c_seq:3396], self[log_term:6, g_seq:3397, c_seq:3396] 2026-08-24 20:17:38.757 [INFO] database P0000027760 T0000000000000029607 rraft recv vote request from[CJC01], state-changed[new term elect req] term[7->8] state[CANDIDATE->FOLLOWER] leader[UNKNOWN], vote_granted[1]. 2026-08-24 20:17:38.757 [INFO] database P0000027760 T0000000000000029607 [rraft] [send] node[id: 2] vote res, term: 8, voted: 1. 2026-08-24 20:17:38.759 [INFO] database P0000027760 T0000000000000029607 rraft recv hb from[CJC01], election-end[leader elected] term[8] state[FOLLOWER] leader[UNKNOWN->CJC01]. 2026-08-24 20:17:38.838 [INFO] database P0000027760 T0000000000000027832 rafil_close_with_trunc file[/dm9/arch/STANDBY_ARCHIVE_0x4F294787_EP0_0xEE2F95F_2026-08-24_17-05-27.log] to 262144 len, g_next_seq:3397, ret = 1! 2026-08-24 20:17:38.838 [INFO] database P0000027760 T0000000000000027832 rfil_close_low set arch rfil[/dm9/arch/STANDBY_ARCHIVE_0x4F294787_EP0_0xEE2F95F_2026-08-24_17-05-27.log]'s sta to inactive, l_next_seq = 3397, g_next_seq = 3397, clsn = 53697, handle = 47, free=262144, len=262144 2026-08-24 20:17:38.838 [INFO] database P0000027760 T0000000000000027832 rafil_file_create [/dm9/arch/STANDBY_ARCHIVE_0x390358F9_EP0_0xEE2F95F_2026-08-24_17-17-38.log] start 2026-08-24 20:17:38.839 [INFO] database P0000027760 T0000000000000027832 rfil_close_low set arch rfil[/dm9/arch/STANDBY_ARCHIVE_0x390358F9_EP0_0xEE2F95F_2026-08-24_17-17-38.log]'s sta to inactive, l_next_seq = 2457, g_next_seq = 2457, clsn = 0, handle = 47, free=4096, len=67108864 2026-08-24 20:17:38.840 [INFO] database P0000027760 T0000000000000027832 rafil_file_create [/dm9/arch/STANDBY_ARCHIVE_0x390358F9_EP0_0xEE2F95F_2026-08-24_17-17-38.log] success, handle = 47 2026-08-24 20:17:38.840 [INFO] database P0000027760 T0000000000000027832 rafil_switch_if_necessary, rafil_new_arch_file, rafil create new arch file [/dm9/arch/STANDBY_ARCHIVE_0x390358F9_EP0_0xEE2F95F_2026-08-24_17-17-38.log] success 2026-08-24 20:17:38.840 [INFO] database P0000027760 T0000000000000027847 rlog4_apply_db_magic_set, set apply_info_lsn[53397->53697] 2026-08-24 20:17:38.840 [INFO] database P0000027760 T0000000000000027847 rlog4_apply_db_magic_set, set p_db_magic[1328105351->956520697], n_apply_ep[1->1] 2026-08-24 20:17:38.856 [INFO] database P0000027760 T0000000000000029607 rraft_process_ini_sync_primary success, set msg_ini_version to 671323118 2026-08-24 20:18:07.044 [INFO] database P0000027760 T0000000000000027789 rraft_set_arch_chg_info, set rraft_sys.arch_chg_flag TRUE, arch_chg_stat 0 to 9. 2026-08-24 20:18:07.046 [INFO] database P0000027760 T0000000000000027789 rraft_reset_arch_chg_info success.
切换期间,通过查看节点3的日志,可以看到,切换过程大概如下:
1.选举触发
本节点原为 Follower,Leader 是 CJC。
20:17:35 发生选举超时(elect timeout),说明在规定时间内未收到原 Leader 的心跳,判断 Leader 可能故障或网络隔离。
节点提升任期(term 6→7),状态转为 Candidate,发起选举。
2.快速退让并投票
仅 3 秒后,节点收到来自 CJC01 的投票请求,且对方任期更高(term=8)。
Raft 协议要求 Candidate 若收到更高任期的投票请求,必须立即退让,转为 Follower 并投票。
本节点正确执行了该逻辑:状态 CANDIDATE→FOLLOWER,vote_granted=1。
3.新 Leader 确认
随后收到 CJC01 的心跳,确认 CJC01 当选为新 Leader。
本节点 Leader 从 UNKNOWN 变为 CJC01,选举结束,集群恢复有主状态。
4.数据同步与归档切换
节点开始接收新 Leader 的日志:
关闭旧归档文件并截断至安全长度(262144 字节)。
创建新归档文件 STANDBY_ARCHIVE_…_17-17-38.log。
apply_info_lsn 前进(53397→53697),说明日志已应用到新位置。
db_magic 值变化,表示数据库内部状态/角色信息已更新。
这些操作表明本节点作为 Follower 正在追赶新主的数据,确保数据一致性。
5.初始同步完成
rraft_process_ini_sync_primary success 表明备库已完成与新主库的初始同步,可以正常提供只读服务或继续作为备库运行。
6.归档变更处理
20:18:07 设置 arch_chg_flag,随后重置成功。
这通常用于切换后更新归档配置、清理旧归档信息,确保后续日志归档正确。
1.仅供参考
达梦官方技术文档里没有找到DMAFC自治容灾集群的相关内容,部署部分参考了鲲鹏昇腾开发者社区-三节点AFC集群搭建操作指南,全文仅供参考,如有疑问,请咨询达梦原厂工程师;
2.和达梦数据守护集群DMDataWatch的区别
DMAFC的安装配置比DMDataWatch简单很多,没有守护进程(dmwatcher)、监视器(dmmonitor)、MAL组件等,为容灾、高可用场景新增了一种不错的解决方案。
DMDataWatch:

DMAFC:

《DM9,打出一张容灾王 牌》 https://mp.weixin.qq.com/s/LbRWv_nvsnnVBoJG0U8krg 《三节点AFC集群搭建操作指南》 https://hwcomputing.csdn.net/6a7ae96010ee7a33f2996f13.html 《DM8 数据守护与读写分离集群》 https://eco.dameng.com/document/dm/zh-cn/pm/data-watch-overview.html
#达梦数据库 #达梦同行者征文
欢迎关注我的公众号《 IT小Chen》
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29785807/viewspace-3182997/ ,如需转载,请注明出处,否则将追究法律责任。