YashanDB高可用实战:五条关键路径从备份到预案
半夜两点被值班电话吵醒大概率不是什么好事。去年有个客户项目就赶上这么一回DBA半夜接到告警某套YashanDB实例的磁盘空间满了归档日志写不进去数据库直接hang住。当时整个团队先是一脸懵——这块业务平时跑得挺稳怎么突然就挂了等把磁盘腾出来、手动拉起实例、追回缺失的日志已经是三个小时之后。复盘时发现问题其实不在磁盘满本身而是三个环节叠加备份策略没有覆盖归档日志关键指标没接进监控切换预案停留在纸面。这种场景我见过不止一次尤其是这两年从Oracle迁到YashanDB的团队SQL兼容性上手都很快但高可用与可靠性这套运维体系不少还停留在“能用就行”。这篇不打算讲大而全的理论而是结合我自己实操中踩过的坑把YashanDB高可用和可靠性的5条关键路径拆开备份恢复怎么做、主备复制怎么配、多节点集群什么时候上、监控告警怎么调、应急预案怎么落。看完之后你可以直接拿这份清单去检查自己环境里缺了哪层。1. 高可用到底在防什么先拆一遍YashanDB的故障面1.1 故障是一个面不是一条线“高可用”这个词用多了大家反而容易糊。我习惯先问自己和团队你要防的到底是谁很多人的第一反应是“防止数据库宕机”但宕机只是最终表现根因千差万别。我把这些年遇到过的数据库故障按来源大致分了分类故障类型典型场景我粗略的统计占比人为误操作删表、错误update、drop表空间35%硬件故障磁盘坏道、内存故障、网卡抖动25%数据库自身问题配置错误、版本BUG、归档中断20%环境类故障机房断电、网络分区、资源超卖20%这个分类想说明一件事误操作才是第一大故障源而不是硬件。硬件故障虽然动静大但通常有替代方案删错数据这种事真的是数据库层面一点办法都没有——如果你没有备份和恢复手段的话。另一个容易被忽视的点故障类型不同应对手段完全不同。硬件故障可以靠主备切换解决但误操作如果发生在主库上备库大概率也会有一样的问题因为复制同步过去的就是错误操作。这种情况下能救命的不是高可用集群而是备份和时间点恢复。所以高可用建设的第一步是正视这个“故障面”而不是只盯着某一个点。1.2 YashanDB架构里的四层高可用底座YashanDB是Oracle兼容度很高的国产关系型数据库装完实例你会发现目录结构、常见视图、SQL方言都有Oracle的影子。这对迁移团队是好事但也容易让人产生错觉觉得Oracle那套运维经验原样搬过来就行。实际上组件名、参数名、操作路径差异都不小而且不同版本能力边界不一样照抄容易出问题。如果从高可用角度去看YashanDB我习惯把它的能力底座分成四层存储层数据文件、重做日志的组织与管理方式决定恢复速度的上限。实例层内存结构、后台进程、SGA和各类内存参数决定单实例稳定性的下限。复制层主备同步机制决定故障切换能快到什么程度、最多丢多少数据。集群层多节点共享存储架构决定能不能在数据库层面对抗单机故障。四层里面最常被忽略的是存储层。我见过有人把数据文件和重做日志放在同一块盘上主库正常时没什么感觉一旦磁盘IO抖动日志写不进去整个实例就hang住。高可用设计首先要尊重一个原则重做日志、归档日志、数据文件的物理位置要适当分离减少单点争用。1.3 用RTO和RPO把目标量化不然全是空谈高可用建设不谈指标后面所有技术选型都是拍脑袋。这里引入两个运维圈公认的度量RTORecovery Time Objective恢复时间目标和RPORecovery Point Objective恢复点目标。RTO就是故障发生后系统需要多久恢复可用RPO就是允许丢失多少数据。举个例子你拍板定了“RTO小于30分钟RPO小于5分钟”含义是故障发生后30分钟内要恢复服务且最多丢5分钟以内的数据。这两个数字一旦定下来所有方案都能拿来做校准。只做每日凌晨一次的物理备份RPO天然就是24小时级别不够。加一个主备实时同步RPO才有条件压缩到秒级。完全不配置复制RTO只能按“人工介入、从备份恢复”来算主导权不在你手里。我见过很多团队上来就讨论该买多少台机器、该用什么集群软件问他们RTO/RPO是多少反而是沉默。这里没有标准答案金融核心和内部系统的容忍度天差地别但没有指标就谈不上高可用这个顺序必须反着来先定指标再选方案。2. 备份与恢复平时看不到价值出事全靠它兜底2.1 物理备份全量加增量的基础节奏先说第一种方法也是最基础的一种备份与恢复。物理备份的概念不复杂——把数据库的数据文件、控制文件、重做日志整体拷贝到备份介质恢复时把文件原样放回去速度最快、粒度最完整。YashanDB自带的备份通道基本沿用了成熟数据库的逻辑全量备份打底增量备份缩短恢复时间归档日志连续保留。我比较推荐的基础节奏是全量备份每周一次放在业务最低谷比如周日凌晨。增量备份每天一次比如凌晨2点减少恢复时需要重放的数据量。归档日志连续归档至少保留15天有条件就留30天。备份保留期至少保留最近两个完整周期。为什么全量要放周日而不是每天因为全量备份对磁盘IO有压力虽然YashanDB的备份支持在线执行业务高峰期跑全量还是会挤占资源。增量备份每天做可以把恢复窗口缩短到“最近24小时内的少量日志重放”同时也让备份文件本身更小、更不容易损坏。这里有个我自己踩过的坑归档日志的备份必须独立于数据文件备份。有几次我以为“全量备份已经包含归档了”结果恢复时发现日志有断层时间点怎么都补不齐。后来我改成全量备份完成后立刻把归档日志单独归档备份一次之后备份介质上同时存在“数据文件快照”和“日志增量”两个缺一不可。2.2 逻辑备份精确到表和行的后悔药物理备份恢复时是整体还原动辄整个实例或表空间级别比较重。逻辑备份则是把数据以SQL或标准格式导出来可以精确到表、模式甚至行。它的价值在误操作场景下特别突出。举个例子业务人员10:23误删了一张核心配置表物理备份恢复得把整个实例恢复到某个时间点影响面大、审批流程复杂逻辑备份如果恰好有当天早上9点的导出你可以直接只恢复这一张表把影响范围控制在表级别。这个区别在真实运维里太重要了。我的建议是在关键业务表上做额外的逻辑备份频率可以一天两次挂在任务计划里自动执行。有人觉得多此一举、占用存储但一次误删的教训抵得上存储空间那点成本。逻辑备份和物理备份不冲突它们解决的是不同粒度的问题物理备份解决“系统崩了怎么回来”逻辑备份解决“某个对象坏了怎么单捞”。2.3 时间点恢复把数据库恢复到误操作之前PITRPoint-In-Time Recovery时间点恢复是恢复体系里含金量最高的一环。它允许你选择某个精确时刻把数据库恢复到那一刻的状态。刚才那个误删场景如果能在10:23之前选一个时间点比如10:22:30恢复出来再把那几分钟的新数据补录几乎是无损救回。但PITR不是随便就能用的前置条件很严格必须有一个完整的基础全量备份。全量备份之后的归档日志必须完整无断层。必须能准确判断误操作发生的时刻。第三点最容易被忽略。很多人在恢复时“拍脑袋”选时间点选得比误操作时刻还晚恢复出来发现数据还是错的只能再折腾一轮。我的做法是恢复之前先查日志和审计记录把误操作的时间精确到分钟甚至秒再往前挪一点点留出安全余量然后才执行恢复。另外恢复前把现有归档日志再复制一份留底别在恢复过程中因为日志写入失败把唯一一份数据搞坏这种事听起来蠢但每年都有团队栽在上面。2.4 恢复演练比备份本身更有说服力备份做完不演练等于没做。这话我说了很多年但每次出事都能验证一遍。演练的价值在于备份文件存在 ≠ 备份文件可恢复。我遇到过的情况包括备份介质上的文件其实是坏的、归档日志中间断档恢复到一个点就报错、测试机和线上版本不一致导致恢复流程走不通。这些在演练里全部暴露过。恢复演练的具体做法准备一台隔离的测试机装好和线上同版本的YashanDB。从备份介质拷贝最近一次全量备份和增量备份。执行恢复流程查几张关键表的数据做校验。记录恢复耗时、报错点对比RTO目标是否存在差距。频率上我建议至少每个季度做一次金融类项目做到每月。演练还有一个额外好处把操作步骤跑熟了等真出事的时候团队不会手足无措因为按钮是点过很多次的。3. 主备复制把故障切换从小时级压到分钟级3.1 先想清楚同步模式再谈部署主备复制是解决“单台机器宕机”最常见的方案原理也不绕弯主库产生重做日志把日志传给备库并应用备库保持和主库近乎一致的数据状态。主库故障时备库可以迅速接管服务。真正需要认真想的是同步模式三种模式各有取舍模式数据安全性性能影响适用场景同步复制高提交前确认备库已收到受网络延迟影响明显同机房RPO要求极低半同步复制较高至少一台备库确认折中多数生产环境的折中选型异步复制低可能丢数据基本无额外延迟跨城容灾能接受少量丢失我的观点是很多人一上来就选同步复制理由是“数据不能丢”但没想清楚同步复制对主库写入性能的影响。如果主备在同一个机房、万兆内网同步复制带来的延迟通常可接受一旦跨机房部署、网络往返几百公里主库提交就会被拖慢业务等不起最后还是被迫改异步。比较合理的路线同机房主备用半同步或者同步保护最核心的业务库跨城容灾用异步复制同时接受“灾难级故障时可能丢最后几秒数据”的代价这些在RPO设计阶段就该讲清楚。3.2 部署过程中的几个关键配置细节YashanDB主备部署的具体命令不同版本略有差异但有几个配置逻辑是通用的我逐个说一下。归档模式必须开启。主备复制依赖重做日志的连续传递如果数据库没有跑在归档模式日志一切换就被覆盖备库就追不上了。这算是最基础也最容易被忽略的一步。备库参数和主库保持一致或更强。备库不只是用来顶着主库跑还可能承担只读查询。如果备库的SGA、CPU配置明显弱于主库平时没问题一旦切换上去性能断崖式下跌所谓高可用就变成了“可用但卡死”。网络带宽要提前压测。主备之间的日志传输是持续性的不是出事时才传。业务高峰期的日志量很大如果带宽不够日志堆积、备库延迟持续拉大复制就形同虚设。我见过一个案例主备间日志生成峰值约50MB/s但链路只有百兆备库延迟越拉越大最后切上去丢了大量数据。压测方法不复杂跑一轮峰值业务负载观察备库日志应用延迟确认链路余量。3.3 自动切换与脑裂防护别让备库“抢”成两个主库主备切换不是手动切一下那么简单真正的考验在于故障发生时能不能自动、正确地接管。自动切换机制通常依赖集群管理组件或外部仲裁关键在于防止脑裂——也就是主备之间网络异常备库以为主库挂了自己也升级成主库两边同时接受写入数据分裂这比宕机还可怕。脑裂防护的常见手段是仲裁节点和多数派原则核心思路是“避免双主”而不是“追求快速切换”。有些切换脚本本身写得比较草率只检查“ping不通主库”就触发提升这在网络抖动时很容易误判。我的建议是自动切换前有多重判定网络不通、实例进程异常、心跳丢失至少两个条件同时成立才触发切换。切换前必须有“隔离主库”的步骤比如强制踢掉主库的会话或通过存储层阻止主库再写入。人工接管通道要保留自动切换机制出问题时能让DBA介入做决定。这里面最反直觉的一点是让系统在切换上“慢一拍”反而更可靠。宁可多等30秒确认也不要因为一次网络抖动就来回切换把业务搞得更乱。3.4 复制延迟的监控与排查主备复制光配好还不够日常必须盯“延迟”这个指标。备库应用日志的速度赶不上主库生成日志的速度延迟就会累积最终表现为切换时丢数据、恢复时间拉长。我常用的排查路径延迟持续增大先看网络链路带宽占用率是否过高TCP重传是否频繁。再查主库日志生成速率有没有某张大表批处理导致日志暴增。然后看备库的资源情况备库IO是否被备份任务挤占内存是否不够导致排序频繁落盘。明确一点复制延迟不会自己消失它只会累积到一个阈值后触发告警。所以监控阈值要设梯度延迟超过某个阈值比如30秒告警提示超过更大阈值比如5分钟升级通知。等延迟变成小时级别再去处理基本只能靠重建备库来解决。4. 多节点集群从系统架构上消除单点4.1 什么时候该上多节点切换窗口才是核心指标主备复制能解决故障切换但切换过程是有窗口的备库要提升、应用要重连这个窗口往往按分钟算。如果业务对中断极度敏感希望应用无感知或接近无感知就需要进入第四种方法多节点集群。YashanDB支持多实例共享存储的集群部署思路和Oracle RAC同源多个实例同时挂载同一份数据文件任何一个实例宕机其他实例继续对外提供服务会话会自动迁移到存活实例上负载重新分配。对应用来说连接串里配置多个实例地址故障发生时基本是无感的。什么时候该上多节点我总结了几个条件业务连续性要求RTO小于1分钟主备切换的分钟级窗口满足不了。单实例的资源利用率已经接近天花板需要多实例横向扩展处理能力。团队有专职DBA能处理集群部署和故障诊断的复杂度。如果以上条件都不满足我反而建议老老实实做主备方案别追求架构上的“高级感”。多节点集群引入的管理复杂度是实打实的运维跟不上会变成一个更大的坑。4.2 部署前最容易低估的三件事多节点集群不是简单地多装几个实例有几个前置条件极其容易低估。存储是决定成败的底座。多节点共享同一份数据文件意味着所有写操作都要经过共享存储存储的IO能力和可靠性直接决定集群上限。存储必须自身具备高可用能力比如双控制器、副本机制否则存储反而成了最大的单点。一台存储挂了所有节点一起挂这种事故比单机故障更难恢复。网络质量要求比主备更高。集群节点之间需要频繁通信包括锁管理、缓存合并、心跳检测对网络的延迟和稳定性要求都很高。跨地域部署多节点基本不现实这个架构天然适合同机房或同城低延迟网络。节点配置要统一。多节点是负载均衡和故障转移一体的方案如果节点CPU、内存差异太大负载调度就会倾斜弱的节点反而成为瓶颈。配置统一可以简化问题别在这种地方省预算。4.3 节点故障后的行为与应用侧配合节点宕机时数据库层会自动处理连接转移但这不意味着应用什么都不用管。应用侧的连接池配置需要提前做好两件事连接串必须配置多个节点地址而不是只写一个主节点。连接池的创建和回收参数要调得合理空闲连接要定期探活避免故障后大量失效连接积压。我以前遇到过一次真实事故集群本身切换得很顺利数据库层只花了十几秒就恢复了但应用侧连接池里的旧连接全部失效应用在重连时没有快速释放失效连接导致后端涌入大量新连接数据库直接被压垮。别看数据库层做得再好应用侧的配合不到位整个链路依然会断。4.4 多节点和主备复制如何叠加使用多节点解决了单实例故障但它防不住“整库被误删”“机房级别灾难”这类问题。误操作、逻辑损坏、机房断电这些场景照样需要另外一份独立的物理备份和跨域容灾。所以在真实生产里比较完善的组合是同机房多节点集群处理单实例故障跨机房主备复制处理机房级灾难每天物理备份加逻辑备份处理逻辑错误三层各司其职。这里面的成本确实不低但高可用的价值本来就和业务重要性成正比核心系统投入多少都不为过边缘系统则不必这么奢侈。5. 监控告警与容量管理高可用是养出来的不是配出来的5.1 需要盯住的四类核心监控指标第五种方法听起来不像技术方案但恰恰是最容易被忽略的持续监控与容量管理。一套高可用架构上线之后如果没有配套监控它衰减成“低可用”只是时间问题。我习惯把监控指标分成四类可用性指标实例是否在线、主备状态、集群节点状态、监听端口连通性。这类指标出问题就是大事告警必须最高优先级。性能指标CPU、内存、磁盘IO、会话数、活跃SQL数量、锁等待。这些指标反映数据库“喘不喘得过气”。空间指标数据文件剩余空间、归档日志目录空间、备份介质空间。空间耗尽是我遇到的最多的“慢性杀手”而且往往是在凌晨爆发。复制指标主备延迟、归档日志生成速率、日志应用进度。复制延迟是切换能否成功的前瞻性指标。四类里空间指标最土但出事率最高。我见过归档目录满了、实例挂掉的次数比什么性能故障多得多。空间监控不要只看百分比要结合业务增长速度看“按当前速率还能撑几天”。5.2 告警阈值不是拍脑袋分层分级才有效告警阈值设得太宽松故障发生没人知道设得太敏感运维天天被误报骚扰最后连真告警也没人看了。这个问题我经历了一个明显的认知反转告警要做“减法”而不是“加法”。合理的做法是分层分级告警级别示例响应要求致命级实例宕机、主备切换、集群节点离线7x24小时电话通知立即响应严重级磁盘空间不足、复制延迟超阈值工作时间30分钟响应非工作时间次日处理警告级CPU持续过高、锁等待增多记录并观察纳入日报别一上来就设几十条告警每条都要响等于每条都不响。我建议先从最核心的20条开始跑一段时间再根据遗漏和误报做调整把告警体系“养”出来。另一个细节告警里的“持续”二字很重要。单次抖动不代表故障连续N分钟超过阈值才触发告警能过滤掉大量网络瞬时波动引发的假信号。这个N值要根据业务波动来定太短会天天误报太长会错过处理窗口。5.3 容量规划等打满再扩容就晚了容量管理和高可用是强关联的。磁盘打满、内存打满、连接数打满最终表现都是数据库不可用所以算容量其实是提前防止故障。我的做法是每月做一次容量评估拿趋势数据说话数据文件增长趋势按月增长率推算未来3个月空间需求。归档日志日增量决定归档目录和备份保留天数是否需要调整。峰值会话数和CPU使用率判断是否有必要提前扩容或调整参数。备份耗时趋势备份时间在拉长说明数据量增长已经影响到备份窗口。这里有一个很容易犯的错只统计数据文件大小不统计归档日志增长速度。有些库数据文件不大但修改频繁归档日志一天好几个GB日志目录区设计小了迟早出事。5.4 应急预案和故障演练把纸面预案变成肌肉记忆最后想说一件所有高可用技术之上、又最容易被跳过的事应急预案。技术方案再完美没有人按预案执行一切等于零。我们团队现在对每个核心系统都维护一份应急预案里面不写空话只写“第一步干什么、第二步干什么、谁负责、谁来复核、关键命令是什么”甚至包括“什么情况下要放弃抢救、切换到灾备”。每季度配合恢复演练一起做一次故障模拟让DBA按预案走一遍流程然后当场修订预案里对不上的地方。印象最深的一次模拟演练预案里写的备库IP已经变了切换脚本里的路径写错导致模拟切换时多花了近40分钟。真出事的时候这40分钟就是业务不可用的40分钟。高可用建设是一个持续迭代的过程不是上线当天就结束的项目。从我个人的体会来说很多团队对YashanDB的SQL兼容性充满信心却对高可用体系的建设缺乏同等投入。备份恢复、主备复制、多节点集群、监控告警、应急预案这五条路径没有哪条可以省略也没有哪条可以一次性做到位。如果你现在只做了其中一两层不用焦虑按这篇文章的顺序从这里开始补一层层加总比出事之后才想起来要好。