恢复MySQL数据前须先确认备份类型并验证文件可读性、版本兼容性、是否含CREATE DATABASE语句及binlog状态;再清空原表,确保外键依赖的父表结构一并导入。

确认备份类型再动手,别直接 mysql -u root -p
90% 的恢复失败源于没看清备份文件本质。用 head -n 20 backup.sql 快速扫一眼:如果开头是 CREATE DATABASE、USE `xxx` 和大量 INSERT INTO,那就是标准 mysqldump 逻辑备份;如果全是二进制乱码或目录结构(如 ibdata1、xxx.ibd),那属于物理备份,不能用 SQL 导入方式处理。
常见错误现象:直接导入 XtraBackup 生成的压缩包,报错 ERROR 1064 (42000) —— 实际是把二进制当 SQL 解析了。
- 逻辑备份(
.sql):走 MySQL 客户端导入流程 - 物理备份(
.xbstream/backup_dir/):必须用xtrabackup --prepare+--copy-back - 混合备份(如 mysqldump + binlog):先全量导入,再用
mysqlbinlog补增量
导入大 SQL 文件时,别在 shell 里硬扛 mysql -u ...
超过 200MB 的 .sql 文件用重定向容易卡死、超时或内存溢出,尤其在低配 ECS 或 Docker 环境中。MySQL 默认会逐条执行并刷日志,没做任何优化。
实操建议优先用客户端内 source 并关闭约束:
- 登录后先执行:
SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0; - 再执行:
source /path/to/backup.sql; - 导入完立刻启用:
SET autocommit=1; SET unique_checks=1; SET foreign_key_checks=1;
若仍卡顿,加个进度提示:pv backup.sql | mysql -u root -p your_db(需提前 apt install pv)。
字符集不一致会导致中文变问号或报错 ERROR 1366 (HY000)
备份时用的是 utf8mb4,但目标库默认字符集是 latin1 或旧版 utf8,导入后所有中文字段显示为 ???,甚至建表失败。
解决方法不是改数据,而是对齐环境:
- 导入前在 MySQL 客户端执行:
SET NAMES 'utf8mb4'; - 确保目标库创建时指定字符集:
CREATE DATABASE your_db CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; - 检查 my.cnf 是否全局配置:
character-set-server = utf8mb4和collation-server = utf8mb4_unicode_ci
注意:utf8 在 MySQL 里实际是 utf8mb3,不支持 emoji 和部分生僻汉字,务必用 utf8mb4。
只恢复单张表?别全量导入再删数据
误删了 orders 表,但备份是整个库的 full_backup.sql,没必要重导全部——既耗时又可能覆盖其他新数据。
精准提取 + 恢复更安全:
- 用
sed或awk提取建表和插入语句:sed -n '/^CREATE TABLE `orders`/,/^INSERT INTO `orders`/p' full_backup.sql > orders_restore.sql - 或更稳妥地用
grep -A 500 "INSERT INTO \`orders\`" full_backup.sql | grep -E "^INSERT|^CREATE" > orders_restore.sql - 导入前先清空原表(如有):
TRUNCATE TABLE orders;,再source orders_restore.sql
注意:如果表有外键依赖,提取时要一并包含被引用的父表结构,否则 CREATE TABLE 会失败。
真正麻烦的从来不是命令怎么写,而是恢复前没验证备份文件是否可读、是否跨版本、是否缺 CREATE DATABASE 语句,以及是否忘了关 binlog 写入——这些细节一旦漏掉,恢复过程就会变成修罗场。











