确认备份类型再动手,别直接 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 写入——这些细节一旦漏掉,恢复过程就会变成修罗场。
