mysql从MyISAM迁移到InnoDB如何操作_mysql引擎迁移步骤

3次阅读

ALTER table t ENGINE=InnoDB 会加全表独占锁,阻塞所有DML,5.6前还阻塞select;不支持ALgoRITHM=INPLACE,必须copy模式,需低峰期操作并预留双倍磁盘空间。

mysql从MyISAM迁移到InnoDB如何操作_mysql引擎迁移步骤

ALTER TABLE 强制转换引擎会锁表吗

会,而且是全表独占锁。在高并发写入场景下,ALTER TABLE t ENGINE=InnoDB 执行期间,所有对该表的 DML(INSERT/UPDATE/delete)都会被阻塞,直到转换完成。5.6 之前的 mysql 还会阻塞 SELECT(只读事务除外),5.7+ 支持在线 DDL 的部分操作,但引擎切换仍不支持 ALGORITHM=INPLACE,必须走 COPY 模式。

实操建议:

  • 务必在业务低峰期执行,提前评估表大小——1GB 表可能耗时数分钟,10GB+ 建议用其他方式
  • 确认磁盘剩余空间 ≥ 当前表 .MYD 文件大小 × 2(InnoDB 需要重建数据+索引)
  • 避免在主库直接操作;若用 GTID 复制,从库会同步该 DDL,同样触发锁,需主从协同窗口
  • 可先在从库试跑,观察 SHOW PROCEsslIST 中状态是否长期卡在 copy to tmp table

MyISAM 特有语法迁移后失效怎么办

MyISAM 支持全文索引(FULLTEXT)、AUTO_INCREMENT 不依赖主键、表级锁语义等,迁到 InnoDB 后行为变化明显:

  • FULLTEXT 索引在 InnoDB 中可用,但分词器和停用词规则不同(如默认不忽略单字符),需重建:ALTER TABLE t DROP INDEX ft_idx; ALTER TABLE t ADD FULLTEXT(title, content);
  • InnoDB 要求 AUTO_INCREMENT 字段必须是索引的一部分(通常是主键或含主键的联合索引),否则建表报错 Error 1075
  • 原 MyISAM 的 INSERT DELAYED 已被 MySQL 5.6 废弃,InnoDB 完全不支持,需改用批量 INSERT 或应用层队列
  • MyISAM 的 SELECT count(*) FROM t 极快(直接读元数据),InnoDB 需扫描索引,大表会变慢——这不是 bug,是事务一致性代价

外键约束和事务隔离怎么补上

MyISAM 不支持外键和事务,迁移后若业务逻辑依赖级联更新/删除或 ACID,必须显式补全:

  • 先检查是否有隐式外键关系(比如代码里硬编码的关联字段名),再用 ALTER TABLE child ADD CONSTRaiNT fk_uid forEIGN KEY (user_id) REFERENCES user(id) ON DELETE CAScadE;
  • InnoDB 默认隔离级别是 REPEATABLE READ,但 MyISAM 无隔离概念;若原应用靠“写不阻塞读”设计,迁后可能因 gap lock 导致死锁,需审查 UPDATE/DELETE 的 WHERE 条件是否走索引
  • 未提交事务中对 InnoDB 表的修改,对其他连接不可见;而 MyISAM 下所有修改立即可见——这点常导致测试环境查不到刚插入的数据
  • 务必关闭 autocommit=0 的旧习惯,或确保每个事务以 COMMITROLLBACK 显式结束

如何安全验证迁移结果一致性

不能只看 SHOW CREATE TABLEENGINE=InnoDB 就算完事。真实差异藏在数据逻辑和边界行为里:

  • mysqldump --no-create-info --skip-extended-insert db t | md5sum 对比 MyISAM 和 InnoDB 表导出的纯数据行(注意排序!加 ORDER BY 再 dump)
  • 检查 NULL 值处理:MyISAM 允许唯一索引含多个 NULL,InnoDB 视 NULL 为相等值,唯一索引中最多一个 NULL——迁移后可能报 Duplicate entry '' for key 'uk_col'
  • 运行 mysqlcheck -u root -p --check --databases db,重点看是否提示 error : record is crashed(MyISAM 崩溃表无法直接转,得先 REPAIR TABLE
  • 触发器、存储过程里若有 SELECT ... LOCK IN SHARE MODEFOR UPDATE,仅在 InnoDB 生效,MyISAM 下静默忽略——这类逻辑必须重测

最易被忽略的是字符集和排序规则继承问题:MyISAM 表级 COLLATE 可能没设,迁后 InnoDB 按库默认值继承,导致 ORDER BY 结果不一致。务必核对 SHOW CREATE TABLE 输出中的 COLLATE 字段是否与预期一致。

text=ZqhQzanResources