不能直接用alter table t engine=innodb批量执行——会锁写入、耗磁盘、拖垮主从;应先筛选需转的myisam表:有写入、数据量>1gb、需事务/行锁/崩溃恢复的表,排除只读小表及含fulltext的低版本表。

不能直接用 ALTER TABLE t ENGINE=InnoDB 在生产环境批量执行——它会锁死写入、吃光磁盘、拖垮主从,且不支持在线操作。
哪些表真该转?先过滤再动手
不是所有 MyISAM 表都值得动。盲目转换可能引入全文索引不兼容、自增列约束失败、或性能反降等问题。
- 跑这句查出待评估清单:
SELECT table_schema, table_name, table_rows, data_length FROM information_schema.tables WHERE engine = 'MyISAM' AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema'); - 重点关注三类表:有写入(
table_rows持续变动)、数据量 >1GB、需事务/行锁/崩溃恢复能力的表 - 可暂缓迁移的表:只读小表(≤100MB)、带 FULLTEXT 但 MySQL 版本 pt-online-schema-change 不支持)
- 特别注意:若表含
AUTO_INCREMENT列但未建索引,ALTER TABLE会报ERROR 1075;MyISAM 允许,InnoDB 不允许
大表必须用 pt-online-schema-change,别信 ALGORITHM=INPLACE
MySQL 8.0+ 对 ENGINE 变更仍强制走 COPY 算法,ALGORITHM=INPLACE 不生效。所谓“在线”只是幻觉。
-
pt-online-schema-change是目前唯一能绕开锁表的成熟方案,原理是影子表 + 触发器双写 - 前提硬性要求:目标表必须有主键或唯一非空索引,否则报错
This table has no primary key or unique index - 命令示例:
pt-online-schema-change --alter "ENGINE=InnoDB" D=your_db,t=big_table --execute - 关键参数要设:
--chunk-size=1000(控制每批迁移行数)、--max-lag=1(从库延迟超1秒自动暂停)、--check-interval=5(每5秒检查一次) - 注意:迁移后旧的
.MYD和.MYI文件不会自动删除,需人工清理(先确认新表数据一致再删)
转换后必须验证和调参,否则性能可能更差
InnoDB 和 MyISAM 行为差异极大,不调参等于白转。
- 引擎改完立刻验证两件事:
COUNT(*)结果是否与原表一致;业务 SQL 是否仍能正常执行(尤其涉及MATCH AGAINST的全文查询) - 必须调整配置项:
innodb_buffer_pool_size设为物理内存的 50%–75%;key_buffer_size从几百 MB 降到 32M 左右;innodb_flush_log_at_trx_commit非金融场景可设为2 - 全文索引要重测:
MyISAM的布尔模式(如+(apple banana) -orange)在InnoDB中部分不支持,嵌套括号可能失效 - 监控关键指标:转换后若
innodb_log_waits持续上升,说明日志刷写跟不上,需增大innodb_log_file_size
最常被忽略的是磁盘空间预估——转换过程实际占用空间远超“原表大小 ×2”,redo log、临时排序区、触发器日志都会叠加消耗;没留够空间,pt-osc 会静默失败,只留下半截影子表。











