TiDB 备份恢复与容灾方案

一、备份恢复概述

1.1 为什么需要备份

即使 TiDB 提供了高可用能力(多副本、自动故障转移),备份仍然不可或缺:

场景 高可用能否解决 备份能否解决
磁盘故障 -
机房断电 -
误删数据
应用 Bug 损坏数据
勒索软件
合规要求 -

高可用解决的是硬件故障,备份解决的是人为错误和灾难

1.2 TiDB 的备份方式

方式 工具 特点 适用场景
物理备份 BR 速度快,备份 KV 层数据 大数据量
逻辑备份 Dumpling 兼容性好,备份 SQL 文件 小数据量、跨版本迁移
快照备份 BR + 外部存储 完整集群快照 灾难恢复
日志备份 + PITR BR 支持恢复到任意时间点 误操作恢复

二、BR 工具备份与恢复

2.1 BR 简介

BR(Backup & Restore)是 TiDB 的物理备份恢复工具,直接在 KV 层操作,速度远快于逻辑备份:

BR 工作原理:

  ┌─────┐  ┌─────┐  ┌─────┐
  │TiKV1│  │TiKV2│  │TiKV3│
  └──┬──┘  └──┬──┘  └──┬──┘
     │        │        │
     └────────┼────────┘
              │
          ┌───┴───┐
          │  BR   │  直接与 TiKV 通信
          └───┬───┘
              │
              v
      ┌───────────────┐
      │ 外部存储       │
      │ (S3/NFS/本地) │
      └───────────────┘

2.2 安装 BR

BR 通过 TiUP 安装:

# 安装 BR 组件
tiup install br

2.3 快照备份

# 备份到本地
br backup full \
    --pd "10.0.1.11:2379" \
    --storage "local:///backup/tidb/full-20240521" \
    --ratelimit 128 \
    --log-file backupfull.log

# 备份到 NFS
br backup full \
    --pd "10.0.1.11:2379" \
    --storage "nfs://10.0.3.100:/backup/tidb" \
    --log-file backupfull.log

# 备份到 S3
br backup full \
    --pd "10.0.1.11:2379" \
    --storage "s3://backup-bucket/tidb/full-20240521" \
    --send-credentials-to-tikv=true \
    --log-file backupfull.log

# 只备份特定数据库
br backup db \
    --pd "10.0.1.11:2379" \
    --db mydb \
    --storage "local:///backup/tidb/mydb-20240521"

# 只备份特定表
br backup table \
    --pd "10.0.1.11:2379" \
    --db mydb \
    --table orders \
    --storage "local:///backup/tidb/mydb-orders-20240521"

2.4 快照恢复

# 从本地恢复
br restore full \
    --pd "10.0.1.11:2379" \
    --storage "local:///backup/tidb/full-20240521" \
    --log-file restorefull.log

# 从 S3 恢复
br restore full \
    --pd "10.0.1.11:2379" \
    --storage "s3://backup-bucket/tidb/full-20240521" \
    --send-credentials-to-tikv=true

# 注意:BR 不支持通过 --filter 重命名数据库。
# 如需恢复到不同库名,可先用 BR 恢复到临时库,再通过 RENAME TABLE 迁移。
# 或使用 TiDB Lightning 的 "rename" 功能。

恢复注意事项

  • 恢复会覆盖目标库中的同名表
  • 恢复前建议先备份当前数据
  • 恢复期间集群性能会下降

2.5 备份验证

# 查看备份元数据(自动读取 backupmeta 文件)
br validate decode \
    --storage "local:///backup/tidb/full-20240521"

# 校验备份完整性
br validate checksum \
    --storage "local:///backup/tidb/full-20240521"

三、日志备份与 PITR

3.1 什么是 PITR

PITR(Point-In-Time Recovery)允许你将数据库恢复到任意时间点,而不仅仅是备份时刻:

时间线:

10:00  ── 全量备份
  │
10:30  ── 日志备份(持续捕获变更)
  │
11:00  ── 日志备份
  │
