ARTICLE DETAIL

资讯详情

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

DM8实时主备故障模拟实战:从原理到演练全解析

DM8实时主备故障模拟实战:从原理到演练全解析 干这一行的都有过这种体会主备环境平时跑得好好的日常巡检也是绿灯可真到出故障那天会发现一堆平时根本想不到的问题。备库同步延迟大、归档日志断档、切换脚本没做过验证、甚至DBA自己都不敢在主库上敲failover命令。所以我一直坚持一个观点——高可用架构不是“搭出来”的是“练出来”的。这也是我想写这篇DM数据库实时主备故障模拟的初衷。这篇内容面向的是实际负责达梦数据库DM8主备环境运维的同学不管是刚接触达梦的DBA还是被安排去搭建和实施主备环境的项目工程师都可以直接参考。我会把整个故障模拟的过程拆开来讲从主备架构的基本原理到演练前要做的准备再到真实的故障场景操作步骤最后是常见问题和排查思路。内容比较长但都是能直接用上的东西建议先收藏再慢慢看。1. 为什么要把“好端端”的主备环境搞出故障来很多人觉得主备环境搭好就完事了平时主库正常干活备库安安静静跟着同步根本没有必要主动去破坏它。这是非常危险的想法。数据库高可用体系里“故障切换”和“日常同步”是两码事前者才是真正决定RTO和RPO的关键环节。我先说一个自己遇到过的例子。某次客户环境做月度演练主备集群用的是达梦DM8实时归档模式备库状态看监控是正常的主库一天的归档量也不大。可演练一开始主库进程杀掉之后备库迟迟没能在预期时间内完成接管最后发现备库的redo日志应用一直卡在一个大事务上平时同步稍微滞后一点根本看不出来但切换时这就成了致命问题。所以故障模拟的核心价值有几点验证切换链路是否真的可用。守护进程、监视器、手动切换命令、应用连接串的failover配置这些环节任何一个有问题故障发生时都会掉链子。验证RPO是否可接受。实时主备不等于零丢失某些模式下最多可能丢一个归档日志。你到底能接受丢多少数据必须实测出来。验证回切路径是否顺畅。很多团队只做“主切备”从不做“备切主”。等主库修好了想切回去的时候才发现原有的主库状态不对或者归档补齐有问题直接抓瞎。验证人的操作熟练度。这个最容易被忽视。故障处理是有时间压力的如果操作者平时没练过真到半夜故障时一边查手册一边敲命令RTO基本不可能达标。DM数据库的主备架构有几种常见形态实时归档主备、自动归档主备、读写分离集群、共享存储集群DSC。这次故障模拟我以最常见的“实时归档主备”为对象。之所以选它是因为这套架构部署量最大而且它本质上和Oracle的Data Guard非常像理解了一个很多思路可以平移过去。实时归档模式下主库产生的redo日志会通过MAL系统实时传递到备库备库收到后立即应用主备数据保持一致。守护进程dmwatcher负责监控主备状态监视器dmmonitor负责在必要时发起自动或手动切换。故障模拟要做的就是在这种架构下人为制造异常验证整个生命周期是否经得起考验。1.1 主备同步的基础概念要知道动手演练之前有几个基础概念必须心里有数不然后面操作容易看懵。redo日志和归档日志。主库上的每一个事务提交都会先写redo日志redo日志写满后触发归档生成归档日志。实时主备的核心逻辑就是redo日志每次切换或写入时通过MAL通道实时传到备库备库应用redo和归档让数据保持同步。可以把它理解成“流水线”——主库不断产出日志备库不断消费日志任何一个环节卡住同步就会滞后。备库的两种应用模式。达梦实时主备里备库可以按需配置为realtime模式或timely模式。realtime模式是实时应用收到的redo日志timely模式则强调更严格的一致性备库在应用日志时会更谨慎。还有一种是本地归档日志应用适合用来做时间点恢复。我们做故障模拟时一般建议用timely或realtime因为这两种才能真正做到“分钟级甚至秒级接管”。守护进程和监视器的角色。守护进程跑在主备库上负责收集本机数据库状态并上报给监视器监视器可以理解为“指挥中心”它能看见整个主备集群的状态执行switchover计划内切换或failover故障强制切换。没有监视器你是没法一键切换的只能手工登录到备库执行命令。我们的演练默认是有监视器的环境因为生产上不可能裸奔。1.2 故障模拟和其他高可用方案的区别很多接触过Oracle的人会问达梦主备和Oracle Data Guard是不是一回事机制上确实很像都有主备、日志传输、应用、切换这套流程但达梦有几点不同需要注意。第一达梦的守护进程和监视器是一套独立的进程体系配置和启动顺序有严格要求乱启动会直接导致监视器看不到集群状态。第二达梦的MAL系统配置涉及多个配置文件任何一个节点配置不一致日志传输就起不来。第三达梦的failover命令和Oracle不太一样执行前对两端状态有更严格的约束。这些差异只有真正动手做过演练才能体会。这个章节不是让你去背概念而是先建立一个全局认识。接下来我们进入正题演练前需要准备什么。2. 演练准备动手“搞破坏”之前先把底线画好故障模拟不是上去就把数据库杀掉它本质上是一次有预案的破坏性测试。准备工作做得好不好直接决定演练过程和结果分析有没有参考价值。2.1 准备一套尽量接近生产的测试环境如果你手头有生产环境的备库理论上可以直接在备库上做验证但我强烈建议先用测试环境来一遍。原因很简单故障模拟中会出现各种不可控的意外比如网络中断后恢复异常、归档断档需要补日志、主库修复后状态不对需要重建这些操作在生产上做风险是不可逆的。测试环境的搭建可以走标准的达梦主备流程准备两台Linux服务器一台主库一台备库操作系统版本一致DM8数据库版本一致最好连补丁版本都一致。主库安装数据库实例开启归档dmarch.ini配置MAL系统dmmal.ini备库通过备份恢复方式搭建确保两端的数据结构完全一致。配置守护进程dmwatcher.ini和监视器dmmonitor.ini测试环境可以配一个非确认监视器生产上建议至少两个监视器避免监视器自身单点。启动顺序有讲究先启动主库和备库实例然后启动守护进程最后启动监视器。监视器里执行show global info能看到两端状态处于正常同步才可以开始演练。测试环境的数据尽量模拟生产形态有常规业务表、有索引、有存储过程、有大事务表如果能导入一份业务相关的dmp数据就更好了。数据越接近真实切换时的耗时和资源使用越有参考价值。2.2 先给环境留几条“后路”既然是故意制造故障就一定要先确保即使演练翻车也能恢复原状。我的习惯是动手前先做三件事全量备份主库。用dmrman或者DMRMAN的命令做一次在线备份万一演练过程中数据文件损坏可以快速恢复基线。记录当前主备的日志序列号。查一下主备库当前的redo日志序号和归档日志序号记录下来。演练结束后通过对比日志序号能快速判断同步是否有断点。检查两端的时间同步。如果主备库时间差太多日志传输的时间戳会对不上造成莫名其妙的同步中断。用ntpdate或者chronyc校准一下再开始。额外说一句我习惯在演练开始前建一张“标志表”比如CREATE TABLE FLAG_TEST(ID INT, FLAG_TIME DATETIME); INSERT INTO FLAG_TEST VALUES(1, SYSDATE); COMMIT;这表看着简单但演练时很有用。切换完成后登录备库查这张表能直接看到切换前提交的数据是否已经同步过来了比看监控和日志直观得多。2.3 定好演练场景和预期目标准备环境只是第一步更重要的是定好演练场景。我自己常用的故障场景有以下几类这次挑几个有代表性的展开讲主库实例进程崩溃模拟掉电、数据库异常宕机。主库数据文件误删或文件系统损坏。备库节点掉线后恢复验证主库不受影响以及备库自动追平。主备网络心跳断开验证脑裂防护机制。每一个场景都要有明确的预期什么时候触发切换、切换耗时多少、数据有没有丢、切换后应用能否正常读写、如何回切。没有预期目标演练变成了瞎折腾复盘的时候也说不清到底有没有达到高可用要求。3. 核心实操四个典型故障场景的模拟全过程准备工作做完下面进入真正的“破坏”环节。我会按每个场景的完整过程来写包括触发操作的命令、观察到的现象、验证的方法和关键注意事项。这些内容都是我实际演练中跑过或见过别人跑过之后总结出来的直接抄作业是没问题的。3.1 场景一主库实例进程崩溃这是最经典的故障模拟模拟的是主库突然宕机比如服务器掉电、操作系统卡死或者数据库进程被误杀。重点验证的是备库能否快速接管、切换后数据是否完整。第一步触发故障。不要用SHUTDOWN NORMAL或SHUTDOWN IMMEDIATE因为那属于正常关闭主库会及时通知守护进程。要模拟“瞬间死亡”用强制终止进程的方式# 找到主库的dm进程 ps -ef | grep dmserver # 强制干掉进程模拟瞬间崩溃 kill -9 dmserver_pid如果没有自动切换配置这一步执行后监视器里会看到主库状态变成ERROR或UNKNOWN守护进程不断尝试重连。这时不要慌张这是正常的。第二步在监视器里观察状态show global info;重点关注几个字段主库状态是否异常、备库状态是否还是STANDBY、日志发送是否中断。如果配置了自动切换备库可能会自动变成PRIMARY这取决于你的故障自动切换策略。第三步手动执行failover切换。即使有自动切换我通常也会用手动命令再验证一次因为生产上很多时候自动切换会因为各种条件不满足而没有触发-- 在监视器里执行 failover 组名.备库名;执行过程中监视器会尝试把备库提升为新的主库。命令执行完再登录新的主库查询状态SELECT DATABASE_MODE FROM V$INSTANCE;结果应为PRIMARY。同时查一下最开始建好的FLAG_TEST表看切换前那条记录在不在。这里要特别提醒一个坑failover之后原来的主库如果没有被完全清理状态可能处于UNKNOWN或RECOVERY状态。不要急着把它的数据拿回来直接用后续要重新规划角色——要么作为新备库重新搭建要么彻底清理后重建。我之前见过有人failover后直接把老主库强制启动结果同一套环境出现两个PRIMARY业务写入直接错乱教训非常深刻。3.2 场景二主库数据文件误删这个场景模拟的是文件系统层面的损坏比如运维误删了数据文件或者磁盘坏道导致数据文件不可读。操作上我推荐在数据文件目录下手动改名或删除一个用户表空间的数据文件而不是动系统表空间的文件。动系统表空间属于另一个极端场景影响面太大不利于演练后的快速恢复。假设我们要删除用户表空间 TS_APP 对应的数据文件# 进入数据文件目录 cd /dm8/data/DAMENG # 找到TS_APP的数据文件改名模拟损坏 mv TS_APP01.DBF TS_APP01.DBF.BAK然后尝试在主库上访问这个表空间中的表让错误暴露出来-- 在主库执行 SELECT COUNT(*) FROM APP.USER_ORDER;此时大概率会收到文件读写错误因为DM在做物理读时发现文件找不到了。观察主库日志会出现大量的IO错误记录但备库此时通常不受影响因为备库走的是日志应用和数据文件物理路径没有直接关系。在这个场景中要验证的关键点是主库“坏了”之后业务是否能切到备库继续跑。操作流程和场景一类似在监视器里执行failover即可。但有一点和进程崩溃不同切换完成后原来的主库因为有物理文件缺失已经不能简单重启拉起来只能通过新备份的方式重建或者先把误删的文件恢复回去再处理归档追平。我在复盘这个场景时经常强调数据文件被误删是“高可用”最尴尬的敌人。备库虽然能接管业务但如果平时备份策略不到位等你想把旧主库修好时才发现备库没有全量备份那就只能靠日志慢慢追RTO直接拉长到无法接受。3.3 场景三备库掉线后再恢复上线生产上备库掉线也是常事比如备库服务器要重启、网络抖动导致MAL连接中断、备库磁盘空间满了导致归档应用暂停。这个场景验证的不是“切换”而是“追平”的能力——备库脱离一段时间后能否自动把缺失的日志补回来回到实时同步状态。触发方式很简单直接停掉备库实例# 在备库服务器上执行 DmServiceDMSERVER stop此时主库对外服务完全不受影响业务继续正常写入。注意观察主库的归档日志目录会发现文件在不断增加但因为备库不在线日志传输中断主库归档目录占用会持续增长。如果磁盘空间有限这里就是一个很现实的隐患。过一段时间建议至少让主库产生几十个归档日志重新启动备库实例。正常情况下备库启动后会自动从断点处请求主库补发缺失的日志不需要人工干预。在监视器里查看状态备库会经历RECOVERY状态到OPEN状态的转变。登录备库查FLAG_TEST表主库最新写入的数据应该已经同步过来。这个场景里最容易出的问题就是“归档断档”。如果主库的归档日志因为磁盘空间清理被删掉了备库就无法补传只能重新做一次全量恢复。所以日常运维中主库的归档日志保留策略必须和备库同步消耗速度匹配至少保留一天以上不要一归档就清理。3.4 场景四主备间网络心跳中断这个场景最刺激也最容易让人在演练时翻车。主备库之间的网络断开后备库不知道主库是否还活着主库也不知道备库状态如何两边都可能认为自己应该接管服务形成“脑裂”。达梦的守护进程设计上会尽量避免脑裂但前提是配置正确。触发方式可以这样在主库和备库之间的网络链路上做隔离或者直接用防火墙阻断MAL端口。# 在主库服务器上阻断到备库MAL端口的通信 iptables -A INPUT -s 备库IP -j DROP操作后观察监视器主备之间会断连守护进程会报告网络异常。这里关键要看两点第一备库是否会因为没有收到主库的心跳而自动提升为PRIMARY第二主库端是否会误以为备库全部下线而出现异常行为。默认配置下达梦不会在网络中断瞬间就自动切换而是会经过一个判断超时窗口避免主库只是短暂卡顿就触发切换。如果你的环境在演练中发现备库“抢主”很快或者两个节点同时变成PRIMARY那说明你的超时参数和仲裁策略需要调整。这个场景的演练结果往往不是“切换是否成功”而是“切换决策是否符合预期”。比如网络中断30秒后系统决定不切换等网络恢复后自动重新同步这算正常如果网络中断30分钟备库依然迟迟不切换那就要考虑是否需要调整超时参数。生产上我倾向于让网络断开的场景由人工介入决策因为自动切换在网络抖动时的误判率并不低。4. 故障模拟中常见的问题与排查方法故障模拟的价值不仅仅在于“成功切换”这个结果更多在于演练过程中暴露出的问题。我把自己见过、处理过的几类高频问题整理成了一张表看的时候可以对号入座。问题现象可能原因处理思路备库无法提升为PRIMARY备库缺少关键日志或备库状态不是STANDBY检查归档是否连续必要时重建备库切换后FLAG_TEST数据缺失实时归档有延迟或备库应用卡顿检查备库redo应用状态确认RPO监视器看不到集群状态守护进程未启动或MAL配置不一致按顺序重启守护进程和监视器主库归档日志持续增长备库不消费备库掉线且主库归档保留策略过短清理前先判断备库是否可以补传failover后老主库仍显示PRIMARY老主库未清理或网络恢复后角色冲突禁止强制启动老主库重建或重启后确认状态切换后应用无法连接数据库JDBC或ODBC连接串没有配置failover检查连接串配置多地址failover主备恢复后同步断档归档日志已被清理无法补传使用全量备份重建备库回切时原主库状态异常原主库存在未恢复日志或物理文件问题先恢复原主库到一致状态再执行switchover下面挑几个典型问题再展开说因为光看表格不一定知道具体怎么处理。4.1 备库无法切换为Primary的原因分析这个问题的出现频率非常高。某次演练中备库状态看起来一切正常但执行failover时报错说当前备库不允许切换。查日志发现备库的redo日志应用进度落后了主库一大截原来实时归档模式下备库虽然“在线”但应用日志的进程因为一个超大事务卡了很久表面上是同步状态实际数据滞后严重。排查思路是查看主备库的日志应用进度用V$RLOG和V$ARCH_STATUS等视图对比两端的日志序列号确认备库是否已经应用到最后一条日志。如果差得远就不要硬切换先让备库追平。这个场景也说明了为什么演练前要在非高峰期进行避免大事务干扰。4.2 切换后应用连不上数据库有一次演练切换整个过程非常顺利备库已经变成PRIMARY但业务应用的连接全部报错排查下来发现是应用连接串只写了原主库的IP没有配置备库地址。达梦JDBC驱动支持多地址连接串生产上建议从一开始就配置好别等切换了再改应用。示例连接串配置可以参考jdbc:dm://主库IP:5236,备库IP:5236?failoveronautoReconnecttrue这样主库故障时应用会自动尝试连接备库地址。当然如果应用层用了中间件或连接池也要同步检查连接池的故障转移配置这些不是数据库侧能解决的。4.3 回切失败的常见原因演练中“切过去”很开心“切回来”却经常卡壳。回切的前提是原主库已经修复好状态和新的主库一致。有人直接启动老主库结果它因为还保留着PRIMARY标识和新主库产生角色冲突。正确做法是先把老主库启动到MOUNT状态然后执行转换为STANDBY的操作再启动守护进程让它重新加入集群最后再执行一次计划内的switchover把主库角色切回老主库。回切命令我建议用switchover来做流程是可控的。如果老主库数据落后太多switchover会拒绝执行这时需要先通过日志修复让老主库追平。我在演练中至少遇到过两次因为老主库在故障期间还有其他独立写入导致角色切换时日志冲突最终只能靠备份重建耗时很长。5. 复盘与收尾让演练不止于演练所有故障场景都跑完之后最重要的工作就是复盘。不要觉得切换成功了就万事大吉整个演练过程的每个决策点、每个耗时环节、每个异常告警都值得仔细过一遍。我习惯用一张清单来做复盘你可以直接拿去改故障发现到切换启动花了多长时间这个时间有没有超出预期切换命令从发起到数据库角色变更完成花了多长时间切换完成后业务验证是手工做的还是自动做的耗时多久有没有出现备库追不上日志、归档断档、连接串失效这些问题故障期间监控告警是否及时告警信息是否准确有没有漏报误报演练结束时主备状态是否完全恢复正常同步是否实时演练过程中哪些操作是临时查手册才做的把这些操作沉淀成SOP。演练后配置、脚本、备份策略有哪些调整项补充分享一个我在复盘时经常用的小技巧。演练开始前我在两张表记录时间点一张是业务侧的时间戳FLAG_TEST一张是数据库日志中的切换时间。结束后把两张表的时间点放在一起对比就能还原出最接近真实的“故障时间线”。比如故障发生在10:00守护进程发现主库异常用了30秒failover执行用了45秒应用重新连上新主库用了1分钟最终RTO就是2分15秒。这个数字比任何监控大屏展示的都直观。再讲一点关于RPO的体会。使用实时归档模式时很多人以为数据完全不会丢但实际演练中发现如果在主库崩溃瞬间恰好有redo日志还没来得及传输这部分数据就会丢失。具体丢多少要看日志传输的实时性和网络延迟。我见过一个极端案例大事务产生的redo巨多传输滞后了十几秒崩溃后直接丢了十几秒的数据。所以演练之后一定要明确记录这个“丢数窗口”并把它同步给业务方让对方评估可接受性。最后说一个我个人一直坚持的习惯故障模拟不是一次性工作建议至少每季度做一次并且在每次数据库版本升级、服务器迁移、网络架构调整后都要补做一次。另外每次演练尽量让团队里不同角色轮流担任“故障指挥官”DBA、运维、应用负责人各自负责一块。毕竟真实故障发生时你的团队有没有形成肌肉记忆比任何架构文档都靠得住。演练结束大家一起把检查清单签完字把产生的新配置项和优化任务落实到下一迭代这才算真正完成了一次有价值的主备故障模拟。
返回列表