【MySql】MVCC的总结

168 阅读3分钟

参考视频和文档

www.bilibili.com/video/BV186…

www.php.cn/mysql-tutor…

MVCC multi-version concurrency contro 多版本并发控制,目的是为了让读写能并行,但不是想串行化那样加锁实现(加了读锁)

(1)当前读和快照读

当前读:读到最新的版本,即数据库中的记录,不涉及到undolog; ①select lock in share mode (共享锁);②select for update (排他锁);③update (排他锁);④insert (排他锁) ;⑤delete (排他锁);⑥串行化事务隔离级别

快照读:基于MVCC,读到的数据不一定是最新版本。比如,不加锁的select操作(事务级别不是串行化)

(2)一条记录的隐藏信息

image.png

一条记录的有3个隐藏字段: rowid:隐藏的主键id trx_id: 当前新增或者修改当前记录的事务id roll_ptr: 回滚指针,指向这条记录的上个版本。需要配合UndoLog日志使用,第一次insert后是null

(3)undoLog

进行insert、delete、update时产生的日志。 其中版本链=当前记录+undolog

image.png

(4)读视图( Read View)

①作用:在某事务在执行快照读操作时,会创建Read View ,把它作为条件去判断看到哪个版本的数据(这个数据既可能是当前最新的数据,也有可能是该行记录的undo log里面某个版本的数据)

②构成:trx_ids:正在活跃的事务id1,活跃的事务id2 up_limit_id: trx_ids 里最小的值 low_limit_id :是指下一个要生成的事务 id。即当前系统最大事务编码+1; creator_trx_id:创建当前Read View的事务id。注意,同一个事务,可能会创建多个Read View

③根据读视图自上而下检索undo log时每一个版本的数据时, 该版本数据能够被看到的判断逻辑? a,Read View活跃事务id全部 > 记录上最新的事务trx_id,则当前事务能看到当前的记录(说明是之前事务生成的); b,Read View中创建当前Read View的事务id=记录上最新的事务trx_id,则当前事务能看到当前的记录(说明记录最近一次是被当前事务修改的); c,记录上最新的事务trx_id >= Read View将要生成的事务id,则当前事务不能看到当前的记录(说明记录是本次读之后的事务产生的); d,记录上最新的事务trx_id< Read View将要生成的事物id。记录上最新的事务trx_id 在 Read View活跃事务id全部 ?如果在,说明未提交,当前事务不能看到当前的记录;如果不在,说明已经被提交了,当前事务能看到当前的记录。

④读已提交RC和可重复读RR,如何通过Read View控制可重复读的? a,在读已提交隔离级别时,每次读都会重新获取最新的Read View; b,可重复读时,只会在第1次读时获取Read View,即第2次及之后读都只会用第一次的Read View; 对于可重复读,因为Read View是一样的,虽然 记录上最新的事务trx_id在不断变化,对于新事务提交的或者旧事务提交的,对于Read View依旧维持旧的trx_ids,因而trx_id在不断变化并不会导致前后两次读到的数据不一致。