网站制作产品优化,网站建设j介绍ppt模板,北京建站模板源码,优化分析点击蓝色“架构文摘”关注我哟加个“星标”#xff0c;每天上午 09:25#xff0c;干货推送#xff01;来源#xff1a;https://segmentfault.com/a/1190000037557620作者#xff1a;白菜1031一、什么是多版本并发控制多版本并发控制 技术的英文全称是 Multiversion Concur… 点击蓝色“架构文摘”关注我哟加个“星标”每天上午 09:25干货推送来源https://segmentfault.com/a/1190000037557620作者白菜1031一、什么是多版本并发控制多版本并发控制 技术的英文全称是 Multiversion Concurrency Control 简称 MVCC 。多版本并发控制(MVCC)是通过保存数据在某个时间点的快照来实现并发控制的。也就是说不管事务执行多长时间事务内部看到的数据是不受其它事务影响的根据事务开始的时间不同每个事务对同一张表同一时刻看到的数据可能是不一样的。简单来说 多版本并发控制的思想就是保存数据的历史版本通过对数据行的多个版本管理来实现数据库的并发控制。这样我们就可以通过比较版本号决定数据是否显示出来读取数据的时候不需要加锁也可以保证事务的隔离效果。可以认为 多版本并发控制(MVCC)是行级锁的一个变种但是它在很多情况下避免了加锁操作因此开销更低。虽然实现机制有所不同但大都实现了非阻塞的读操作写操作也只锁定必要的行。MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑它们一般都同时实现了多版本并发控制(MVCC)。不仅是MySQL包括Oracle、PostgreSQL等其他数据库系统也都实现了MVCC但各自的实现机制不尽相同因为MVCC没有一个统一的实现标准典型的有乐观(optimistic)并发控制 和 悲观(pessimistic)并发控制 。二、多版本并发控制解决了哪些问题1. 读写之间阻塞的问题通过 MVCC 可以让读写互相不阻塞即读不阻塞写写不阻塞读这样就可以提升事务并发处理能力。提高并发的演进思路普通锁只能串行执行读写锁可以实现读读并发数据多版本并发控制可以实现读写并发。2. 降低了死锁的概率因为 InnoDB 的 MVCC 采用了乐观锁的方式读取数据时并不需要加锁对于写操作也只锁定必要的行。3. 解决一致性读的问题一致性读也被称为 快照读当我们查询数据库在某个时间点的快照时只能看到这个时间点之前事务提交更新的结果而不能看到这个时间点之后事务提交的更新结果。三、快照读与当前读快照读(SnapShot Read) 是一种 一致性不加锁的读 是 InnoDB并发如此之高的核心原因之一 。这里的 一致性 是指事务读取到的数据要么是 事务开始前就已经存在的数据 要么是 事务自身插入或者修改过的数据 。不加锁的简单的 SELECT 都属于 快照读 例如 SELECT * FROM t WHERE id1与 快照读 相对应的则是 当前读 当前读 就是读取最新数据而不是历史版本的数据。加锁的 SELECT 就属于当前读例如 SELECT * FROM t WHERE id1 LOCK IN SHARE MODE; SELECT * FROM t WHERE id1 FOR UPDATE;四、InnoDB 的 MVCC 是如何工作的1. InnoDB 是如何存储记录的多个版本的事务版本号每开启一个事务我们都会从数据库中获得一个事务 ID(也就是事务版本号)这个事务 ID 是自增长的通过 ID 大小我们就可以判断事务的时间顺序。行记录的隐藏列InnoDB 的叶子段存储了数据页数据页中保存了行记录而在行记录中有一些重要的隐藏字段DB_ROW_ID 6-byte隐藏的行 ID用来生成默认聚簇索引。如果我们创建数据表的时候没有指定聚簇索引这时 InnoDB 就会用这个隐藏 ID 来创建聚集索引。采用聚簇索引的方式可以提升数据的查找效率。DB_TRX_ID 6-byte操作这个数据的事务 ID也就是最后一个对该数据进行插入或更新的事务 ID。DB_ROLL_PTR 7-byte回滚指针也就是指向这个记录的 Undo Log 信息。InnoDB数据记录隐藏列Undo LogInnoDB 将行记录快照保存在了 Undo Log 里我们可以在回滚段中找到它们如下图所示Undo Log回滚历史记录从图中能看到回滚指针将数据行的所有快照记录都通过链表的结构串联了起来每个快照的记录都保存了当时的 db_trx_id也是那个时间点操作这个数据的事务ID。这样如果我们想要找历史快照就可以通过遍历回滚指针的方式进行查找。2. 在 可重复读(REPEATABLE READ) 隔离级别下 InnoDB 的 MVCC 是如何工作的查询(SELECT)InnoDB 会根据以下两个条件检查每行记录InnoDB只查找版本早于当前事务版本的数据行(也就是行的系统版本号小于或等于事务的系统版本号)这样可以 确保事务读取的行要么是在事务开始前已经存在的要么是事务自身插入或者修改过的 。行的删除版本要么未定义要么大于当前事务版本号。这可以确保 事务读取到的行在事务开始之前未被删除 。只有符合上述两个条件的记录才能返回作为查询结果。插入(INSERT)InnoDB为新插入的每一行保存当前系统版本号作为行版本号。删除(DELETE)InnoDB为删除的每一行保存当前系统版本号作为行删除标识。 删除在内部被视为更新行中的一个特殊位会被设置为已删除。更新(UPDATE)InnoDB为插入一行新记录保存当前系统版本号作为行版本号同时保存当前系统版本号到原来的行作为行删除标识。五、总结多版本并发控制(MVCC) 在一定程度上实现了 读写并发 它只在 可重复读(REPEATABLE READ) 和提交读(READ COMMITTED) 两个隔离级别下工作。其他两个隔离级别都和 MVCC 不兼容因为 未提交读(READ UNCOMMITTED) 总是读取最新的数据行而不是符合当前事务版本的数据行。而 可串行化(SERIALIZABLE)则会对所有读取的行都加锁。行锁并发事务回滚 等多种特性都和MVCC相关。参考MySQL5.7文档innodb-multi-versioning 《高性能MySQL》end推荐阅读TCP 三次握手、四手挥手这样说你能明白吧拜托不要再问我线程池啦为什么 Redis 单线程还这么快Spring Cloud架构的各个组件的原理分析一口气说出 5 种 IO 模型蒙圈了如有收获点个在看诚挚感谢