Navicat不支持在线DDL,所有变更均转为ALTER TABLE语句执行;是否锁表取决于MySQL版本及参数设置,需手动添加ALGORITHM=INPLACE, LOCK=NONE或使用pt-online-schema-change等工具。
Navicat 本身不支持在线 DDL,别指望它绕过 MySQL 的锁机制
navicat 只是图形化客户端,所有表结构变更最终都转化为 alter table 语句发给 mysql 执行。mysql 5.6+ 虽支持部分 algorithm=inplace 操作,但字段类型变更(如 varchar(50) → varchar(200))是否真正免锁,取决于具体类型、长度、字符集和 mysql 版本——navicat 完全不参与优化或降级处理。
你点“修改字段”→ 点“保存”→ Navicat 自动生成 ALTER TABLE ... MODIFY COLUMN 并执行,和你在命令行敲一模一样。它不会自动加 ALGORITHM=INPLACE, LOCK=NONE,更不会拆成 pt-online-schema-change 那样的影子表流程。
真正能“不锁表”的操作,必须手动控制 ALTER 语句参数
MySQL 8.0+ 对某些变更支持 LOCK=NONE,但需同时满足:目标类型兼容(如扩大 VARCHAR 长度、添加 NOT NULL 默认值为空字符串)、表使用 innodb_file_per_table=ON、且无全文索引/空间索引等限制。直接在 Navicat 中改字段后,务必点开“SQL 预览”(右键表 → “设计表” → 修改后点左下角“SQL 预览”),手动补全安全参数:
- 把自动生成的
ALTER TABLE `t_user` MODIFY COLUMN `name` VARCHAR(200)改成:ALTER TABLE `t_user` MODIFY COLUMN `name` VARCHAR(200) ALGORITHM=INPLACE, LOCK=NONE;
- 执行前先在命令行验证:
SELECT @@innodb_file_per_table;必须为ON - 若报错
ALGORITHM=INPLACE is not supported或LOCK=NONE is not supported,说明当前变更无法免锁,强制加LOCK=NONE会失败,不能跳过检查
千万级表改字段类型,99% 的场景该用 pt-online-schema-change
当 LOCK=NONE 不可用(比如要改 INT → BIGINT、或缩小字段长度),唯一靠谱方案是 Percona Toolkit 的 pt-online-schema-change。Navicat 完全不集成此工具,必须脱离 GUI 操作:
- 在数据库服务器上安装
percona-toolkit(注意版本兼容 MySQL 8.0/5.7) - 执行命令示例(以改字段类型为例):
pt-online-schema-change --host=localhost --user=root --password=xxx \ --alter "MODIFY COLUMN name VARCHAR(200)" \ D=test,t=t_user \ --no-check-alter \ --execute
-
--no-check-alter是必需的——因为pt-osc默认禁止高危变更,而字段类型修改被列为高危;但它实际通过触发器+影子表实现,不影响主表读写 - 全程监控
SHOW PROCESSLIST和慢日志,避免从库延迟或磁盘爆满(临时表会占用双倍空间)
Navicat 的“快速修改”按钮是最大陷阱,关掉它
Navicat 默认开启“保存时自动执行 DDL”,界面点“保存”就立刻发 ALTER。对千万级表,这等于直接锁表几分钟甚至几小时。必须关闭:
- 菜单栏 → “工具” → “选项” → “常规” → 取消勾选
Automatically execute DDL statements when saving table structure - 改字段后只点“保存”,不点“运行”,然后手动复制 SQL 预览里的语句,粘贴到新查询窗口,自己加参数、加判断、分步执行
- 永远在低峰期操作,并提前在测试库用相同数据量压测——
EXPLAIN FORMAT=JSON ALTER TABLE ...在 MySQL 8.0.12+ 可预估执行计划,但不保证锁行为
字段类型变更本质是数据重写,没有银弹。所谓“不锁表”,要么靠 MySQL 底层支持(条件苛刻),要么靠外部工具模拟(运维成本高)。Navicat 不提供任何中间态能力,依赖它点点点,只会放大风险。


















