myisam不支持mvcc,因其不支持事务、无undo log、无隐藏版本字段、无read view机制,且mysql server层不会为其注入mvcc逻辑。

MyISAM 没有 undo log,MVCC 根本无从“回溯”
MVCC 的核心能力之一是让事务读取到“过去某个时间点”的数据版本,这依赖于 undo log 中保存的历史记录。而 MyISAM 引擎完全不生成、不维护 undo log —— 它连事务回滚都做不到,更别说按版本号筛选快照了。你执行 SELECT 时,它只能返回磁盘上最新的那一行,没有“历史”可言。
MyISAM 只有表级锁,没有行级版本控制的物理基础
InnoDB 在每行后面加了两个隐藏列:DB_TRX_ID(创建事务ID)和 DB_ROLL_PTR(指向 undo log 的指针),这是 MVCC 版本链的载体。而 MyISAM 表结构里压根没预留这些字段,也没有事务 ID 生命周期管理机制。它用的是全局表锁,所有并发修改都串行排队,自然不需要区分“谁改的哪一行”或“该行在哪个事务里可见”。
MyISAM 不支持事务,Read View 机制无法构建
MVCC 的可见性判断依赖 Read View:一个事务启动时会拍下当前活跃事务 ID 列表,后续所有 SELECT 都基于这个快照做版本比对。但 MyISAM 不跟踪事务状态,BEGIN 和 COMMIT 对它只是语法糖,引擎层根本不记录“当前有哪些事务正在运行”。没有 Read View,就等于没有判断依据,SELECT 只能直读最新数据。
MySQL Server 层不会为 MyISAM 强行注入 MVCC 逻辑
即使你在 READ COMMITTED 隔离级别下查 MyISAM 表,MySQL Server 层也不会调用任何 MVCC 相关路径。源码里 handle_select 走的是纯堆扫描逻辑,跳过所有 trx_sys、purge_sys、read_view 相关分支。换句话说,MVCC 是 InnoDB 存储引擎自己实现的一套闭环机制,Server 层只负责把 SQL 转发给对应引擎,不越界补功能。
真正容易被忽略的是:哪怕你把 autocommit=0、显式 BEGIN、甚至用 Spring @Transactional 包裹查询,只要底层表是 MyISAM,所有这些操作都不会触发 MVCC 行为——不是配置没生效,而是引擎压根没提供这个能力接口。











