网站建设怎么打广告,wordpress 去除category,湛江市工程建设领域网站,江苏省住房和城乡建设部网站MVCC
MVCC 是多版本并发控制方法#xff0c;用来解决读和写之间的冲突#xff0c;比如脏读、不可重复读问题#xff0c;MVCC主要针对读操作做限制#xff0c;保证每次读取到的数据都是本次读取之前的已经提交事务所修改的。
概述
当一个事务要对数据库中的数据进行selec…MVCC
MVCC 是多版本并发控制方法用来解决读和写之间的冲突比如脏读、不可重复读问题MVCC主要针对读操作做限制保证每次读取到的数据都是本次读取之前的已经提交事务所修改的。
概述
当一个事务要对数据库中的数据进行select查找时MVCC 会为该事务创建一个read view数据快照查询语句会把在read view产生之前没提交的修改以及在read view产生之后才提交的事务对应的修改屏蔽掉最终只能读取到这个read view产生之前其它事务所提交的更改。换句话说读操作读取的是旧版本数据也可能是最新的而写操作是针对最新的版本记录所以能解决读-写冲突问题。
具体实现
它基于数据行的隐藏字段、undo log版本链、read view实现
数据隐藏字段最后修改事务id、回滚记录指针 undo log 版本链用于记录某行数据的多个版本的数据通过一个回滚指针字段链接起来 read view : 每个事务的读取时会产生一个read view记录了一些列的事务id具体有如下四个字段
creator_trx_id创建当前Read View的事务ID。trx_ids表示在生成ReadView时当前系统中活跃的读写事务的事务id列表。min_limit_trx_id活跃的事务中最小的事务id。max_trx_id表示生成ReadView时系统中应该分配给下一个事务的id值。low_limit_id是系统最大的事务id值这里要注意是系统中的所有事务id不仅包含正在活跃的事务id、还包含之前已提交的事务id。
注意:
只有在对表中的记录做改动时(执行INSERT、DELETE、UPDATE这些语句时)才会为事务分配事务id否则在一个只读事务中的事务id值都默认为0。low_limit_id并不是活跃事务列表trx_ids中的最大值而是所有事务id中最大的1这里的所有事务包括活跃的、已提交的。比如现在有id为123这三个事务之后id为3的事务提交了。那么一个新的读事务在生成ReadView时trx_ids就包括1和2up_limit_id的值就是1,low_limit_id的值就是4。
MVCC工作流程
某个事务执行select查找时首先根据数据行的某个字段获取事务自己的版本号也就是事务ID;然后创建ReadView;查询得到最新数据然后与ReadView中的事务版本号按照一定规则进行比较;如果不符合ReadView规则就需要从Undo Log 中获取历史快照;一直往前查找直到返回符合规则的数据。
read view是怎么去找到当前read view创建之前已经提交修改的最新数据的具体规则是什么
先根据数据行记录的回滚指针在undo日志中找到最新一条记录找到其对应的事务id然后做四轮对比
对比最新记录的事务id和当前read view的事务id如果相同则说明最新的数据就是当前事务修改的可以直接读。等于当前id代表是自己改的则可读对比最新记录的事务id和当前read view的记录的活跃事务id最小值看看是不是当前记录是不是read view创建之前就已经提交完的如果是则可以直接读。小于最小活跃事务id代表之前提交的修改则可读对比最新记录的事务id和当前read view的记录的最大事务id看看当前记录是不是read view创建之后才有的如果是就不读。大于最大事务id代表后面才提交的修改不可读对比最新记录的事务id是不是存在于当前活跃事务id列表当中如果存在则说明是未提交的数据不能读取如果不存在则可读。在活跃事务列表里代表未提交的修改可读
这四轮对比完之后如果都显示不能读则找到undo日志的下一跳数据继续四轮对比。知道找到某条可读的记录。
假设事务5创建read view时系统中有8个事务对应查找情况如下 疑问其实整个流程就是把那些活跃事务未提交造成的修改排除掉然后再判断下当前事务是创建read view之前提交的还是创建read view之后提交的那为什么要在最后一步才去判断事务id是否在活跃id列表中 自我理解因为判断某个id是否在活跃事务id列表里需要一次遍历操作放在第一步去做的话每次都要遍历速度很慢其实可以先把其它情况处理掉不需要遍历当别的情况都不满足时最后再考虑是否在活跃id列表中以此提高查找效率。
事务隔离级别与MVCC
四个事务隔离级别与MVCC的关系
首先最低的读未提交和串行化没有用到MVCC机制而读已提交和可重复度用到了MVCC去解决读写冲突中的脏读取和不可重复读的问题。
读已提交隔离级别中MVCC怎么解决脏读的
同一个事务中每次读取时创建一个read view根据read view中记录的事务id去undo log中把其它未提交事务的记录个过滤掉只会读取已提交事务所造成的修改。
问题因为每次查询都会创建一个read view所以两次查询之间如果其它事务对数据进行修改这时对第二次查询产生的read view的视角下刚刚的修改是可见的所以这就有了不可重复读的问题。 可重复读隔离级别中MVCC怎么解决不可重复读保证可重复读
对于同一个事务中对同一条数据的多次读取复用之前的read view也就是只有在首次读取数据时才会产生read view这就避免了出现在一个事务中的多次读取结果不一样的情况。 总结MVCC机制
MVCC 是多版本并发控制方法用来解决读和写之间的冲突比如脏读、不可重复读问题MVCC主要针对读操作做限制保证每次读取到的数据都是本次读取之前的已经提交事务所修改的。
它具体实现依赖于数据行隐藏字段、undo log版本链和read view。
具体过程在某个事务执行读操作时可以通过数据行的隐藏列去找到undo日志中的历史版本记录每个历史版本记录里面都记录了事务id然后会读操作会创建一个read view视图里面包含了一些事务id的数据然后通过对比read view里面的事务id数据和undo版本链中的事务id数据就可以找到read view创建之前所提交的数据。
追问read view具体记录了哪些数据具体怎么去和undo log中记录的id对比最后找到想要的数据的
read view视图里面记录了当前事务id、当前未提交事务活跃事务id列表、当前未提交事务id列表的最小值、当前最大事务id。先找到undo log第一条数据对比事务id和read view当前事务id是否一样。。对比事务id是不是小于最小活跃事务id。。。然后对比事务id是不是大于最大事务id。。。最后判断事务id是不是在活跃事务id列表里面。。