不能直接在千万级表上用Navicat点击“添加字段”提交,因其底层执行ALTER TABLE ADD COLUMN会触发全表MDL锁,导致业务写入阻塞、查询变慢甚至超时雪崩;必须改用pt-online-schema-change等在线工具或严格满足INPLACE条件的手动分步操作。

直接在千万级表上用 Navicat 点击“添加字段”并提交,等于执行 ALTER TABLE ADD COLUMN —— 这会触发全表元数据锁(MDL),业务写入阻塞、查询变慢、甚至引发超时雪崩。不能这么干。
Navicat 默认操作本质是 DDL,不是在线变更
Navicat 的「设计表 → 添加字段 → 保存」流程,底层生成的是标准 ALTER TABLE 语句。MySQL 5.6+ 虽支持部分 ADD COLUMN 的 inplace 算法,但前提是:不指定 AFTER、无默认值或默认值为常量、表引擎为 InnoDB、且未开启 old_alter_table=ON。而生产环境往往不满足全部条件,尤其带 DEFAULT 或 COMMENT 时,仍会拷贝全表。
常见错误现象:
- 点击“保存”后界面卡住十几秒到几分钟,Navicat 显示“正在执行”,但业务接口开始报
Lock wait timeout exceeded - 监控发现
Threads_running暴涨,innodb_row_lock_time_avg持续升高 - 后续查
information_schema.INNODB_TRX,能看到长事务持有着metadata lock
所以:Navicat 是操作入口,不是安全方案本身。它不提供原生的在线 DDL 能力。
必须绕过 Navicat 的 GUI,改用 pt-online-schema-change
真正安全的方式,是用 Percona Toolkit 的 pt-online-schema-change 工具,在 Navicat 外部执行,再刷新 Navicat 表结构视图即可。它不依赖 Navicat,但和 Navicat 完全兼容。
执行前确认:
- 目标表必须有主键或唯一非空索引(否则无法构建触发器同步)
- 数据库账号需具备
SELECT, INSERT, UPDATE, DELETE, DROP, CREATE, ALTER, SUPER, REPLICATION CLIENT权限 - 磁盘剩余空间 ≥ 原表大小 × 2(临时表 + 日志)
- 避免在业务高峰执行;通过
--max-load="Threads_running=30"控制负载阈值
典型命令示例(加一个可空的 remark 字段):
pt-online-schema-change \ --alter "ADD COLUMN remark TEXT NULL COMMENT '备注'" \ D=your_db,t=orders \ --charset=utf8mb4 \ --critical-load="Threads_running=80" \ --max-load="Threads_running=40" \ --recursion-method=none \ --print \ --execute
执行完成后,在 Navicat 中右键表 → 「刷新」,就能看到新字段。注意:不要在执行过程中手动修改原表结构或删触发器——pt-osc 会自动清理。
如果只能用 Navicat,且表确实不能停写,怎么办?
没有万全办法,但可以降级保障:用 Navicat 配合手动分步 + 应用层兜底,把风险控制在分钟级。
操作要点:
- 先在 Navicat 中执行
ALTER TABLE orders ADD COLUMN new_col VARCHAR(64) DEFAULT '' NOT NULL(显式指定NOT NULL+ 空默认值,减少初始化开销) - 立即在应用代码中补全对该字段的读写逻辑(哪怕先写空字符串),避免后续因字段缺失报错
- 再用 Navicat 执行
UPDATE orders SET new_col = 'migrated' WHERE new_col = '' LIMIT 10000分批更新旧数据,每次间隔 1 秒以上 - 最后执行
ALTER TABLE orders MODIFY COLUMN new_col VARCHAR(64) NULL(如需允许 NULL)——这步通常很快,锁表时间极短
这个方案不解决首次 DDL 锁表问题,但把高风险操作压缩到一次可控的短锁,并把数据补全拆成无锁的 UPDATE,适合实在无法引入外部工具的封闭环境。
真正危险的不是“怎么点 Navicat”,而是误以为图形界面能绕过 MySQL 的 DDL 本质。千万级表加字段,核心永远是:用对工具、看清锁类型、接受分步代价。任何想“一键安全”的幻想,都会在 SHOW PROCESSLIST 里现出原形。


















