一篇了解全MVCC

一、什么是MVCCMVCC,全称Multi-Version Concurrency Control,即多版本并发控制,是一种并发控制的方法,一般用在数据库管理系统中,实现对数据库的并发访问,比如在MySQL InnoDB中主要是为了提高数据库并发性能,不用加锁,非阻塞并发读 。MVCC多版本并发控制指的是维持一个数据的多个版本,使得读写操作没有冲突,快照读是MySQL为实现MVCC的一个非阻塞读功能 。
二、解决的问题是什么?1、三种数据库并发场景:

  • 读读:不会有问题,也不需要并发控制
  • ?读写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读、幻读、不可重复读
  • ?写写:有线程安全问题,可能存在更新丢失问题
2、解决问题?MVCC是一种用来解决读写冲突的无锁并发控制,也就是为事务分配单项增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该事务开始前的数据库的快照(隔离级别RC下),所以MVCC为数据库解决了以下问题:
  • 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
  • 解决脏读、幻读、不可重复读等事务隔离问题,但是不能解决更新丢失问题
三、实现原理主要依赖于记录中的三个隐藏字段、undolog,read view来实现的 。
1、隐藏字段每行记录,除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段:
  • DB_ROW_ID:6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动生成一个6字节的row_id
  • ?DB_TRX_ID:6字节,最近修改事务id,记录创建这条记录或者最后一次修改该记录的事务id
  • DB_ROLL_PTR:7字节,回滚指针,用于配合undo日志,指向上一个旧版本
假设记录如图所示:
一篇了解全MVCC

文章插图
2、undolog1)概念回滚日志,表示在进行insert,delete,update操作的时候产生的方便回滚的日志 。
2)说明
  • 当进行insert操作的时候,产生的undolog,只在事务回滚的时候需要用到,并且在事务提交之后可以被立刻丢弃
  • 当进行update和delete操作的时候,产生的undolog,不仅仅在事务回滚的时候需要,在快照读的时候也需要,所以不能随便删除,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被purge线程统一清除
当数据发生更新和删除操作的时候,实际只是设置了旧记录的deleted_bit,并不是将过时的记录删除,因为为了节省磁盘空间,innodb有专门的purge线程来清除deleted_bit为true的记录,如果某个记录的deleted_id为true,并且DB_TRX_ID相对于purge线程的read view 可见,那么这条记录就是可以被清除的
3)undolog生成的记录链表(1)假设有一个事务编号为1的事务向表中插入一条记录,那么此时行数据如下,主键id=1,事务id=1
一篇了解全MVCC

文章插图
(2)假设有第二个事务(编号为2)对该记录的name做出修改,改为lisi底层操作:在事务2修改该行记录数据时1、对该数据行加排他锁2、把该行数据拷贝到undolog中,作为旧记录3、修改该行name为lisi,并且修改事务id=2,回滚指针指向拷贝到undolog的副本记录中4、提交事务,释放锁
一篇了解全MVCC

文章插图
(3)假设有第三个事务(编号为3)对该记录的age做了修改,改为32底层操作:在事务3修改该行记录数据时1、对该数据行加排他锁2、把该行数据拷贝到undolog中,作为旧记录,发现该行记录已经有undolog了,那么最新的旧数据作为链表的表头,插在该行记录的undolog最前面3、修改该行age为32岁,并且修改事务id=3,回滚指针指向刚刚拷贝的undolog的副本记录4、提交事务,释放锁

经验总结扩展阅读