MVCC

MVCC

Multi Version Concurrency Control 多版本并发控制

什么是 MySQL InnoDB 下的当前读和快照读?

  • 快照读:一般的 select 都是快照读(事务级别不是串行化),基于 MVCC 实现,既然如此,读到的数据就不一定是当前最新的数据,有可能是之前历史版本的数据
  • 当前读:读取的数据是当前最新的版本,会对数据进行加锁,防止其他事务修改,属于悲观锁
    • selet in share mode(共享锁)
    • select for udate(排他锁)
    • update, insert, delete(排他锁)
    • 串行化事务隔离级别

MVCC 是怎么实现的?

表中一行数据包含数据本身,事务 ID(自增)和回滚指针

  • undo log
  • 版本链
  • readview
    • creator_id:表示生成该 readview 的事务的事务 id
    • m_ids: 表示在生成 readview 时当前系统中活跃的读写事务的事务 id 列表,活跃指的就是还没 commit
    • min_trx_id:表示在生成 readview 时当前系统中活跃的读写事务中的最小事务 id,也就是 m_ids 最小值,第 0 个元素
    • max_trx_id:表示生成 readview 时系统中应该分配给下一个事务的 id(和 min 不同,max 不是 m_ids 最后一个,而是下一个)

trx_id 是数据库中数据的 trx_id

trx_id == creator_trx_id:可以正常访问,场景可能是 update 了后,马上开始 select

trx_id < min_trx_id:可以访问,表示 trx_id 已经是提交的了

trx_id > max_trx_id:不可以访问,已经超出版本链了

min_trx_id <= trx_id <= max_trx_id:如果 trx_id 在 m_ids 里,不可以访问,不在则可以