MySQL备份与恢复 #

一、备份概述 #

1.1 为什么需要备份 #

text
数据丢失原因:
├── 硬件故障
├── 软件错误
├── 人为误操作
├── 恶意攻击
└── 自然灾害

1.2 备份类型 #

类型 说明 特点
物理备份 复制数据库文件 速度快,依赖平台
逻辑备份 导出SQL语句 速度慢,可移植性好
全量备份 备份所有数据 完整但占用空间大
增量备份 只备份变化数据 节省空间,恢复复杂
差异备份 备份自全量以来的变化 介于两者之间

1.3 备份策略 #

text
备份策略示例:
├── 每周日:全量备份
├── 每天凌晨:增量备份
├── 每小时:二进制日志备份
└── 异地备份:定期同步到远程

二、mysqldump备份 #

2.1 基本用法 #

bash
# 备份单个数据库
mysqldump -u root -p mydb > mydb_backup.sql

# 备份多个数据库
mysqldump -u root -p --databases mydb test > databases_backup.sql

# 备份所有数据库
mysqldump -u root -p --all-databases > all_backup.sql

# 备份单个表
mysqldump -u root -p mydb users > users_backup.sql

# 备份多个表
mysqldump -u root -p mydb users orders > tables_backup.sql

2.2 常用选项 #

bash
# 只备份结构
mysqldump -u root -p --no-data mydb > structure.sql

# 只备份数据
mysqldump -u root -p --no-create-info mydb > data.sql

# 包含存储过程和函数
mysqldump -u root -p --routines --triggers mydb > full_backup.sql

# 压缩备份
mysqldump -u root -p mydb | gzip > mydb_backup.sql.gz

# 远程备份
mysqldump -h 192.168.1.100 -u root -p mydb > remote_backup.sql

2.3 一致性备份 #

bash
# 使用单一事务(InnoDB)
mysqldump -u root -p --single-transaction mydb > consistent_backup.sql

# 锁定所有表
mysqldump -u root -p --lock-all-tables mydb > locked_backup.sql

# 主从复制备份
mysqldump -u root -p --master-data=2 --single-transaction mydb > master_backup.sql

2.4 备份脚本示例 #

bash
#!/bin/bash

# 配置
DB_USER="root"
DB_PASS="password"
DB_NAME="mydb"
BACKUP_DIR="/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz"

# 创建备份目录
mkdir -p $BACKUP_DIR

# 执行备份
mysqldump -u $DB_USER -p$DB_PASS --single-transaction --routines --triggers $DB_NAME | gzip > $BACKUP_FILE

# 删除7天前的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

echo "Backup completed: $BACKUP_FILE"

三、物理备份 #

3.1 冷备份 #

bash
# 停止MySQL服务
systemctl stop mysql

# 复制数据目录
cp -r /var/lib/mysql /backup/mysql_cold_backup

# 启动MySQL服务
systemctl start mysql

3.2 热备份(使用Percona XtraBackup) #

bash
# 安装XtraBackup
# Ubuntu/Debian
apt-get install percona-xtrabackup-80

# CentOS/RHEL
yum install percona-xtrabackup-80

# 全量备份
xtrabackup --backup --target-dir=/backup/full --user=root --password=password

# 准备备份
xtrabackup --prepare --target-dir=/backup/full

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

# 修改权限
chown -R mysql:mysql /var/lib/mysql

3.3 增量备份 #

bash
# 创建基础备份
xtrabackup --backup --target-dir=/backup/base --user=root --password=password

# 创建增量备份
xtrabackup --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base --user=root --password=password

# 准备基础备份
xtrabackup --prepare --apply-log-only --target-dir=/backup/base

# 应用增量备份
xtrabackup --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1

四、二进制日志备份 #

4.1 开启二进制日志 #

sql
-- 查看二进制日志状态
SHOW VARIABLES LIKE 'log_bin';

-- 查看二进制日志文件
SHOW BINARY LOGS;

-- 查看当前二进制日志
SHOW MASTER STATUS;

4.2 配置二进制日志 #

ini
[mysqld]
log-bin=mysql-bin
binlog_format=ROW
expire_logs_days=7
max_binlog_size=100M

4.3 备份二进制日志 #

bash
# 刷新日志
mysqladmin -u root -p flush-logs

# 复制二进制日志
cp /var/lib/mysql/mysql-bin.* /backup/binlog/

