MySQL 备份与容灾实战:从逻辑备份到主从复制的完整体系
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 增量 + 异地 + 定期演练,这套组合能覆盖绝大多数数据事故。把备份脚本、恢复手册、演练记录沉淀为团队的运维资产,你才能真正在深夜收到"误删数据"的电话时,保持冷静、按章操作、快速恢复。
读完了?给作者一点支持
评论区加载中…