分布式数据库的全局快照备份与跨区域灾备恢复,核心要解决的就是三个问题:怎么在不停机的情况下拿到一份完整的数据快照、怎么把这个快照安全地搬到异地、以及灾难真正发生时怎么在规定时间内把业务切过去并验证数据一致性。我们团队在过去一个季度里,针对TiDB、OceanBase和PolarDB三套主流分布式数据库做了完整的灾备演练,踩了不少坑,也总结了一套可复用的方法论,下面直接把干货全部摊开讲。

一、为什么分布式数据库的全局快照比单机数据库难十倍

单机数据库做备份,本质上就是把一个文件拷走。但分布式数据库的数据分散在多个节点、多个分片上,每个节点还有自己的Raft日志或者Binlog,时间线不统一。你如果逐个节点去备份,拿到的数据在逻辑上是"撕裂"的——A节点是T1时刻,B节点是T2时刻,拼起来根本不能用。所以全局快照的核心难点在于:必须在一个逻辑时间点上,把所有分片、所有副本的状态同时冻结,形成一个自洽的数据集。

目前主流的做法有三种。第一种是利用数据库自带的快照功能,比如TiDB的BR工具、OceanBase的物理备份模块,它们内部会协调一个全局一致性时间戳(TSO),在这个时间点上截断所有事务。第二种是从存储层下手,用LVM快照或者云盘快照对每个节点的磁盘做一致性快照,再通过脚本拼接。第三种是应用层双写,在业务代码里同时写两份数据,天然实现异地冗余,但改造成本最高。我们演练中主要采用第一种方案,因为对业务侵入最小。

二、全局快照备份的具体操作流程与关键参数

以TiDB为例,我们用BR(Backup & Restore)工具做全量快照。核心命令如下:

br backup full --pd "pd-node1:2379,pd-node2:2379,pd-node3:2379" \
  --storage "s3://backup-bucket/tidb-snapshot-20240615" \
  --rate-limit 500 \
  --concurrency 16 \
  --checksum

这里有几个参数必须讲清楚。--rate-limit设成500MB/s是为了不打爆生产网络带宽,我们实测超过800MB/s就会影响在线业务的P99延迟。--concurrency设16是因为我们有16个TiKV节点,每个节点一个线程并行备份效率最高。--checksum一定要开,不然备份文件损坏了你根本不知道,等到恢复时才发现数据是坏的就晚了。

备份完成后,我们会做两件事。第一是校验:用br validate命令对比快照的checksum和元数据,确认完整性。第二是把快照文件从对象存储同步到灾备区域的存储桶,用的是云厂商提供的跨区域复制功能,大概200GB的全量快照,跨区域复制耗时约45分钟。我们建议每周做一次全量快照,每天做一次增量快照(基于上次全量的差分),这样RPO可以控制在24小时以内。

三、跨区域灾备架构设计的核心要素

我们的灾备架构是"两地三中心":同城双活数据中心加一个异地灾备中心。同城两个机房之间用专线连接,延迟在1毫秒以内,跑的是同步复制,任何一个机房挂了另一个秒级接管。异地灾备中心距离主中心约800公里,用的是异步复制,数据延迟大概在3到5秒。这个架构的好处是:同城故障几乎无感,异地故障也能在分钟级恢复。

架构里有一个容易被忽略的细节:灾备中心的数据库集群不能是"冷备",必须是长期运行的热备。原因很简单,冷备意味着你要在灾难发生后先启动集群、再导入数据、再校验,这个过程可能要几个小时。热备集群平时就在接收异步复制的数据,随时可以提升为读写模式。我们的灾备中心OceanBase集群平时以只读模式运行,承接部分报表查询流量,既验证了数据可用性,又分摊了主中心压力。

四、灾备恢复演练的完整步骤与时间线

我们把演练分成四个阶段,每个阶段都有明确的时间目标和验收标准。

第一阶段:故障模拟与告警触发。我们在主中心人为断开数据库集群的网络,模拟机房级故障。监控系统在15秒内发出告警,运维团队在3分钟内确认故障并启动灾备预案。这个阶段考核的是监控覆盖度和响应速度。

第二阶段:流量切换。通过DNS切换和负载均衡器配置变更,把业务流量从主中心切到灾备中心。我们用的是加权轮询的方式逐步切流:先切10%流量观察5分钟,没问题再切50%,最后全量切换。整个切流过程控制在15分钟以内。这里有个坑:有些老旧的客户端连接用的是硬编码IP,切了DNS也没用,必须提前梳理所有直连IP的服务并改成域名方式访问。

第三阶段:数据一致性校验。流量切过去之后,我们立刻跑数据比对脚本,抽样检查关键业务表的行数、关键字段的聚合值。比如订单表的总金额、用户表的注册总数,这些指标在主备之间的差异必须为零。我们还会做一轮业务回归测试,跑预定义的200条核心交易链路,全部通过才算恢复成功。

第四阶段:回切演练。灾难恢复后,主中心修复完毕,需要把流量切回来。回切比正向切换更危险,因为要处理灾备期间产生的新数据。我们的做法是:先在主中心追平灾备期间的增量数据,做一次反向同步,然后再按正向切换的步骤把流量切回。回切耗时约30分钟。

五、演练中暴露的问题与优化方案

第一次演练我们暴露出三个严重问题。一是灾备中心的连接池配置和主中心不一样,切过去后连接数瞬间打满,导致部分请求超时。解决方案是把灾备集群的连接池参数提前调优到和主中心一致,并且做压测验证。二是跨区域的网络带宽在演练时被其他业务占满了,数据同步速度从预期的500MB/s降到了80MB/s,全量同步要5个多小时。后来我们申请了独立的跨区域带宽通道,并在非高峰期做同步。三是部分微服务的配置文件里写死了主中心数据库的地址,没有走配置中心动态下发,导致切流后这些服务连不上数据库。我们后来把所有数据库连接信息统一迁移到配置中心,支持运行时动态切换。

六、RPO和RTO的实际达成情况

经过三轮迭代优化,我们目前的指标是:RPO(数据恢复点目标)小于1分钟,因为同城同步复制几乎零丢失,异地异步复制的延迟在3秒左右。RTO(恢复时间目标)小于30分钟,从故障发生到业务完全恢复的端到端时间。这个指标在行业里属于中上水平,金融行业通常要求RTO小于15分钟,我们还有优化空间,主要瓶颈在流量切换和数据校验环节。

七、给其他团队的实操建议

第一,不要等到出事才做演练,至少每季度一次,而且要做"不通知"的突袭演练,才能暴露真实问题。第二,备份文件一定要做异地存储,主备同一个机房的备份等于没备份。第三,灾备切换的操作手册要写得像菜谱一样,每一步有命令、有预期输出、有回滚方案,不能靠人的记忆。第四,定期做数据恢复验证,光备份不恢复等于没备份,我们每两周会从备份里随机抽一份数据做一次完整恢复测试。第五,关注数据库版本升级对备份工具的兼容性,我们就遇到过升级后BR工具报错的情况,提前在测试环境验证非常重要。

分布式数据库的灾备不是一个技术问题,而是一个系统工程,涉及架构设计、网络规划、运维流程、团队协作等多个层面。把每一个环节都做到位,才能在真正的灾难面前不慌不乱。这篇总结里的方法和踩坑经验,希望能给正在做分布式数据库灾备建设的团队一些实实在在的参考。