myisam在电商库存扣减场景下根本不可用:其表级锁导致高并发时整表阻塞,无事务机制使跨语句操作无法原子执行,崩溃后无redo/undo log致数据错位或丢失,修复风险高且不可验证。

电商库存扣减场景下,MyISAM 不是“性能不好”,而是根本不可用——它会在高并发写入时锁死整张表,且无法保障扣减操作的原子性,数据不一致风险直接暴露在用户下单链路中。
MyISAM 表级锁会让“扣库存”变成串行排队
库存扣减本质是高频、短事务的 UPDATE 操作,例如:UPDATE stock SET qty = qty - 1 WHERE sku = 'A001'。MyISAM 对该语句会加**整张表的写锁**,哪怕只改一行,其他所有库存更新(包括不同 SKU)、甚至 SELECT 查询都得等它释放锁。
- 现象:双十一流量高峰时,
SHOW PROCESSLIST中大量线程卡在Waiting for table level lock - 后果:用户点“立即购买”后页面长时间转圈,超时失败率飙升
- 对比:InnoDB 在
WHERE sku = ?能命中索引时,只锁匹配行,多 SKU 并发扣减互不干扰
没有事务意味着“扣一半就断”无法回滚
真实库存扣减往往不是单条 SQL,而是嵌套在订单创建流程中:扣库存 → 写订单 → 记日志 → 发消息。MyISAM 不支持 BEGIN/COMMIT,也没有 UNDO LOG,任意一步失败(如网络中断、应用崩溃),前面已执行的 UPDATE 就永久生效。
- 错误现象:库存被扣减了,但订单没生成,用户收不到确认,客服查不到记录
- 更糟的是:MyISAM 的“原子性”仅限单语句内部,对跨语句逻辑完全无保障
- InnoDB 下,整个流程可包裹在事务中,任一环节失败自动回滚,状态始终一致
崩溃后无法恢复,修表可能越修越错
电商系统无法承受计划外停机。MyISAM 没有 REDO LOG,服务器意外断电或 MySQL 进程被 kill 后,.MYD 和 .MYI 文件极易错位,出现 Table is marked as crashed。
- 修复只能靠
REPAIR TABLE或myisamchk,但这是暴力重建索引,不校验业务逻辑正确性 - 曾有案例:某平台凌晨停电后修复 MyISAM 库存表,修复后显示 qty = -127,而实际应为正数
- InnoDB 崩溃重启后自动前滚已提交事务、回滚未提交事务,整个过程无需人工干预,且结果严格可验证
真正容易被忽略的是:MyISAM 的“可用假象”常出现在低流量测试环境,一旦写入压力上来、异常真实发生,修复成本远高于初期迁移成本。电商核心链路里,没有“试错空间”。











