myisam不支持事务,故sysbench oltp_read_write会报错或卡死;其高tps多来自纯读脚本,无法反映真实oltp并发性能,且表级锁导致tps剧烈抖动、p99延迟失控。

别直接跑同一套 sysbench 命令对比两个引擎——结果完全不可比,本质是拿不同设计目标的系统硬拼指标。
为什么 sysbench oltp_read_write 在 MyISAM 上根本跑不通
MyISAM 不支持事务,而 oltp_read_write 默认包含 COMMIT、SELECT ... FOR UPDATE 和写后立即读验证逻辑。一执行就报错:ERROR 1036 (HY000): Table 'sbtest1' is read only 或直接卡在 Locked 状态。你看到的“TPS 高”,大概率是 oltp_point_select 这种纯读脚本跑出来的假象——它绕开了写瓶颈和锁争用,测不出真实 OLTP 场景下的并发退化。
实操建议:
- 真要压测 MyISAM,必须加
--oltp-read-only=on,且确认脚本里没混入任何INSERT/UPDATE - 用
SHOW PROCESSLIST;观察线程状态:大量Locked就是 MyISAM 表级锁在生效;InnoDB 卡住时显示的是updating或waiting for index lock - MyISAM 的
concurrent_insert=2只对尾部INSERT有效,对主键更新、非空字段修改完全不缓解
buffer_pool_size 和 key_buffer_size 别设反了
innodb_buffer_pool_size 是 InnoDB 的命脉,缓存数据页+索引页;key_buffer_size 只给 MyISAM 的索引缓存用,对数据页无效——MyISAM 数据页全靠 OS page cache,key_buffer_size 再大也加速不了 SELECT *。
常见错误:
- 把
key_buffer_size设到物理内存 50%,导致系统 swap 频繁,反而拖慢所有引擎 - InnoDB 测试时仍用默认
128M的innodb_buffer_pool_size,结果全表走磁盘,QPS 断崖下跌 - 混合引擎库中,只调大
key_buffer_size却忽略innodb_buffer_pool_size,InnoDB 表性能被严重低估
压测前必须分别调优:innodb_buffer_pool_size = 70% RAM;MyISAM 则需加大 key_buffer_size 并确保 read_buffer_size 足够,否则随机读成瓶颈主因。
建表语句和 sysbench prepare 必须显式指定 ENGINE
sysbench --mysql-storage-engine=MyISAM prepare 在 MySQL 8.0+ 和 Percona Server 中早已失效——SHOW ENGINES; 返回 SUPPORT=NO 就说明 MyISAM 已被禁用,强行指定会静默回退为 InnoDB。
正确做法:
- 手动建表:
CREATE TABLE sbtest1 (...) ENGINE=MyISAM;,再用sysbench --tables=1 --table-size=1000000 prepare - MyISAM 不支持在线 DDL,
--oltp-table-size=10000000后若需OPTIMIZE TABLE,可能卡死数小时;InnoDB 却能在线重建 - MyISAM 的
DELAY_KEY_WRITE=1能压测时提升写吞吐,但断电即索引损坏,线上绝对禁用
响应时间抖动大、TPS 波动剧烈?先看是不是 MyISAM 锁在拖后腿
跑 sysbench --threads=32 run 时,InnoDB 通常呈现平滑 QPS 曲线;MyISAM 往往在 5–10 秒内反复跌零——这不是机器问题,是写操作触发整表锁,所有线程排队等待。
关键识别点:
- MyISAM 下
ALTER TABLE或慢INSERT ... SELECT会让整张表不可用,连SELECT COUNT(*)都卡住 -
REPAIR TABLE过程中表完全不可读;InnoDB 根本不需要这种操作 - SSD 上 MyISAM 基准测试反而比 HDD 差:因为 SSD 放大了 MyISAM 随机读瓶颈,而 HDD 的寻道延迟掩盖了部分问题
真正需要关注的不是“哪个引擎原始 TPS 高”,而是“在写入并发 >50 且混合读写时,谁的 P99 延迟稳定、谁的锁队列不堆积”。这点上,MyISAM 的表级锁机制决定了它无法通过调优绕过根本限制。











