根据《高性能mysql》一书的描述,mvcc实现应该大致如下:
1、每行数据后面有两个隐藏的字段,一个字段为更新标识,一个字段为删除标识,记录内容为更新/删除时候的系统版本号。
2、select过程中,会根据当前事务版本号去过滤小于等于的数据。
3、update操作实际会新增一行记录,而并非在原数据上修改。
4、delete也并非物理删除,而是在删除标识字段上加上版本号。
听起来蛮不错的,然而innodb的mvcc实现并非如此!!
在innodb中,两个隐藏字段分别为DATA_TRX_ID、DATA_ROLL_PTR(如果没有主键,则还会多一个隐藏的主键列)。
DATA_TRX_ID
记录最近更新这条行记录的事务 ID,大小为 6 个字节
DATA_ROLL_PTR
表示指向该行回滚段(rollback segment)的指针,大小为 7 个字节,InnoDB 便是通过这个指针找到之前版本的数据。该行记录上所有旧版本,在 undo 中都通过链表的形式组织,在网上搜了一下,大概格式如下,它记录的是每个版本被修改的数据,并非是一条操作的反操作。
所以,实际上每次进行update操作时,并非是会创建一个新的副本。而是会先将就的数据行copy进undo log中去,随后修