# 使用mysqlbinlog备份
mysqlbinlog --read-from-remote-server --host=localhost --raw mysql-bin.000001

五、数据恢复 #

5.1 恢复逻辑备份 #

bash
# 恢复数据库
mysql -u root -p mydb < mydb_backup.sql

# 恢复压缩备份
gunzip < mydb_backup.sql.gz | mysql -u root -p mydb

# 在MySQL命令行中恢复
mysql> USE mydb;
mysql> SOURCE /path/to/backup.sql;

5.2 恢复单个表 #

bash
# 创建临时数据库
mysql -u root -p -e "CREATE DATABASE temp_db;"

# 恢复到临时数据库
mysql -u root -p temp_db < table_backup.sql

# 复制表到目标数据库
mysql -u root -p -e "
USE temp_db;
CREATE TABLE mydb.users LIKE users;
INSERT INTO mydb.users SELECT * FROM users;
"

# 删除临时数据库
mysql -u root -p -e "DROP DATABASE temp_db;"

5.3 时间点恢复 #

bash
# 恢复全量备份
mysql -u root -p mydb < full_backup.sql

# 应用二进制日志到指定时间点
mysqlbinlog --stop-datetime="2024-01-15 10:00:00" /var/lib/mysql/mysql-bin.000001 | mysql -u root -p

# 应用多个二进制日志
mysqlbinlog mysql-bin.000001 mysql-bin.000002 | mysql -u root -p

5.4 恢复误删数据 #

bash
# 1. 立即停止应用写入
# 2. 创建当前数据快照
mysqldump -u root -p --single-transaction mydb > current_snapshot.sql

# 3. 从备份恢复
mysql -u root -p mydb < backup.sql

# 4. 应用二进制日志(跳过误操作)
mysqlbinlog --start-datetime="2024-01-15 09:00:00" --stop-datetime="2024-01-15 09:30:00" mysql-bin.000001 | mysql -u root -p

六、自动化备份 #

6.1 定时备份脚本 #

bash
#!/bin/bash

# 配置
BACKUP_DIR="/backup/mysql"
DB_USER="root"
DB_PASS="password"
RETENTION_DAYS=7

# 创建日期目录
DATE=$(date +%Y%m%d)
BACKUP_PATH="${BACKUP_DIR}/${DATE}"
mkdir -p $BACKUP_PATH

# 全量备份
mysqldump -u $DB_USER -p$DB_PASS --single-transaction --routines --triggers --all-databases | gzip > "${BACKUP_PATH}/full_backup.sql.gz"

# 备份二进制日志
mysqladmin -u $DB_USER -p$DB_PASS flush-logs
cp /var/lib/mysql/mysql-bin.* $BACKUP_PATH/

# 清理旧备份
find $BACKUP_DIR -type d -mtime +$RETENTION_DAYS -exec rm -rf {} \;

# 记录日志
echo "$(date) - Backup completed" >> $BACKUP_DIR/backup.log

6.2 Crontab定时任务 #

bash
# 编辑crontab
crontab -e

# 每天凌晨2点执行全量备份
0 2 * * * /scripts/mysql_backup.sh

# 每小时备份二进制日志
0 * * * * /scripts/binlog_backup.sh

七、备份验证 #

7.1 验证备份完整性 #

bash
# 检查备份文件大小
ls -lh /backup/mysql/

# 检查备份内容
head -n 50 backup.sql
tail -n 50 backup.sql

# 验证SQL文件
grep "CREATE TABLE" backup.sql
grep "INSERT INTO" backup.sql

7.2 测试恢复 #

bash
# 创建测试数据库
mysql -u root -p -e "CREATE DATABASE test_restore;"

# 恢复到测试数据库
mysql -u root -p test_restore < backup.sql

# 验证数据
mysql -u root -p test_restore -e "SHOW TABLES; SELECT COUNT(*) FROM users;"

# 清理测试数据库
mysql -u root -p -e "DROP DATABASE test_restore;"

八、总结 #

备份恢复要点:

类型 工具 特点
逻辑备份 mysqldump 可移植,速度慢
物理备份 XtraBackup 速度快,依赖平台
增量备份 二进制日志 时间点恢复

最佳实践:

  1. 定期备份,自动化执行
  2. 异地备份,防止单点故障
  3. 定期验证备份可用性
  4. 制定恢复计划并演练
  5. 保留足够的历史备份

下一步,让我们学习性能优化!

最后更新:2026-03-26