688 字
3 分钟
面试鸭-MySQL中的MVCC是什么?

MySQL中的MVCC是什么?#

MVCC指的是多版本并发控制,主要是为了时读写操作互不阻塞,能同时进行。

原理是这样的: 在执行写操作或更新操作的时候,MySQL会生成一个新版本的记录,然后保留对应的版本号,并使用指针连起来成为一个链表,由新指向旧,形成版本链。 在进行普通读操作的时候,就可以去根据信息去版本链上找到自己可以读取的那个版本,就不需要加锁,读写不阻塞。

具体实现是: InnoDB的每条记录会有两个隐藏字段

  • trx_id表示最后修改这条记录的事务id。
  • roll_pointer是指向旧版本数据的指针。

每次进行更新操作的时候不是直接覆盖数据,而是把旧的值写到undo log里,新值写到数据页,然后roll_pointer指向旧版本,当执行普通的select的时候,会创建一个快照,这个快照存储了几个相关字段,然后根据这些字段去版本链上找到自己对应的版本。

问题#

undo log什么时候会被清理?#

插入操作(增加数据行)产生的undo log会立刻被清除,因为数据出现以前没有内容可以读,其他的undo log则要等到没有任何事务需要它时才会被后台的purge线程清理,具体方式是:找到系统里活跃中的事务的最老的ReadView,比这个ReadView还老的undo log才可以删除。(也就是看还需要用到最老的版本是哪个,最老的那个readview都用不上就可以删掉了)

MVCC能不能解决写写冲突?#

不能。MVCC解决的是读写冲突,写写冲突要依靠锁来解决。比如两个事务同时update同一行数据,让先执行的锁住,后执行等它执行完才能拿到锁。

为什么ReadView里面要记录max_trx_id?只使用m_ids不行吗?#

不行,因为m_ids只记录了生成readview那一刻的所有活跃事务,生成后还有可能出现新启动的事务,然后事务id是递增的,那些新启动的事务id肯定比m_ids里的大,会导致新事务的修改被认为可见的。max_trx_id就是用来判断在这之后的事务都属于不可见的。

只读事务的creator_trx_id是0,那它自己修改的数据怎么判断可见?#

只读事务没有修改操作,所以不会出现读自己修改数据的情况,如果有修改操作InnoDB就会给它分配真正的事务id。

面试鸭-MySQL中的MVCC是什么?
http://www.shineacz.top/posts/面试鸭-mysql中的mvcc是什么/
作者
shineAcZ
发布于
2026-03-14
许可协议
CC BY 4.0