MySQL多版本并发控制机制(MVCC)源码浅析
由上面的lock_clust_rec_cons_read_sees可知,行版本可见性由read_view_sees_trx_id函数判断: 其实上述函数就是一个二分法,read_view其实保存的是当前活跃事务的所有事务id,如果当前行版本对应修改的事务id不在当前活跃事务里面的话,就返回true,表示当前版本可见,否则就是不可见,如下图所示。 接上述lock_clust_rec_cons_read_sees的返回: undolog搜索可见版本的过程 我们现在考察一下row_sel_build_prev_vers_for_mysql函数:
主要是调用了row_ver_build_for_consistent_read方法返回可见版本: 整个过程如下图所示: 至于undolog怎么恢复出对应版本的row记录就又是一个复杂的过程了,由于篇幅原因,在此略过不表。 read_view创建时机再讨论 在创建一致性视图的row_search_for_mysql的代码中 trx_assign_read_view中由这么一段代码 所以综合这两段代码,即在一个事务中,只有第一次运行select(不加锁)的时候才会创建一致性视图,如下图所示: 笔者构造了此种场景模拟过,确实如此。 MVCC和锁的同时作用导致的一些现象 MySQL是通过MVCC和二阶段锁(2PL)来兼顾性能和一致性的,但是由于MySQL仅仅在select时候才创建一致性视图,而在update等加锁操作的时候并不做如此操作,所以就会产生一些诡异的现象。如下图所示: 如果理解了update不走一致性视图(read_view),而select走一致性视图(read_view),就可以很好解释这个现象。 如下图所示: 总结 MySQL为了兼顾性能和ACID使用了大量复杂的机制,2PL(两阶段锁)和MVCC就是其实现的典型。幸好可以通过xcode等IDE进行方便的debug,这样就可以非常精确加便捷的追踪其各种机制的实现。希望这篇文章能够帮助到喜欢研究MySQL源码的读者们。 【编辑推荐】
点赞 0 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |