《高性能MySQL》MVCC(多版本并发控制)

咱们知道事务的隔离级别中只有:可串行化 能够解决幻读的问题,但串行化会在读取的每一行数据上都加锁,这可能会致使大量的超时和锁争用的问题,锁开销很是之大,在实际的项目应用中,只有在必须确保数据的一致性且没有并发的状况下才会考虑使用,通常这一隔离级别不多会被用到。而在MySQL的事务型存储引擎中,默认隔离级别是 可重复读,但可重复读并不能解决幻读的问题,所以,MySQL便引入的MCVV(多版本控制, 将历史数据存一份快照,因此其余事务增长与删除数据,对于当前事务来讲是不可见的。 来解决幻读的问题,并使大多数的读操做均可以不用加锁。并发

MVCC能够当作是行锁的变种,但它的开销更低,这得益于它的实现机制,使它能在不少状况下避免加锁操做,例如非阻塞的读操做。MVCC经过保存数据在某个时间点的快照来实现,根据每一个事务的开始时间不一样,每一个事务对同一张表,同一时刻看到的数据都是不同的,而每一个事务在他们各自的事务内的数据又是保持一致。spa

以MySQL中的InnoDB为例,其MVCC实现是经过在每行记录后面保存两个隐藏的列,而这两个列分别保存了行的建立时间和行的删除时间,这个存储的时间值实际是系统版本号。每开启一个新事务,系统版本号都会自动递增,而某个事务开始时刻的系统版本号就会做为该事务的版本号,用来和查询获得的每行记录的版本号进行比较。这种描述是否是有点似曾相识的味道,没错,这种并发实现和咱们日常的用时间戳或版本号实现乐观锁大同小异。不一样的是,MVCC在修改数据行时是对其副本进行修改,以此来保证各个事务互不干扰,在保存时比较版本号无误以后才会覆盖原来的记录。怎样才算无误呢?特此附上比较规则:版本控制

1,select操做事务

a,行的系统版本号要小于或等于事务的系统版本号date

b,行的删除版本号要么未定义,要么大于当前事务版本号select

 2,insert操做时间戳

为新插入的每一行保存当前系统版本号做为行版本号数据

3,delete操做项目

为删除的每一行保存当前系统版本号做为行删除标识 查询

 4,update

插入一行新记录,保存当前系统版本号做为行版本号,同时保存当前系统版本号到原来的行做为删除标识

相关文章
相关标签/搜索