目录
什么是mvcc?
MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。
什么是快照读,和当前读?
1、当前读
select lock in share mode(共享锁), select for update ; update, insert,delete(排他锁)这些操作都是一种当前读
当前读就是读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁
2、快照读
不加锁的操作(select)就是快照读,即不加锁的非阻塞读;
快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;
即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销
快照读的实现是基于多版本并发控制,既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本
mvcc的作用?
mvcc的作用主要是在多线程的环境下,提高数据库读写性,解决读(快照读)-写问题的无锁并发控制。
mvcc的实现原理?
mvcc的实现原理是通过数据库的隐藏字段和undolog 以及 readview实现的
隐藏字段:
DB_TRX_ID
6字节,最近修改的事务的id,记录创建这条或者最后一次修改该记录的id。
DB_ROLL_PTR
7字节,回滚指针,指向这条记录的上一个版本用于配合undolog,指向上一个旧版本。
DB_ROW_ID
6字节,隐藏的主键,如果数据表没有主键,那么inodb会自动生成一个6字节的row_id。
uodolog:
uodolog被称为回滚日志,表示在进行delete,update,insert时方便回滚的日志。
readview:
readview是事务进行快照读操作时产生的视图,在该事务执行快照读的时刻,会生成一个数据系统当前的快照,记录并维护当前活跃事务的id,事务id的值是递增的。
readview中的三个全局属性:
trx_list:一个数值列表,用来维护readview 生成时刻系统正在活跃的事务id
up_limit_id:记录trx_list列表中事务id最小的id
low_limit_id:readview 生成时刻系统尚未分配的下一个事务ID
mvcc的实现过程:
以下是模拟图(假设事务一的id为1,以此类推)
具体比较规则如下:
1.首先比较DB_TRX_ID(最近修改的事务的id 6)< up_limit_id(记录trx_list列表中事务id最小的id
1) ,则能看到DB_TRX_ID所在的记录,如果大于等于进入下一个判断。(显然6>1 进入第二个判断)
2.接下来判断DB_TRX_ID(6)>=low_limit_id(生成时刻系统尚未分配的下一个事务ID 7) ,如果大于等于代表DB_TRX_ID所在记录在readview 生成后才出现,所以对于当前事务肯定是不可见的,如果小于,则进入下一个判断。(6<7表示并不是readview生成后才出现的进入下一个判断)
3.判断DB_TRX_ID是否在活跃的事务中,如果在表示在readview生成的时刻,这个事务还是活跃状态,还没有commit,修改的数据当前事务也是看不到的,如果不在表示这个事务在readview生成前就已经开始commit,那么修改结果是看得见的。
RC,RR下的inoodb有什么不同?
主要是因为RC与RR的readview生成时机不同,在RC的隔离机制下,每个快照读都会生成并获取最新的readview,而RR则是事务中的第一个快照读才会创建readview,之后的readview都是同一个。