生产环境不可直接批量执行alter table...engine=innodb,须人工筛选大表(data_length>1gb、有写入、需事务)、跳过系统表/只读小表/低版本全文索引表,用pt-online-schema-change迁移并调优innodb参数。

MySQL
编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。
下载
直接批量执行
ALTER TABLE ... ENGINE=InnoDB 在生产环境会锁死写入、吃光磁盘空间、拖垮主从同步——这不是操作慢的问题,是根本不可行。
哪些表真该转?先过滤再动手
盲目转换反而引入新问题:全文索引失效、自增列报错、性能下降。必须人工评估,不能全量硬切。
- 重点关注三类表:
table_rows 持续变动(有写入)、data_length > 1073741824(即 >1GB)、需事务/行锁/崩溃恢复能力
- 可跳过:
table_schema IN ('mysql', 'information_schema', 'performance_schema') 的系统表;只读小表(≤100MB);含 FULLTEXT 索引但 MySQL 版本
- 查清单命令:
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');
大表必须用 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 行为差异极大,配置没跟上,性能可能更差。
-
innodb_buffer_pool_size 必须设为物理内存的 50%–75%,否则大量磁盘读,比 MyISAM 还慢
-
key_buffer_size 要从几百 MB 降到 32M 左右,避免内存争抢
- 非金融场景可设
innodb_flush_log_at_trx_commit=2,否则写入吞吐卡在默认值 1 上
- 必须验证:
COUNT(*) 结果是否与原表一致;业务 SQL 是否仍能执行(尤其 MATCH AGAINST 全文查询);SHOW TABLE STATUS LIKE 'table_name' 确认 Engine 字段已变
真正容易被忽略的是:转换后
SELECT COUNT(*) 性能反降、
FULLTEXT 布尔语法(如
+(apple banana) -orange)嵌套括号失效、
AUTO_INCREMENT 列若未建索引会直接报
ERROR 1075——这些不是“转完就完事”,而是刚起步。