电商系统严禁使用MyISAM,因其表级锁导致下单卡死、无事务引发库存与订单状态不一致、无崩溃恢复机制使断电后数据错乱且REPAIR TABLE可能越修越坏。

电商交易系统里用 MyISAM 就是埋雷,不是“不推荐”,而是明确禁止——只要涉及订单、库存、账户、支付等任何状态变更,MyISAM 的表级锁、无事务、无崩溃恢复三重缺陷会直接导致数据不一致、请求卡死、故障不可恢复。
MyISAM 表级锁会让下单请求排队卡死
用户点“立即购买”时,后端通常要执行库存扣减 + 订单插入 + 日志记录。MyISAM 对 UPDATE 或 INSERT 会锁整张表,哪怕只改一行 sku = 'A001',其他所有用户对这张表的读写都得等。常见现象:
-
SHOW PROCESSLIST中大量出现Waiting for table level lock -
Table_locks_waited指标陡增,监控告警频繁 - 一个慢查询(如没走索引的
WHERE status = 1)就能让整张订单表瘫痪数秒
InnoDB 默认行级锁,张三改第 5 行、李四改第 200 行互不影响;而 MyISAM 下,哪怕并发只有 20 QPS 写入,响应延迟就可能从 20ms 拉到 2s+。
没有事务保障会导致库存/订单状态不一致
电商核心逻辑必须原子化:比如“扣库存成功但订单创建失败”,或“订单已生成但库存没扣”,都会造成资损或超卖。MyISAM 完全无法做到:
-
START TRANSACTION和ROLLBACK语法被忽略,autocommit设置无效 - 执行
UPDATE stock SET qty = qty - 1 WHERE sku = 'A001'途中网络中断,部分行已更新、部分未更新,数据库自己不报错也不回滚 -
INSERT INTO orders ...; INSERT INTO order_items ...这种多语句逻辑,前一条成功、后一条失败,就会留下脏数据
InnoDB 靠 undo log 实现事务回滚,靠 redo log 保证提交后崩溃不丢,这是电商系统可用性的底线。
崩溃后无法自恢复,REPAIR TABLE 可能越修越坏
服务器断电、OOM、MySQL 被 kill —— 这些不是小概率事件。MyISAM 没有 redo log 和 undo log,数据直写 .MYD、索引直写 .MYI,崩溃后:
-
CHECK TABLE常报error: 126 / 134 / 144,提示“Table is marked as crashed” -
REPAIR TABLE是暴力重建索引,不校验业务逻辑,修复后可能COUNT(*)和实际行数对不上 - 主从复制中,从库执行
REPLACE INTO后看似成功,但金额或状态已错乱,且无错误日志可查 - MySQL 8.0+ 中
mysqlcheck --repair对 MyISAM 的修复成功率显著下降,官方已弱化支持
而 InnoDB 崩溃重启时自动重放 redo log、回滚未提交事务,全程无需人工干预——这才是生产环境敢用的前提。
MySQL 8.0 已事实弃用,禁用配置仍可能绕过
MySQL 8.0 所有系统表(mysql.user、mysql.db 等)全部强制使用 InnoDB,因为 MyISAM 系统表损坏会导致权限失效、实例无法启动。虽然可通过 disabled_storage_engines="MyISAM" 禁用建表,但仍有漏网之鱼:
-
CREATE TABLE t AS SELECT * FROM myisam_table会沿用源表引擎,不校验白名单 - 旧版
mysqldump导出的 SQL 若含ENGINE=MyISAM,导入时照样执行 - 已有 MyISAM 表不受影响,仍可读写——这意味着隐患长期潜伏,直到某次扩容或故障才暴露
真正难处理的不是“怎么换引擎”,而是线上千万级 orders 表执行 ALTER TABLE ... ENGINE=InnoDB 时需预留 1.5 倍磁盘空间、低峰期窗口、以及全量重建期间的业务容忍度——这些成本远低于早期规范卡死。


















