mysqldump 不是万能迁移工具,大库或跨版本迁移易出错,导出导入须配对验证;--single-transaction 适用于 InnoDB 和 REPEATABLE READ 隔离级别,不锁表;--lock-all-tables 适用于混合引擎或老版本 MySQL,会全局读锁阻塞写入。

直接说结论:mysqldump 不是万能迁移工具,大库或跨版本迁移时容易出错,导出导入必须配对验证。
导出时加 --single-transaction 还是 --lock-all-tables?
选哪个取决于你的业务是否允许短时只读,以及 MySQL 版本:
-
--single-transaction适合 InnoDB 表,靠 MVCC 实现一致性快照,不锁表,但要求事务隔离级别是 REPEATABLE READ(默认),且不能有 DDL 同时执行; -
--lock-all-tables会全局加读锁,阻塞写入,适合混合引擎(比如含 MyISAM 表)或老版本 MySQL( - 如果导出时报错
ERROR 1290 (HY000): The MySQL server is running with the --single-transaction option...,说明服务器启用了--skip-innodb或禁用了事务引擎,只能换--lock-all-tables; - 导出前务必确认
max_allowed_packet足够大(比如设为 512M),否则大 BLOB 字段会截断。
导入失败常见报错和对应处理
导入不是“source xxx.sql”就完事,很多错误藏在细节里:
-
ERROR 1044 (42000): Access denied for user ... when using LOCK TABLES:用户缺少LOCK TABLES权限,加--skip-lock-tables导出,或给账号授予权限; -
ERROR 1062 (23000): Duplicate entry '...' for key 'PRIMARY':目标库已有数据,用--ignore-table=db.table跳过,或先清空再导入; -
ERROR 1231 (42000): Variable 'sql_mode' can't be set to the value of 'NO_AUTO_CREATE_USER':MySQL 8.0+ 已移除该 mode,导出时加--set-gtid-purged=OFF并手动删掉 dump 文件里的SET SQL_MODE行; - 导入卡住不动?检查是不是没关 autocommit:
mysql -u user -p -e "SET autocommit=0; SOURCE /path/dump.sql; COMMIT;"比单纯 source 快得多。
跨版本迁移(如 5.7 → 8.0)必须绕开的坑
mysqldump 本身不校验语法兼容性,但高版本新增的关键字、默认行为变化会导致导入失败:
- MySQL 8.0 默认启用
caching_sha2_password插件,但 dump 文件里建用户语句仍用mysql_native_password,导入后用户可能无法登录,需手动ALTER USER ... IDENTIFIED WITH mysql_native_password; -
utf8mb4_0900_as_cs是 8.0 默认 collation,而 5.7 dump 出来的可能是utf8mb4_general_ci,导入时若目标库未启用新 collation 会报错,建议导出时加--default-character-set=utf8mb4,并提前在目标库执行SET NAMES utf8mb4; - 用
mysqldump --no-tablespaces避免导出CREATE TABLESPACE语句(5.7 有,8.0 默认禁用),否则导入报错ERROR 3138 (HY000)。
真正麻烦的不是命令怎么写,而是导出和导入两端的字符集、SQL mode、GTID 状态、权限模型是否对齐——这些没法靠一个参数自动搞定,得一条条核对。










