本测试旨在验证达梦数据库 MAL 系统在不同网络异常场景下的行为表现。MAL 系统作为集群内部通信的基础,其链路检测机制直接决定了集群的高可用响应速度与稳定性。
根据配置文档说明,MAL 系统通过心跳机制维护链路状态,其核心行为由 dmmal.ini 中的以下两个参数控制:
MAL_CHECK_INTERVAL (检测间隔)
MAL_CONN_FAIL_INTERVAL (断开判定阈值)
MAL_CHECK_INTERVAL 不为 0 时有效。在发起检测后,如果在此设定的时间内无法连通,则认定链路断开。当发生物理断网(如拔除网线)或严重丢包导致网络不可达时,系统检测到链路断开的时间并非立即触发,而是由上述两个参数共同决定。
理论上的链路故障发现时间 T_malbreak 计算逻辑如下:
MAL_CHECK_INTERVAL 才会发起下一次检测。MAL_CONN_FAIL_INTERVAL 耗尽以确认超时。因此,MAL 层面的最大故障认定时间公式为:
T_malbreak = MAL_CHECK_INTERVAL + MAL_CONN_FAIL_INTERVAL 注意: MAL 链路断开并不等于立即执行故障切换。在数据守护环境中,守护进程(dmwatcher)在得知 MAL 链路断开后,还需经过 DW_ERROR_TIME (配置在 dmwatcher.ini 中) 的超时判断,才会最终认定远程节点故障并启动 Failover 流程。
根据您提供的技术资料,现将其整理为规范的总结报告格式,作为 1.3节 的内容:
本节补充当DM检测到MAL链路中断时,底层的发生机制。内容主要是达梦MAL 系统的底层通信协议、故障检测的归责逻辑,以及例举极端网络隔离场景下的系统行为。
MAL(Message Agency Layer)系统是集群内部通信的基础,其底层机制如下:
dmmal.ini 配置文件,在各节点间建立长效的 TCP 连接。MAL_CHECK_INTERVAL 控制),在物理层面上表现为在 TCP 通道上发送探测数据包,并等待对端的 TCP ACK(确认应答)。在链路出现异常时,系统如何判定是“对方故障”还是“自身故障”,取决于检测主体的机制及配置策略。
1. 故障发现主体:
dm_mal_thd),而非守护进程(dmwatcher)或监视器(dmmonitor)。MAL link broken -> 修改内存中的链路状态为 DISCONNECTED -> 守护进程(dmwatcher)轮询到此状态后介入处理。2.故障归责逻辑
系统对链路中断的判定逻辑分为两种情况:
MAL_CHECK_IP)—— “默认对方故障”
MAL_CHECK_IP)—— “自我反省机制”
完全网络隔离(无第三方检测)
前置条件: 实时主备(Realtime) + 故障自动切换模式 + 未配置 MAL_CHECK_IP + 物理断网(主库同时失去与备库、监视器的连接)。
在此场景下,系统不会立即“踢出”备库,而是陷入逻辑死锁(僵死状态),具体推演如下:
1. 归档阻塞与状态保护(dmserver 层)
SUSPEND(挂起) 状态。2. 仲裁请求与逻辑锁死(dmwatcher 层)
CONFIRM(确认) 状态,向确认监视器求证备库是否真的故障。CONFIRM 状态。3. 最终状态僵死(DW_FAILOVER_FORCE = 0):
如果DW_FAILOVER_FORCE = 0,那么主库将不会进行自动恢复。
主库 A:
SUSPEND,守护进程处于 CONFIRM。MAL_CHECK_IP 参数,主库缺乏基于第三方参考点(如网关 Ping 检测)的自检机制。系统无法区分“自身网络隔离”与“对端故障”,因此保留进程存活状态以待网络恢复。备库 B: 若备库网络正常,确认监视器会判定主库 A 失联,将备库 B 提升为新主库。
除了上述针对伙伴节点的检测外,MAL 系统还提供了针对自身网络环境的“主动检测”机制,用于防止因自身网卡假死或交换机故障导致的“脑裂”风险。该机制涉及以下参数:
MAL_CHECK_IP:配置第三方确认机器的 IP(通常为网关或独立外网机器)。MAL_CHECK_TIMEOUT:单个实例的 MAL 网络最大延迟时间。工作机制:
MAL_CHECK_IP。MAL_CHECK_TIMEOUT),系统将判定为自身网络环境故障(而非对方故障)。本节规划了详细的测试环境、参数分组、故障模拟手段及日志观测点,旨在验证 MAL_CHECK_INTERVAL 与 MAL_CONN_FAIL_INTERVAL 在不同网络恶劣条件下的实际表现。
为了对比参数对故障发现时间的影响,设计以下三组对照实验。修改 dmmal.ini 后需重启集群生效。
| 测试组别 | MAL_CHECK_INTERVAL (秒) | MAL_CONN_FAIL_INTERVAL (秒) | 理论故障认定时间 | 预期行为特征 |
|---|---|---|---|---|
| A组 (默认/宽松) | 30 (缺省值) | 10 (缺省值) | ≈ 40秒 | 反应较慢。适合网络质量较差的环境,能容忍较大的网络抖动,但故障发生时业务中断时间较长。 |
| B组 (推荐/标准) | 10 | 10 | ≈ 20秒 | 反应适中。官方搭建文档示例中常用的配置,平衡了灵敏度与稳定性。 |
| C组 (激进/敏捷) | 2 | 2 | ≈ 4秒 | 反应极快。任何轻微的连续丢包都可能导致主备连接断开,极易造成误切换。 |
针对每一组参数,依次执行以下三种网络故障模拟。
场景 1:完全断网 (Network Partition)
目的:验证 MAL 链路在物理中断下的最大故障发现时间。
操作:使用 iptables 丢弃来自对端 IP 的 TCP 包(沉默无回复,模拟拔网线)。
# 在备库机器执行,拦截来自主库(IP为192.168.79.141)的MAL端口(61141)
iptables -I INPUT -s 192.168.79.141 -p tcp --dport 61141 -j DROP
恢复:iptables -F
场景 2:严重丢包 (Packet Loss)
目的:验证 MAL 协议在丢包情况下的重试机制与连接保持能力。
操作:模拟 50% 的随机丢包率。loss 50% 表示每个发送的数据包都会以 独立 50% 随机概率被 drop
验证点: 达梦是否会因为重传耗时太久,误以为连接断开。或者达梦的 MAL_CONN_FAIL_INTERVAL 设置得太短,导致在还没有重传成功之前,就判定对方挂了。
# 在网卡设备(如ens33)上添加规则
tc qdisc add dev ens33 root netem loss 50%
恢复:tc qdisc del dev ens33 root
本测试的核心目标是验证 MAL 参数的实际生效机制。由于故障检测是层层递进的(链路层 -> 守护层 -> 全局视图),我们需要通过多窗口实时监控,捕捉故障传导的精确时间戳。
测试期间需同时开启三个终端窗口进行 tail -f 监控。
**1. 实例日志 (dmserver log) **
../log/dm_实例名_年月.logsend mal msg failed 或 wait mal response timeout。这表明心跳包发送受阻或超时。set link status to DISCONNECT 或 Close mal connection、MAL link broken。
DISCONNECT**2. 守护进程日志 (dmwatcher log) **
DISCONNECT 状态,即启动计时器(DW_ERROR_TIME)并决定是否切换。../log/dm_dmwatcher_实例名_年月.logReceive notify from dmserver, mal link [...] 在·broken。WSTATUS 从 OPEN 切换为 ERROR(表示认定远程节点故障)或 CONFIRM(自动模式下的仲裁请求)。DW_ERROR_TIME(默认 10s-15s)的超时逻辑是否生效。3. 监视器界面 (dmmonitor)
WSTATUS 字段变化,以及是否出现 Switchover success 或 Takeover success 提示。基于 MAL 的通信原理,针对前文设计的三个测试场景,预判日志中将出现的关键信息特征:
场景 1:完全断网 (iptables DROP)
CHECK_INTERVAL)。wait mal response timeout(等待 CONN_FAIL_INTERVAL)。set link status to DISCONNECT。场景 2:严重丢包 (tc loss 50%)
send mal msg failed(发送失败)和 MAL connection recovery(重连成功)。MAL_CONN_FAIL_INTERVAL,则会打印 DISCONNECT。场景 3:高延迟 (tc delay 3000ms)
MAL_CONN_FAIL_INTERVAL = 5s)。wait mal response timeout,因为 6s > 5s。DISCONNECT,判定对方故障。以下是针对 A 组参数 的完整测试步骤(B、C 组只需重复此流程,修改参数即可)。
目标: 将集群配置为测试目标状态(A 组:Check=30s, Fail=10s)。
修改配置文件 (dmmal.ini)
在 主库 和 备库 机器上,分别编辑 dmmal.ini 文件。
修改内容:
vi /dm8/data/DAMENG/dmmal.ini
MAL_CHECK_INTERVAL = 30
MAL_CONN_FAIL_INTERVAL = 10
重启生效
systemctl stop DmMonitorServiceGRP1systemctl stop DmWatcherServiceGRP1systemctl stop DmServiceGRP1_RT_01/DmServiceGRP1_RT_02systemctl start DmWatcherServiceGRP1systemctl start DmMonitorServiceGRP1确认生效
show,确保 WSTATUS 为 OPEN,RSTAT 为 VALID。4.开启监控窗口 (准备 3 个终端) 在执行故障模拟前,先打开日志监控
窗口 1 (备库实例日志): 捕捉 MAL 链路断开
# 实时监控实例日志,只看 MAL 相关的断开/错误信息
tail -f /dm8/log/dm_GRP1_RT_02_202512.log | grep -iE "MAL.*disconnect|link.*broken|free link"
窗口 2 (备库守护进程日志): 捕捉守护进程认定故障的时间
tail -f /dm8/log/dm_dmwatcher_GRP1_RT_02_202512.log | grep -iE "WSTATUS|switch|failover|error"
窗口 3 (备库操作窗口): 用于执行下述故障模拟命令。
iptables)或流量控制(tc),拦截来自主库的数据包。这在逻辑上等同于“主库对备库不可见”或“主库断网”。1.注入故障 (时间锚点)
在 备库 终端执行:
# 打印当前时间作为 T0,随后立即阻断来自主库的包
echo "====== TEST START: T0 = $(date '+%H:%M:%S.%N') ======" >> test_result.txt && \
iptables -I INPUT -s 192.168.79.141 -j DROP
记录: 终端打印的时间 T_0
[root@localhost dm8]# cat test_result.txt ====== TEST START: T0 = 16:56:00.482257722 ====== [root@localhost dm8]#
2. 观察与记录 (Observation)
**总结:**守护进程先发现对方守护进程(12s)失联,在故障第25s与监视器协调完毕进行状态机制,收到监视器切换命令。show查看,原备库已切换为新主库。
| 观测对象 | 耗时 | 对应参数 | 结论分析 |
|---|---|---|---|
| 守护进程 | 11s | DW_ERROR_TIME (10s) |
符合预期。断网后约 11-12秒 认定远程守护进程故障,触发状态切换逻辑。 |
| 数据库实例 | 18s | MAL_CHECK (30s) + MAL_FAIL (10s) |
符合预期。耗时介于 10s ~ 40s 之间。说明故障发生在下一次心跳检测周期的前 8秒 左右,导致检测提前触发。 |
实例日志: 等待并记录出现 [ERROR]: MAL link broken 或 set link status to DISCONNECT 的时间 T_1。
预期耗时: T_1 - T_0 =30s + 10s = 40s (最坏情况)。
**实际耗时:**18s
[root@localhost ~]# tail -f /dm8/log/dm_GRP1_RT_02_202512.log | grep -iE "MAL.*disconnect|link.*broken|free link" 2025-12-09 16:56:18.472 [WARNING] database P0000052213 T0000000000000052690 [!!!DSC INFO!!!]Site(1) or site(0) interface with IP address no longer running or dsc_ep service on mal_site[192.168.79.141:61141] has broken.It cause network disconnection. #报告断联 2025-12-09 16:56:19.473 [WARNING] database P0000052213 T0000000000000052690 [!!!DSC INFO!!!]Site(1) or site(0) interface with IP address no longer running or dsc_ep service on mal_site[192.168.79.141:61141] has broken.It cause network disconnection.
守护日志: 记录 WSTATUS 变为 ERROR 或 FAILOVER 的时间 T_2。
预期耗时: T_2 - T_1=DW_ERROR_TIME。
**分析:**守护进程之间的 TCP 连接(走 52141 端口)也断了。
DW_ERROR_TIME 是默认的 10s。11秒 > 10秒,所以立即判定对方 ERROR。(每秒轮询)ERROR。本地(备库)实例状态:OK。归档状态:INVALIDprocess_switchover_msg:说明备库守护进程收到了来自监视器(Monitor)的切换指令。16:56:25,距离发现故障(12秒)过去了 13秒。在这 13秒 里,守护进程向监视器汇报了故障,监视器确认后,下达了“备库接管(Takeover)”的命令。这是故障自动切换流程的体现。2025-12-09 16:56:12.341 [INFO] dmwatcher P0000050209 T0000000000000050213 没有收到远程守护进程(GRP1_RT_01)消息,原状态为(OPEN),距上次接收消息时间间隔(11)s, 设置远程守护进程为ERROR状态 2025-12-09 16:56:12.341 [INFO] dmwatcher P0000050209 T0000000000000055151 dw2_group_tcp_recv_thread, receive tcp msg failed, close tcp port, vio:0, mid:-1, from_flag:0, from_name:GRP1_RT_01, dw_closed:1, ip:::ffff:192.168.79.141, port:45092, errno:0, error:Failure occurs in data_recv_inet_once, code(0) len(8128, 0), code:-6007 2025-12-09 16:56:12.392 [INFO] dmwatcher P0000050209 T0000000000000050213 Instance: 守护进程状态(ERROR) 实例状态(OK) 实例名(GRP1_RT_01) 模式(PRIMARY) 实例状态(OPEN) 归档状态(INVALID) POCNT(6) FLSN(47514) CLSN(47514) SLSN(47514) SSLSN(47514) 2025-12-09 16:56:25.261 [INFO] dmwatcher P0000050209 T0000000000000057540 dw2_group_process_switchover_msg, set mid, old mid:256182020, from mid:256182020 2025-12-09 16:56:25.261 [INFO] dmwatcher P0000050209 T0000000000000050213 switch sub_state to sub_stat_start! 2025-12-09 16:56:33.441 [INFO] dmwatcher P0000050209 T0000000000000050213 After monitor execute SWITCHOVER/TAKEOVER/OPEN INSTANCE command, reset all standby instance recover info 2025-12-09 16:56:33.441 [INFO] dmwatcher P0000050209 T0000000000000050213 switch sub_state to sub_stat_start!
4. 恢复环境
iptables -F
验证: 观察监视器,确认集群恢复 Open/Valid 状态,且发生了主备切换
**日志:**故障恢复后,备库实例没有打印新日志。守护进程打印新日志如下:
分析:
17:09:13.370:MAL 与守护进程链路恢复,新主库(02)的守护进程首次获取到原主库(01)的状态信息。日志显示 实例名(GRP1_RT_01) 模式(PRIMARY)。这意味着原主库在断网期间并未停机(Halt),且在网络恢复的瞬间,它依然认为自己是主库。2025-12-09 17:09:16.662:状态变更: 原主库(01)的状态被识别为 SUSPEND。说明原主库在断网期间因无法收到备库的归档确认,受限于实时归档(Realtime)机制,被迫挂起所有写操作。2025-12-09 17:09:34.244 至 17:09:36.288:守护进程检测到“双主”冲突及原主库的 SUSPEND 状态,结合监视器的仲裁,触发了自动**故障恢复(Recovery)**流程。2025-12-09 17:09:13.370 [INFO] dmwatcher P0000050209 T0000000000000560008 Instance: 守护进程状态(ERROR) 实例状态(OK) 实例名(GRP1_RT_01) 模式(PRIMARY) 实例状态(OPEN) 归档状态(INVALID) POCNT(6) FLSN(47514) CLSN(47514) SLSN(47514) SSLSN(47514) 2025-12-09 17:09:16.662 [INFO] dmwatcher P0000050209 T0000000000000560008 Instance: 守护进程状态(STARTUP) 实例状态(ERROR) 实例名(GRP1_RT_01) 模式(PRIMARY) 实例状态(SUSPEND) 归档状态(INVALID) POCNT(6) FLSN(47514) CLSN(47514) SLSN(47514) SSLSN(47514) 2025-12-09 17:09:17.724 [INFO] dmwatcher P0000050209 T0000000000000057540 dw2_group_tcp_recv_thread, receive tcp msg failed, close tcp port, vio:8, mid:256182020, from_flag:1, from_name:dmmonitor, dw_closed:0, ip:::ffff:192.168.79.142, port:42198, errno:2019, error:msg too long to 3385379273, code:-6007 2025-12-09 17:09:33.578 [INFO] dmwatcher P0000050209 T0000000000000560008 Instance: 守护进程状态(STARTUP) 实例状态(ERROR) 实例名(GRP1_RT_01) 模式(PRIMARY) 实例状态(SUSPEND) 归档状态(INVALID) POCNT(6) FLSN(47514) CLSN(47514) SLSN(47514) SSLSN(47514) 2025-12-09 17:09:34.244 [INFO] dmwatcher P0000050209 T0000000000000050213 switch sub_state to pre_set_dw_stat! 2025-12-09 17:09:36.288 [INFO] dmwatcher P0000050209 T0000000000000050213 switch sub_state to sub_stat_start!
1. 注入故障 (时间锚点)
在 备库 终端执行:
# 记录 T0 并设置备库对主库出站流量 50% 丢包
tc qdisc add dev ens33 root handle 1: prio
tc qdisc add dev ens33 parent 1:1 handle 10: netem loss 50%
date; tc filter add dev ens33 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.79.142/32 flowid 1:1
#时间点:
17:43:37 CST
2. 观察与记录 (Observation)
实例日志:
**50%丢包预期:**观察是否出现 MAL connection recovery。 A 组参数(30s/10s)很宽容,可能不会断开——结果:无错误日志打印
将丢包率提升为90%:17:49:16 CST
**链路中断:**30s
2025-12-09 17:49:46.022 [WARNING] database P0000050194 T0000000000000050277 [!!!DSC INFO!!!]Site(0) or site(1) interface with IP address no longer running or dsc_ep service on mal_site[192.168.79.142:61142] has broken.It cause network disconnection. 2025-12-09 17:49:47.023 [WARNING] database P0000050194 T0000000000000050277 [!!!DSC INFO!!!]Site(0) or site(1) interface with IP address no longer running or dsc_ep service on mal_site[192.168.79.142:61142] has broken.It cause network disconnection.
守护日志:
**50%丢包预期:**无错误日志打印
将丢包率提升为90%:17:49:16 CST
分析:
频繁的 Socket 物理报错 (-6007)。90% 的丢包率极易导致 TCP 连接在传输数据时发生重传超时或 RST 复位。达梦底层的网络库捕捉到了这些 Socket 异常,直接抛出 -6007 错误。
自动重连:日志在 17:49:33 报错断开后,到了 17:50:03 又再次报错断开。只有连上了才能再次断开,说明发生了典型的**“链路震荡”**。守护进程发现断了 -> 立即重连 -> 90%丢包下侥幸连上了 -> 试图发消息 -> 又丢包报错 -> 又断开。
2025-12-09 17:49:26.452 [INFO] dmwatcher P0000038840 T0000000000000050422 dw2_group_tcp_recv_thread, receive tcp msg failed, close tcp port, vio:6, mid:1664017214, from_flag:1, from_name:dmmonitor, dw_closed:0, ip:::ffff:192.168.79.142, port:39670, errno:0, error:Failure occurs in data_recv_inet_once, code(0) len(8128, 0), code:-6007
2025-12-09 17:49:28.174 [INFO] dmwatcher P0000038840 T0000000000000118162 dw2_group_tcp_recv_thread, receive tcp msg failed, close tcp port, vio:7, mid:256182020, from_flag:1, from_name:dmmonitor, dw_closed:0, ip:::ffff:192.168.79.142, port:56842, errno:0, error:Failure occurs in data_recv_inet_once, code(0) len(8128, 0), code:-6007
2025-12-09 17:49:33.234 [INFO] dmwatcher P0000038840 T0000000000000113457 dw2_group_tcp_recv_thread, receive tcp msg failed, close tcp port, vio:4, mid:-1, from_flag:0, from_name:GRP1_RT_02, dw_closed:0, ip:192.168.79.142, port:52142, errno:104, error:Failure occurs in data_recv_inet_once, code(104) len(8128, -1), code:-6007
2025-12-09 17:49:33.634 [INFO] dmwatcher P0000038840 T0000000000000038844 没有收到远程守护进程(GRP1_RT_02)消息,原状态为(OPEN),距上次接收消息时间间隔(9)s, 设置远程守护进程为ERROR状态
2025-12-09 17:49:33.634 [INFO] dmwatcher P0000038840 T0000000000000038844 Instance: 守护进程状态(ERROR) 实例状态(OK) 实例名(GRP1_RT_02) 模式(PRIMARY) 实例状态(OPEN) 归档状态(INVALID) POCNT(7) FLSN(47568) CLSN(47568) SLSN(47568) SSLSN(47568)
2025-12-09 17:49:39.237 [ERROR] dmwatcher P0000038840 T0000000000000038846 Can't connect to DM server on '192.168.79.142' port(52142) errno(115)
2025-12-09 17:49:46.798 [INFO] dmwatcher P0000038840 T0000000000000325587 Instance: 守护进程状态(ERROR) 实例状态(OK) 实例名(GRP1_RT_02) 模式(PRIMARY) 实例状态(OPEN) 归档状态(INVALID) POCNT(7) FLSN(47568) CLSN(47568) SLSN(47568) SSLSN(47568)
2025-12-09 17:49:58.180 [INFO] dmwatcher P0000038840 T0000000000000323945 dw2_group_tcp_recv_thread, receive tcp msg failed, close tcp port, vio:6, mid:256182020, from_flag:1, from_name:dmmonitor, dw_closed:0, ip:::ffff:192.168.79.142, port:55592, errno:0, error:Failure occurs in data_recv_inet_once, code(0) len(8128, 0), code:-6007
2025-12-09 17:50:03.253 [INFO] dmwatcher P0000038840 T0000000000000325587 dw2_group_tcp_recv_thread, receive tcp msg failed, close tcp port, vio:4, mid:-1, from_flag:0, from_name:GRP1_RT_02, dw_closed:0, ip:192.168.79.142, port:52142, errno:0, error:Failure occurs in data_recv_inet_once, code(0) len(8128, 0), code:-6007
2025-12-09 17:50:03.654 [INFO] dmwatcher P0000038840 T0000000000000038844 没有收到远程守护进程(GRP1_RT_02)消息,原状态为(OPEN),距上次接收消息时间间隔(1)s, 设置远程守护进程为ERROR状态
4. 恢复环境
tc qdisc del dev ens33 root
本节汇总了 A、B、C 三组参数在不同故障场景下的表现。数据取自每组三次测试的平均值,以消除单次测试的随机误差。
测试场景:完全断网
统计口径:
DISCONNECT/BROKEN T_1 的平均耗时。ERROR/FAILOVER T_2的平均耗时。| 测试组别 | 参数配置 (Check / Fail) | 实例认定耗时 (Avg) | 守护进程认定耗时 (Avg) | 理论预期 (实例/守护) | 结论 |
|---|---|---|---|---|---|
| A组 (宽松) | 30s / 10s | 25s | 11s | 40s / 10s | 错误认定时间较长 |
| B组 (标准) | 10s / 10s | 13.5s | 11s | 10s / 10s | 表现均衡。 |
| C组 (激进) | 2s / 2s | 3s | 10s | 4s / 10s | 出现“守护进程瓶颈”。实例在 3s 内认定链路断开,但守护进程仍需等待默认的 10s才做出决定 |
注:守护进程的故障认定时间主要受
dmwatcher.ini中的DW_ERROR_TIME(默认10s) 控制,理论上各组应基本一致,主要观察实例层面的差异。
本测试验证不同参数组在网络质量恶化时的临界崩溃点。
测试策略:
| 测试组别 | 场景 A:50% 丢包表现 | 场景 B: | 耐受度 |
|---|---|---|---|
| A组 (30/10) | 稳定 (无错误日志) | 90% 丢包表现:13s后出现震荡,30s后出现链路中断 (日志频繁交替报错与重连,Socket -6007) | 极强,仅在极端丢包下异常 |
| B组 (10/10) | 稳定 (无错误日志) | 70% 丢包表现:21s后出现震荡 (日志频繁交替报错与重连,Socket -6007) | 中等 |
| C组 (2/2) | 50% 丢包表现:5s后出现链路中断,10s出现震荡 | ⛔ 跳过 | 较低,对网络质量要求极高,不具备抗抖动能力。 |
基于上述定量与定性测试数据,得出以下关键结论:
1. 参数敏感度与“木桶效应”
MAL_CHECK_INTERVAL 和 MAL_CONN_FAIL_INTERVAL 的缩减确实能显著降低数据库实例(Instance)发现故障的时间(从 A 组的 25s 降至 C 组的 3s)。DW_ERROR_TIME (10s)。因此,单纯激进地调整 dmmal.ini 而不配套调整 dmwatcher.ini,无法有效降低 RTO,反而徒增网络抖动导致的误判风险。2. 丢包耐受度阈值
3. 生产环境配置建议
MAL_CHECK_INTERVAL=10, MAL_CONN_FAIL_INTERVAL=10。MAL_CHECK=2, MAL_FAIL=2,且必须同步调整 dmwatcher.ini 中的 DW_ERROR_TIME 为 3~5s。测试目的:验证当节点自身网络完全隔离(既连不上伙伴,也连不上网关)时,MAL_CHECK_IP 机制能否触发实例主动停机 (HALT),从而防止脑裂。
修改主备库的 dmmal.ini,在原有配置基础上增加主动检测参数:
MAL_CHECK_IP = 192.168.79.1 (假设这是你的网关IP,或者一个局域网内始终在线的第三方IP)MAL_CHECK_TIMEOUT = 5000 (检测超时时间,单位ms,建议设大一点以免误判,文档单位是ms,请注意确认,通常配置为 2000-5000)注意:根据文档,
MAL_CHECK_TIMEOUT缺省为 0,表示不检测。必须配置有效值配合MAL_CHECK_IP使用。
Linux前置环境准备:
机制: 当配置了 MAL_CHECK_IP 后,数据库进程(dmserver)会尝试通过 ICMP 协议(Ping) 去探测目标 IP。
Linux 限制: 在 Linux 中,发送 ICMP 包(Ping)需要创建 RAW Socket。出于安全考虑,默认情况下,只有 root 用户 才有权限创建 RAW Socket。
问题: 达梦数据库是由普通用户(通常是 dmdba)启动的,因此操作系统内核一般会拒绝了 dmserver 创建 RAW Socket 的请求。
解决方案:
赋予 dmserver 网络特权
su - root
setcap cap_net_raw+ep /dm8/bin/dmserver
故障模拟机器:备库(192.168.79.141)
这次不仅要切断到达主库的路,还要切断到达 MAL_CHECK_IP (网关) 的路,模拟“拔网线”的最真实效果。
1.监控命令 (在备库执行):
# 实例日志:重点捕捉 HALT 关键字。
tail -f /dm8/log/dm_GRP1_RT_01_202512.log | grep -iE "HALT|check ip|failed"
# 守护进程日志:捕捉重启命令、状态检测和重启限制告警
tail -f /dm8/log/dm_dmwatcher_GRP1_RT_01_202512.log | grep -iE "Start instance|Startup command|Restart count|limit|mode change"
2. 注入故障 (双重阻断) 在 备库 (.141) 终端执行:
# 记录时间 T0
echo "=== TEST START: T0 = $(date '+%H:%M:%S.%N') ===" >> test_result.txt
# 1. 切断与主库 (.142) 的联系
iptables -I INPUT -s 192.168.79.142 -j DROP
# 2. 切断与网关 (.1) 的联系 (模拟自身网卡彻底挂掉)。Ping需要 INPUT 和 OUTPUT 都通
# 只丢弃来自网关的 ICMP (Ping) 包,但不影响 SSH (TCP)
iptables -I INPUT -s 192.168.79.1 -p icmp -j DROP
观察 dmserver.log:
预期会出现类似:Mal check ip [...] failed, instance will halt 的严重错误信息。
随后实例会执行 shutdown 流程或直接退出。
如下:
025-12-09 23:54:06.318 [INFO] database P0002312265 T0000000000002312978 mal_site_link_check->mal_recv_force_wait failed, code:-6010!, wait_time:2
2025-12-09 23:54:07.319 [INFO] database P0002312265 T0000000000002312978 mal_site_link_check->mal_recv_force_wait failed, code:-6010!, wait_time:1
2025-12-09 23:54:07.319 [INFO] database P0002312265 T0000000000002312978 mal_site_link_check from mal_site(0) to mal_site(1) failed, call mal_site_port_close!
2025-12-09 23:54:07.319 [WARNING] database P0002312265 T0000000000002312953 mal_site_letter_recv code=-6007, errno=0, site(0) recv from site(1) failed, socket handle = 0
2025-12-09 23:54:07.319 [WARNING] database P0002312265 T0000000000002312953 site(0) data_link mal_site_letter_recv from site(1) failed, socket handle = 0, mal sys status is 0, try to get mal_port again
2025-12-09 23:54:07.320 [WARNING] database P0002312265 T0000000000002312952 mal_site_letter_recv code=-6007, errno=0, site(0) recv from site(1) failed, socket handle = 0
2025-12-09 23:54:07.320 [WARNING] database P0002312265 T0000000000002312952 site(0) ctl_link mal_site_letter_recv from site(1) failed, socket handle = 0, mal sys status is 0, try to get mal_port again
2025-12-09 23:54:15.427 [FATAL] database P0002312265 T0000000000002312978 code = -8708, dm_sys_halt now!!!
2025-12-09 23:54:15.428 [WARNING] database P0002312265 T0000000000002313612 utsk_dw_tcp_recv_thread, dmserver receive TCP message from dmwatcher(seqno: 0, name: )failed, close tcp port, code: -6007, errno: 0
2025-12-09 23:54:15.434 [WARNING] database P0002312265 T0000000000002312949 mal_site_letter_recv code=-6007, errno=0, site(0) recv from site(0) failed, socket handle = 0
2025-12-09 23:54:15.434 [WARNING] database P0002312265 T0000000000002312949 site(0) data_link mal_site_letter_recv from site(0) failed, socket handle = 0, mal sys status is 0, try to get mal_port again
2025-12-09 23:54:15.434 [FATAL] database P0002312265 T0000000000002312949 MAL link self lost, halt now!!
观察 dmmonitor:
由于实例已经 HALT(挂掉),恢复步骤如下:
恢复网络: iptables -F
重启数据库:自动切换模式下不用手动重启
[monitor] 2025-12-09 23:56:19: 守护进程(GRP1_RT_01)状态切换 [STARTUP-->UNIFY EP]
WTIME WSTATUS INST_OK INAME ISTATUS IMODE RSTAT N_OPEN FLSN CLSN
2025-12-09 23:56:19 UNIFY EP OK GRP1_RT_01 MOUNT STANDBY VALID 12 47855 47855
[monitor] 2025-12-09 23:56:19: 守护进程(GRP1_RT_01)状态切换 [UNIFY EP-->STARTUP]
WTIME WSTATUS INST_OK INAME ISTATUS IMODE RSTAT N_OPEN FLSN CLSN
2025-12-09 23:56:19 STARTUP OK GRP1_RT_01 OPEN STANDBY VALID 12 47855 47855
[monitor] 2025-12-09 23:56:19: 守护进程(GRP1_RT_01)状态切换 [STARTUP-->OPEN]
WTIME WSTATUS INST_OK INAME ISTATUS IMODE RSTAT N_OPEN FLSN CLSN
2025-12-09 23:56:19 OPEN OK GRP1_RT_01 OPEN STANDBY VALID 12 47855 47855
检查集群状态:确保备库重新加入并恢复 OPEN/VALID 状态。
文章
阅读量
获赞
