| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 简单梳理一下MySQL多版本并发控制原理 -> 正文阅读 |
|
[大数据]简单梳理一下MySQL多版本并发控制原理 |
1 事务的基本概念1.1 事务用户定义的一个数据库操作序列,这些操作要么全部都做,要么全不做,是一个不可分割的工作单位。事务是恢复和并发控制的基本单位。 1.2 事务的4个特性
保证事务ACID特性是事务管理的重要任务 。事务ACID特性遭到破坏的因素有:
2 标准SQL事务隔离级别2.1 事务并发问题在高等教育出版社的《数据库系统概论》中认为并发操作带来的数据不一致性包括丢失修改、不可重复读和读“脏”数据。
一般认为,按照不同操作类型导致的数据不一致分为脏读、不可重复读 、幻读。简单来说:
2.2 事务隔离级别2.2.1 标准SQL事务隔离级别实现原理解决并发事务问题的最常见方式就是悲观并发控制了(也就是数据库中的锁),封锁是实现并发控制的一个非常重要的技术。标准SQL定义了四种事务隔离级别,它们的实现是依赖锁的。不同的隔离级别及其实现方式如下表所示:
2.2.2 并发操作带来的数据不一致性
2.3 设置MySQL隔离级别SQL 标准定义的四种隔离级别,MySQL 全都支持。MySQL的事务实现逻辑是位于引擎层的,并且不是所有的引擎都支持事务的,后文引用的例子都是以InnoDB引擎为基准。 2.3.1 查询当前会话的隔离级别
此时返回的是: 2.3.2 查询系统全局的隔离级别
此时返回的是: 由此可见系统全局设置的隔离级别和数据库设置的隔离级别可以是不同的。 2.3.3 设置会话的隔离级别
3 不同隔离级别与并发事务演示3.1 读未提交MySQL演示: 设
3.2 读已提交MySQL演示:
3.3 可重复读MySQL演示:
3.4 序列化读序列化读的隔离级别严格按照先后顺序执行数据变更操作,读写加锁。演示略。 4 MySQL 实现事务隔离的原理并发控制的方法包括封锁技术、时间戳方法、乐观控制法和多版本控制法等。 在只使用锁来实现隔离级别的控制的时候,需要频繁的加锁解锁,而且很容易发生读写的冲突。例如在RC级别下,事务A更新了数据行1,事务B则在事务A提交前读取数据行1都要等待事务A提交并释放锁,如下表所示:
为了不加锁解决读写冲突的问题,MySQL引入了多版本并发控制(Multi-Version Concurrency Control, MVCC)机制。 4.1 多版本并发控制版本(version)是指数据库中数据对象的一个快照,记录了数据对象某个时刻的状态。多版本并发控制是指在数据库汇总通过维护数据对象的多个版本信息来实现高效并发控制的一种策略。 在多版本机制中,每个数据对象Q的写操作都创建一个新版本,这样一个数据对象就有一个版本序列Q1,Q2, … ,Qm 与之相关联。每一个版本Qk拥有版本的值,创建Qk的事务的时间戳和成功读取Qk的事务的最大时间戳。
多版本协议 用TS(T)表示事务T的时间戳,TS(Ti)<TS(Tj)表示事务Ti在事务Tj之前开始执行。 多版本协议描述如下: ? 假设版本Qk具有小于或等于TS(T)的最大时间戳。 若一个数据对象的两个版本Qk和Ql,其 W-timestamp 都系统中最老的事务的时间戳。那么这两个版本中较旧的那个版本将不再被用到,因而可以从系统中删除。 多版本并发控制利用物理存储上的多版本来维护数据的一致性。这就意味着当检索数据库时,每个事务都看到一个数据的一段时间前的快照,而不管正在处理的数据当前的状态。多版本并发控制和封锁体制相比,主要的好处是消除的数据库中数据对象读和写操作的冲突,有效地提高了系统的性能。 4.2 MySQL快照读和当前读4.2.1 快照读快照读即 snapshot read,它的官方叫法是Consistent Nonlocking Reads,不加锁的非阻塞读,即一致性非锁定读。 它是InnoDB 通过 MVCC(多版本控制)将数据库在过去某个时刻的快照应用在查询上,使得这次查询只能看到别的事务生成快照前提交的数据,而不能看到别的事务生成快照后提交的数据或者未提交的数据。简而言之,读取的记录是快照版本,也就是历史版本。 快照读的问题在于:在同一个事务中,能够读取到之前提交的数据。表现为
一致读取是InnoDB处理 在 在 在 注意:在事务中,为查询创建的快照,并不适用于 4.2.2 当前读当前读即 current read,它的官方叫法是 Locking Reads,加锁的阻塞读,即锁定读。 它读取记录的最新版本。读取时还要保证其他并发事务不能修改当前记录,并且会对读取的记录进行加锁。像UPDATE、DELETE、INSERT、SELECT … LOCK IN SHARE MODE、SELECT … FOR UPDATE这些操作都是一种当前读。 4.2.3 MySQL快照读和当前读演示假设现在的隔离级别是读已提交。
4.3 MySQL日志机制MySQL日志机制是MySQL实现数据库事务功能除了锁技术和MVCC的另一项重要技术。 4.3.1 bin logbin log,即归档日志。 bin log是MySQL层面的,以二进制记录的日志,用于数据库基于时间点的还原。它会记录DDL、DML以及数据库表的操作语句等,同时操作的消耗时间也会记录进去。事务提交之后会记录bin log,定时刷盘。如果操作没有记录到bin log里面,那么一系列提交和未提交的事务都将数据丢失。它提供了整体业务层面的保障。 4.3.2 redo logredo log,即重做日志。 redo log是InnoDB存储引擎层面的日志,记录的是数据修改之后的值,不管事务是否提交都会记录下来。重做日志对数据的正确提交提供保障。对数据的操作,比如更新或者插入操作,经常会伴随数据的持久化,如果直接进行刷盘,对应IO层是一个资源浪费,或者说性能阻塞,所以说,InnoDB通过先写日志,再写磁盘,将读写持久化进行分离,可以高速写入日志再慢慢写入磁盘 ,通过这个机制保证数据IO高效。如果写入磁盘失败或者延迟,可以通过redo log重新快速刷入磁盘中。 4.3.3 undo logundo log,即回滚日志。 undo log也是InnoDB存储引擎层面的日志,它保存事务发生之前的数据版本,可以用于回滚,同时可以提供MVCC下的读,也即非锁定读。 4.4 隐式字段4.4.1 DB_TRX_ID
4.4.2 DB_ROLL_PTR
4.4.3 DB_ROW_ID
4.4.4 其他字段比如 创建版本号、删除版本号等字段 4.6 读视图read view,读视图,决定了数据是否可以可被其他事务读取的关键因素。
演示1:
演示2:
4.7 数据可见性算法4.8 InnoDB的事务具体实现仅仅MVCC能否解决幻读问题?实际上MVCC并不能解决幻读问题,因为为查询创建的快照,并不适用于 假设 student 表为空表
可以看到前后查出来的数据行不一致,发生了幻读。所以说只有MVCC是不能解决幻读问题的,解决幻读问题靠的是间隙锁。如下:
参阅官方文档了解MySQL的锁定读和一致性非锁定读以及隐式锁定和显式锁定等相关概念之后,来看下InnoDB的事务具体是怎么实现的(下面的读都指的是非主动加锁的select):
可以看到,InnoDB通过MVCC很好的解决了读写冲突的问题,而且提前一个级别就解决了标准级别下会出现的幻读和不可重复读问题,大大提升了数据库的并发能力。 5. 经验与扩展5.1 选择隔离级别
5.2 改进的多版本并发控制多版本协议可以进一步改进。区分事务的类型为只读事务和更新事务。对于只读事务,发生冲突的可能性很小,可以采用多版本时间戳。对于更新事务,采用教保守的两阶段封锁(2PL)协议。这样的混合协会称为MV2PV。具体做法如下: 除了传统的读锁(共享锁)和写锁(排他锁)外,引进一个新的封锁了类型,称为验证锁(certify lock, Clock)。封锁的相容矩阵如下表所示:
注:Y表示相容请求,N表示不相容请求 在这里,系统最多只要维护数据对象的两个版本。多个读操作可以和一个写操作并发执行。这种情况是传统的2PL锁不允许的,提高了读写事务之间的并发度。 目前的很多商用数据库系统,例如Oracle,Kingbase ES都是采用MV2PL协议的。 具体请查阅相关资料:数据库系统概述-高等教育出版社 6 小结在本文中介绍了事务的基本概念和隔离级别,以及MySQL对事务的实现原理,包括MySQL Logs、隐式字段、快照读和当前读、读视图以及数据可见性算法等组成MVCC基本结构的内容。 参考资料[1] https://www.imooc.com/learn/1309 普贤. 探秘 MySQL 多版本并发控制原理.慕课网. [2] https://cloud.tencent.com/developer/article/1708499 X先生. 深入理解MySQL中事务隔离级别的实现原理. 腾讯云+社区. 2020-10-29. [3] https://segmentfault.com/a/1190000023332101 X先生. 一文读懂数据库中的乐观锁和悲观锁和MVCC. 思否. 2020-07-22. [4] https://dev.mysql.com/doc/refman/8.0/en/ MySQL 8.0 Reference Manual [5] https://www.docs4dev.com/docs/zh/mysql/5.7/reference/ MySQL5.7中文文档 [6] https://www.thegeeksearch.com/understanding-innodb-locking-in-mysql-database Understanding InnoDB locking in MySQL database [7] 王珊 萨师煊. 数据库系统概述(第5版). 高等教育出版社. 2015. |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 8:55:31- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |