【Day 33】Linux-MySQL 备份与恢复详解
(一)备份基础:核心概念与分类
在选择备份方案前,需先明确备份的核心维度,避免盲目操作。
维度 | 确认项 |
---|---|
需求明确 | 要保多久数据、故障后能接受丢多少数据(RPO)、多久能恢复业务(RTO)、需要恢复全库还是单表 / 单条数据; |
环境适配 | 数据库是什么引擎、数据量多大、业务忙不忙、服务器空间够不够、有没有从库可用、是否支持增量备份和时间点恢复、备份工具兼容和方案是否适配 |
风险规避 | 备份时数据会不会被修改、备份时会不会影响业务、备份后文件会不会损坏、恢复时能不能用(比如定期测试) |
1. 按备份数据范围分类
备份类型 | 定义 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
全量备份 | 备份整个数据库实例(所有数据库、表、结构 + 数据) | 恢复简单(直接恢复即可) | 备份文件大、耗时久、占用资源多 | 基础备份、小型数据库 |
增量备份 | 仅备份上一次备份(全量 / 增量)后变化的数据 必须按顺序恢复增量备份 | 备份文件小、速度快、资源占用低 | 恢复复杂(需先恢复全量 + 按顺序恢复增量) | 大型数据库 |
差异备份 | 仅备份上一次全量备份后变化的数据 | 恢复较增量简单(全量 + 最新差异)、文件比增量大但比全量小 | 备份文件随时间增大(直到下一次全量) | 中型数据库 |
2. 按备份时数据库状态分类
冷备份(离线备份):备份前需停止 MySQL 服务,确保数据无写入。
优点:备份文件一致性极高;缺点:业务中断,适用于非核心低峰期或测试环境。热备份(在线备份):备份时数据库可正常读写,无感知。
优点:零业务中断;缺点:需特定工具(如mysqldump --single-transaction、Percona XtraBackup),仅支持 InnoDB 引擎(MyISAM 不支持事务,无法热备份)。温备份(半在线备份):备份时数据库可读取,但禁止写入。
优点:业务只读不中断;缺点:影响写操作,适用于读多写少场景。
3. 按备份文件格式分类
逻辑备份:将操作备份为 SQL 语句文件,可跨版本、跨平台恢复。mysqldump
物理备份:直接拷贝数据文件。直接拷贝 MySQL 存储引擎的物理文件(如 .ibd .frm 文件),恢复速度快,但仅支持相同版本、相同架构的 MySQL。Percona XtraBackup
二、核心备份工具与方法
MySQL 官方及第三方提供了多种备份工具,不同工具适配不同场景。
1. mysqldump
// MySQL 自带的逻辑备份工具,通过导出 SQL 语句实现备份。
1.1 基础语法
- mysqldump 选项 数据库名 表名 > 备份文件.sql
需求 | 命令 | 说明 |
---|---|---|
全量备份(所有库) | mysqldump -uroot -p --all-databases > | 备份所有数据库(含系统库 mysql),需输入密码 |
单库备份 | mysqldump -uroot -p 库名 > | 仅备份此数据库 |
多库备份 | mysqldump -uroot -p --databases 库名1 库名2 > | 仅备份此数据库 |
单表备份 | mysqldump -uroot -p 库名 表名 > | 仅备份此库中的此表 |
热备份(InnoDB 引擎) | mysqldump -uroot -p --single-transaction 库名 | 通过事务快照实现热备份,不锁表(仅 InnoDB 生效) |
温备份(锁表) | mysqldump -uroot -p --lock-all-tables 库名 > | 加全局读锁,禁止写入,确保数据一致性,直到备份结束 |
在备份文件中记录备份时 MySQL 二进制日志(binlog)的文件名和位置 | mysqldump -uroot -p --master-date=1 > | =1 记录的 binlog 位置信息以非注释的 SQL 语句形式写入备份文件,恢复时会自动执行 =2 记录的 binlog 位置信息以注释形式写入备份文件,恢复时不会执行 |
1.2 案例显示
1、准备存放备份数据的目录
2、周一
① 全量备份
- # mysqldump -uroot -p --lock-all-tables --master-data=2 --all-databases > full_backup_$(date +%F_%T).sql
注意:--master-data 参数,备份文件中会自动记录备份开始时的 binlog 文件名和位置。
② 不加此参数的话, 备份完成后,需立即记录此时主库的 binlog 状态作为后续增量备份的起点
- SHOW MASTER STATUS; //
③ 模拟数据库变化,登录 MySQL,手动插入测试数据(生成 binlog 事件)
3、周二
(1)查看一会增量备份需要的起始位置和文件名
① 周一全量备份加了 --master-data参数
# grep "end_log_pos" 全量备份文件.sql | tail -1
② 全量备份时未加此参数但是手动记录了,直接使用
③ 全量备份时未加此参数且没手动记录
- 查看所有 binlog 文件,结合文件名的生成顺序,大致判断哪些文件包含需要的日志
#若知道索引文件路径
ls /Log/*.index
# 输出/Log/master.index
cat /Log/master.index
# 若不知道
grep "log_bin_index" /etc/my.cnf
# 输出log_bin=/Log/master
# 若未找到,查找数据目录 datadir(索引文件默认在 datadir 下)
grep "datadir" /etc/my.cnf
# 输出 datadir=/var/lib/mysql
ls -l /var/lib/mysql/binlog.*
- 查看日志,根据上次备份的时间,找到需要的位置
// 这里可知是1325
(2)增量备份
- # mysqlbinlog --start-position=起始位置 二进制日志文件名 > /db/bak/data_$(date +%F_%T).sql // 起始位置和文件名:基于上一次备份的终点信息
注意:mysqlbinlog 是解析 binlog 的工具,它生成的 SQL 文件中,每个事件都会明确记录 end_log_pos(事件结束位置)
(3)模拟数据库变化,登录 MySQL,手动插入测试数据(生成 binlog 事件)
4、周三
- # grep "end_log_pos" /db/bak/increment_tue_*.sql | tail -1
- //查看周二增量备份的最后位置(假设周二增量结束位置是2500)
- # mysqlbinlog --start-position=2500 /db/log/binlog.000021 > /db/bak/increment_wed_2025-08-27_10:00:00.sql
- //从2500位置开始备份周三的新增数据(假设binlog仍为000021)
5、模拟报错
- >DROP TABLE sul123.store; // 模拟故障:误删除store表
(7)临时关闭二进制功能(防止恢复过程生成新日志干扰)
(8)恢复周一的全局
(9)依次恢复增量
(10)根据二进制日志恢复未备份的数据
假设故障发生在周三增量备份后,需提取 “周三增量结束位置” 到 “故障发生前” 的 binlog 事件:
意思是备份到了8582
- SET sql_log_bin = 1; // 恢复binlog记录(可选,根据业务需求)
恢复后若用户无法使用,执行FLUSH PRIVILEGES;
或重新授权。
跨版本恢复时避免直接恢复 mysql
库:若从 5.7 恢复到 8.0,建议:
- 仅恢复业务库(排除
mysql
库); - 手动在新库中重新创建用户并授权(避免版本兼容问题)。
2. Percona XtraBackup(第三方物理热备份工具)
Percona XtraBackup(简称 PXB)是 Percona 推出的免费物理备份工具,支持 InnoDB 引擎的热备份,备份 / 恢复速度远快于 mysqldump,适用于大型数据库(数据量 > 10GB)。
(1)下载
(2)自动拷贝(会自动锁表)
(3)完全备份
(4)增量备份
(5)模拟损坏
(6)恢复备份数据
- # xtrabackup --prepare --apply-log-only --target-dir=/db/bak/data_2024-11-05_full/
- # xtrabackup --prepare --apply-log-only --target-dir=/db/bak/data_2024-11-05_full/ --incremental-dir=<第一次增量目录>
- # xtrabackup --prepare --target-dir=/db/bak/data_2024-11-05_full/ --incremental-dir=<最后一次增量目录> //准备最后一次增量备份时,不需要加--apply-log-only参数
- # xtrabackup --no-defaults --copy-back --target-dir=/db/bak/data_2024-11-05_full/ --datadir=原始数据目录 //恢复数据
- # chown -R mysql.mysql /db/data/ //修改权限并重启
(7)将未备份的数据恢复