MySQL 自带的备份恢复手段主要分两条路:逻辑备份用 mysqldump、mysqlpump、MySQL Shell 的 util dumpInstance,物理备份用 MySQL Enterprise Backup(商业版);恢复时再配合 mysqlbinlog 把二进制日志追到目标时刻。至于该用哪条,先别急着敲命令,用 mysql --version 看版本、用 SHOW VARIABLES LIKE 'log_bin' 看 binlog 是否真的开着,再查一遍库里有没有非 InnoDB 表,这三项基本决定了后面的命令能不能照抄。
适用场景:单库或中小数据量、需要跨版本迁移,优先选 mysqldump 做逻辑备份;数据量大、恢复时间要求紧,再考虑物理备份工具。动手前先确认版本、binlog 是否开启、是否存在非 InnoDB 表。验证方式是还原到独立实例,比对表数量与校验和。边界要说清楚:binlog 只记录基线备份之后的变更,没有基线备份,单靠 binlog 完不成恢复。
MySQL提供的备份恢复方法有哪些
这一步解决的是「你的实例上到底有哪些手段可用」,不是「立刻开始备份」。用下面几条命令核对,比翻文档猜快:
mysql --version:5.7 和 8.0 在参数名上有差别,8.0.26 之后--master-data改叫--source-data。mysqlsh --version:有输出说明 MySQL Shell 已装,可以用util dumpInstance/util loadDump做并行逻辑备份。mysqlpump --version:部分版本还带这个工具,但已被标记为废弃,新环境优先用 MySQL Shell。mysqlbackup --version:只有 MySQL Enterprise Backup 才有,命令存在才谈得上物理热备。mysql -e "SHOW VARIABLES LIKE 'log_bin'":Value 为 ON,才具备基于 binlog 的时间点恢复能力。mysql -e "SHOW BINARY LOGS":能列出文件,说明 binlog 确实在写,而不是只开了参数没落地。
如果 log_bin 是 OFF,那么「备份 + 追日志」这条路直接不通,只能恢复到备份那一刻,这个结论要提前告诉使用方,而不是等出事那天再说。
MySQL提供的备份恢复:先把能核对的事实摆清楚
先把对象和前提摆出来,这一节不下结论,只列能当场查到的项:
- 版本与引擎:
SELECT VERSION();,以及SELECT table_schema, engine, COUNT(*) FROM information_schema.tables WHERE table_schema NOT IN ('mysql','sys','information_schema','performance_schema') GROUP BY table_schema, engine;。出现 MyISAM 表,就要知道--single-transaction的一致性对它不成立。 - 数据量量级:
SELECT table_schema, ROUND(SUM(data_length+index_length)/1024/1024/1024,2) AS gb FROM information_schema.tables GROUP BY table_schema;,这个数字决定逻辑备份大概要跑多久。 - binlog 形态:
SHOW VARIABLES LIKE 'binlog_format';、SHOW VARIABLES LIKE 'gtid_mode';,ROW 与 GTID 会直接影响后面追日志的写法。 - 文件位置:
SHOW VARIABLES LIKE 'datadir';、SHOW VARIABLES LIKE 'log_error';。binlog 文件落在 datadir 下,报错去 log_error 指向的文件里看。 - 磁盘余量:
df -h /backup。逻辑备份通常比数据目录小,但别按「一定更小」来估算。
这些信息都能当场取到,先记下来;只要有一项和预想不一样,后面的参数就得跟着改,不能照抄。
MySQL提供的备份恢复最容易搞错的一点
最常见的误解是:开了 binlog、也做过一次 mysqldump,就等于「任何时刻都能恢复」。真正的分界线在于——binlog 只记录基线备份之后的变更,它必须挂在一个基线备份后面才有意义;没有基线,binlog 单独跑不起来。
性质相同的另一种误解是「把 datadir 拷一份就是物理备份」。分界点是一致性:mysqld 运行中直接 cp -r 数据目录,InnoDB 的 redo/undo 可能还没落盘,拷出来的文件不保证能启动。
能区分这两种情况的检查动作:
SELECT table_name, engine
FROM information_schema.tables
WHERE table_schema = 'appdb' AND engine <> 'InnoDB';只要返回了行,就说明 mysqldump --single-transaction 拿到的不是全局一致快照(该参数只对 InnoDB 生效);这类库要么改 --lock-tables(会阻塞写入),要么放到维护窗口做冷备,要么用物理备份工具。反过来说,返回空结果集,才能按 InnoDB 一致性快照这条路走。
MySQL提供的备份恢复:一个照着就能做完的做法
以 InnoDB 单库、8.0.26 及以上版本为例,替换库名、路径和账号后执行。
1)先准备一个只读备份账号和配置文件,避免密码进 shell 历史:
[client]
user=backup_user
password=替换成实际密码
host=127.0.0.1
port=3306保存为 /etc/my_backup.cnf,再 chmod 600 /etc/my_backup.cnf。

