MySQL 学习笔记(第六期):MySQL 备份与恢复
本笔记承接第五期,进入数据安全保障的核心------备份与恢复。涵盖:数据备份的重要性与分类、冷备份、逻辑备份(mysqldump)、增量备份与二进制日志恢复、以及多种恢复场景的实战操作。所有代码均已加以整理和注释。
一、数据备份的重要性
在生产环境中,数据安全性至关重要。任何数据的丢失都可能产生严重后果。
造成数据丢失的常见原因:
- 程序错误
- 人为误操作
- 运算错误
- 磁盘故障
- 灾难(火灾、地震)和盗窃
二、数据库备份的分类
| 分类角度 | 类型 | 说明 |
|---|---|---|
| 物理/逻辑 | 物理备份 | 直接复制数据库的物理文件(数据文件、日志文件等) |
| 逻辑备份 | 备份数据库的逻辑组件(表、视图、存储过程等),通常导出 SQL 语句 | |
| 数据库状态 | 冷备份(脱机备份) | 关闭数据库时进行备份 |
| 热备份(联机备份) | 数据库处于运行状态,依赖于日志文件进行备份 | |
| 温备份 | 数据库锁定表格(不可写但可读)的状态下进行备份 | |
| 常用工具 | mysqldump | 常用的逻辑备份工具 |
| mysqlhotcopy | 仅备份 MyISAM 和 ARCHIVE 表 | |
| 二进制日志 | 用于增量备份 | |
| Percona XtraBackup | 第三方热备份工具(免费) |
三、冷备份(物理冷备)
冷备份在数据库关闭状态下,直接打包数据目录。
3.1 完整冷备份步骤
bash
# 1. 停止 MySQL 服务
systemctl stop mysqld
# 2. 进入数据目录
cd /usr/local/mysql/data
# 3. 创建备份目录并打包数据文件
mkdir /mysql_bak
tar czf /mysql_bak/mysql-backup-$(date +%F).tar.gz *
# 4. 启动 MySQL 服务
systemctl start mysqld
3.2 冷备份恢复步骤(模拟数据丢失)
bash
# 1. 停止 MySQL 服务
systemctl stop mysqld
# 2. 清空数据目录(危险操作!仅演练时使用)
rm -rf /usr/local/mysql/data/*
# 3. 解压备份包到数据目录
tar xzf /mysql_bak/mysql-backup-2025-10-15.tar.gz -C /usr/local/mysql/data/
# 4. 恢复权限
chown -R mysql:mysql /usr/local/mysql/data
# 5. 启动 MySQL 服务
systemctl start mysqld
# 6. 验证数据是否恢复
mysql -e "SHOW DATABASES;"
优点 :简单、快速、恢复容易。
缺点:需要停机,不适合 7×24 小时生产环境。
四、逻辑备份(mysqldump)
mysqldump 是 MySQL 自带的逻辑备份工具,导出 SQL 语句,恢复时重新执行。
4.1 备份单个数据库
bash
mysqldump -u root -p school > /mysql_bak/school.sql
4.2 备份多个数据库
bash
mysqldump -u root -p --databases school mysql > /mysql_bak/school_mysql.sql
4.3 备份所有数据库
bash
mysqldump -u root -p --opt --all-databases > /mysql_bak/all.sql
4.4 备份单个表
bash
mysqldump -u root -p school student > /mysql_bak/student.sql
4.5 恢复逻辑备份
sql
-- 方法1:使用 mysql 客户端执行
mysql -u root -p school < /mysql_bak/school.sql
-- 方法2:登录后使用 source 命令
mysql> USE school;
mysql> SOURCE /mysql_bak/student.sql;
优点 :不需要停机,备份文件可读,跨平台。
缺点:备份和恢复速度较慢,适合中小规模数据。
五、增量备份与二进制日志恢复
增量备份基于 MySQL 的二进制日志(binlog),记录所有数据更改操作。配合全量备份,可实现时间点恢复。
5.1 开启二进制日志
编辑配置文件 /etc/my.cnf,在 [mysqld] 段添加:
ini
log-bin = mysql-bin
重启 MySQL:
bash
systemctl restart mysqld
二进制日志文件将出现在数据目录中,如 mysql-bin.000001、mysql-bin.000002 等。mysql-bin.index 文件记录所有日志文件列表。
5.2 增量备份完整流程
步骤1:进行全量备份
bash
mysqldump -u root -p school > /opt/school.sql
步骤2:刷新日志,产生新的 binlog 文件
bash
mysqladmin -u root -p flush-logs
此时新产生的 binlog 文件(如 mysql-bin.000002)只记录刷新之后的操作。
步骤3:模拟增量数据变更
sql
-- 插入新记录
USE school;
INSERT INTO student (name, age) VALUES ('美猴王', 75);
-- 再次刷新日志
mysqladmin -u root -p flush-logs
步骤4:模拟误删除操作
sql
-- 误删数据
DELETE FROM student WHERE id = 5;
DELETE FROM student WHERE id = 6;
5.3 使用 binlog 恢复数据
查看 binlog 内容(解码后)
bash
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000003
恢复:先恢复全量备份,再应用增量日志
bash
# 1. 恢复全量备份
mysql -u root -p school < /opt/school.sql
# 2. 应用 binlog 恢复增量数据(包括误删除之前的所有操作)
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000003 | mysql -u root -p
原理 :
mysqlbinlog将二进制日志转换为 SQL 语句,再通过管道执行。
5.4 精确时间点恢复
如果需要恢复到误操作之前的时间点,可使用 --stop-datetime 参数:
bash
mysqlbinlog --stop-datetime="2025-10-15 14:23:00" mysql-bin.000003 | mysql -u root -p
其他常用参数:
| 参数 | 作用 |
|---|---|
--start-datetime |
从指定时间开始恢复 |
--stop-datetime |
恢复到指定时间为止 |
--start-position |
从指定位置开始 |
--stop-position |
恢复到指定位置为止 |
六、备份策略最佳实践
| 策略 | 说明 |
|---|---|
| 全量备份 + 增量备份 | 每周一次全量,每天一次增量,保留最近 7 天 |
| 定期测试恢复 | 备份只有在恢复成功时才有效 |
| 异地存储 | 备份文件应复制到不同物理位置或云存储 |
| 逻辑备份与物理备份结合 | mysqldump 便于迁移,冷备份便于快速恢复 |
| 开启二进制日志 | 实现时间点恢复的必要条件 |
七、本期知识点归纳一览表
| 类别 | 知识点 | 关键命令/语句 |
|---|---|---|
| 冷备份 | 停机打包数据目录 | systemctl stop mysqld; tar czf backup.tar.gz * |
| 冷恢复 | 解压并恢复权限 | tar xzf backup.tar.gz; chown -R mysql:mysql |
| 逻辑备份(mysqldump) | 备份库/表 | mysqldump -u root -p dbname > backup.sql |
| 备份多个库 | --databases db1 db2 |
|
| 备份所有库 | --all-databases |
|
| 逻辑恢复 | 使用 mysql 客户端 | mysql -u root -p dbname < backup.sql |
| 使用 source 命令 | SOURCE /path/backup.sql; |
|
| 增量备份 | 开启 binlog | log-bin=mysql-bin 在 my.cnf |
| 刷新日志 | mysqladmin flush-logs |
|
| binlog 恢复 | 查看 binlog | mysqlbinlog --base64-output=decode-rows -v binlog |
| 应用 binlog | `mysqlbinlog binlog | |
| 时间点恢复 | --stop-datetime / --start-datetime |
|
| 清空表 | TRUNCATE vs DELETE | TRUNCATE(DDL,重置自增) vs DELETE(DML,可回滚) |
八、综合实战演练
假设场景:周二上午 10:00 全量备份,周二下午 14:00 发生误删除。需要恢复到 13:59 的状态。
bash
# 1. 全量备份(周一执行)
mysqldump -u root -p school > /backup/school_full.sql
# 2. 刷新日志,开始新的 binlog
mysqladmin -u root -p flush-logs
# 3. 用户正常操作(记录在 mysql-bin.000022 中)
# 4. 误删除发生在 14:00,执行时间点恢复
mysql -u root -p school < /backup/school_full.sql # 恢复全量
mysqlbinlog --stop-datetime="2025-10-15 13:59:59" /var/lib/mysql/mysql-bin.000022 | mysql -u root -p
# 5. 验证数据是否恢复到正确状态
重要提醒:生产环境执行恢复操作前,务必先备份当前状态,并在测试环境验证恢复步骤。
下一期预告:高可用架构之主从复制与读写分离(主从复制原理、一主两从搭建、Amoeba 读写分离配置与验证)。