
这个系列走到第四篇前面已经聊了不少GBase 8s高可用架构的形态、部署和基础配置。本来计划继续往下铺新特性但最近连续处理了几个客户的故障案例我改主意了想专门聊聊那些“架构图画得很漂亮、一到真实故障就露馅”的环节。GBase 8s的高可用架构网上能查到的拓扑图和官方文档已经够多了真正缺的是从“方案文档”到“生产可用”之间的那段距离切换逻辑到底怎么判断主库不可用数据同步的水位线卡在哪里备库提升为主库之后应用侧还有哪些坑这些细节才决定了一套数据库高可用架构能不能在关键时刻兜住底。这篇文章不打算复述概念我按方案选型、同步原理、自动切换、巡检演练、应急接管这个顺序讲每一部分都会带上实际生产环境里验证过的做法和踩过的坑。1. GBase 8s高可用不是一张拓扑图三条路线怎么选很多人一聊高可用就喜欢先画图主库一台、备库一台、中间画条双向箭头然后问“这样是不是就够了”。实际上GBase 8s的高可用体系里至少有三条截然不同的技术路线它们解决的是不同层面的问题选错路线才是生产事故的真正起点。1.1 HAC、SSC、RSS分别解决了什么问题GBase 8s官方体系里最常见的三个方案缩写是HAC、SSC和RSS。三套方案虽然都叫高可用但底层机制差别很大适用的故障场景也完全不同。方案同步机制RPORTO典型应用场景主要风险点HAC主备集群逻辑日志复制备库回放主库日志接近0秒级到分钟级同城机房双活、读写分离、快速故障切换依赖网络质量备库日志积压会影响切换完整性SSC共享存储集群多实例共享同一份数据文件0存储不丢才算数分钟级实例重新拉起应用层透明切换、数据库实例级故障保护存储仍是单点存储坏了整集群都受影响RSS远程备集群逻辑日志传递到异地备库接近0取决于网络分钟级到小时级异地容灾、灾难恢复网络延迟可能拉大同步延迟日常成本较高HAC的核心思路是“数据不动、实例复制”。主库每提交一个事务产生的逻辑日志会通过网络传给备库备库重新应用这些日志保持自己和主库处于相同的数据状态。这套机制的好处是备库也可以提供只读查询服务不会白白闲置一台机器。SSC则完全不复制数据所有实例共享同一套数据文件节点宕机后由其他实例继续提供服务切换成本低但存储设备一旦出问题整个集群没有撤退余地。RSS更像是一个“异地保险”它的数据同步跨地域可以做到几百公里外的灾备但一般不建议直接作为日常切换的主力。1.2 “能同步”不等于“能切换”我见过不少项目POC测试时只看数据能不能同步主库插入一条记录备库几秒后查到了就觉得高可用搞定了。这是很危险的理解。数据同步只是高可用链条的第一环真正决定业务连续性的是身份接管和连接迁移。备库哪怕数据完全一致如果它不知道“现在该我对外提供服务了”或者客户端还死盯着旧主库的地址业务一样是中断的。GBase 8s的CM连接管理器在这套体系里承担了流量调度和故障转移的决策角色但CM本身的配置、心跳网络的设计、仲裁机制的完善程度都会直接影响切换能不能成功。数据同步是“能不能切”的前提连接管理是“切了之后业务通不通”的保障两者缺一不可。1.3 选型时先回答三个问题我给客户做方案评审时一般先逼着业务方回答三个问题答清楚了方案自然就清楚。业务允许丢多少数据如果是资金流水一类RPO必须趋近于零那HAC是底线如果只是一般业务数据且有其他补偿机制RSS也能接受。业务能容忍多久不服务RTO决定了备份机制和切换自动化程度。RTO在分钟级必须配CM的自动切换能力RTO可以到小时级那手工切换也能接受。故障发生在哪个层级只担心数据库实例崩溃SSC性价比很高担心整个机房断电那就必须在另一个机房部署RSS担心运维误操作、逻辑损坏任何高可用方案都救不了必须叠加备份和误操作防护。这三个问题问完之后你会发现很多项目其实需要的是“HACRSS”的组合而不是单一方案。本地HAC负责日常故障秒级切换异地RSS负责机房级灾难兜底这才是一个完整的GBase 8s高可用保障体系。2. 决定RPO上限的两个水位线日志复制链路拆解HAC方案里有一个经常被忽略的细节备库和应用之间虽然看起来都叫“复制”但数据库的日志复制有严格的水位线概念。不理解这两个水位线就理解不了为什么有时候切换会丢数据为什么有时候主库还会反过来被备库拖慢。2.1 从主库日志落盘到备库应用中间发生了什么可以把主库的日志复制想象成一套快递流程。应用提交事务时主库先把事务的日志记录写到本地的逻辑日志缓冲区然后刷到磁盘上的逻辑日志文件这个动作完成之后事务才算真正提交成功。接着逻辑日志传送线程把已落盘的日志块通过网络发送给备库备库的接收线程拿到日志后写入自己的存储再由恢复线程把日志内容解析、回放到数据文件中。这条链路上任何一个环节慢下来都会在“主库日志当前位置”和“备库日志应用位置”之间拉开差距。这里有一个最容易误判的点主库提交成功只代表日志在主库本地落盘了并不代表备库也收到了。HMAC场景下如果主库提交完事务、日志还没传到备库时主库宕机这部分数据在切换后就丢了。所以HAC的RPO不是严格为零而是取决于日志传送链路的实时延迟。生产环境里这个延迟通常只有几百毫秒但遇到大事务、批量更新、网络抖动延迟会肉眼可见地放大。2.2 用onstat命令把同步延迟“看”出来GBase 8s提供了几个很直接的查看手段运维人员应该把这几条命令练成本能反应。onstat -g hac这条命令查看HAC备库的同步状态重点看备库接收日志的位置和已经应用日志的位置。输出里的关键字段一般包括主库当前日志序列号、备库接收到的日志序列号、备库已应用日志序列号。三者之间的差值就是当前的同步延迟量。正常情况下这个差值应该稳定保持很小只有毫秒级的时间差。如果差值持续增长说明备库应用日志的速度跟不上主库产生日志的速度。onstat -g rssRSS场景看这条命令关注点类似但要注意RSS备库的日志传送通常会有更大延迟因为它可能跨地域网络往返时间本身就高。onstat -l这条命令看逻辑日志空间的使用情况。同步延迟过大时主库已经写过的逻辑日志不能立即释放因为备库可能还要读取。如果逻辑日志空间被这些“等待传送”的日志占满主库的日志写入就会卡住严重时直接阻塞所有写事务。简单说我判断一套GBase 8s高可用环境是否健康第一眼永远先看这三个数字之间的差值。延迟稳定在毫秒级环境基本安全延迟出现秒级甚至分钟级波动就要进入排查模式了。2.3 日志积压场景一次批量更新引发的风险之前有个客户的HAC环境出现了奇怪的现象日常业务量不大同步延迟正常但每天定时跑一次报表批量更新任务时备库同步延迟就会暴涨高峰期能差出几分钟。主库逻辑日志空间也在不断报警。排查下来发现那张报表任务一次update语句要更新上百万行产生了巨量日志记录。日志传送线程虽然在全力转发但备库的单线程恢复机制根本来不及逐条回放积压就产生了。这个问题的解法不是改什么大参数而是从业务侧拆分。把批量更新拆成按分区、按主键范围分批提交每一批之间留出短暂停顿让备库恢复线程能够追上。同时把逻辑日志的数量和大小按峰值吞吐量重新评估避免积压期间把日志空间耗尽。那个案例之后我的习惯是凡是接入高可用环境的批量任务上线前必须做一次日志产生量评估不能只盯着功能正确性。3. 自动切换的本质系统如何“确认主库真的挂了”自动切换是最容易让人产生虚假安全感的功能。按钮和开关看起来都在但很多人没想过一个问题数据库系统不是人它怎么知道主库是“真挂了”还是“只是网络不通”判断错了要么该切没切导致长时间停服要么不该切乱切导致双主风险。这里面的机制比多数人想象的要复杂。3.1 连接管理器与FOC的决策流程GBase 8s的CM组件除了做连接分发还有一个FOCFailover Connection Manager角色专门负责自动切换决策。FOC的决策过程大概是CM配置了主库和备库地址通过心跳机制周期性检查各节点的存活状态。当主库心跳连续超时达到预设阈值CM会先确认备库的数据同步状态确认备库具备接管条件后执行提升备库为主库的动作然后更新自己的路由表把后续客户端连接引向新主库。整个流程里有两个关键点容易出问题。一是心跳阈值的设置阈值太短网络抖动就能触发切换阈值太长主库真宕机时业务中断时间会变长。二是数据同步确认CM提升备库之前必须判断备库日志应用到了什么位置。如果备库还差一大截日志没应用直接切换会产生明显数据丢失这种时候CM宁可等待或者放弃自动切换也不能盲目接管。3.2 心跳网络与脑裂防范心跳机制依赖网络而网络本身可能故障。如果心跳网络和业务网络混用业务高峰期出现拥塞、网络设备升级瞬间丢包都可能让CM误判主库失联。更危险的是脑裂场景主库还活着但因为网络隔离CM联系不上主库于是把备库提升为新主库。此时旧主库还在接受新的写入请求两个节点各自写入数据直接分叉。GBase 8s的高可用架构里防脑裂主要靠这样几层设计独立的心跳网段让心跳流量不受业务流量的干扰网络设备冗余避免单台交换机故障导致心跳中断配置合理的故障判定阈值和触发延迟给网络抖动留出缓冲时间关键生产环境引入第三方仲裁节点当两个节点都无法互相确认时由仲裁节点决定谁有资格继续服务。3.3 一次网络抖动引发的误判复盘我参与处理过一个故障某机房做网络设备升级操作过程里出现了几十秒的丢包。结果CM的心跳超时阈值设得比较激进丢包刚开始就触发了切换流程备库被提升为主库。等到网络恢复旧主库发现自己被剥夺了主库身份。幸好当时做了防脑裂配置旧主库没有继续提供服务否则就是一场双主事故。最终业务只中断了几分钟但这次事件暴露了一个问题自动切换的参数配置必须结合网络环境的真实稳定性来设计不能照抄默认值。我把那次的心跳阈值从秒级调整成包含连续多次探测失败才触发同时要求所有网络变更操作提前申请维护窗口。生产环境里最贵的不是自动切换功能而是对“什么时候不该切”的准确判断。4. 从“有方案”到“敢切换”巡检与演练的设计思路高可用架构部署完如果不经过反复验证本质上只是“纸面高可用”。我在给客户做验收时经常说一句话你敢不敢在业务低峰期主动拔掉主库电源然后站在旁边看着系统自动恢复不敢说明方案还没闭环。而要把这个“敢”字练出来靠的是巡检和故障演练。4.1 巡检不是看集群状态绿不绿多数团队的巡检就是看一眼集群管理页面状态显示正常就结束。但高可用真正要盯的是一组动态指标我日常巡检会固定看这几项主备同步延迟不管页面显示多健康都用onstat命令实测日志差值这个数字超过阈值就要处理。逻辑日志空间占用趋势特别是批量任务后是否出现积压回落。CM的心跳状态和FOC配置是否仍然正确有没有人在维护过程中改坏配置。备库恢复线程是否正常运行备库是否被测试脚本、报表查询意外拖垮。网络丢包率和延迟抖动指标心跳网络的健康度单独记录。数据库告警日志重点关注日志传送、连接管理器相关的错误信息。每次巡检不是“看一眼”而是把以上指标完整记录并对比上周趋势。很多故障不是突然发生的而是连续几周延迟缓慢增长没人发现最后在某次高峰彻底爆发。4.2 故障演练的三种标准剧本演练这套东西我最推荐的三个剧本覆盖了高可用的大部分风险场景。节点宕机演练在业务低峰期对主库执行模拟宕机操作观察CM能否在预期时间内完成自动切换应用侧连接能否自动恢复。演练完成后还要验证回切流程也就是把原主库重新加入集群恢复原来的主备关系。网络隔离演练断掉主库和CM之间的心跳链路观察系统会不会产生误判再断掉备库的网络观察主库是否还能正常工作。这个剧本专门用来检验脑裂防控机制。数据恢复演练模拟备库数据文件损坏或日志异常的场景验证RSS备库是否能在灾难情况下提供有效数据。这个剧本最能暴露“备份有了、但关键时刻不能用”的问题。每次演练要有明确的时间窗口、负责人、回滚方案而且演练结束后要当场出复盘报告。我最反对的演练方式是“找个时间按一下按钮看它切过去了就结束”那种演练只能证明切换功能本身可用证明不了整个链路可靠。4.3 我踩过的三个坑演练做得多了踩过的坑足够写一份很长的避坑清单但有三个坑我认为最具代表性。第一个坑演练前没检查备库日志积压情况。有一次直接从主库做强制切换动作结果备库因为没有完全应用完日志切换后丢失了前几分钟的事务数据。事后检查发现备库同步延迟早就不正常了但平时没人看。从那之后我的演练前检查单里第一项永远写的是“确认备库同步延迟处于正常范围”这一项不过就取消演练。第二个坑切换完成后只验证了数据库没验证应用的连接池。数据库层面新主库一切正常但应用服务器缓存了旧的连接信息客户端请求还是不断发往已经失效的地址业务恢复时间被白白拖长。现在演练脚本里一定包含应用侧连接验证和连接池重启步骤。第三个坑回切流程不走心。原主库恢复后直接把它当作备库重新接入集群忽略了它离线期间的日志差异和身份信息问题导致节点重新加入失败。正确做法是先按GBase 8s的机制补齐日志、确认节点身份再执行回切操作。回切比切换更容易出事故因为它往往是凌晨三四点、团队注意力最差的时候在做。5. 主库真挂了的应急全流程被动等待与主动接管自动切换做得再完善也总有需要人上手的时候。CM自动切换失败、主库和备库同时失联、或者网络分区让CM不敢做决定这些场景下DBA必须在几分钟内做出判断和执行操作。这一节的应急流程我建议每个团队都打印一份贴在机房里。5.1 什么故障该切什么故障不该切不是所有主库故障都适合立刻切换。我先给一个简单的判断维度。主库进程崩溃、服务器宕机、硬件故障这类场景适合立刻切换备库数据状态通常比较新。主库存储出现IO悬挂、文件系统异常但数据库进程还活着切换决策要谨慎先确认备库是否也受影响。网络分区导致CM与主库失联但两者其实都活着此时切换需要仲裁机制或者人工确认后决定是否接管。逻辑错误、误操作、数据被批量删除这类故障靠切换解决不了备库大概率也同步了错误操作必须依赖时间点恢复或备份而不是盲目提升备库。5.2 手动接管的标准步骤当自动切换没有生效需要DBA手动接管时我建议按下面这个顺序操作每一步都有目的。停止旧主库的对外服务或确认它确实不可用避免两个节点同时写的风险。这一步的目的是把写入入口收敛到一个点。登录备库用onstat命令检查同步状态确认日志应用位置是否停留在最新合理位置。如果延迟过大先评估可接受的数据损失范围。提升备库为主库执行对应角色切换命令让备库接管主库身份并开始对外提供写入服务。验证新主库数据完整性抽查关键业务表数据、确认关键事务没有异常丢失同时观察告警日志。更新CM配置和路由信息确保客户端连接请求被引到新主库这一步最容易遗漏也最影响业务恢复。通知应用团队重启连接池或更新连接串然后持续观察业务流量是否恢复正常。手动接管最怕的也是顺序颠倒。有些DBA一上来就急着提升备库完全没确认旧主库状态结果两个节点同时认为自己是主库后面的数据清理工作远比切换本身更痛苦。5.3 备库日志延迟很大的时候怎么取舍应急场景里最真实的冲突是备库同步延迟明显数据有缺口但业务已经停了好几分钟。这时候要做一个不完美的决定。我的处理原则是量化损失再决定。先在备库上确认日志应用位置距离主库最终提交位置差了多少通过日志文件大小、时间范围估算出大致的数据缺失窗口。如果缺失窗口只有几十秒且不是关键业务直接接管事后通过日志分析和业务补偿机制补齐数据。如果缺失窗口很大先确认有没有其他数据来源比如异地RSS备库或者最近的逻辑备份综合考虑恢复速度和数据完整性再决定。这种情况下最忌讳的是犹豫不决。高可用架构存在的意义是让业务连续如果数据缺失在可接受范围内先恢复业务一定是第一优先级。等业务恢复后再把旧主库降级为备库利用日志补齐机制尝试追回数据。我之前遇到过主库磁盘损坏、日志完全读不出的极端情况最后只能接受数据损失到最近一次成功备份的时间点这个教训让团队把“备份有效性验证”提升到了和“高可用切换演练”同等重要的位置。高可用保障方案解析得再多最终落点还是“关键时刻是否真的敢切、会切、能切”。这套逻辑在GBase 8s上适用放在其他数据库上思路也完全通用。