MySQL提供的备份恢复方法是什么

文章导读
MySQL 自带的备份恢复手段主要分两条路:逻辑备份用 mysqldump、mysqlpump、MySQL Shell 的 util dumpInstance,物理备份用 MySQL Enterprise Backup(商业版);恢复时再配合 mysqlbinlog 把二进制日志追到目标时刻。至于该用哪条,先别急着敲命令,用 mysql --version 看版本、用 SHOW VARIABLES
📋 目录
  1. A MySQL提供的备份恢复方法有哪些
  2. B MySQL提供的备份恢复:先把能核对的事实摆清楚
  3. C MySQL提供的备份恢复最容易搞错的一点
  4. D MySQL提供的备份恢复:一个照着就能做完的做法
  5. E MySQL提供的备份恢复:怎么验证结果对不对
A A

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。

MySQL提供的备份恢复方法是什么

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).sql

5.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.sql

5)把 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 位点」这条链上找断点,而不是把命令重跑一遍。