MySQL

MVCC 的版本链存在哪

每一行在聚簇索引的叶子上只存最新版本,外加两个隐藏列:

  • DB_TRX_ID(6 字节):最后改它的事务 id
  • DB_ROLL_PTR(7 字节):指向 undo log 里上一个版本

旧版本不是整行拷贝,而是 undo log 里的记录,只记被改掉的列。读旧版本时,从最新行出发,倒着一条条套 undo,拼出当时的样子。

所以版本链是一条从新到旧的单向链表:最新的在 B+ 树叶子上,旧的在 undo 表空间里。

几个推论:

  • 没人再需要的旧版本,由后台 purge 线程清理。
  • 长事务会让 undo 越积越多:它的快照很旧,之后产生的 undo 都不能删。
  • 二级索引记录上没有 trx_id,只有页级别的 PAGE_MAX_TRX_ID,判断不了可见性时就要回表。
esc