会,alter table ... engine=innodb 在大表上会加全表独占写锁,导致dml和ddl阻塞数十分钟至数小时;myisam转innodb不支持algorithm=inplace,实际执行copy-alter流程。

ALTER TABLE ... ENGINE=InnoDB 会锁表吗?
会,而且是**全表独占写锁**(DML 和 DDL 都阻塞),在大表上执行可能让业务中断几十分钟甚至数小时。MySQL 5.6+ 支持 ALGORITHM=INPLACE,但 MyISAM 转 InnoDB **不支持原地升级**——ALTER TABLE t ENGINE=InnoDB 实际走的是 copy-alter 流程:建新表、逐行拷贝、重建索引、rename。这意味着整个过程期间,原表不可写。
怎么避免长时间锁表?用 pt-online-schema-change
Percona Toolkit 的 pt-online-schema-change 是最成熟的选择,它通过触发器+影子表实现“无锁”迁移(实际是低影响,非绝对零锁)。关键点:
- 要求源表有主键或唯一非空索引(否则无法可靠追踪变更)
- 必须在从库停复制的情况下操作,或确保主从延迟可控;否则触发器写入可能被复制冲突打乱
- 默认每秒拷贝 1000 行,可通过
--chunk-size和--max-load控制节奏,避免拖垮 I/O 或 CPU - 执行前先用
--dry-run和--execute配合测试,别跳过验证步骤
示例命令:
pt-online-schema-change --host=localhost --user=root --password=xxx \ --alter "ENGINE=InnoDB" \ D=test,t=myisam_table \ --no-check-replication-filters \ --chunk-time=0.5 \ --max-load="Threads_running=25" \ --critical-load="Threads_running=50" \ --execute
为什么不能用 mysqldump + 导入?
可以,但不是“平滑”的解法:
- dump 过程中,原表仍可写,但 dump 出的数据是某个时间点快照,中间的写入会丢失
- 导入时新表仍是空的,业务需切流,存在数据断层风险
- 大表 dump 文件巨大,网络/磁盘 IO 压力集中,导入耗时长且期间无法回滚到旧结构
- 外键、触发器、注释等元数据容易遗漏,需额外处理
它适合维护窗口明确、能接受短时停服的场景,不属于“平滑”范畴。
转换后必须检查的三件事
InnoDB 和 MyISAM 行为差异明显,转完不是万事大吉:
-
SELECT COUNT(*)变慢了?MyISAM 存行数缓存,InnoDB 需实时扫描;如有高频全表计数,考虑加汇总表或缓存 - 全文索引失效?MyISAM 的
FULLTEXT在 InnoDB 中语法相同,但分词器、最小词长等参数不同(如innodb_ft_min_token_size默认是 3),需比对并重置 - 自增字段表现异常?InnoDB 的自增值不持久化到磁盘(MySQL 8.0.21+ 才默认持久),重启后可能回退;若依赖严格递增,要确认
innodb_autoinc_lock_mode设置(推荐 2)
真正麻烦的从来不是转换动作本身,而是那些隐含在存储引擎语义里的行为偏移——它们往往在线上压测阶段才暴露。











