mysqldump 是导出工具而非导入工具;执行 mysqldump -u root -p db_name 实际会导出数据库,无法完成导入操作,正确导入应使用 mysql 命令。

导入命令误用 mysqldump 而非 mysql
最常见却最容易被忽略的问题:用 mysqldump 命令尝试“导入”,它根本不是导入工具。执行 mysqldump -u root -p db_name 实际上是在做导出(且会覆盖 backup.sql),不会读取文件内容。真正该用的是 <code>mysql 客户端命令。
正确写法:mysql -u root -p db_name 。注意没有 <code>dump 二字;如果指定了端口或主机,用 -P(大写)和 -h,别漏掉数据库名作为最后一个参数。
SQL 文件含 MySQL 8.0 特有语法,目标库却是 5.7 或更老版本
比如导出时用了 MySQL 8.0 默认的 utf8mb4_0900_ai_ci 排序规则,或表定义里带 DATETIME(6)、JSON 类型、WITH 子句——这些在 5.7 中全都不认识,报错 ERROR 1064 (42000) 是必然的。
- 打开 SQL 文件,搜
CREATE DATABASE和第一个CREATE TABLE,看有没有utf8mb4_0900_ai_ci、JSON、DATETIME(、WITH - 降级导出:加
--compatible=mysql57参数重导(但注意会丢失部分语义,如引号转义逻辑) - 手动替换:把
utf8mb4_0900_ai_ci换成utf8mb4_general_ci,DATETIME(6)改成DATETIME
导出时未处理 DEFINER,导入后触发器/存储过程无法执行
报错 ERROR 1449 (HY000): The user specified as a definer ('xxx'@'yyy') does not exist,不是语法错,是权限上下文失效。MySQL 执行触发器时严格校验 DEFINER 用户是否存在且主机名完全匹配。
- 导出时加
--skip-definer,让 mysqldump 不写DEFINER=子句 - 已导出的文件,可用
sed -i 's/DEFINER=`[^`]*`@`[^`]*`//g' backup.sql批量清除(Linux/macOS) - 别只改触发器——视图、存储过程、事件也带 DEFINER,得一并清理
字符集与 sql_mode 不兼容,导入中途静默失败
即使 SQL 文件能解析,也可能在插入数据时崩:比如源库允许 '0000-00-00' 日期,但目标库 8.0 开启了严格模式,直接报 ERROR 1067 (42000): Invalid default value;或者中文变问号,其实是连接层字符集没对齐。
- 导入前先在目标库执行:
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; - 导入命令必须显式指定字符集:
mysql --default-character-set=utf8mb4 -u root -p db_name - 检查 SQL 文件头是否有
/*!40101 SET NAMES utf8mb4 */;;没有就说明导出时漏了--default-character-set=utf8mb4
DEFINER,又调用了 SELECT 却没写 INTO,还用了 NO_AUTO_CREATE_USER 相关逻辑——这种得一层层剥开修,不能指望一次替换搞定。











