MySQL 备份与容灾实战:从逻辑备份到主从复制的完整体系

打打工人2026-10-20数据库⏱ 5min

MySQL 备份与容灾实战:从逻辑备份到主从复制的完整体系

数据库备份是运维的最后一道防线。99% 的数据事故都不可怕,可怕的是"没有备份"或"备份不可用"。本文从备份类型讲起,到自动化备份、恢复演练与主从容灾,给出生产可用的完整方案。

一、备份类型的选择

| 类型 | 工具 | 特点 | 适用 | |------|------|------|------| | 逻辑备份 | mysqldump | 跨版本/跨平台恢复,慢 | 小库(<10GB)、迁移 | | 物理备份 | Percona XtraBackup | 快、在线热备 | 大库、生产环境 | | 二进制日志 | binlog | 增量、按时间点恢复 | 所有生产库 |

黄金组合:定期全量(XtraBackup)+ 持续增量(binlog)+ 定期演练恢复。

二、逻辑备份:mysqldump 的正确姿势

# 单库备份(带表结构)
mysqldump -u backup -p \
  --single-transaction --set-gtid-purged=OFF \
  --databases app_db > app_db_$(date +%F).sql

# 只备份数据(不含建库语句)
mysqldump -u backup -p --no-create-info \
  --single-transaction app_db > app_db_data_$(date +%F).sql

关键参数解读:

  • --single-transaction:InnoDB 下基于事务快照,备份期间不锁表,是热备的核心;
  • --set-gtid-purged=OFF:避免恢复时 GTID 冲突;
  • 备份账号只授予 SELECT, LOCK TABLES, SHOW VIEW 等最小权限。

三、物理备份:Percona XtraBackup

# 全量备份
xtrabackup --backup --target-dir=/backup/full \
  --host=127.0.0.1 --user=backup --password=xxx

# 准备阶段(应用日志,使备份一致)
xtrabackup --prepare --target-dir=/backup/full

# 恢复
xtrabackup --copy-back --target-dir=/backup/full

为什么大库用物理备份:mysqldump 对 100GB 库可能要跑几小时,XtraBackup 通过物理复制数据文件 + redo log 增量,速度提升一个数量级。

四、增量与时间点恢复:binlog 的妙用

4.1 开启 binlog

# my.cnf
[mysqld]
server-id = 1
log-bin = /var/lib/mysql/mysql-bin
binlog_format = ROW
expire_logs_days = 7

4.2 按时间点恢复

# 1. 恢复最近一次全量备份
mysql -u root -p < full_backup.sql

# 2. 应用备份点之后的 binlog(到误操作前的时刻)
mysqlbinlog --stop-datetime="2026-10-20 03:00:00" \
  mysql-bin.000012 mysql-bin.000013 | mysql -u root -p app_db

演练价值:这一整套命令只有在定期演练时才能确保手到擒来。

五、自动化备份脚本

#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR="/backup/db"
RETENTION_DAYS=14
DB_NAME="app_db"
DATE=$(date +%F)

# 全量备份
mysqldump --single-transaction --databases "$DB_NAME" \
  > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql"

# 压缩(gzip 或 zstd)
gzip -9 "$BACKUP_DIR/${DB_NAME}_${DATE}.sql"

# 清理过期备份
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +"$RETENTION_DAYS" -delete

# 上传异地(对象存储/SFTP),防本地磁盘一起损坏
rclone copy "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz" remote:backup/db/
# crontab 每日凌晨 2 点执行
0 2 * * * /opt/scripts/backup_db.sh >> /var/log/backup_db.log 2>&1

异地备份是底线:本地磁盘故障、机房火灾都会同时摧毁主库与备份,必须异地/异机一份。

六、主从复制:读写分离与容灾

6.1 搭建一主一从

-- 主库:创建复制账号并记录位点
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_pass';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;   -- 记录 File 与 Position
-- 从库:先导入主库备份,再启动复制
CHANGE MASTER TO
  MASTER_HOST='10.0.1.11',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl_pass',
  MASTER_LOG_FILE='mysql-bin.000012',
  MASTER_LOG_POS=123456;
START SLAVE;
SHOW SLAVE STATUS\G   -- Slave_IO_Running / Slave_SQL_Running 均为 Yes

6.2 主从延迟的监控

-- 从库执行,Seconds_Behind_Master 是延迟秒数
SHOW SLAVE STATUS\G

延迟持续增长时排查:从库 IO 压力、大事务、DDL 锁、单线程应用(可用 MTS 并行复制优化)。

6.3 故障切换(MHA / Orchestrator)

生产环境用 Orchestrator 等工具管理拓扑:主库宕机自动提升从库、迁移 VIP、通知告警。注意:自动切换只解决"可用性",数据丢失(半同步复制可缓解)取决于复制延迟。

七、恢复演练:备份的灵魂

演练场景:误删 app_db 核心表,恢复到 30 分钟前。
演练步骤:
1. 恢复最近全量备份到临时实例
2. 应用 binlog 到误删前时刻
3. 导出误删表数据,导回生产
4. 对比行数/关键业务校验

结论:没有演练过的备份等于没有备份。建议每季度全流程演练一次,并把演练时长计入 SLO。

结语

备份体系的完备度不取决于工具多先进,而取决于恢复路径是否被验证过。全量 + binlog 增量 + 异地 + 定期演练,这套组合能覆盖绝大多数数据事故。把备份脚本、恢复手册、演练记录沉淀为团队的运维资产,你才能真正在深夜收到"误删数据"的电话时,保持冷静、按章操作、快速恢复。

读完了?给作者一点支持

本文采用 CC BY 4.0 协议转载 · © 打工人

评论区加载中…

🔗 相关文章