应先执行SELECT VERSION()确认目标库真实版本,再启用Navicat兼容模式并手动处理触发器、CHECK约束及视图等敏感对象。
确认目标库真实版本,别信 Navicat 连接栏显示的数字
navicat 左下角显示的 mysql 8.0.33 是它当前连接用的客户端版本或缓存值,不是目标库实际运行版本。同步失败时第一件事:在目标库执行 select version();,看返回结果。常见陷阱是 navicat 连的是跳板机或代理(如 mysql router、proxysql),背后真实实例可能是 5.7;或者目标库是 docker 容器但镜像没更新,mysql --version 和 select version() 结果不一致也常发生。
强制启用兼容模式,否则 Navicat 默认按高版本生成语法
Navicat 16+ 的结构同步向导里,“高级”设置中藏着关键开关:Compatibility Mode。不点开就默认按源库版本生成 DDL,哪怕你往 MySQL 5.7 同步也会输出 CREATE OR REPLACE VIEW 或 ALGORITHM=INSTANT —— 这些在 5.7 直接报 ERROR 1064 (42000)。必须手动选中对应目标版本:
- 同步到 MySQL 5.7 → 选
MySQL 5.7 - 不确定目标版本?选
MySQL 5.6更稳妥,它生成的语句基本能跑通 5.6–8.0 - 选了之后,Navicat 会自动降级:把
utf8mb4_0900_as_cs换成utf8mb4_general_ci,删掉LOCK=NONE,禁用函数默认值(如DEFAULT (NOW()))
绕过 Navicat 自动生成逻辑,用 SHOW CREATE TABLE 手动兜底
即使开了兼容模式,Navicat 仍可能因“自动依赖解析”或“优化 DDL 输出”重写语句,导致和 SHOW CREATE TABLE 结果不一致。典型表现:明明源表没改过,同步却生成一堆 MODIFY COLUMN;或视图定义被加了多余引号、换行错乱。这时最可靠的做法是:
- 在源库执行
SHOW CREATE TABLE `t_name`;,复制完整建表语句 - 在目标库手动执行该语句(注意检查
ENGINE、CHARSET是否适配) - 若涉及视图/存储过程,同样用
SHOW CREATE VIEW或SHOW CREATE PROCEDURE获取原始定义,再人工调整DEFINER和语法后执行
触发器和 CHECK 约束必须单独处理,Navicat 同步几乎总出错
Navicat 对触发器的 DEFINER 处理极脆弱:同步脚本若含 CREATE DEFINER='admin'@'localhost' TRIGGER,而目标库没有该用户,MySQL 会创建但标记为 INVALID,且不会自动启用。CHECK 约束更麻烦——Navicat 15 及更早版本可能跳过它,或把表达式写成带双引号列名、含子查询等目标库不认的形式(报 ERROR 3819)。实操上:
- 同步前在 Navicat 设置里关掉
Generate CHECK constraints(路径:Tools → Options → Data Synchronization → Advanced) - 触发器一律不用同步功能,改用
SHOW CREATE TRIGGER取出定义,把DEFINER替换为CURRENT_USER,再执行并补上ALTER TRIGGER `name` ENABLE; - 别信预览窗口里的 SQL——它不校验
DEFINER是否存在,也不检查 CHECK 表达式是否可执行


















