SQL导入失败主因是语法不兼容,如MySQL 8.0导出的JSON类型、utf8mb4_0900_as_cs排序规则或WITH/CTE等新特性在5.7及更早版本不支持;应检查CREATE DATABASE/TABLE语句中的关键字与字符集,使用--compatible降级导出,并添加--skip-extended-insert分条插入,同时调大max_allowed_packet至256M。
导出的 SQL 文件导入失败,先看 ERROR 1064 或 syntax error
绝大多数“导不出又导不进”的问题,其实卡在语法不兼容上。比如 mysql 8.0 导出的 create table 里带 json 类型或 utf8mb4_0900_as_cs 排序规则,往 5.7 导就直接报错。别急着重导,先用文本编辑器打开 sql 文件,搜前几行的 create database 和第一个 create table,重点看里面有没有不认识的关键字或字符集声明。
- 常见雷区:
IF NOT EXISTS在老版本(如 5.1)不支持;WITH子句、窗口函数、CTE 都是 8.0+ 才有的 - 导出时加
--compatible=mysql40或--compatible=ansi可降级语法,但会丢部分特性(比如自动转义引号) - 如果文件里有
SET SESSION sql_mode,检查目标库是否允许该模式——有些托管服务(如阿里云 RDS)默认禁用STRICT_TRANS_TABLES
mysqldump 导出时没加 --skip-extended-insert,导入卡死或超时
默认 mysqldump 会把千行数据塞进一条 INSERT,看起来文件小,但导入时解析慢、内存吃紧、还容易触发 max_allowed_packet 限制。尤其在低配服务器或 Docker 容器里,导入中途静默退出,日志却只显示“Lost connection”。
- 重导建议加参数:
mysqldump --skip-extended-insert --compact ...,每行一条INSERT,便于定位哪条数据出问题 - 导入前确认目标库配置:
max_allowed_packet至少设为 256M(改完要重启或SET GLOBAL) - 用
mysql -u user -p db_name 导入时,别加 <code>-e(执行模式),它会跳过错误继续,掩盖真实问题
字符集不一致导致中文变问号或乱码,不是编码问题而是连接层没对齐
导出文件开头有 SET NAMES utf8mb4,但目标库的 character_set_client、collation_connection 没跟着设,或者客户端连接时没指定 --default-character-set=utf8mb4,结果 SQL 里的中文被按 latin1 解析了。
- 检查导出文件头三行:是否有
/*!40101 SET NAMES utf8mb4 */;?没有就说明 dump 时没设好源库字符集 - 导入命令必须显式指定:
mysql --default-character-set=utf8mb4 -u user -p db_name - 目标库建库语句如果写的是
CHARACTER SET utf8(不是utf8mb4),哪怕文件里全是utf8mb4,也会在插入 emoji 时截断或报错
用 phpMyAdmin 或 Navicat 导入大 SQL 文件失败,其实是 HTTP 或前端限制
这类工具走的是 Web 接口,上传文件大小受 upload_max_filesize、post_max_size、max_execution_time 三重限制,和数据库本身无关。你看到“导入失败”或进度条不动,大概率是 PHP 层先扛不住了。
- 查 phpMyAdmin 的
phpinfo()页面,确认upload_max_filesize≥ 你文件大小(注意单位是 M,不是 MB) - Navicat 的“运行 SQL 文件”功能对 >50MB 的文件极不稳定,换用命令行:
mysql -h host -P port -u user -p db - 如果必须用图形界面,先把 SQL 拆成多个小文件(用
split -l 1000 file.sql part_),再逐个导入
真正麻烦的不是语法或字符集,而是导出和导入两端的“隐式假设”不一致——比如你以为 mysqldump 默认兼容所有版本,其实它只保证跟本机 mysqld 版本兼容;你以为文件里写了 utf8mb4 就万事大吉,其实连接层一个参数没对上,中文照样变方块。










