目标数据库不存在时,需先手动创建空库再导入;若备份含create database语句,则需用sed替换库名或过滤建库/use语句,避免语法错误,并注意字符集、权限、sql模式及存储引擎兼容性问题。

恢复前目标数据库不存在怎么办
直接执行 mysql -u root -p target_db 会报错 <code>ERROR 1049 (42000): Unknown database 'target_db'。mysqldump 生成的 SQL 文件默认不带 CREATE DATABASE 语句(除非用了 --databases 或 -B 参数),所以目标库必须提前存在。
- 先登录 MySQL 创建空库:
CREATE DATABASE target_db CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;(字符集建议与原库一致) - 确认原备份文件是否含
USE old_db;—— 若有,导入时会自动切换,但前提是该语句指向的库名在当前实例中不能真实存在,否则可能覆盖错误库 - 更稳妥的做法是:用
sed或文本编辑器删掉备份文件开头的USE old_db;和CREATE DATABASE(如果存在),避免冲突
备份文件里有 CREATE DATABASE 怎么办
如果你当初用 mysqldump --databases old_db > backup.sql 或 mysqldump -B old_db > backup.sql 导出,文件开头会有类似 CREATE DATABASE IF NOT EXISTS `old_db` 和 USE `old_db`。直接导入会创建同名库,无法重定向到新库名。
- 用
sed -i 's/old_db/target_db/g' backup.sql替换所有库名(注意反引号和大小写) - 或者用
grep -v "^CREATE DATABASE" backup.sql | grep -v "^USE " > clean_backup.sql剔除建库和切换语句,再手动USE target_db;后source - 不推荐直接改
CREATE DATABASE行里的名字——因为后续CREATE TABLE语句可能仍带`old_db`.`table_name`全限定名,导致语法错误
用 source 在 MySQL 客户端内导入更可控
命令行管道导入(mysql -u ... )对大文件容易因超时、编码或换行问题中断;而 <code>source 是 MySQL 客户端内置命令,解析更稳定,也便于中途检查。
- 登录:
mysql -u root -p - 创建目标库:
CREATE DATABASE target_db; - 切换并导入:
USE target_db; source /path/to/backup.sql; - 若备份文件里有
USE old_db,source会尝试切换过去——此时它找不到old_db就会报错,反而帮你提前发现命名冲突
跨版本恢复时容易忽略的兼容性坑
MySQL 5.7 备份导入到 8.0 实例,或反过来,不是单纯“能跑就行”。mysqldump 默认输出格式会随版本变化,比如 8.0 默认启用 default_authentication_plugin=caching_sha2_password,而老备份里用户权限语句可能不兼容。
- 导出时显式指定兼容参数:
mysqldump --compatible=mysql40 --skip-triggers --no-tablespaces -u root -p old_db > backup.sql - 导入前检查目标库 SQL mode:
SELECT @@sql_mode;,若含STRICT_TRANS_TABLES,而备份里有隐式类型转换,可能报错中断 - 表引擎差异:MyISAM 表在 8.0 中虽支持,但已弃用;InnoDB 的页大小、压缩参数等也可能不向下兼容
CREATE USER 'xxx'@'%' IDENTIFIED WITH caching_sha2_password,而目标 MySQL 是 5.7,就会失败。遇到这类问题,先用 grep -n "CREATE USER\|GRANT" backup.sql 定位,手动删或注释掉权限部分,数据导入完成后再单独处理账号。











