学会MySQL数据备份与恢复,删库不跑路!
2020年2月,某上市公司运维人员因纠纷手动执行rm -rf /*,直接导致市值蒸发超10亿。
2022年5月,某电商平台因未配置备库,主库故障后宕机11小时,损失千万订单。
这些真实案例告诉我们:没有安全的数据库,就像没有安全绳的走钢丝——一次误操作就可能让业务坠入深渊。
在实际的运维过程中,做好数据库的备份和恢复至关重要,也是运维工程师和dba需要掌握的基本技能。
一、数据库需要哪些“后悔药”?
- • 冷备份(需停库):直接对数据库数据目录文件进行
tar
归档。 - • 热备份:使用
mysqldump
或XtraBackup
进行在线备份。 - • 增量备份:基于 binlog 或者 InnoDB 事务日志进行数据恢复。
1. 全量备份:整库的存档快照
逻辑备份:mysqldump(适合中小型数据库)
# 导出整个数据库
mysqldump -u root -p --all-databases > full_backup.sql
优点:跨版本兼容,单个 SQL 文件易于管理
缺点:恢复速度较慢,备份文件较大
需停机:否
物理备份:XtraBackup(适合大规模数据库)
# 全量备份
xtrabackup --backup --user=root --password=123456 --target-dir=/backups/full
优点:恢复速度快,适合 TB 级数据库
缺点:需与 MySQL 版本严格匹配
需停机:否(支持热备)
物理备份:Tar冷备(适合低频备份和迁移)
# 停库保障一致性(需停机!)
systemctl stop mysql
tar -czvf /backups/mysql_$(date +%F).tar.gz /var/lib/mysql/*
systemctl start mysql
优点:简单直观,操作简单,适合小型数据库或临时备份
缺点:必须停机,否则数据可能不一致
需停机:是
2. 增量备份:只存“变化量”的智能方案
依赖 binlog 日志(记录所有数据变更):
# 导出某时间点后的 binlog
mysqlbinlog --start-datetime="2024-01-01 00:00:00" mysql-bin.000001 > incr_backup.sql
优点:节省空间,可精确恢复到秒级
缺点:恢复流程复杂,需结合全量备份
需停机:否
二、数据备份方案怎么选?
备份类型 | 速度 | 恢复难度 | 适用场景 | 代表工具 | 是否需停机 |
逻辑全备 | 慢 | 简单 | 小数据量,跨版本迁移 | mysqldump | 否 |
物理全备 | 快 | 中等 | 大数据量,快速恢复 | XtraBackup | 否 |
binlog 增量 | 极快 | 复杂 | 需精确到时间点的恢复 | mysqlbinlog | 否 |
Tar 冷备 | 中等 | 简单 | 停机情况下的完整备份 | tar | 是 |
快照备份 | 最快 | 简单 | 云服务器 + 大容量存储 | LVM/云磁盘快照 | 否 |
黄金法则:
- 中小项目:每周全备 + 每日 binlog 增量
- 大型系统:物理全备(XtraBackup)+ 每小时 binlog
- 致命操作前:临时表级备份(如 ALTER TABLE 前)
三、XtraBackup:TB级数据库的“救世主”
1. 为什么选择 XtraBackup?
- 热备份:备份期间数据库正常读写,业务无感知
- 增量备份:仅备份变化的数据块,节省时间和空间
- 支持压缩加密:边备份边压缩,直传云端存储
2. 核心操作(以 MySQL 8.0 为例)
# 全量备份
xtrabackup --backup --user=root --password=123456 --target-dir=/backups/full
# 增量备份(基于上一次备份)
xtrabackup --backup --target-dir=/backups/inc1 --incremental-basedir=/backups/full
# 恢复数据(合并增量到全量)
xtrabackup --prepare --apply-log-only --target-dir=/backups/full
xtrabackup --prepare --target-dir=/backups/full --incremental-dir=/backups/inc1
四、如何避免数据灾难?
1. 误删数据恢复
mysql -u root -p < full_backup.sql # 导入全量备份
mysqlbinlog binlog.000002 | mysql -u root -p # 追增量日志
2. 突然断电后的恢复
InnoDB 自动恢复:MySQL 重启时,通过 redo log 自动回放未提交事务
手动检查:
mysqlcheck -u root -p --all-databases # 检查所有表状态
五、防翻车指南:必须知道的 5 个 Tips
- 备份验证:定期试恢复备份文件到测试环境
- binlog 必开:配置文件中确保有
log-bin=mysql-bin
- 监控告警:用 Prometheus 监控备份任务是否成功
- 多副本存储:备份文件至少存 3 份(本地 + 异机 + 云存储)
- 防删库大招:
-- 设置 sql_safe_updates 强制 WHERE 条件
SET sql_safe_updates=1;
六、数据库断电恢复
如果数据库没有备份的情况下,可以尝试如下方式恢复数据,降低损失
1. innodb_force_recovery:数据崩溃后的急救方案
在数据库异常崩溃或断电后,InnoDB 数据文件可能损坏,导致 MySQL 无法启动。此时,可借助 innodb_force_recovery
参数强制启动 MySQL,并尝试修复数据。
2. 使用场景
现象:MySQL 启动失败,日志中出现如下错误:
InnoDB: Database page corruption on disk or a failed file read
InnoDB: Crash recovery is in progress...
适用情况:
- 断电或强制关机导致 InnoDB 表损坏
- 数据文件(.ibd)损坏但未完全丢失
- 目标是紧急启动 MySQL,导出数据后重建数据库
3.操作步骤
第 1 步:修改配置,启用强制恢复模式
在 my.cnf
的 [mysqld]
段添加:
[mysqld]
innodb_force_recovery=1 # 从级别 1 开始尝试
第 2 步:逐级尝试启动
innodb_force_recovery
取值范围 1~6
,数字越大,修复越激进。
sudo systemctl restart mysql
检查日志,若仍无法启动,则逐级提高 innodb_force_recovery
级别。
级别 | 含义 |
1 | 忽略损坏页,尝试读取表 |
2 | 禁止后台线程(如 purge 线程)运行 |
3 | 不执行事务回滚 |
4 | 禁止插入缓冲合并 |
5 | 不查看 Undo 日志 |
6 | 不执行 redo 日志前滚 |
第 3 步:启动成功后紧急备份
mysqldump -u root -p --all-databases > emergency_backup.sql
如果发现部分表损坏,可以使用mysqlcheck 检查所有表的状态
mysqlcheck -u root -p --all-databases # 检查所有表状态
如果表损坏,可以使用'mysqlcheck'工具的'--repair'选项来修复表,
- MyISAM:支持
--repair
直接修复 - InnoDB:支持
--check
进行检查,但修复需结合innodb_force_recovery
如果确认损坏表为非关键表,导出数据库时也可以加--ignore-table并跳过指定表
mysqldump -u username -p --ignore-table=database_name.table_name database_name > backup.sql
mysql命令行导出数据库并跳过指定表
与其他类似工具相比,'mysqlcheck'是 MySQL 官方提供的工具,与 MySQL 数据库紧密集成,具有更好的兼容性和可靠性。
第 4 步:重建数据库
- 清空数据目录
/var/lib/mysql
- 重新初始化 MySQL
- 导入备份数据
注意事项
- 强制恢复模式下禁用写操作,只能用于数据导出。
- 临时方案,导出数据后应关闭
innodb_force_recovery
并重建数据库。 - 可能丢失数据,
innodb_force_recovery >= 4
可能导致事务丢失。
实战案例
场景:某电商数据库因机房断电无法启动。
- 设定
innodb_force_recovery=1
,启动失败。 - 设定
innodb_force_recovery=2
,启动成功,但部分表无法访问。 - 使用
mysqlcheck
检查表:
mysqlcheck -u root -p --all-databases --check --extended
- 设定
预防措施
硬件层面:
- 使用 UPS 防止断电。
- 启用 RAID 10 保障磁盘冗余。
数据库层面:
- 设置
innodb_flush_log_at_trx_commit=1
,确保事务日志实时写入。 - 定期执行
CHECK TABLE
检测表健康状态。
总结
innodb_force_recovery
是数据库崩溃后的应急方案,使用时需谨慎。真正的安全保障是 定期备份 + 备份恢复演练。
结论
小库轻量级:mysqldump + binlog
大库高性能:XtraBackup + 快照
作死保护:操作前手动备份关键表
结合物理备份与二进制日志,可实现任意时间点恢复(PITR):
- 每天凌晨 用 XtraBackup 做全量备份
- 每小时 采集一次 binlog 并上传到云存储
- 故障时 先用全量备份恢复,再重放 binlog 到指定时间点