2)执行逻辑备份,并在 dump 文件头部记下 binlog 位点:
mysqldump --defaults-extra-file=/etc/my_backup.cnf \
--single-transaction --quick --routines --triggers --events \
--source-data=2 --set-gtid-purged=OFF \
--databases appdb \
> /backup/appdb_$(date +%F_%H%M).sql5.7 或 8.0.26 之前的版本,把 --source-data=2 换成 --master-data=2。执行期间终端不输出内容,跑完后应看到新文件生成,tail -n 3 备份文件 能看到 -- Dump completed on ...,这是第一个可核对的信号。
3)确认位点与 binlog 范围:
grep -m1 -E "CHANGE MASTER|CHANGE REPLICATION SOURCE" /backup/appdb_*.sql
mysql -e "SHOW BINARY LOGS;"记下 dump 头部的 binlog 文件名和 position,以及 SHOW BINARY LOGS 里当前最新的文件。恢复时只需要从备份位点往后追,之前的日志不必重放。
4)恢复基线:
mysql --defaults-extra-file=/etc/my_backup.cnf < /backup/appdb_20240601_0300.sql5)把 binlog 追到目标时刻:
mysqlbinlog --stop-datetime="2024-06-01 10:30:00" \
/var/lib/mysql/binlog.000123 \
| mysql --defaults-extra-file=/etc/my_backup.cnf开了 GTID 的实例改成按 GTID 追,避免位置号对不上:
mysqlbinlog --include-gtids='3E11FA47-71CA-11E1-9E33-C80AA9429562:1-100' \
/var/lib/mysql/binlog.000123 \
| mysql --defaults-extra-file=/etc/my_backup.cnf这里有个边界要留意:--set-gtid-purged=OFF 适合恢复到不带 GTID 的目标实例;如果要恢复到 GTID 集群节点,应改成 AUTO,并先确认目标库的 gtid_executed 不冲突。
MySQL提供的备份恢复:怎么验证结果对不对
备份文件生成成功不等于能恢复,得真还原一次。建议在另一台实例或容器里做,别在源库上验证。
- 还原时看
mysql客户端的输出:出现ERROR就停下来,不要继续追 binlog。 - 比对表数量:源库和目标库分别执行
SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='appdb';,数字应一致。 - 比对内容:
CHECKSUM TABLE appdb.orders;在两边各执行一次,同版本、同行格式前提下结果相同;大表会扫全表,挑关键表做就行。 - 核对行数:
SELECT COUNT(*) FROM appdb.orders;与源库同一时刻的计数比较。 - 看错误日志:
SHOW VARIABLES LIKE 'log_error';找到文件,检查还原期间有没有 InnoDB 相关的[ERROR]。
正常结果的样子是:dump 文件尾部有 Dump completed 行;还原全程无 ERROR 输出;目标库表数量与源库一致;抽查表的 CHECKSUM 相同;追日志时最后一条语句的时间不超过指定的 --stop-datetime。哪一项对不上,就回到「基线备份 + binlog 位点」这条链上找断点,而不是把命令重跑一遍。