直接回答:把 sql 文件导入 MySQL 最常用的就两条命令——mysql -u 用户 -p 库名 < 文件.sql 或者进到交互界面后 source /路径/文件.sql。导入失败八成是三个原因:文件编码和连接字符集不一致、单条语句超过 max_allowed_packet、以及数据库里已经有同名表。
先看两种导入方式怎么选
| 方式 | 写法 | 适合场景 |
|---|---|---|
| 重定向 | mysql -uroot -p db < backup.sql |
大文件、脚本化、CI 里用 |
| 交互式 source | 进 mysql 客户端后 source /path/backup.sql |
临时导入、路径中含特殊字符不好处理时 |
两种本质一样,都是把 SQL 文本喂给客户端执行。source 的优点是可以先在客户端里 use 库名,并且出错时更容易看清是哪一行。
1 | # 方式一:连接时直接指定库 |
注意 -p 和密码之间不要有空格,-p 密码 会被当成两个参数。
导出:mysqldump 的常用姿势
导入之前通常先要导出:
1 | # 只导结构 |
--single-transaction 对 InnoDB 很重要:它让导出期间不锁表、仍然一个一致性快照,线上库备份尽量加上,避免影响业务写入。
导入大文件要注意的参数
几十 MB 以上的文件,直接导经常在中间报错。提前做这几件事:
1 | # 服务端:允许更大的单条语句 |
如果文件里有大量 INSERT,加上这两个参数能快不少(针对 InnoDB):
1 | mysql -u root -p mydb < full.sql \ |
代价是导入过程中不再做外键和唯一性检查,只在自己确认数据干净、且这段时间没人用它的时候用。
几个最常见的失败原因
1. 中文变成问号或乱码
导入和导出两端都要是 utf8mb4。老库里常见 utf8(其实是三字节的假 utf8),导到新库之前最好先把库和表统一改成 utf8mb4,否则 emoji 会直接报错。
2. ERROR 2006: MySQL server has gone away
基本就是单条语句超过了 max_allowed_packet。按上面的方法调大服务端和客户端两边的值,改完需要重连。
3. Table 'xxx' already exists
导入的库里已经有同名表了。要么在导出时带 --add-drop-table,要么导入前先删库重建:
1 | DROP DATABASE IF EXISTS mydb; |
4. 权限不足
导入需要 CREATE、INSERT 权限,带了建库语句还需要 CREATE DATABASE。用只读账号导入,报的错会让人以为文件有问题。
Docker 里导入的特别提醒
数据库跑在容器里时,mysql 客户端在容器内,你本地路径它看不见。两种做法:
1 | # 方式一:把文件拷进容器再导 |
方式二更简单:只要容器把 3306 映射出来,本地客户端连上去就行,文件根本不用进容器。但要注意大文件走网络可能比直接进容器慢,几 GB 的备份还是拷进容器更快。
导入完记得验证
导入成功不等于数据对。花一分钟确认一下:
1 | USE mydb; |
表数量对不上,往往是导出时漏了 --databases 或者漏了某张视图;行数对不上就去看导入日志里有没有被跳过的语句。
本文整理自我自己早先的操作笔记和一份入门资料,按"导出 → 导入 → 排查失败 → 验证"的顺序重新组织,并补充了 Docker 场景,文字由 AI 协助改写后经我复核。参数细节以所用 MySQL 版本的官方文档为准。
这篇笔记整理自我自己的实践记录,如果做法有出入,或者你踩过别的坑,欢迎到留言板一起聊聊。