MVCC作用
MVCC使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,而是把数据库的行锁和行的版本号结合起来,只需要很小的开销,就可以实现非锁定读。从而提高数据库的并发性能。
MVCC是采用无锁的形式解决读-写冲突问题。这里的读是指的快照读。即MVCC实现的快照读!!!
什么是MVCC
多版本并发控制(MVCC)是一种解决读-写冲突的无锁并发控制。
每一行记录都有两个隐藏列:创建版本号和回滚指针。事务开启后存在一个事务id。多个并发事务同时操作某行,不同的事务对该行update操作会产生多个版本,然后通过回滚指针组成undo log链。而MVCC的快照读正是通过事务id和创建版本号从而实现的快照读。
MVCC与隔离级别的关系
MVCC是为了解决读-写问题。且通过不同的配置,也可以解决事务开启后,快照读不可重复读的问题。
不可重复读:同一个事务中读取某些数据已经发生改变,或某些记录已经删除。
幻读:一个事务按照相同的查询条件重新读取以前检索过的数据,却发现其他事务插入了满足查询条件的新数据,这种现象被称为幻读。
RC和RR均实现了MVCC,但是为什么RR解决了RC不可重复读的问题?
你可以这样认为,RC之所以有不可重复读的问题,只是因为开发者有意设置的(设置多种隔离级别,用户可以根据情况设置)。本来数据都提交到数据库了,RC读取出来也没什么问题呀?况且Oracle数据库本身的隔离级别就是RC。
READ-COMMITTED(读已提交)
读已提交RC,在这一隔离级别下,可以在SQL级别做到一致性读,每次SQL语句都会产生新的ReadView。这就意味着两次查询之间有别的事务提交了,是可以读到不一致的数据的。
REPEATABLE-READ(可重复读)
可重复读RR,在第一次创建ReadView后,这个ReadView就会一直维持到事务结束,也就是说,在事务执行期间可见性不会发生变化,从而实现了事务内的可重复读。
MVCC和间隙锁
MVCC无锁解决了读-写冲突的问题。并且解决了不可重复读问题。从而实现了RC和RR两个隔离级别。
而间隙锁本质上依旧是锁,会阻塞两个并发事务的执行。
那么RR为什么还要进入间隙锁,难道仅仅为了解决幻读的问题吗?
注意:只有RR隔离级别才存在间隙锁。
间隙锁在一定程度上可以解决幻读的问题,但是间隙锁的引入我觉得更多是为了处理binlog的statement模式的bug。
mysql数据库的主从复制依靠的是binlog。而在mysql5.0之前,binlog模式只有statement格式。这种模式的特点:binlog的记录顺序是按照数据库事务commit顺序为顺序的。
当不存在间隙锁的情况下,会有如下的场景:
master库有这么两个事务:
1、事务a先delete id<6,然后在commit前;
2、事务b直接insert id=3,并且完成commit;
3、事务a进行commit;
此时binlog记录的日志是:事务b先执行,事务a在执行(binlog记录的是commit顺序)
那么主库此时表里面有id=3的记录,但是从库是先插入再删除,从库里面是没有记录的。
这就导致了主从数据不一致。
为了解决这个bug,所以RR级别引入了间隙锁。
未经允许不得转载:任鹏个人博客 » 什么是MVCC,为什么要设计间隙锁?
最新评论
Forex wiki. https://lt.forex-stock-bitcoin-brokers.com
Magnificent items from you, man. I have take note your stuff
Following on from the 3rd March Meetings held by economic de
It is remarkable, rather valuable message dfgdlfg2131.32
一般都会有一个沙盒期的,过了沙盒期就会慢慢放出来
百度不收录是应为是新站的原因吗?
The spike in consumer prices that left inflation at a four-d