mysql使用mysqldump进行版本迁移与数据导出

来源:这里教程网 时间:2026-02-28 20:44:43 作者:

mysqldump 导出时指定 --compatible 参数能解决跨版本兼容问题吗

不能直接解决,但能缓解部分语法差异。MySQL 5.7 和 8.0 之间存在默认 SQL 模式、保留字、JSON 函数等不兼容点,

--compatible
只控制导出语句的“外观”,比如去掉
DEFINER
、禁用
ENGINE=InnoDB
显式声明、避免使用
ROW_FORMAT
等,但它不会重写
JSON_EXTRACT()
或自动降级窗口函数。

实操建议:

导出 MySQL 8.0 库到 5.7 时,必须加
--compatible=mysql40
--compatible=ansi
,否则可能含
utf8mb4_0900_as_cs
这类 8.0 特有排序规则
若目标库是 5.7,优先在源库执行
SET SESSION sql_mode='NO_ENGINE_SUBSTITUTION';
再导出,比依赖
--compatible
更可靠
--compatible
不影响数据内容,只改 DDL 语句格式;BLOB/TEXT 字段、时间戳精度丢失等问题需另作处理

导出大表时如何避免锁表和超时

默认

mysqldump
对 InnoDB 表加
SELECT ... FOR EXPORT
(5.6+)或
FLUSH TABLES WITH READ LOCK
(老版本),会阻塞写入。关键不是“要不要锁”,而是“用什么方式锁”。

实操建议:

强制启用一致性快照(推荐):
mysqldump --single-transaction --skip-lock-tables
—— 仅对 InnoDB 有效,不锁表,但要求事务隔离级别为
REPEATABLE READ
跳过统计信息收集(加速元数据获取):
--skip-tables-list
不适用,改用
--no-tablespaces
+
--skip-triggers
(若无需触发器)
超时由客户端控制:
mysql --connect-timeout=30 --net-read-timeout=3600
不影响
mysqldump
,应改用
mysqldump --net-timeout=3600
(注意这是 MySQL 8.0.22+ 新增参数)
分表导出更可控:
mysqldump db_name table1 table2 > dump.sql
,避免单文件过大导致恢复失败

导入时提示 ERROR 1231 (HY000): Variable 'sql_mode' can't be set to the value of 'NO_AUTO_CREATE_USER'

这是 MySQL 8.0 移除了

NO_AUTO_CREATE_USER
模式值,但 mysqldump 在 5.7 导出的文件里仍会写入该设置。导入到 8.0 时直接报错,且无法通过
--force
跳过。

实操建议:

导出时不写 sql_mode:加
--set-gtid-purged=OFF --skip-set-charset --no-defaults
,并手动删掉 dump 文件头部的
SET sql_mode
导入前预处理 dump 文件:
sed -i '/^SET sql_mode/d' dump.sql
若用管道导入,可用
grep -v '^SET sql_mode' dump.sql | mysql -u root -p db_name
更稳妥的做法:在目标 MySQL 8.0 上提前执行
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'NO_AUTO_CREATE_USER',''));
,再导入

mysqldump 导出的 SQL 在目标库执行后主从不一致

常见于启用了 GTID 的环境。

mysqldump
默认导出
SET @@GLOBAL.GTID_PURGED
,如果目标从库已有其他事务,强行设置会清空已同步的 GTID 集合,导致后续复制中断或跳过事务。

实操建议:

从库导入前确认是否要保留原有复制位置:
--set-gtid-purged=OFF
(最常用),或
--set-gtid-purged=AUTO
(仅当源库
gtid_mode=ON
且无未 purged 事务时安全)
若目标是新从库,且需基于 dump 建立复制,应配合
--master-data=2
(记录 binlog 位置)而非依赖 GTID
导入后务必检查:
SHOW SLAVE STATUS\G
中的
Retrieved_Gtid_Set
Executed_Gtid_Set
是否连续,不连续说明 GTID 被覆盖
--single-transaction
--set-gtid-purged
组合使用时,GTID 设置发生在事务 START TRANSACTION 之后,顺序敏感,不可随意调换参数位置
实际迁移中最容易被忽略的是字符集隐式转换——比如源库用
utf8mb4_unicode_ci
,dump 文件里没显式声明,目标库若默认
utf8mb4_0900_as_cs
,导入后排序行为就变了。这不会报错,但业务查询结果可能异常。

相关推荐