IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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事务、事务实现的原理、隔离级别

事务的四大特性(ACID)

  1. 性(Atomicity):?事务是最?的执单位,不允许分割。事务的原性确保动作要么全部完成,要么完全不起作
  2. 致性(Consistency):?事务前后,数据保持致,多个事务对同个数据读取的结果是相同的;
  3. 隔离性(Isolation):?并发访问数据库时,户的事务不被其他事务所扰,各并发事务之间数据库是独的;
  4. 持久性(Durability):?个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发故障也不应该对其有任何影响。

并发事务带来的问题

脏读(Dirty?read: 个事务正在访问数据并且对数据进了修改,这种修改还没有提交到数据库中,这时另外个事务也访问了这个数据,然后使了这个数据。因这个数据是还没有提交的数据,那么另外个事务读到的这个数据是脏数据,依据脏数据所做的操作可能是不正确的。

丢失修改(Lost?to?modify:?指在个事务读取个数据时,另外个事务也访问了该数据,那么在第个事务中修改了这个数据后,第个事务也修改了这个数据。这样第务内的修改结果就被丢失,因此称丢失修改。 例如:事务1读取某表中的数据A=202也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。

不可重复读(Unrepeatableread: 指在个事务内多读同数据。在这个事务还没有结束时,另个事务也访问该数据。那么,在第个事务中的两读数据之间,由于第个事务的修改导致第个事务两读取的数据可能不太样。这就发了在个事务内读到的数据是不的情况,因此称不可重复读。

幻读(Phantom read: 幻读与不可重复读类似。它发个事务(T1)读取了几行数据,接着另个并发事务(T2)插?了些数据时。在随后的查询中,第个事务(T1) 就会发现多了些原本不存在的记录,就好像发了幻觉样,所以称幻读。

MySQL底层实现事务的四大特性的方法

  • 原子性(隔离性)是undo log(回滚日志)实现的。
  • 一致性是由代码逻辑层面和其他三个特性保证的。
  • 隔离性是由mvcc实现的。
  • 持久性是基于redo log (重做日志)实现的。?
  • 持久性的实现:

基本的修改数据的过程为:

这样做有严重的性能问题:InnoDB在磁盘中存储的基本单元是页,可能本次修改只变更页一中几个字节,但是需要刷新整页的数据。一个事务可能修改了多页中的数据,页之间又是不连续的,就会产生随机IO。

为了解决上述问题,InnoDB提供了缓存解决这一问题(Buffer Pool),BP中包含了部分数据页的映射,作为访问数据库的缓冲;当从数据库读取数据时,会首先写入BP,BP中修改的数据会定期刷新到磁盘中(这一过程称之为刷脏

如果MySQL宕机,而此时BP中修改的数据还没有刷新的磁盘,就会导致数据的丢失,事务的持久性无法保证。

引入redo log(重做日志)是为了解决上述问题。?Redo Log记录的是物理日志,也就是磁盘数据的修改。当数据被修改时,除了修改BP中的数据,还会在redo log中记录这次操作,当事务提交时,会调用fsync接口对 redo log进行刷盘,如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复,redo log采用的是WAL(Write-ahead logging,预写式日志), 所有修改先写入日志,再更新到磁盘。日志从redo log buffer 先write到文件系统的page cache,在fsync到磁盘。保证了数据不会因为MySQL宕机而丢失,从而满足了持久性的要求。引入重做日志后从磁盘加载数据到内存过程如下:

  • 在内存中修改数据
  • 把新数据写到Redo Log Buffer中
  • 把Redo Log Buffer中数据持久化到Redo Log文件中
  • 把Redo Log文件中数据持久化到数据库磁盘中

原子性的实现

实现原子性的核心就在于如何实现回滚,当事务回滚时能够撤销所有已经执行成功的SQL语句。InnoDB实现回滚,靠的是undo log。undo log属于逻辑日志,它记录的是SQL执行相关的信息。当事务对数据库进行修改时,InnoDB会生成对应的回滚日志。每条数据变更(insert/update/delete)操作都伴随一条undo log的生成,并且回滚日志必须先于数据持久化到磁盘上,undo log记录了数据被修改前的信息以及新增和被删除的数据信息。以update操作为例,当事务执行update时,其生成的undo log中会包含被修改行的主键(一遍知道修改了哪些行),修改了哪些列、这些列在修改前后的值的信息,回滚时便可以使用这些信息将数据还原到update之前的状态。回滚就是根据回滚日志做逆向操作,比如delete的逆向操作为insert,insert的逆向操作为delete,update的逆向为update等。如果事务执行失败或者调用了rollback,导致事务需要回滚,根据undo log生成回滚语句回滚到修改之前的样子

完整过程的顺序如下:


?

隔离性的实现

SQL 标准定义了四个隔离级别:

  • READ-UNCOMMITTED(读取未提交)最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
  • READ-COMMITTED(读取已提交)允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发
  • REPEATABLE-READ(可重复读): ?对同字段的多读取结果都是致的,除数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发
  • SERIALIZABLE(可串): ?最?的隔离级别,完全服从ACID的隔离级别。所有的事务依逐个执,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读

级别越低的隔离级别可以执行越高的并发,但同时实现复杂度以及开销也越大。

原子性,隔离性,持久性的目的都是为了要做到一致性。原子性和持久性是为了要实现数据的可性保障靠,隔离性是要管理多个并发读写请求的访问顺序。

READ UNCOMMITTED

READ UNCOMMITTED隔离级别下,事务中的修改即使还没提交,对其他事务是可见的。事务可以读取未提交的数据,造成脏读。因为读不会加任何锁,所以写操作在读的过程中修改数据,所以会造成脏读。好处是可以提升并发处理性能,能做到读写并行。换句话说,读的操作不能排斥写请求。

优点:读写并行,性能高
缺点:造成脏读

READ COMMITTED

一个事务的修改在他提交之前的所有修改,对其他事务都是不可见的。其他事务能读到已提交的修改变化。InnoDB在 READ COMMITTED中,使用排它锁,读取数据不加锁而是使用了MVCC机制。或者换句话说他采用了读写分离机制。但是该级别会产生不可重读以及幻读问题。这跟 READ COMMITTED 级别下的MVCC机制有关系,在该隔离级别下每次 select的时候新生成一个版本号,所以每次select的时候读的不是一个副本而是不同的副本。

在每次select之间有其他事务更新了我们读取的数据并提交了,那就出现了不可重复读。

REPEATABLE READ(Mysql默认隔离级别)

在一个事务内的多次读取的结果是一样的。这种级别下可以避免,脏读,不可重复读等查询问题。mysql 有两种机制可以达到这种隔离级别的效果,分别是采用读写锁以及MVCC。只要没释放读锁,在次读的时候还是可以读到第一次读的数据。
优点:实现起来简单
缺点:无法做到读写并行

  • 采用读写锁实现:只要没释放读锁,在次读的时候还是可以读到第一次读的数据。优点:实现起来简单。缺点:无法做到读写并行

  • ?采用MVCC实现:多次读取只生成一个版本,读到的是相同数据。优点:读写并行缺点:实现的复杂度高。但是在该隔离级别下仍会存在幻读的问题。

SERIALIZABLE

该隔离级别理解起来最简单,实现也最单。在隔离级别下除了不会造成数据不一致问题,没其他优点。

?一致性的实现

  • 原子性,隔离性,持久性的目的都是为了要做到一致性。
  • 数据库本身提供保障,例如不允许向整形列插入字符串值、字符串长度不能超过列的限制等
  • 应用层面(代码层面)进行保障,例如如果转账操作只扣除转账者的余额,而没有增加接收者的余额,无论数据库实现的多么完美,也无法保证状态的一致

5分钟了解MySQL中的Buffer pool

MySQL事务实现原理详解

图解mysql事务实现原理

在Mysql中,事务是如何实现的呢?

MySQL的WAL(Write-Ahead Logging)机制

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 10:50:33  更:2022-08-06 10:51:59 
 
开发: 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年5日历 -2024/5/20 0:18:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码