ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

达梦DM8主备集群高可用搭建实战:从配置到故障切换

达梦DM8主备集群高可用搭建实战:从配置到故障切换 1. 为什么单机DM8扛不住生产环境主备集群解决的三个核心问题先说说我自己的经历。前几年做国产化替代项目客户核心业务库从国外数据库迁到达梦DM8最初部署就是一台物理机单机。单机跑了一段时间开发测试都挺顺利真正快上线的时候客户问了一句“这台机器如果凌晨三点挂了我们的业务几点能恢复”我一下被问住了。因为单机环境下最典型的恢复路径是找一台备用机重新装数据库、导入备份、追归档日志运气好恢复时间按小时算运气不好备份和归档刚好有缺口数据直接倒不回去。这种可用性水平放在交易类系统里是完全不可接受的。所以“DM8主备集群”这个需求本质上不是一道数据库命令题而是一道高可用工程题。它要解决三个问题故障切换问题主库宕机后备库能否在几十秒内接管业务而不是让业务等人工干预。数据丢失问题主备之间日志实时同步主库故障瞬间丢失的数据尽可能趋近于零也就是RPO接近0。日常维护问题需要做硬件更换、系统补丁、数据库升级时能不能先在备库上操作再平滑切换做到业务无感。DM8主备集群的底层机制简单说就是主库不停产生Redo日志通过网络传递给备库备库自动重演日志达梦的守护进程DM Watcher专门负责监控角色和状态一旦发现主库失联备库守护进程会在配置的时间窗口内完成角色切换把备库提升为新主库继续服务。这个思路和Oracle DataGuard类似但具体实现和配置文件完全是达梦自己的体系不能想当然照搬Oracle命令。那为什么不一步到位上DSC共享存储集群这取决于预算和场景。DSC需要共享存储比如SAN磁盘阵列或者裸设备由多个实例同时挂载同一套数据文件节点故障后另一个节点直接接管RTO可以做到秒级甚至更快。但共享存储的采购成本、网络要求、运维门槛都更高。主备集群只需要两台独立服务器加普通网络数据通过日志同步来保持一致性不需要额外存储设备对大多数中小规模生产系统来说主备集群已经是性价比最高的高可用形态。我通常会建议用户这样选型如果系统要求RPO为0、RTO在秒钟级别并且预算允许上共享存储选DSC如果业务可以接受最多丢失一条日志的时间、切换时间在几十秒内主备集群足够如果是边缘节点或者纯查询报表库甚至可以做异步级的主备进一步降低网络和同步压力。2. 搭建前的规划比命令更重要网络、端口、目录、用户这些细节说实话真正把主备集群搭崩掉的人大多不是死在配置文件语法上而是死在环境准备上。我自己第一次搭的时候两台机器的主机名、时间、用户权限乱七八糟排错排了一整天最后发现是备库服务器时间比主库快了五分钟守护进程一直认为日志序号错乱。所以先别急着敲命令把以下准备工作一条条过掉。2.1 操作系统与用户规划DM8支持主流Linux发行版常见的有麒麟V10、统信UOS、CentOS 7 x86_64这些。无论用什么系统建议都用独立的dmdba用户来安装和运行数据库不要用root直接跑数据库进程。原因很简单数据库进程被攻破或误操作时进程权限越小破坏范围越小另外达梦很多初始化工具直接用root运行会存在文件属主问题导致后续服务起不来。创建用户的典型操作groupadd dinstall useradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdba passwd dmdba然后规划安装目录和数据目录。我的习惯是这样分开/dm8数据库软件安装目录放可执行程序、jar包、驱动、内置工具。/dm8/data数据目录放控制文件、数据文件、Redo日志。/dm8/arch归档日志目录。/dm8/backup备份文件目录也是搭建备库时备份集暂存区。归档目录和数据目录最好放在不同的物理磁盘或文件系统上避免磁盘写满时互相拖累。2.2 网络与端口规划主备集群需要网络传输大量Redo日志同步网的好坏直接决定同步延迟。生产环境最好单独用一张网卡做数据库实例之间的数据同步不要和业务流量、备份流量混在一起。我见过客户把日志同步和业务请求放在同一个千兆网口上业务高峰时同步延迟飙到几十秒备库追不上主库一发生切换丢数据丢得心惊肉跳。端口规划要有全局观。假设主库在192.168.10.11备库在192.168.10.12我习惯使用以下分配逻辑用途主库备库说明数据库实例监听端口52365237客户端通过该端口连接数据库MAL通信端口63366337实例间日志同步专用通道守护进程端口83368337DM Watcher之间互相通信、传递心跳这个规划的核心是数据库端口、MAL端口、守护端口三者互不冲突且在主备两台机器上保持一致错位。防火墙记得放行这些端口如果用云主机安全组也要在安全组规则里配置。不然配置全对网络不通守护进程会一直报错。2.3 时间同步主备集群里两台机器的时间差不能太大。Redo日志的序号虽然不依赖系统时间但守护进程判断日志应用状态、故障时间线时如果时间差距过大轻则告警日志刷屏重则切换逻辑判断错乱。推荐每台机器都配置chrony或ntpd指向公司内网时间源并设置开机自启。配置完用chronyc sources -v验证同步状态。3. 主备集群的四个配置文件每份文件到底是干什么的DM8主备集群的核心配置集中在四个文件里把它们之间的关系搞清楚配置就不会觉得乱。这四个文件我都放在数据目录下也就是/dm8/data/DAMENG下。dm.ini实例配置文件相当于实例的“身份证”。里面定义实例名、端口号、是否启用MAL和归档等核心开关。dmmal.iniMAL系统配置文件相当于集群节点之间的“通讯录”。各节点的MAL主机地址、端口都在这里面登记。dmarch.ini归档配置文件定义日志归档到哪里、归档文件大小限制等。dmwatcher.ini守护进程配置文件定义守护组的模式、故障判定时间、节点信息等。3.1 dm.ini中最关键的四个参数每个节点的dm.ini至少要关注以下参数INSTANCE_NAME DM1 PORT_NUM 5236 MAL_INI 1 ARCH_INI 1注意主备实例名必须不同比如主库叫DM1备库叫DM2。数据库名DB_NAME则要完全一致否则后面备份恢复会报“库不匹配”。MAL_INI1表示实例启动时启用MAL系统这是日志同步和守护进程通信的前提。ARCH_INI1表示启用归档配置等于告诉实例去读取dmarch.ini。这两个开关都在数据库实例启动前就要定好运行过程中不能随便改。3.2 dmmal.ini集群的通讯录dmmal.ini在主备两台机器上的内容基本一致每个节点占一个小节。以两节点为例# 全局配置 MAL_CHECK_INTERVAL 5 MAL_CONN_FAIL_INTERVAL 5 # 主库节点 [MAL1] MAL_INST_NAME DM1 MAL_INST_HOST 192.168.10.11 MAL_INST_PORT 6336 MAL_DW_PORT 8336 # 备库节点 [MAL2] MAL_INST_NAME DM2 MAL_INST_HOST 192.168.10.12 MAL_INST_PORT 6337 MAL_DW_PORT 8337MAL_INST_HOST要写对方机器能访问到的实际IP不要写localhost。MAL_INST_PORT是MAL通信的数据通道端口MAL_DW_PORT是守护进程通道端口这两个端口和dmwatcher.ini中的DW_PORT需要保持一致。3.3 dmarch.ini归档日志的存放规则主备节点都要配置归档因为主库要归档日志给备库同步备库自己也需要保留日志便于追溯。[ARCHIVE_LOCAL1] ARCH_TYPE LOCAL ARCH_DEST /dm8/arch ARCH_FILE_SIZE 1024 ARCH_SPACE_LIMIT 0ARCH_FILE_SIZE单位是MB这里设置单个归档文件最大1024MBARCH_SPACE_LIMIT 0表示不限制归档空间总大小生产环境建议限制一个合理值不然归档文件堆满磁盘会导致数据库hang住。3.4 dmwatcher.ini故障切换的总调度守护进程是主备集群的大脑。dmwatcher.ini示例DW_MODE AUTO DW_INACTIVE_INTERVAL 10 DW_ERROR_TIME 30 [DM1] DW_INST_NAME DM1 DW_HOST 192.168.10.11 DW_PORT 8336 DM_INI_PATH /dm8/data/DAMENG/dm.ini [DM2] DW_INST_NAME DM2 DW_HOST 192.168.10.12 DW_PORT 8337 DM_INI_PATH /dm8/data/DAMENG/dm.iniDW_MODE有两种值AUTO和MANUAL。AUTO模式下主库故障后守护进程自动把备库切换为主库这就是自动故障转移MANUAL模式下主库故障后需要DBA手动干预适合那些需要人工确认后才能切换的严肃生产系统。绝大多数场景我都会推荐AUTO。DW_INACTIVE_INTERVAL是实例被判定失效的时间窗口单位是秒。这个值不能设得太小否则网络抖动容易误判也不能设得太大否则业务等待时间过长。一般10秒左右比较稳妥。DW_ERROR_TIME是守护进程报错后的等待时间设30秒。需要注意dmwatcher.ini的节点块名称在不同版本里可能有细节差异我在实操中见过的写法是直接用小节名对应实例名。如果你用的是某个特定版本以该版本官方手册中的示例为准但整体字段逻辑是通用的。4. 主备搭建实操过程从库初始化到备份恢复配置文件的逻辑理清后实际操作就容易多了。整个流程可以分成四步初始化两套实例、配置主库归档并做备份、把备份恢复到备库、启动守护进程完成角色确认。4.1 初始化主备实例安装好DM8软件后用dminit工具初始化数据库实例。主库和备库分别执行以下命令只是实例名和端口不同。主库dminit PATH/dm8/data PAGE_SIZE32 CASE_SENSITIVE1 CHARSET1 DB_NAMEDAMENG INSTANCE_NAMEDM1 PORT_NUM5236备库dminit PATH/dm8/data PAGE_SIZE32 CASE_SENSITIVE1 CHARSET1 DB_NAMEDAMENG INSTANCE_NAMEDM2 PORT_NUM5237这里有三个参数必须严格一致PAGE_SIZE、CASE_SENSITIVE、CHARSET。页面大小不一致会导致备份集无法在备库恢复大小写敏感设置不一致会导致恢复后数据行为不同字符集不一致会导致中文乱码甚至恢复报错。所以初始化之前就要想好一套标准参数两台机器照着用。初始化完成后先把两套实例都正常注册服务并启动起来。服务注册一般使用达梦自带的dm_service_installer.sh脚本注册好后把实例先启动到OPEN状态再通过disql连接到实例执行ALTER DATABASE MOUNT;为什么要切到MOUNT状态因为主备集群的日志同步要求主库和备库都先以MOUNT状态收拢后续由守护进程控制角色切换。备库必须保持MOUNT状态不能处于OPEN状态去对外提供读写否则主备逻辑会错乱。4.2 主库开启归档并做备份在MOUNT状态下配置主库的归档。达梦支持在线修改归档配置命令如下ALTER DATABASE ADD ARCHIVELOG TYPELOCAL, DEST/dm8/arch, FILE_SIZE1024, SPACE_LIMIT0; ALTER DATABASE ARCHIVELOG;这两句执行完后主库的归档模式就打开了。接着恢复主库到OPEN状态ALTER DATABASE OPEN;然后对主库发起一个完整的联机备份备份集放到指定目录BACKUP DATABASE FULL TO FULL_BAK_20250321 BACKUPSET /dm8/backup/full_bak_20250321;这里我不展开说语法细节因为不同小版本略有差异但完整备份这一步是搭建备库的数据基础。主库确认备份成功后把备份集整个目录拷贝到备库服务器的/dm8/backup目录下scp -r /dm8/backup/full_bak_20250321 dmdba192.168.10.12:/dm8/backup/4.3 在备库执行恢复备库实例此时应该处于停止状态不能开着服务去恢复覆盖数据文件。使用达梦自带的备份恢复工具dmrmandmrman进入工具后依次执行RESTORE DATABASE FROM BACKUPSET /dm8/backup/full_bak_20250321; RECOVER DATABASE FROM BACKUPSET /dm8/backup/full_bak_20250321;RESTORE把备份集的数据文件还原到备库的数据目录RECOVER则把备份过程中产生的Redo日志重演到备份结束的那个时间点。两条命令都完成后备库的数据就已经和主库备份时刻的数据一致了。这里要注意备份集的文件权限。拷贝过来的备份文件如果属主不是dmdbadmrman会拒绝读取拷贝后记得检查一遍chown -R dmdba:dinstall /dm8/backup chown -R dmdba:dinstall /dm8/data4.4 分发并核对配置文件现在把主库的dm.ini、dmmal.ini、dmarch.ini、dmwatcher.ini检查一遍备库也要对应准备。注意dm.ini里INSTANCE_NAME和PORT_NUM要改成备库的值其他三个文件的节点信息都包含主备两端内容基本可以一致使用。我一般会在备库准备一份单独的配置清单逐项打勾dm.ini中INSTANCE_NAMEDM2是否正确。PORT_NUM5237是否和主库不同。MAL_INI1是否开启。ARCH_INI1是否开启。dmmal.ini中两个节点IP、端口是否对应实际环境。dmwatcher.ini中DW_INST_NAME是否和dm.ini的实例名一致。4.5 按照正确顺序启动服务启动顺序错了也会踩坑。我推荐的顺序是先启动备库到MOUNT再启动主库到MOUNT然后启动两台机器的守护进程。具体操作启动备库数据库实例用disql连接后执行ALTER DATABASE MOUNT;。启动主库数据库实例同样切到MOUNT状态。在主库节点启动守护进程dmwatcher /dm8/data/DAMENG/dmwatcher.ini以服务方式启动也可以。在备库节点启动守护进程。守护进程启动后观察日志输出。正常情况主库守护进程会把主库自动置为PRIMARY并切换到OPEN状态备库会自动变成STANDBY状态并开始从主库接收和应用Redo日志。这个过程可能要等十几秒别刚看到日志没输出就急着重启。启动完成后在任意一台机器上用disql登录数据库查询视图SELECT NAME, INSTANCE_NAME, ROLE, STATUS FROM V$DATABASE;如果主库ROLE显示PRIMARY备库ROLE显示STANDBY说明主备关系建立成功。此时再往主库建一张测试表插入数据备库应该能很快查到同样的数据这说明日志同步链路是通的。5. 故障切换验证和回切演练时最容易暴露问题的环节配置搭完不代表高可用已经生效真正决定集群质量的是故障切换能不能在预期时间内完成。很多团队搭建完成后直接丢到生产三个月后主库真挂了才发现备库数据延迟了好几分钟或者备库根本没有自动切换。所以上线前必须做至少两轮故障演练。5.1 模拟主库宕机我常用的最小化演练方式是直接在主库节点上杀掉数据库服务进程模拟最极端的硬件故障kill -9 $(pgrep -f dmserver)守护进程检测到主库失联后会等待DW_INACTIVE_INTERVAL设定的时间窗口然后通知备库守护进程执行角色切换。按我上面的10秒配置大概十几秒后原备库就会变成PRIMARY并对外提供服务。在这个环节你要重点观察两件事切换时间是否符合预期。如果超过一分钟还没切换优先检查守护进程日志看故障检测是卡在哪个阶段。业务侧是否真的能连上新主库。如果业务连接串还指向原主库IP切换后业务自然连不上。生产环境一般配合VIP漂移或者应用连接池的重连机制来解决。5.2 主库恢复后重新加入集群故障切换只是第一步原主库修复后怎么让它重新回到集群作为备库才是最容易出乱子的地方。不要直接启动原主库让它自己同步因为此时原主库的数据已经和现主库不一致了。正确的思路是把现主库做一个新的完整备份恢复到原主库节点让原主库以备库身份重新加入集群。具体流程和执行上面搭建备库是一样的现主库备份、拷贝备份集到原主库、原主库停机恢复、重新启动守护进程观察状态。很多人在这一步图省事直接启动原主库然后指望日志追赶结果两个实例互相认为自己是主库脑裂风险极大。对于主备集群任何情况下都不要让两个实例同时以PRIMARY角色对外服务。5.3 平时运维必须盯的指标主备集群平时的运维重点盯三个地方归档目录使用率。日志同步依赖归档归档目录满了数据库会停止写入整个系统直接不可用这是生产事故的重灾区。同步延迟。可以通过守护进程日志或者系统视图观察备库应用日志是否滞后如果持续增长说明网络带宽不够或者备库性能跟不上。备库状态。定期确认备库仍是STANDBY角色且数据库处于正常的MOUNT状态防止备库被误操作打开变成普通库。6. 写在实际操作之后的几条心得这套主备集群搭建方式我在多个现场环境里验证过也帮客户排过不少后续问题。最后补几个实际踩过坑之后得出的经验。第一个建议是配置文件的字段名核对问题。达梦不同版本、不同补丁之间某些参数写法可能有细微差异比如DW_MODE在高版本里可能默认值不同dmmal.ini的块名称也可能受版本影响。所以每次到新环境我第一件事是打开官方手册翻阅对应版本的主备集群章节把字段名和当前环境的示例文件逐个对照再开始动手。别觉得自己搭过一次就能凭记忆盲写。第二个经验是备份集一定要保留到集群稳定运行几天后再删。搭建备库时产生的那份完整备份是回切和重建备库的重要底座如果删了下次出问题只能在线再打一份备份时间和带宽成本都高。第三个建议是切换演练一定要纳入每季度固定运维计划而不是只在项目上线前做一次。数据库版本升级、操作系统补丁、网络设备调整都可能影响集群行为定期演练才能保证故障发生时预案是真的能跑通的。我见过不止一个项目建集群时测试一切正常半年后网络加了防火墙策略导致守护端口被禁真发生切换时备库根本不知道主库挂了业务直接中断。最后提一句如果你的业务系统对RTO非常敏感网络环境又不稳定可以认真考虑把DW_INACTIVE_INTERVAL调得更短并且给业务连接配上多地址重试机制。集群只是给了数据库一个自动恢复的机会应用侧能不能快速感知和重连直接影响最终的业务中断时间。主备集群是一整套工程不是几条SQL命令的事。
返回列表