You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL行格式从Fixed改为Dynamic时CPU占满问题求助

这事儿我碰到过类似的情况,咱们先从MyISAM两种行格式的核心差异说起,就能明白为啥改完Dynamic后CPU直接拉满了:

核心原因:FIXED vs Dynamic行格式的更新逻辑天差地别

1. FIXED格式的「原地更新」:零额外开销

你的表在FIXED格式下,所有字段都是固定长度:int占4字节、tinyint占1字节、char(10)占10字节,算下来每行总长度固定为32字节(大概核算:4(id)+4(r1)+10(r2)+1(r3)+1(r4)+4(r5)+4(r6)+4(r7))。

这种情况下,MySQL定位行的方式超级简单:行号 × 固定行长度就能直接算出该行在磁盘上的偏移量,更新操作就是直接找到这个位置覆盖旧数据——完全不需要移动其他行,也不需要额外计算行长度、更新索引指针之类的操作,CPU和IO开销都极低,特别适配你这种有大量更新的场景。

2. Dynamic格式的「动态行处理」:额外开销暴增

当你改成Dynamic格式后,哪怕你的字段看起来都是固定长度,MyISAM的处理逻辑也完全变了:

  • 首先,Dynamic格式会给每行额外加一个行长度指示器,用来标识当前行的实际长度(哪怕长度没变,这个指示器也得维护)。每次更新时,MySQL都要先读取并校验这个指示器,多了一层计算开销。
  • 更关键的是:Dynamic格式的设计初衷是适配可变长度字段(比如VARCHAR、TEXT),它默认会假设行长度可能发生变化。哪怕你实际更新的是固定长度字段(比如r1、r3这些),MySQL在处理更新时也会走一遍「检查行长度是否变化→如果变化则移动行→更新所有索引中指向该行的指针」的完整流程。
  • 你的表有12.8亿行,哪怕只有一小部分更新,这个额外的检查、索引指针更新逻辑都会让CPU疯狂工作——尤其是MyISAM是表级锁,大量更新本来就有锁竞争,再加上Dynamic格式的额外计算,直接把CPU拉满就不奇怪了。

3. 补充:为啥char(10)在Dynamic下也会有影响?

虽然你的r2是char(10),在latin1字符集下不管存多少都是10字节,但Dynamic格式下,MySQL对char字段的存储逻辑还是会和FIXED有差异:FIXED下char是直接存满固定长度,Dynamic下会额外记录字段的实际有效长度(哪怕和固定长度一致),这又多了一层计算步骤。

总结

你的场景完全不适合Dynamic行格式——MyISAM的FIXED格式就是为固定长度字段、大量更新的场景设计的,改回FIXED应该就能解决CPU满负荷的问题。

内容的提问来源于stack exchange,提问作者Fish Wu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:10:30