11:30  ── 误操作! DROP TABLE orders
  │
  v

恢复目标: 恢复到 11:29:59(误操作前一秒)

  ── 全量备份(10:00) + 日志回放(10:00~11:29:59) = 恢复点状态

3.2 开启日志备份

# 使用 BR 命令开启日志备份(需要指定 task-name)
br log start \
    --pd "10.0.1.11:2379" \
    --storage "s3://backup-bucket/tidb/log-backup" \
    --task-name log-backup-task

# 查看日志备份状态
br log status \
    --pd "10.0.1.11:2379"

3.3 PITR 恢复

# 恢复到指定时间点
br restore point \
    --pd "10.0.1.11:2379" \
    --storage "s3://backup-bucket/tidb/log-backup" \
    --full-backup-storage "s3://backup-bucket/tidb/full-20240521" \
    --restored-ts "2024-05-21 11:29:59+0800" \
    --log-file pitr-restore.log

恢复过程:

1. 从全量备份恢复到临时集群
2. 从全量备份时间点开始,重放日志到指定时间
3. 恢复完成

3.4 压缩日志备份

日志备份会持续产生数据,需要定期压缩:

br log truncate \
    --pd "10.0.1.11:2379" \
    --storage "s3://backup-bucket/tidb/log-backup" \
    --until "2024-05-20 00:00:00+0800"
# 删除 2024-05-20 之前的日志备份

四、使用 Dumpling 逻辑备份

4.1 Dumpling 备份

# 全量逻辑备份
dumpling \
    -h 10.0.1.14 \
    -P 4000 \
    -u root \
    -B mydb \
    -t 8 \
    -r 200000 \
    -o /data/dumpling/mydb-$(date +%Y%m%d) \
    --filetype sql

# 备份到 S3
dumpling \
    -h 10.0.1.14 \
    -P 4000 \
    -u root \
    -B mydb \
    --s3.region us-east-1 \
    --s3.endpoint https://s3.amazonaws.com \
    -o "s3://backup-bucket/dumpling/mydb"

4.2 Dumpling 恢复

逻辑备份使用 TiDB Lightning 或 mysql 客户端恢复:

# 方式一: 使用 mysql 客户端(小数据量)
mysql -h 10.0.1.14 -P 4000 -u root < /data/dumpling/mydb-schema.sql
mysql -h 10.0.1.14 -P 4000 -u root < /data/dumpling/mydb.table1.000000000.sql

# 方式二: 使用 TiDB Lightning(大数据量,推荐)
tiup tidb-lightning -config lightning-restore.toml

五、容灾方案

5.1 容灾等级

等级 方案 RPO RTO 适用场景
基础 备份 + 恢复 数小时 数小时 小业务
标准 PITR 秒级 数十分钟 一般业务
高级 主备集群 秒级 分钟级 核心业务
金融级 两地三中心 秒级 分钟级 金融业务

RPO(Recovery Point Objective):允许丢失的最大数据量(以时间衡量)
RTO(Recovery Time Objective):恢复服务所需的时间

5.2 主备集群容灾

主集群              同步              备集群
┌──────────┐    TiCDC/BDR     ┌──────────┐
│ TiDB     │ ──────────────>  │ TiDB     │
│ TiKV     │   实时/近实时     │ TiKV     │
│ PD       │                  │ PD       │
└──────────┘                  └──────────┘

正常: 写入主集群,实时同步到备集群
故障: 切换到备集群,备变主

搭建主备复制:

# 使用 BR 备份主集群
br backup full \
    --pd "primary-pd:2379" \
    --storage "s3://backup-bucket/primary-snapshot"

# 在备集群恢复
br restore full \
    --pd "secondary-pd:2379" \
    --storage "s3://backup-bucket/primary-snapshot"

# 使用 TiCDC 持续同步
# 注意:sink-uri 需指定具体数据库,如 mysql://root@host:4000/dbname
tiup cdc cli changefeed create \
    --server=http://primary-cdc:8300 \
    --sink-uri="mysql://root@secondary-tidb:4000/?time-zone=UTC" \
    --changefeed-id="primary-to-secondary"

