资讯动态

达梦DM8主备集群部署实战:从初始化到故障自动切换

发布时间:2026/10/22 16:22:21 来源:尧图企业网站定制
去年在机房做模拟故障切换我把主库数据库进程直接kill掉然后掐表。业务侧同事还没来得及抱怨备库已经自动接管客户端连接自动漂移过去整个过程不到半分钟。那一刻其实我心里也没底因为这是整套达梦DM8主备集群搭好之后的第一次真刀真枪演练结果比预想顺利。这个结果不是运气而是DM8守护进程体系在起作用主库、备库、监控进程三者配合自动完成了身份判定、日志补追和接管动作。如果你现在还停留在“每天手动做备份出了事再想办法恢复”的阶段或者刚好在做数据库国产化替代正纠结高可用方案怎么选那这篇东西值得你花十分钟看完。我会从方案对比讲起一直讲到具体的初始化命令、配置文件和排错实录尽量做到你照着操作能独立搭出一套能用的主备。1. 为什么选主备而不是其它——四类高可用方案的一次横向对比先不急着敲命令得想清楚一个问题你生产环境到底需要哪种级别的可用性达梦DM8给的高可用路线其实有三四条我在不同的项目里都试过各有各的适用场景如果只看“有集群”三个字就冲后面八成会后悔。第一类是最朴素的备份恢复。每天做全备或者全备加归档备份出故障时把备份拉起来。这个方案最大的问题是恢复时间不可控你永远不知道上一次备份离故障点有多远恢复过程中还要处理日志断裂、归档缺失的连锁问题。它适合作为兜底手段比如审计留档、灾备演练验证但不适合当主要的高可用手段。第二类是实时归档或异步备库。主库把归档日志实时或者准实时传到备库备库处于恢复状态随时可以把备库激活成主库。这个方案比纯备份强很多数据丢失窗口可以压到秒级甚至更小但有个前提——需要人工介入。主库挂了之后你得登录备库手动执行激活操作如果是凌晨三点出事响应时间完全取决于运维值班人员的速度。第三类就是我这次要展开讲的主备守护集群DM官方的叫法是DataWatch。主库、备库前面各挂一个守护进程还有一个独立的监控进程在旁边盯着。主库心跳断了监控和备库守护进程配合自动把备库提升为主库。这里的关键词是“自动”也就是说业务中断的时间取决于集群自身的检测速度而不是取决于人。第四类是共享存储集群多个实例同时访问同一套数据文件故障切换更快但对存储设备的依赖和license成本都上了一个台阶一般规模的业务系统未必有必要上。这几类方案不是替换关系而是配合关系。我现在的典型做法是生产主库每天做增量备份加定期全备同时跑一套主备集群应对硬件故障和实例崩溃备份用于对付逻辑错误和误操作。下面这张表是我在选择方案时常用的判断依据方案数据丢失量RPO恢复时间RTO是否需要人工介入成本与复杂程度备份恢复取决于备份周期小时级甚至更长需要且操作链长最低异步备库秒级到分钟级分钟级加人工激活需要中低主备守护集群取决于配置实时归档时趋近于0数十秒内可自动切换不需要故障时自动接管中共享存储集群接近0秒级不需要最高主备守护集群在RPO和RTO之间找到了一个很务实的平衡点也正因为如此它成了达梦DM8部署中最常见的高可用形态。接下来要做的就是把这个形态从概念落到具体的服务器上。2. 部署前的底子——操作系统、磁盘规划与初始化参数是后续一切的地基主备集群部署失败的案例里有相当大一部分不是配置写错而是环境没准备好。达梦对系统参数的依赖不算苛刻但有几个坑很常见我在部署前会专门花半天做一遍环境清点。2.1 主机与磁盘规划先说集群拓扑。我以一个模拟项目为例环境是两台Linux服务器计划角色如下项目主机1主库候选主机2备库候选IP地址192.168.1.10192.168.1.11实例名GRP1_RT_01GRP1_RT_02实例端口52365236MAL系统端口6114161141守护进程端口52155215数据目录/dm/data/dm/data归档目录/dm/arch/dm/arch两条主机建议用同样配置的机器CPU和内存不用追求完全一致但不能差太远否则切换后单边性能可能扛不住业务。磁盘规划这里我提一个容易被忽略的点归档目录和数据目录尽量不要共用一块磁盘。实时归档是主备集群的核心机制归档落盘的速度直接关系到主库事务的提交效率如果数据文件、归档文件、系统日志同时抢一块盘的I/O性能抖动很难看。2.2 操作系统层面需要处理的事项配置/etc/hosts把两台机器的IP和主机名都写进去集群的心跳通信依赖主机名解析这一步不做好后面启守护进程时处处报错。关闭防火墙或放行端口。如果安全要求不允许关闭至少要放行5236、61141、5215这几个端口且只对集群内两台机器的IP开放。SELinux或者类似的强制访问控制建议直接关闭在默认策略下达梦的守护进程通信经常被无故拦掉排查起来非常浪费时间。调整文件句柄限制/etc/security/limits.conf里面把nofile和nproc调大DBA用户建议直接设置为65535以上。数据库进程本身连接数就多再加上守护进程的额外文件操作默认1024肯定不够。2.3 初始化参数为什么必须在建库时定死达梦很多参数可以在线修改但有一部分只能在dminit初始化实例时确定后期无法修改除非重建库。最容易踩坑的是这三个PAGE_SIZE页大小默认8K我习惯设置为32K。页大小影响行大小上限和一张表最多能存多少列如果业务场景涉及大字段或者宽表8K很容易碰到行溢出限制。LENGTH_IN_CHAR是否以字符为单位存储VARCHAR等类型。设置为1可以在建表时不用手动乘以字符字节数对UTF-8和多语言场景很友好。CASE_SENSITIVE大小写敏感设置为0时标识符不区分大小写建表时不需要给表名加双引号。这个参数影响所有后续的SQL写法一旦定下来中途改的成本极高。我遇到过不止一次初始化实例时没想清楚直接默认参数建库业务开始跑了一个多月才发现字符集和大小写敏感不合适。这时候唯一的办法是新建实例重新导数据代价非常大。所以任何一次搭建哪怕是测试环境我都在初始化命令里显式指定这三个参数cd /dm/dmdbms/bin ./dminit PATH/dm/data INSTANCE_NAMEGRP1_RT_01 PAGE_SIZE32 LENGTH_IN_CHAR1 CASE_SENSITIVE0备库GRP1_RT_02用同样的命令只改INSTANCE_NAME。这一步没有任何省略余地两个库的页大小、字符集、大小写敏感如果不一致后面配置主备时会出现日志应用不了或者内部对象对不上的诡异报错。3. 主备集群的三层联动——MAL系统、守护进程与状态机之间的配合逻辑配置写起来不难但如果你不理解这套机制出问题时只能靠猜。DM8主备集群从逻辑上分三个角色数据库实例、守护进程、监控进程它们之间不是简单的“主库挂了备库顶上”而是一整套状态决策链路。3.1 各角色的职责边界数据库实例就是平常说的主库、备库一个处于OPEN状态对外提供服务另一个处于MOUNT或RECOVERY状态接收日志并应用。守护进程dmwatcher是每个数据库实例前面的哨兵数据库实例不是自己直接和对方通信的所有心跳、身份判断、日志同步状态的上报都要经过守护进程。监控进程dmwatch或者图形化的控制台工具是决策端它同时盯着主备两个守护进程的心跳当主库守护进程在设定时间内没有响应监控进程会联合备库守护进程发起故障接管流程。这里有个很多人第一次接触时容易绕晕的地方主备之间的数据同步和守护进程之间的心跳是两条独立通道。数据同步走的是MAL系统也就是配置里的MAL_INST_HOST、MAL_INST_PORT这些参数它专门负责在实例之间搬运redo日志。守护进程通信走的是另外一组端口。所以即使主库数据库实例已经被打挂守护进程本身可能还活着依然能向监控进程上报状态反过来如果守护进程也挂了监控进程才会判定整机不可用。3.2 redo日志是怎么从主库流到备库的达梦的实时归档链路是这样的主库上的事务产生redo日志redo日志一方面要落盘另一方面实时归档进程把redo数据通过MAL通道发送给备库。备库收到后先把日志写入本地的归档文件然后把日志应用到自己的数据文件上完成一次同步。关键点在ARCH_WAIT_APPLY这个参数。设置为1时备库需要把日志应用完毕后才向主库返回确认主库提交事务的这条链路才会继续往前走。这相当于一个半同步机制保证了在主库返回“事务提交成功”给应用之前这条日志至少已经有一个备库真正接住并落地。有一种常见误解是“主备不就是异步复制嘛丢数据难免”——如果配置了实时归档且ARCH_WAIT_APPLY1这个说法就不成立。这和我写这篇博文时想强调的一点完全一致不是所有主备都一样丢数据关键看归档类型。3.3 状态机与超时判断达梦守护进程模式下实例的状态不是只有OPEN和MOUNT两种还会在故障切换、日志补追时出现各种过程态。你可以把集群想象成一个班级主库是班长备库是副班长监控进程是班主任。正常情况下副班长不发言只在旁边抄笔记应用日志班长失联超过一定时间班主任会先和副班长确认班长是不是真不在了然后发布任命通知。这个“一定时间”就是守护进程配置里的DW_TIMEOUT。设得太短主库短暂网络抖动就会触发切换业务被迫中断设得太长主库真出事时备库要干等很久才接管。我一般设置成10秒左右具体要看你的网络质量和业务容忍度。理解了这套三层联动机制再去看配置文件里的每个参数就不会是“照着抄但不知道为啥”的状态了。4. 一步步把主备搭起来——从实例初始化到守护进程接管全流程现在开始实操。以下命令和配置以我上面规划的两台机器为例环境是Linux使用的达梦版本为DM8。我尽量把每一步在做什么说清楚。4.1 初始化实例并启动到MOUNT状态初始化命令前面已经给过两台机器把实例名分别换掉就可以了。数据目录建好后先用一条命令让两个实例都启动起来执行数据库初始化脚本cd /dm/dmdbms/bin ./dmserver /dm/data/DAMENG/dm.ini第一次启动可以先直接启动到OPEN然后使用disql连接数据库把后续需要在线修改的参数改掉也就是dm.ini里的ARCH_INI、MAL_INI、RLOG_APPLY_MON这些。%RLOG_APPLY_MON用于开启备库日志应用状态的监控主备切换演练时需要靠它观察是否追平。-- 以SYSDBA连接后执行 SP_SET_PARA_VALUE(1, ARCH_INI, 1); SP_SET_PARA_VALUE(1, MAL_INI, 1); SP_SET_PARA_VALUE(1, RLOG_APPLY_MON, 1); SP_SET_PARA_VALUE(1, RLOG_SEND_APPLY_MON, 1);改完后重启实例。主库GRP1_RT_01正常启动到OPEN备库GRP1_RT_02则要启动到MOUNT状态。备库MOUNT状态不对外提供读写服务但可以接收主库推送过来的日志这是加入主备集群的前提。如果备库顺手起了OPEN后面加入集群时会因为状态不对而失败这个坑我后面排错部分还会提。4.2 配置dmarch.ini与dmmal.ini归档配置两个实例都要做。主库的dmarch.ini放在数据目录下内容大致如下[ARCHIVE_REALTIME] ARCH_TYPE REALTIME ARCH_DEST GRP1_RT_02 ARCH_WAIT_APPLY 1这里ARCH_TYPEREALTIME表示实时归档ARCH_DEST不是IP地址而是目标实例名实例名在dmmal.ini里要和MAL_INST_NAME完全一致大小写也不能错。ARCH_WAIT_APPLY1就是我前面说的半同步关键参数如果你允许极端情况下少丢一点数据来换取更低的事务延迟可以设成0但生产环境我不建议这么干。dmmal.ini同样放在数据目录下所有节点都要有内容为MAL_CHECK_INTERVAL 5 MAL_CONN_FAIL_INTERVAL 5 [MAL_INST1] MAL_INST_NAME GRP1_RT_01 MAL_INST_HOST 192.168.1.10 MAL_INST_PORT 61141 MAL_DW_PORT 5215 MAL_INST_DW_PORT 33141 [MAL_INST2] MAL_INST_NAME GRP1_RT_02 MAL_INST_HOST 192.168.1.11 MAL_INST_PORT 61141 MAL_DW_PORT 5215 MAL_INST_DW_PORT 33141MAL_INST_PORT是实例间同步redo日志的端口MAL_DW_PORT是守护进程之间通信的端口MAL_INST_DW_PORT是实例和本地守护进程通信的端口。把端口分开独立配置是为了让数据同步和心跳互不干扰。端口号用什么区间没有硬性规定但我习惯避开常用端口段选一段相对生僻的减少和系统其它服务冲突的概率。4.3 配置dmwatcher.ini守护进程的配置文件同样放数据目录两台机器各一份内容基本一致只需注意对应各自的实例名[DW_GRP1] DW_TYPE GLOBAL DW_MODE AUTO DW_ERROR_TIME 30 INST_RUN_CONFIRM 0 INST_OGUID 45331 INST_INI /dm/data/DAMENG/dm.ini INST_AUTO_RESTART 1 INST_STARTUP_CMD /dm/dmdbms/bin/dmserver RLOG_SEND_THRESHOLD 0 RLOG_APPLY_THRESHOLD 0DW_MODEAUTO是自动切换模式故障时无需人工干预。INST_OGUID是整个集群的标识两个节点必须一致。INST_AUTO_RESTART1表示守护进程发现本机实例异常退出时自动拉起。RLOG_SEND_THRESHOLD和RLOG_APPLY_THRESHOLD这里设置为0表示不限制日志堆积阈值如果你的归档链路比较慢可以设置一个值来触发告警判断。有个细节如果是在部署完守护进程之后再想调整这组配置必须先停掉守护进程再修改否则配置可能被进程缓存覆盖。4.4 启动顺序与控制台注册很多人第一次搭主备时死在这一步。启动顺序有讲究必须先启动主库实例到OPEN再加入备库最后启动守护进程。在主库GRP1_RT_01上正常启动数据库使其处于OPEN状态。在备库GRP1_RT_02上启动数据库但要用MOUNT方式启动不能OPEN。在主库上使用disql添加日志归档目录执行前先看MOUNT状态和守护进程通信的OGUID是否一致-- 主库GRP1_RT_01上执行 ALTER DATABASE ADD ARCHIVELOG DEST/dm/arch;这一步必须趁数据库处于OPEN状态且还没有被守护进程以特殊模式托管时完成。启动守护进程的命令cd /dm/dmdbms/bin ./dmwatcher /dm/data/DAMENG/dmwatcher.ini两台机器都要执行顺序不分先后。守护进程起来之后它会自动读取两个实例的配置把主备关系建立起来。再启动监控进程用dmwatch命令进入控制台找到监控进程启动方式cd /dm/dmdbms/bin ./dmwatch -c /dm/data/DAMENG/dmwatcher.ini在监控进程控制台里设置OGUID并启动守护进程这是很多方案中容易漏掉的一步-- 在dmwatch控制台中执行 SP_SET_OGUID(45331); -- 启动守护进程确认主备关系 START WATCHER;此时通过监控进程可以看到集群的拓扑状态。正常情况是GRP1_RT_01主库OPENGRP1_RT_02备库MOUNT/RECOVERY两边守护进程状态都在线没有报错。到这里主备集群的骨架已经搭起来了。5. 验证不是看STATUS漂亮——主备切换演练与故障接管实测配置上看起来一切正常不代表真正能扛住故障。我会做两步验证第一步是主备手动切换验证切换链路第二步是直接杀掉主库进程验证自动接管是否如预期。这两个测试是主备集群的“出厂检验”不做完我根本不敢把它交付给业务方。5.1 正常的switchover切换流程手动切换用于计划性维护比如主库所在的机器要升级内核、换硬件。流程是在监控进程控制台里执行switchover命令把原本的主库GRP1_RT_01降为备库把GRP1_RT_02提升为主库。-- 在dmwatch控制台执行 SWITCHOVER GRP1_RT_02;执行之后观察集群状态原来的主库会先进入MOUNT状态然后转换为备库并开始接收新主库的日志原来的备库会自动转为OPEN状态对外服务。切换耗时一般在几十秒内取决于归档日志追赶的进度。切换完成后用disql登录GRP1_RT_02执行一条简单的建表和插入语句确认读写已经正常。这个测试的重点不在于“能不能切”而在于切换后业务侧是否要改连接信息。如果应用使用IP加端口直连切换后连接会断需要应用层做重连如果前面挂了达梦的连接中间件或应用自带了故障转移逻辑就能做到对应用透明。我在这里给你的建议是无论应用是否具备重连能力都要在监控和控制台之外单独测试一遍业务连续性别想当然。5.2 故障切换直接把主库进程干掉模拟故障的操作很简单在主库机器上执行kill -9杀掉dmserver进程或者直接杀掉dmwatcher进程模拟整机断电更彻底的方式是shutdown -h now。在故障瞬间监控进程会经历一个心跳超时窗口然后通知备库守护进程接管。我在实际测试中从杀掉主库数据库进程到备库变为OPEN耗时约20到30秒。这个数字在你自己的环境里可能不同和DW_TIMEOUT的配置有直接关系。等故障切换完成重新启动原主库GRP1_RT_01。启动前期它不会立刻加入集群而是会先作为备库尝试和当前主库GRP1_RT_02建立日志同步关系把停机期间缺失的归档日志补追回来。等到它追上主库的日志点状态会变成正常的备库守护进程自动把它纳管。看到这里你应该能理解为什么前面强调ARCH_WAIT_APPLY和归档目录的重要性原主库回归后要补日志如果归档文件不完整补追过程就会卡住备库永远到不了一致状态。5.3 监控视图里的关键指标日常巡检中我主要看两个视图v$dg_monitor和v$rlog。v$dg_monitor显示集群中每个节点的角色、状态、归档同步情况。重点关注几个列STATUS节点当前状态期望值是主库为OPEN备库为MOUNT或RECOVERY。LAST_ARCH_TIME和LAST_APPLY_TIME分别表示最后一次归档时间和最后一次日志应用时间两个时间越接近当前时间越好。MODE_STATUS出现WAS_CONSISTENT意味着节点经历过数据不一致或重新构建需要人工介入确认数据完整性后才能重新加入集群。v$rlog则展示实时日志的发送和应用情况可以理解为redo日志在备库侧追到了哪个日志序列号。如果你发现备库的LAST_APPLY_TIME和主库的LAST_ARCH_TIME差距持续拉大说明日志应用能力跟不上主库写入速度了这时要赶紧排查是归档链路问题还是备库硬件性能问题。6. 排错实录这些坑我搭了一遍才彻底搞明白最后这部分是我最想写的。配置参数对着文档抄不难难的是出问题时怎么定位。以下五个问题我都实际踩过按出现频率从高到低排。6.1 备库以OPEN状态启动导致无法加入集群现象启动备库时没注意直接默认进入了OPEN状态结果监控进程里怎么都看不到备库正常注册执行join操作时报错。原因主备集群要求备库必须处于MOUNT状态才能参与日志同步和守护进程接管。OPEN状态的备库会有自己的本地写事务能力这会让集群判定它不具备成为备库的条件。处理把备库实例正常关掉重新用MOUNT方式启动。达梦的启动方式可以通过dm.ini里的启动参数控制也可以临时用命令指定生产环境建议在启动脚本里明确固定。6.2 dmarch启动报错“归档目录无效”现象启动主库实例时日志提示归档模块初始化失败指向的归档路径不存在或者指向的实例名对不上。原因dmarch.ini里的ARCH_DEST写的是实例名如果大小写或名称和dmmal.ini中的MAL_INST_NAME不一致实例启动时找不到这个“目标实例”就判定归档配置非法。另一个常见原因是归档目录没提前创建达梦不会自动创建目录。处理先检查目录是否存在并且属主正确mkdir -p /dm/arch chown dmdba:dinstall /dm/arch再检查dmarch.ini和dmmal.ini里的实例名是否完全一致。这里没有捷径只能一行对一行查。6.3 两台机器系统时间偏差大导致守护进程误判现象主库明明是健康的备库却无缘无故发起了切换业务被切到备库而原主库其实一直在正常运行。原因守护进程的心跳判断依赖时间戳。如果两台机器系统时间偏差超过DW_ERROR_TIME的容忍范围监控进程会认为对方失联从而触发接管。这个坑特别隐蔽因为它不是进程报错而是“看起来正常但行为异常”。处理两台机器统一配置NTP时间同步部署集群前先检查时间偏差chronyc sources -v偏差超过200毫秒就要先解决时间同步再继续部署。主备切换这种事被一个时钟偏移引发说起来很冤但真的有人遇到过。6.4 备库一直追不上主库的日志应用进度现象v$dg_monitor里备库的LAST_APPLY_TIME远落后于主库堆积的日志量越来越大但数据库本身没有报错。原因可能是主库上某个大事务持续生成海量redo日志备库单线程应用能力不足也可能是备库所在机器的磁盘I/O或者网络带宽成为瓶颈。还有一种情况是归档目录和数据库目录在同一块盘上应用日志时I/O互相抢占。处理先看主库是否有长时间未提交的事务再看备库的磁盘响应时间。如果是硬件瓶颈优先考虑把备库归档目录独立到另一块盘或者调整MAL系统的传输并发参数。这里给个经验值当备库日志延迟超过5分钟时必须人工介入避免故障切换时数据追不完。6.5 守护进程正常但故障时集群不切换现象手动做故障演练时主库进程停了备库和守护进程都活着但集群就是干等不自动接管。原因最常见的是DW_MODE没有设置为AUTO配置成了MANUAL这会导致监控进程只告警不动作。另一个原因是控制台虽然能看到节点但OGUID没有设置成功集群之间没有真正建立信任关系监控进程的接管指令传不到备库守护进程。处理先在控制台确认DW_MODE再执行SP_SET_OGUID(45331)重新设置并启动守护进程最后重新做一次故障切换演练。如果还是不切换用dmwatcher的日志文件排查守护进程的log目录下会记录详细的超时和判定过程定位起来比瞎猜快很多。写在最后主备集群的价值不在于配置那一刻看起来很完美而在日复一日的运行中稳得住。我现在每台部署了DM8主备的机器上都会放一个简单的巡检脚本每天凌晨自动查询v$dg_monitor的状态一旦出现状态异常或归档延迟超阈值就触发告警。另外一个小建议不要因为“切换成功一次”就觉得万事大吉。我每季度至少做一次完整的故障切换演练并且尽量挑在业务低峰期执行模拟的场景越接近真实越好。演练不仅仅是验证配置也是在训练运维人员的肌肉记忆——真正出故障时大家没有时间现场翻文档。这套主备集群技术含量并不算高但把基础做扎实、把验证做够比任何炫技都管用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