MySQL 8.0起分区表必须使用InnoDB,MyISAM分区已被移除且不可靠;5.7是最后支持版本但已不推荐,实际易触发ERROR 1031,InnoDB是唯一完整支持的分区引擎。

分区表必须用 InnoDB,MyISAM 分区已废弃且不可靠
MySQL 8.0 起,MyISAM 分区功能已被移除;5.7 是最后一个支持 MyISAM 分区的版本,但官方明确标记为“不推荐”,且在实际使用中极易触发 ERROR 1031 (HY000): Table storage engine for 't' doesn't support partitioning。InnoDB 是当前唯一被完整支持、持续维护的分区引擎。
为什么 MyISAM 分区在生产环境根本走不通
即使你强行在旧版本(如 MySQL 5.6)上创建了 MyISAM 分区表,也会立刻暴露底层缺陷:
- 崩溃后无法自动恢复:分区表损坏时,
REPAIR TABLE可能只修复单个分区,其余分区仍处于 inconsistent 状态,人工干预成本极高 - 并发写入直接锁全表:哪怕只更新一个分区,MyISAM 仍会施加表级锁,所有其他分区的读写全部阻塞
- 分区裁剪失效风险高:MyISAM 的分区元数据缓存机制松散,
EXPLAIN PARTITIONS显示命中分区,实际执行时可能扫描全部 .MYD 文件 - 无事务保障:
INSERT ... SELECT跨分区操作中途失败,已写入的分区数据无法回滚,留下脏状态
InnoDB 分区的关键实操要点
InnoDB 分区不是“开箱即用”的性能银弹,必须配合具体设计才能生效:
- 分区键必须是主键或唯一索引的一部分,否则建表报错
ERROR 1064 (42000): Constant, random or timezone-dependent expressions in partitioning function are not allowed - RANGE/LIST 分区适合按时间(如
created_at)或状态(如status)归档;HASH/KEY 分区慎用于高并发写,因可能导致热点分区锁争用 - 每个分区仍是独立的 B+ 树结构,但共享同一 Buffer Pool;大分区(如单个超 10GB)会加剧 buffer pool 压力,建议单分区控制在 1–5GB
-
ALTER TABLE ... REORGANIZE PARTITION操作会锁整个表,线上执行前务必评估窗口期
别被 COUNT(*) 误导:MyISAM 的“快”在分区场景下并不存在
有人觉得 MyISAM 分区能更快地 COUNT(*),这是误解。MyISAM 的元数据计数仅对**整张未分区表**有效;一旦分区,每个分区需单独统计再求和,I/O 开销反而高于 InnoDB 的索引快速遍历。真实压测中,InnoDB 分区表在 COUNT(*) WHERE dt BETWEEN '2026-01-01' AND '2026-06-30' 场景下,因分区裁剪+索引覆盖,性能通常反超。
真正容易被忽略的是:InnoDB 分区表的 auto_increment 值在跨分区插入时仍全局唯一,而 MyISAM 分区曾出现过不同分区生成重复 ID 的 bug(尤其在主从切换后),这个问题在 2025 年多个生产事故报告中反复出现。


















