Navicat同步脚本生产报错主因是MySQL版本或sql_mode不一致,需用同步账号分别查VERSION()和@@sql_mode,比对collation、ROW_FORMAT、CURRENT_TIMESTAMP、DEFINER等语法兼容性,并在对应连接的高级选项中关闭CHECK/DEFINER、启用5.7兼容模式且确认保存。
navicat 生成的同步脚本在开发机跑通,一上生产就报错,大概率不是脚本写得有问题,而是两边 mysql 版本或 sql_mode 不一致 —— navicat 默认按“当前连接的数据库版本”生成语法,但不会主动降级适配目标库。
查清两边 MySQL 版本和 sql_mode 差异
别猜,直接连上去查:
- 开发机执行:
SELECT VERSION();和SELECT @@sql_mode; - 生产库同样执行这两条 —— 注意必须用同步时所用的账号执行,权限不足时
@@sql_mode可能返回空或默认值 - 重点比对:是否一方是 MySQL 5.7(不支持
utf8mb4_0900_ai_ci),另一方是 8.0+;是否一方启用了STRICT_TRANS_TABLES或ONLY_FULL_GROUP_BY,另一方没开
Navicat 导出/同步时默认不兼容旧版本
Navicat 16+ 连着 MySQL 8.0 写出来的 DDL,会天然带这些高危成分:
- 字符集声明含
COLLATE utf8mb4_0900_ai_ci→ MySQL 5.7 直接报ERROR 1273 (HY000): Unknown collation - 建表语句用
ENGINE = InnoDB ROW_FORMAT=DYNAMIC→ 5.6 或某些云厂商定制版不认ROW_FORMAT参数 - 时间字段带
DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP→ 5.6 仅支持单个CURRENT_TIMESTAMP,多一个就报ERROR 1067 - 导出视图或存储过程时,自动加上
DEFINER=`user`@`host`→ 若生产库没这个用户,或sql_mode含NO_AUTO_CREATE_USER,就会失败
绕过版本陷阱的实操办法
与其改生产库(通常不允许),不如控制 Navicat 输出:
- 同步前,在 Navicat 连接属性 → 「高级」页勾选
Use MySQL Native Password(尤其 MySQL 8.0+ 环境) - 结构同步向导中,点「选项」→ 「高级」→ 关掉
Generate CHECK constraints、Preserve DEFINER clause - 导出 SQL 文件时,手动把
COLLATE utf8mb4_0900_ai_ci全局替换成COLLATE utf8mb4_unicode_ci(注意只换引号内内容) - 若目标库是 5.7 或更低,导出设置里务必勾选「兼容 MySQL 5.7」—— 这个开关会禁用 8.0+ 专属语法,但 Navicat 15 及更早版没有该选项,只能手改
为什么改了设置还是无效?缓存和连接上下文在作怪
Navicat 的「高级选项」不是全局生效的,它绑定在当前连接 + 当前同步任务实例上:
- 改完「兼容模式」后没重新点「Advanced Options」面板右下角的
OK,等于没保存 - 用 A 连接导出的 SQL,拿去 B 连接执行,B 连接的
sql_mode或字符集可能不同,照样报错 - 同步任务一旦开始,Navicat 就按初始连接的元数据生成全部 SQL —— 中途改连接参数无效
最稳的办法:在生产库上建一个专用同步账号,用它新建 Navicat 连接,所有同步操作都走这个连接,并确认它的 sql_mode 和字符集与目标环境完全一致。否则,你以为在修脚本,其实是在调环境。


















