1.是什么?
多版本并发控制,同一行数据平时发生读写请求时,一般需要上锁,并且阻塞其他线程。但mvcc可以做到在发生读—写请求冲突不用加锁。
2.为什么?
mvcc可以提高数据库的并发性能
可以解决问题如下:
并发读-写时
:可以做到读操作不阻塞写操作,同时写操作也不会阻塞读操作。但是写-写操作得阻塞!- 解决
脏读
、幻读
、不可重复读
等事务隔离问题。
3.怎么样实现的?
它的实现原理主要是版本链
,undo日志
,Read View
来实现的
版本链
数据库中的每行数据除了我们自己设的字段,还有隐藏字段,分别是最近修改事务id:目前正在修改事务的id, 回滚指针: 指向这条记录的上一个版本,隐藏主键:隐藏的自增id。
undo日志
Undo log 主要用于记录
数据被修改之前
的日志,在表信息修改之前先会把数据拷贝到undo log
里。当事务
进行回滚时
可以通过undo log 里的日志进行数据还原
undo log主要分为两种:
insert undo log: 事务提交后立即丢弃
update undo log: 事务回滚时需要,在快照读时也需要,只有在快照读或事务回滚不涉及该日志时,对应的日志才会被清除线程统一清除
读视图
事务进行快照读
操作的时候生产的读视图
(Read View),在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照
,也就是一个复制。
包括3个部分:
- 列表,存放着读视图生成时的活跃的事务id
- 列表中的最小事务id
- 视图生成时的已提交事务中或者列表中活跃事务的最大事务id + 1
假设事务A要读取事务B的数据。
Bid<最小事务id 则代表已经提交,A能读B
Bid > 最大事务id 代表未提交, A不能读B
列表中存放着Bid,代表B正在活跃且没有提交,A读不到B。
最小<=Bid<最大+1且不在list当中,就可以直接读取。