第十一章:备份与恢复
11.1 备份类型
按备份方式分类
| 类型 |
说明 |
优点 |
缺点 |
| 冷备份 |
停机备份 |
简单、一致性好 |
需要停机 |
| 热备份 |
在线备份 |
不影响业务 |
复杂、需要锁 |
| 温备份 |
读锁备份 |
折中方案 |
备份期间只读 |
按备份内容分类
| 类型 |
说明 |
恢复粒度 |
| 全量备份 |
备份所有数据 |
整个数据库 |
| 增量备份 |
备份上次备份后的变更 |
需要全量+增量 |
| 差异备份 |
备份与全量备份的差异 |
需要全量+差异 |
备份策略示意:
时间线:Day1 ────── Day2 ────── Day3 ────── Day4
全量: [Full]
增量: [Incr] [Incr] [Incr]
差异: [Diff] [Diff] [Diff]
11.2 mysqldump 备份
基本用法
# 备份单个数据库
mysqldump -u root -p mydb > mydb_backup.sql
# 备份所有数据库
mysqldump -u root -p --all-databases > all_backup.sql
# 备份多个数据库
mysqldump -u root -p --databases db1 db2 db3 > multi_backup.sql
# 备份单个表
mysqldump -u root -p mydb users > users_table.sql
常用选项
# 备份结构和数据
mysqldump -u root -p mydb > backup.sql
# 只备份结构(不含数据)
mysqldump -u root -p --no-data mydb > structure.sql
# 只备份数据
mysqldump -u root -p --no-create-info mydb > data.sql
# 添加 DROP TABLE 语句
mysqldump -u root -p --add-drop-table mydb > backup.sql
# 备份触发器、存储过程、事件
mysqldump -u root -p --triggers --routines --events mydb > backup.sql
# 压缩备份
mysqldump -u root -p mydb | gzip > mydb_backup.sql.gz
# 指定字符集
mysqldump -u root -p --default-character-set=utf8mb4 mydb > backup.sql
高级选项
# 备份单个事务(InnoDB)
mysqldump -u root -p --single-transaction mydb > backup.sql
# 锁定所有表
mysqldump -u root -p --lock-all-tables mydb > backup.sql
# 记录binlog位置
mysqldump -u root -p --master-data=2 mydb > backup.sql
# 包含建库语句
mysqldump -u root -p --databases mydb > backup.sql
# 定时自动备份脚本
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
mysqldump -u root -p'password' --all-databases --routines --events | gzip > /backup/mysql_${DATE}.sql.gz
find /backup -name "mysql_*.sql.gz" -mtime +7 -delete
11.3 MySQL Enterprise Backup
备份命令
# 在线热备份
mysqlbackup --user=root --password --backup-dir=/backup/ backup
# 备份并压缩
mysqlbackup --user=root --password --backup-dir=/backup/ --compress backup
# 部分备份(指定表)
mysqlbackup --user=root --password --backup-dir=/backup/ \
--include-tables='^mydb\\.users$' backup
# 创建增量备份
mysqlbackup --user=root --password --backup-dir=/backup/incremental \
--incremental backup
11.4 XtraBackup 备份
安装
yum install percona-xtrabackup
全量备份
# 备份
xtrabackup --backup --user=root --password --target-dir=/backup/full/
# 准备恢复
xtrabackup --prepare --target-dir=/backup/full/
增量备份
# 第一次增量备份
xtrabackup --backup --user=root --password \
--target-dir=/backup/inc1 --incremental-basedir=/backup/full/
# 第二次增量备份
xtrabackup --backup --user=root --password \
--target-dir=/backup/inc2 --incremental-basedir=/backup/inc1/
备份加密
# 创建加密密钥
openssl rand -base64 24 > /backup/keyfile
# 加密备份
xtrabackup --backup --user=root --password \
--encrypt=AES256 --encrypt-key-file=/backup/keyfile \
--target-dir=/backup/encrypted/
# 解密并准备
xtrabackup --decrypt --encrypt-key-file=/backup/keyfile \
--target-dir=/backup/encrypted/
11.5 恢复操作
恢复 mysqldump 备份
# 恢复整个备份
mysql -u root -p < mydb_backup.sql
# 恢复压缩备份
gunzip < mydb_backup.sql.gz | mysql -u root -p
# 恢复指定数据库(需要先创建数据库)
mysql -u root -p --one-database mydb < all_backup.sql
# 恢复时跳过外键检查
mysql -u root -p --init-command="SET FOREIGN_KEY_CHECKS=0;" mydb < backup.sql
mysql -u root -p --init-command="SET FOREIGN_KEY_CHECKS=1;" mydb
恢复 XtraBackup 备份
# 停止 MySQL
systemctl stop mysqld
# 清空数据目录
rm -rf /var/lib/mysql/*
# 恢复全量备份
xtrabackup --copy-back --target-dir=/backup/full/
# 恢复增量备份(依次 apply)
xtrabackup --prepare --target-dir=/backup/full/
xtrabackup --prepare --target-dir=/backup/full/ --incremental-dir=/backup/inc1/
xtrabackup --prepare --target-dir=/backup/full/ --incremental-dir=/backup/inc2/
# 修改权限并启动
chown -R mysql:mysql /var/lib/mysql
systemctl start mysqld
11.6 Point-in-Time Recovery
基于 binlog 恢复
-- 1. 查看当前 binlog 位置
SHOW MASTER STATUS;
SHOW BINARY LOGS;
-- 2. 找到需要恢复的时间点
mysqlbinlog /var/lib/mysql/mysql-bin.000001 | grep '2024-01-15 10:30:00'
# 3. 恢复步骤
# 步骤1: 恢复最近的全量备份
mysql -u root -p mydb < /backup/mydb_20240115.sql
# 步骤2: 应用 binlog 到指定时间点
mysqlbinlog --stop-datetime='2024-01-15 10:30:00' \
/var/lib/mysql/mysql-bin.000001 \
/var/lib/mysql/mysql-bin.000002 | mysql -u root -p mydb
# 步骤3: 或者恢复到指定位置
mysqlbinlog --stop-position=1000 --start-position=500 \
/var/lib/mysql/mysql-bin.000001 | mysql -u root -p mydb
11.7 备份策略建议
| 环境 |
备份策略 |
| 开发/测试 |
每日全量备份 |
| 小型生产 |
每日全量 + 每周全量 |
| 中型生产 |
每日增量 + 每周全量 |
| 大型生产 |
每小时增量 + 每日全量 + 远程灾备 |
备份脚本示例
#!/bin/bash
# backup.sh - MySQL 备份脚本
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d)
TIME=$(date +%H%M%S)
LOG_FILE="/var/log/backup.log"
# 创建备份目录
mkdir -p ${BACKUP_DIR}/${DATE}
# 全量备份
echo "[$(date)] Starting full backup..." >> ${LOG_FILE}
mysqldump -u root -p'password' --all-databases \
--triggers --routines --events \
--master-data=2 --single-transaction \
| gzip > ${BACKUP_DIR}/${DATE}/full_${TIME}.sql.gz
# 删除7天前的备份
find ${BACKUP_DIR} -name "*.sql.gz" -mtime +7 -delete
echo "[$(date)] Backup completed: ${BACKUP_DIR}/${DATE}/full_${TIME}.sql.gz" >> ${LOG_FILE}
11.8 本章小结
✅ 备份类型:全量、增量、差异
✅ mysqldump:通用备份工具
✅ XtraBackup:热备份,支持增量
✅ Point-in-Time Recovery:基于 binlog 恢复到任意时间点
✅ 制定合理的备份策略并定期测试恢复