故障切换流程:

1. 确认主集群不可用
2. 停止 TiCDC 同步(确保数据一致性)
3. 将应用连接切换到备集群
4. 备集群变为主集群
5. 修复原主集群后,反向建立同步

5.3 两地三中心部署

        机房 A (主)          机房 B (同城)         机房 C (异地)
     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
     │ TiDB x 2    │     │ TiDB x 1    │     │ TiDB x 1    │
     │ PD x 1(L)   │     │ PD x 1(F)   │     │ PD x 1(F)   │
     │ TiKV x 2(L) │     │ TiKV x 2(F) │     │ TiKV x 1(F) │
     └─────────────┘     └─────────────┘     └─────────────┘
          │                    │                   │
          └────────────────────┼───────────────────┘
                               │
                    Raft 5 副本跨区域复制

Region 的 5 个副本分布:

Region 数据:
  机房 A: 2 副本 (Leader + 1 Follower)  ← 低延迟读写
  机房 B: 2 副本 (Follower)             ← 同城容灾
  机房 C: 1 副本 (Follower)             ← 异地容灾

Raft 多数派 = 3 个副本
容忍: 任意 2 个副本故障

跨机房部署的延迟考量:

同城延迟 (1-3ms):  写入需要 3/5 确认,延迟增加 1-3ms
异地延迟 (20-50ms): 如果异地也参与投票,延迟显著增加

优化方案:
- 异地副本不参与 Raft 投票(Learner 角色)
- 使用 Placement Rules 控制副本分布

5.4 基于备份的容灾

这是最简单但恢复时间最长的方案:

定期备份:
  ── 每天凌晨 2:00 全量备份 (BR)
  ── 每 5 分钟日志备份 (PITR)

恢复:
  ── 从最近的全量备份恢复
  ── 重放日志到目标时间点
  ── 预计恢复时间: 数据量的 10-30%

六、备份策略最佳实践

6.1 推荐备份策略

全量备份:     每周一次(或每日,视数据量而定)
日志备份:     持续开启
保留策略:     全量备份保留 4 周,日志备份保留 7 天
存储位置:     至少 2 个异地位置
定期演练:     每季度做一次恢复演练

6.2 自动化备份脚本

#!/bin/bash
# backup.sh — 自动化备份脚本

BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/tidb/${BACKUP_DATE}"
LOG_FILE="/var/log/tidb-backup-${BACKUP_DATE}.log"
PD_ADDR="10.0.1.11:2379"

echo "开始全量备份: ${BACKUP_DATE}" | tee -a ${LOG_FILE}

br backup full \
    --pd "${PD_ADDR}" \
    --storage "local://${BACKUP_DIR}" \
    --ratelimit 128 \
    --log-file "${LOG_FILE}" \
    2>&1

if [ $? -eq 0 ]; then
    echo "备份成功: ${BACKUP_DIR}" | tee -a ${LOG_FILE}
    # 删除 7 天前的备份
    find /backup/tidb -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
else
    echo "备份失败!" | tee -a ${LOG_FILE}
    # 发送告警
    # curl -X POST "https://alert-url/webhook" -d "{\"text\":\"TiDB 备份失败\"}"
fi

6.3 Cron 定时任务

# 编辑 crontab
crontab -e

# 每天凌晨 2:00 执行备份
0 2 * * * /opt/scripts/backup.sh >> /var/log/tidb-backup-cron.log 2>&1

升级前建议先看 release notes,大版本之间有些参数默认值会变。另外生产环境升级建议先在一个 TiKV 节点灰度验证,观察一段时间没问题再全量升级。

1 个赞

收藏这个操作手册,做方案很好啊

版本升级前务必查阅官方 Release Notes,跨大版本常会出现配置参数默认值变更;生产环境上线升级优先选用单台 TiKV 做灰度试运行,平稳观测无误后再批量全集群升级。

收藏这个操作手册

感谢分享

收藏学习!

感谢分享 收藏学习