DM8主备集群部署详解:守护进程与监视器协同实现高可用
搞了两周DM8主备集群部署文档写了三版才把流程理顺。我最早接触这套集群的时候以为跟传统主从复制一样装上实例配个关系就能跑结果发现主备集群的核心难点根本不在配上而在你理不理解守护进程和监视器之间的协调关系。这篇把整个部署过程拆开讲透从环境规划、实例初始化、主备还原到守护进程配置、切换演练、故障恢复一条线走下来该给的参数、命令、脚本全给你该避的坑也都标出来。1. 部署前的环境规划与前置准备1.1 机器角色与资源规划DM8主备集群最少需要两台机器一台主库一台备库。要是想实现自动故障切换还需要一个确认监视器也叫确认监控这个可以单独部署一台机器也可以放在备库服务器上。我建议条件允许的话单独准备一台轻量机器特别是生产环境确认监视器所在机器和备库宕在一起时故障判定会出问题高可用架构里最怕这种裁判和选手住一间房的情况。硬件方面有个容易被忽视的点主备两台机器的配置尽量保持一致不要出现主库64G内存备库16G这种组合。因为切换之后备库要扛全部业务流量备库配置不够切换完等着你的不是高可用而是业务雪崩。CPU核数、内存大小、磁盘IO能力尽量一致这样切换前后用户体验差别不大。操作系统方面只要是达梦安装包支持的Linux发行版都可以我这次用的是常见的CentOS 7.9。注意内核参数里net.ipv4.tcp_keepalive_time和net.ipv4.tcp_keepalive_intvl建议调小一点主备之间走网络心跳若是系统默认的两小时才探测一次备库发现主库故障的时间会拖得很长切换RTO就没法看了。1.2 安装前的用户与环境配置安装DM8之前建议先把运行用户建好一般用dmdba不要直接用root跑数据库实例这个习惯跟Oracle的oracle用户一个道理权限收敛是为了减少误操作带来的风险。# 创建用户组和用户 groupadd dinstall useradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdba # 设置密码 passwd dmdba然后调整系统资源限制主要改文件句柄数、进程数、栈大小。文件句柄数不够数据库运行一段时间后会出现Too many open files错误主备同步的归档进程也会受影响。cat /etc/security/limits.conf EOF dmdba soft nofile 65536 dmdba hard nofile 65536 dmdba soft nproc 65536 dmdba hard nproc 65536 dmdba soft stack 10240 EOF1.3 磁盘目录规划目录规划这一步很多人会偷懒装完数据库随便找个目录放数据文件后面要扩容、要归档、要备份的时候发现盘不够只能干瞪眼。我建议按照下面这个标准来分目录用途建议大小/dm/soft数据库安装包和解压目录2GB/dm/data数据文件目录按业务量预留建议100GB起/dm/arch归档日志目录按redo产生速度预留20GB~100GB/dm/backup备份文件目录至少为数据目录的1.5倍写一个挂载规划让交付团队直接照抄mkdir -p /dm/soft /dm/data /dm/arch /dm/backup chown -R dmdba:dinstall /dm归档目录和数据目录尽量放在不同的物理盘上避免磁盘写满互相拖累。我遇到过一台机器数据盘和归档盘是同一个挂载点归档日志把根分区写满了主库直接hang住还好备库数据没丢。2. 主库实例初始化和运行参数配置2.1 初始化实例的完整命令主库先用dminit初始化。这里要强调的是初始化参数想清楚再动手特别是PAGE_SIZE和CHARSET。初始化之后字符集不能直接改页大小也不能随便改改错了只能重新建库。我这次用的初始化命令su - dmdba cd /dm/soft/dmdbms/bin ./dminit PATH/dm/data \ PAGE_SIZE32 \ CHARSET1 \ CASE_SENSITIVE1 \ DB_NAMEDAMENG \ INSTANCE_NAMEDW_PRI \ PORT_NUM5236几个关键参数解释一下PAGE_SIZE32页大小32KB。页大小决定了一行数据的最大长度上限页越大单行能塞的数据越多但缓冲区能缓存的页数也会相应减少。OLTP业务选8KB或16KB够用如果表里有大的CLOB/TEXT字段建议选32KB避免行溢出影响性能。CHARSET1UTF-8字符集。如果老系统用的是GBK要跟应用团队的连接串编码确认清楚混用字符集在迁移阶段会出一堆乱码问题。CASE_SENSITIVE1大小写敏感。这个是业务习惯问题如果应用SQL里写的是带双引号的大写表名就选1否则选0。切换一次要重新导数据代价很大所以这一步必须跟研发确认。2.2 修改主库dm.ini核心参数实例初始化好了先别急着开先改dm.ini。主备集群能不能正常搭建很大程度上看这里面的几个参数有没有配对。# 编辑 /dm/data/DAMENG/dm.ini INSTANCE_NAME DW_PRI PORT_NUM 5236 DW_MODE 1 ALTER_MODE_STATUS 0 ENABLE_OFFLINE_REP 2 ARCH_INI 1 TIMER_INI 1 RLOG_APPEND_SEL 1逐个说下我踩过的坑DW_MODE 1是主备模式开关主库和备库都必须设置成1不设的话守护进程起来之后不识别集群。ALTER_MODE_STATUS 0是禁止手工修改数据库模式状态。生产环境强烈建议设成0否则有人在主库执行ALTER DATABASE PRIMARY;或者ALTER DATABASE STANDBY;就能把数据库模式改乱守护进程会被误导整个集群状态就乱了。ENABLE_OFFLINE_REP 2是允许备库做离线恢复。这个参数在第一次还原备库的时候必须开等备库正常加进集群之后可以看情况关掉。RLOG_APPEND_SEL 1是让系统在REDO日志里追加SELECT相关信息。这个跟某些数据同步工具强相关如果没开启这个参数部分第三方同步工具解析不到完整的日志链路。还有一个容易漏的TIMER_INI 1。这个参数与定时作业相关主备库之间需要保持一致。两台机器的dm.ini里凡是影响日志生成的参数都必须一致否则同步过程中随时可能报错。2.3 配置本地归档主备集群的数据同步本质上就是主库把REDO日志传到备库备库拿到日志后重放。所以dmarch.ini必须配好。这个文件在数据目录下不存在就手动创建。# /dm/data/DAMENG/dmarch.ini ARCH_WAIT_APPLY 1 [ARCHIVE_LOCAL1] ARCH_TYPE LOCAL ARCH_DEST /dm/arch ARCH_FILE_SIZE 2048 ARCH_SPACE_LIMIT 102400ARCH_WAIT_APPLY这个参数很多人不注意。主库归档日志写完以后要不要等备库接收确认后再提交事务取1就是等取0就是不等。数据安全要求高的业务必须设1这样主库事务提交的时候日志已经安全到达备库。代价是主库性能会有一点损耗网络RTT越高损耗越明显。ARCH_FILE_SIZE单个归档文件大小MBARCH_SPACE_LIMIT归档总大小上限MB。我设的单个文件2GB总上限100GB这个要根据业务重做日志产生的速度来评估。曾经有一次某个批量任务每小时产生5GB以上的日志一天下来归档空间就顶到上限集群直接断开这个指标上线后要持续观察一段时间。3. 备库的还原与初始化3.1 在线备份还是离线拷贝备库搭建有两条路一条是冷备拷贝一条是用备份还原。我建议正式环境都用备份还原冷备拷贝最容易出问题的点是两台机器实例名不同导致的控制文件路径混乱后面调起来很费劲。在已经启动的主库上直接执行在线备份su - dmdba cd /dm/soft/dmdbms/bin ./disql SYSDBA/******localhost:5236备份命令-- 全量备份带压缩 BACKUP DATABASE FULL BACKUPSET /dm/backup/db_full_bak_20250101 COMPRESSED LEVEL 1;备份完成后把备份目录整个传到备库scp -r /dm/backup/db_full_bak_20250101 dmdba备库IP:/dm/backup/传输大文件千万别用网络盘挂载方式断点续传问题会折磨死人直接scp或者rsync都行。文件传完后在备库上校验一下备份集完整性cd /dm/soft/dmdbms/bin ./dmrman CTLSTMTCHECK BACKUPSET /dm/backup/db_full_bak_20250101这一步不要省我遇到过备份文件拷贝一半scp没有报错但文件大小不对的情况不校验就还原后面备库起不来排查得怀疑人生。3.2 使用dmrman完成还原与恢复备库还原的逻辑要理清楚RESTORE是把全量备份的数据文件恢复到数据目录RECOVER是把备份之后的归档日志重放到一致性点位。这两个步骤分开做中间穿插库的配置修改。先把备库的DM服务停掉确认没有进程占用数据目录ps -ef | grep dmserver | grep -v grep然后执行./dmrman CTLSTMTRESTORE DATABASE /dm/data/DAMENG/dm.ini FROM BACKUPSET /dm/backup/db_full_bak_20250101 ./dmrman CTLSTMTRECOVER DATABASE /dm/data/DAMENG/dm.ini FROM BACKUPSET /dm/backup/db_full_bak_20250101这里有个容易踩的坑RECOVER语句执行完成后系统会提示数据库恢复完成或者数据库需要更新日志如果提示需要更新日志说明备份之后主库还有新的日志没包含在备份集里。这时候要把主库最新的归档日志也拷到备库再执行一次./dmrman CTLSTMTRECOVER DATABASE /dm/data/DAMENG/dm.ini WITH ARCHIVEDIR /dm/arch这一步是很多初学者最容易卡住的地方。原理其实很简单全量备份只能达到备份开始时刻的一致性备份期间业务继续产生的日志就得靠归档日志补上去。所以在线备份方案下备份集加上备份时间点之后的归档日志才能得到一个最新的可用库。还原恢复完成之后改备库的dm.ini# /dm/data/DAMENG/dm.ini INSTANCE_NAME DW_STD PORT_NUM 5236 DW_MODE 1 ALTER_MODE_STATUS 0 ENABLE_OFFLINE_REP 2 ARCH_INI 1 TIMER_INI 1 RLOG_APPEND_SEL 1注意实例名和主库不同端口可以相同也可以不同但为了切换后业务连接不折腾我一般建议两台机器端口保持一致用IP区分实例。3.3 备库的dmarch.ini配置主备集群里备库也要配置归档。备库的归档用于级联场景以及备库自己接收日志后的本地留存。这次只搭一主一备备库的归档路径可以简单些# /dm/data/DAMENG/dmarch.ini ARCH_WAIT_APPLY 1 [ARCHIVE_LOCAL1] ARCH_TYPE LOCAL ARCH_DEST /dm/arch ARCH_FILE_SIZE 2048 ARCH_SPACE_LIMIT 102400 [ARCHIVE_REALTIME1] ARCH_TYPE REALTIME ARCH_DEST DW_PRI这里新增了一个ARCHIVE_REALTIME1类型是REALTIMEARCH_DEST写主库的实例名DW_PRI。这行的作用就是让备库和主库之间建立实时日志同步通道。没有这个配置备库只能接收归档文件实时性无从谈起。ARCH_DEST到底填实例名还是IP取决于dm.ini里的DB_MIRROR_IP配置。最简单的方式是直接填实例名由守护进程解析网络关系。4. 守护进程和监视器的配置与启动4.1 理解守护进程与监视器的分工进入这个环节之前先建立一个整体认知主备集群里跑着三类进程dmserver是数据库实例本身dmwatcher是守护进程负责监控实例状态并执行切换动作dmmonitor是监视器负责接收守护进程上报的状态并发出指令。守护进程管执行监视器管决策。一主一备场景下dmwatcher.ini只需要一份配置主备库通用。配置文件放在数据目录下# /dm/data/DAMENG/dmwatcher.ini DW_MODE 1 DW_ERROR_TIME 30 INST_OGUID 45331 INST_INI /dm/data/DAMENG/dm.ini INST_AUTO_RESTART 1 INST_STARTUP_CMD /dm/soft/dmdbms/bin/dmserver RLOG_SEND_THRESHOLD 0 RLOG_APPLY_THRESHOLD 0参数说明INST_OGUID全局唯一ID主备库必须一致。这个值不要随便乱取保证整个集群内唯一就行。INST_AUTO_RESTART1实例异常退出后守护进程自动重启实例。这个必须开不然实例挂了没人拉起来。DW_ERROR_TIME30守护进程判定实例故障的超时时间秒。设太短网络抖动容易误判设太长切换速度慢。内网环境30秒是比较合理的。RLOG_SEND_THRESHOLD和RLOG_APPLY_THRESHOLD设置0表示不限制日志发送和重放的速度。监视器配置单独放一个文件如果是确认监视器要加MON_CONFIRM 1# /dm/data/dmmonitor.ini MON_LOG_PATH /dm/data/log MON_LOG_INTERVAL 60 MON_LOG_FILE_SIZE 1024 MON_LOG_SPACE_LIMIT 20480 MON_CONFIRM 1 [GROUP_DW] DW_IP 192.168.1.101:5236 DW_IP 192.168.1.102:5236这里192.168.1.101和192.168.1.102是我虚构的主备库IP各位读者替换成自己机器的实际地址。DW_IP后面跟的端口是dmwatcher的监听端口不是数据库端口注意区分。4.2 启动顺序宁可多等不要抢跑配置全部就绪后启动顺序错一步集群就起不来。正确顺序先启动主库dmserver再启动备库dmserver启动主库和备库的dmwatcher启动dmmonitor每启动一个环节先用状态查询确认一下再继续。先把两台服务器的数据库服务拉起su - dmdba cd /dm/soft/dmdbms/bin ./dmserver /dm/data/DAMENG/dm.ini 启动数据库实例后查看日志确认实例正常tail -f /dm/data/DAMENG/dm_DW_PRI.log看到system is ready for use再继续下一步。然后启动守护进程./dmwatcher /dm/data/DAMENG/dmwatcher.ini 守护进程正常启动后再启动监视器./dmmonitor /dm/data/dmmonitor.ini4.3 使用监视器执行集群注册监视器起来之后先用show命令看看集群状态是否正常。这里有个容易被忽略的环节新搭建的集群里主库和备库虽然已经可以用dmserver跑起来但还没加入守护进程的管理范围需要执行一条注册命令在监视器命令行里执行login输入sys用户名和密码后执行register /dm/data/DAMENG/dmwatcher.ini注册完成后执行show global正常情况下能看到类似下面的输出实例名数据库模式实例状态守护进程状态DW_PRIPRIMARYOPENOPENDW_STDSTANDBYMOUNTOPEN看到这个状态基本就可以认为集群注册成功了。备库数据库模式是STANDBY、实例状态是MOUNT这是对的备库在MOUNT状态下接收主库REDO日志并执行重放。如果备库状态一直卡在MOUNT不动多半是实时归档链路没建立成功检查网络和dmarch.ini里的ARCHIVE_REALTIME1配置。5. 连接管理、切换验证与问题排查5.1 应用连接串如何适配主备切换主备集群部署到位只是第一步应用侧连接串不调整切换了业务还是断。不少项目组把数据库连接串写死为主库IP主库一旦宕机切到备库业务就彻底连不上了。两种主流适配方案第一种是借助VIP虚拟IP在集群主备切换后手动或通过脚本把VIP漂移到新主库上。具体做法是在两台机器上部署一套VIP管理脚本监视器检测到切换事件后触发漂移。第二种方案更轻量也推荐优先考虑在应用连接字符串里配置多个地址客户端驱动自身具备故障转移能力。以JDBC为例jdbc:dm://192.168.1.101:5236/DAMENG?failover1autoReconnecttrue多个地址之间用逗号分隔jdbc:dm://192.168.1.101:5236,DW_STD:5236/DAMENG?failover1autoReconnecttrue这个方案要求应用必须使用支持多地址的驱动版本。如果项目用的是老版本达梦JDBC驱动建议先把驱动升级到新版再上线否则failover参数不识别启动直接报错。5.2 手动切换与故障注入验证集群建好之后必须做切换演练这一步不能省。我一般的演练顺序先做手动切换再做主库故障模拟最后验证备库接管后业务链路是否正常。手动切换在监视器里执行switchover DW_PRI执行后系统会提示切换的详细过程等待一段时间后执行show global确认两边的数据库模式已经互换原主库变成STANDBY原备库变成PRIMARY。模拟主库故障更直接找一个业务低峰期在主库机器上执行ps -ef | grep dmserver | grep -v grep | awk {print $2} | xargs kill -9主库实例被强杀后守护进程会在DW_ERROR_TIME超时后向监视器上报确认监视器判定故障成立就会指令备库提升为新的PRIMARY。这个时候注意看两个核心指标一是切换时间二是新主库是否自动恢复到OPEN状态。切换完成后到新的备库上做一次拉起验证su - dmdba cd /dm/soft/dmdbms/bin ./dmserver /dm/data/DAMENG/dm.ini 确认新备库重新加入集群且状态为STANDBY这个集群才算是真正健康。只做一次切换就收工是不够的建议在测试环境至少做三轮切换演练把停主库、断网、备库宕机三个场景都覆盖到确认监视器判断逻辑符合预期。5.3 常见问题速查表把我在部署和运维过程中实际遇到过的几个典型问题整理成表每一条都是真金白银踩出来的故障现象关键排查命令处理思路备库状态一直MOUNT不动show global查看备库日志确认归档链路是否建立检查网络端口可达性主备切换后应用连不上查看错误码提示确认连接串是否支持failover检查VIP是否漂移归档空间写满df -h /dm/arch清理归档扩充磁盘同时检查主库日志生成速度守护进程自动退出cat /dm/data/log/dmwatcher.log检查OGUID是否一致确认dm.ini和dmwatcher.ini参数匹配备库应用日志时报错中断备库实例日志检查TIMER_INI等日志相关参数是否主备一致这个表只是排查起点实际运维中情况往往嵌套比如归档写满和网络抖动同时出现就得先处理归档再看主备状态是否能自动恢复。任何情况下不要在主库上直接ALTER DATABASE PRIMARY去抢状态这种操作很容易把整套集群的逻辑搞乱宁可花时间看日志用正规手段恢复。5.4 业务高峰期切换的RTO评估最后一个建议无论你部署得多么顺利都要留出时间做一次业务高峰期切换的压力评估。我见过有团队在凌晨三点演练一切正常结果白天高峰期故障切换时备库承接流量后事务响应时间翻了三倍业务方炸锅。原因是在真实负载下备库REDO日志重放速度跟不上主库日志产生速度切换后新主库大量回放任务排队性能急剧下降。评估方法很简单在备库上定期查询v$rlog视图对比主库生成的日志量和备库应用日志量之间是否有持续累积滞后SELECT ARCH_SEQNO, APPLY_SEQNO, APPLY_LAG FROM V$RLOG_APPLY_STAT;如果发现APPLY_LAG长期不为0且越来越大说明备库的回放能力存在瓶颈需要检查备库的IO配置、磁盘RAID策略或者参数RLOG_APPLY_THRESHOLD。这些问题在低峰期演练时是暴露不出来的正因为这样压力场景下的切换验证才更有参考价值。我最后再讲一个细节。有次我在备库上执行了一条只读查询发现备库的查询性能比主库差了一大截一开始怀疑是硬件问题查了半天发现是备库dm.ini里的BUFFER_POOLS和主库不一致备库缓冲区配小了。主备集群的参数同步不只是集群参数连性能参数、会话参数也要尽量做成一致否则切换后性能大变脸比不切换还麻烦。项目上线后建议把主备的dm.ini做一次diff比对把有差异的项逐条确认原因确保万无一失。