navicat 17 不支持真正的无锁变更,其结构同步依赖底层数据库的 alter table,默认不启用 online ddl 参数(如 algorithm=inplace、lock=none),易触发表级锁或 mdl 锁阻塞;高危操作(如 drop column、change column、大表加 default)必致全表拷贝,且 navicat 不预警、不校验版本兼容性,生产环境须导出 sql 并手动增强为在线语句或改用 pt-online-schema-change。

Navicat 17 无法实现真正的“无锁变更”——它不提供在线 DDL 能力,所有结构修改操作默认走 ALTER TABLE 同步,会触发表级锁或长事务阻塞。 你看到的“无锁”,其实是通过规避方式降低影响,不是 Navicat 自身支持 Online DDL。
为什么 Navicat 的结构同步会锁表
Navicat 执行结构同步时,底层调用的是标准 SQL(如 ALTER TABLE),而是否加锁完全取决于目标数据库版本和语句类型:
- MySQL 5.6+ 对部分
ADD COLUMN、ADD INDEX支持ALGORITHM=INPLACE,但 Navicat 不暴露该参数控制权 - Navicat 默认生成的语句不含
ALGORITHM或LOCK子句,MySQL 按默认策略执行(例如 MySQL 8.0 中MODIFY COLUMN默认要求LOCK=SHARED) - 若字段长度收缩(如
VARCHAR(255) → VARCHAR(50))、改类型(INT → BIGINT)、或涉及主键变更,MySQL 强制全表拷贝,锁持续到操作完成 - Navicat 同步过程还自带事务包装:START TRANSACTION → 扫描源结构 → 生成并执行 DDL → COMMIT,期间持有 MDL 锁,DDL 未结束,其他 DDL 就卡在
Waiting for table metadata lock
如何用 Navicat 做低风险结构变更
核心思路是:不让 Navicat 直接执行高危 DDL,而是导出脚本 + 手动加 Online DDL 参数 + 分批验证。
- 在结构同步界面勾选
Generate SQL file only(仅生成 SQL 文件),不要点“运行” - 打开生成的
.sql文件,把每条ALTER TABLE改成显式带在线参数的形式,例如:ALTER TABLE `user` ADD COLUMN `status_code` TINYINT DEFAULT 0 AFTER `name`, ALGORITHM=INPLACE, LOCK=NONE;
- 确认目标 MySQL 版本支持对应
ALGORITHM和LOCK组合(MySQL 8.0+ 推荐用ALGORITHM=INSTANT改列名或加虚拟列) - 在生产库中用命令行或带事务控制的客户端分段执行,例如先对小表试跑,再用
pt-online-schema-change处理大表 - 绝对不要让 Navicat 直接连生产库执行“同步到数据库”——它不会校验锁级别,也不会提示你当前语句是否会导致秒级/分钟级阻塞
哪些变更 Navicat 生成的语句天然高危
这些操作即使加了 ALGORITHM=INPLACE,MySQL 仍可能退化为拷贝表,Navicat 完全不预警:
-
DROP COLUMN:MySQL 5.7+ 不支持 inplace drop 列,必拷贝 -
CHANGE COLUMN改类型且非扩展(如TEXT → VARCHAR(200)) - 给大表(>100 万行)的非空字段加
DEFAULT值(MySQL 8.0.13+ 已优化,但 Navicat 不识别版本差异) - 修改
ENUM或SET枚举值列表(内部重建字段,锁表) - 启用
utf8mb4_0900_as_cs这类新排序规则(需重建索引,Navicat 不提示兼容性)
真正要“无锁”,得绕开 Navicat 的图形化同步逻辑。它适合开发/测试环境快速对齐,但生产表结构变更必须回归 SQL 本身——看执行计划、查 INFORMATION_SCHEMA.INNODB_TRX、用 SHOW PROCESSLIST 观察锁等待,这些 Navicat 都不介入。











