面试八股文Mysql:(1)事务实现的原理

1. 什么是事务

事务就是一组数据库操作,这些操作是一个atomic(原子性的操作) ,不可分割,要么都执行,要么回滚(rollback)都不执行。这样就避免了某个操作成功某个操作失败,从而导致数据的不一致。

2. 事务的4大特性

原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durabilily),简称ACID。
在这里插入图片描述
事务的目标:
一致性是事务的最终目的,原子性、隔离性、持久性都是为了实现一致性。

2.1. 并发事务带来的问题 (隔离性带来的问题)

两个并发执行的事务,如果涉及到操作同一条记录的时候,可能会发生问题。因为并发操作会带来数据的不一致性,包括脏读、不可重复读、幻读等。数据库系统提供了隔离级别来让我们有针对性地选择事务的隔离级别,避免数据不一致的问题。

在这里插入图片描述

2.2. 事务隔离级别 (解决隔离性带来的问题)

事务的隔离性是有级别的,在某些级别下,在并发事务的情况下,不能保证一个事务的执行不被其它事务干扰。既然会被干扰,那么就会出现一些问题。

在这里插入图片描述
在MySQL中,如果使用InnoDB,默认的隔离级别是Repeatable Read。

3. 数据库日志

一、redo log 重做日志

内容:物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中去的。
该日志文件主要由两部分组成:重做日志缓冲(redo log buffer)和重做日志文件(redo log),前者存储在内存中,后者存储在磁盘中。mysql 为了提升性能,不会把每次的修改都实时同步到磁盘,而是会先存到 Buffer Pool(缓冲池) 里头,把这个当作缓存来用。然后使用后台线程去做缓冲池和磁盘之间的同步。

作用:确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。

二、undo log 回滚日志

内容:逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。

作用:保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读。

三、bin log 归档日志(二进制日志)

内容:逻辑格式的日志,可以简单认为就是执行过的事务中的sql语句。
但又不完全是sql语句这么简单,而是包括了执行的sql语句(增删改)反向的信息,也就意味着delete对应着delete本身和其反向的insert;update对应着update执行前后的版本的信息;insert对应着delete和insert本身的信息。

作用:用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步。
用于数据库的基于时间点的还原。

binlog 有三种模式:Statement(基于 SQL 语句的复制)、Row(基于行的复制) 以及 Mixed(混合模式)

4. 如何实现事务

务的实现依靠的是innodb的redo log, undo log和锁。

4.1 原子性

原子性的实现主要依靠的是Undo log日志。原子性的体现主要是在sql在执行过程中发生错误而发生回滚上。回滚是要回到执行前的一个状态,那么怎么回到执行前的状态呢?我们是不是就得将执行前的状态记录下来。因此假如由于系统错误或者rollback操作而回滚的话,可以根据undo log的信息来进行回滚到没被修改前的状态。

4.2 持久性

我们需要先来了解下InnoDB是怎么来读写数据的。我们知道数据库的数据都是存放在磁盘中的,但是磁盘I/O的成本是很大的,如果每次读写数据都要访问磁盘,数据库的效率就会非常低。为了解决这个问题,InnoDB提供了 Buffer Pool 作为访问数据库数据的缓冲。

Buffer Pool 是位于内存的,包含了磁盘中部分数据页的映射。当需要读取数据时,InnoDB会首先尝试从Buffer Pool中读取,读取不到的话就会从磁盘读取后放入Buffer Pool;当写入数据时,会先写入Buffer Pool的页面,并把这样的页面标记为dirty,并放到专门的flush list上,这些修改的数据页会在后续某个时刻被刷新到磁盘中(这一过程称为刷脏,由其他后台线程负责) 。

通过前面的介绍,我们知道InnoDB使用 Buffer Pool 来提高读写的性能。但是 Buffer Pool 是在内存的,是易失性的,如果一个事务提交了事务后,MySQL突然宕机,且此时Buffer Pool中修改的数据还没有刷新到磁盘中的话,就会导致数据的丢失,事务的持久性就无法保证。为了解决这个问题,InnoDB引入了 redo log来实现数据修改的持久化。根据我们在上面所介绍的WAL机制,先写日志,再写磁盘,有了redo log,InnoDB就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个 能力称为crash-safe。

4.3 隔离性

数据库的隔离性就是通过加锁和MVCC来实现的。
可重复读的隔离级别会出现幻读的问题,而MySQL的默认隔离级别是可重复读,并且解决了幻读的问题。简单来说,MySQL的默认隔离级别解决了脏读、幻读、不可重复读的问题。

数据库并发场景有三种:
读-读:不存在任何问题,也不需要并发控制
读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
写-写:有线程安全问题,可能存在更新丢失问题,比如第一类更新丢失,第二类更新丢失

写-写操作的线程安全是通过加锁来实现的,但是加锁的操作会严重影响数据库的性能和并发量,因此出现了MVCC—多版本并发控制。MVCC是一种用来解决读-写冲突的无锁并发控制,MVCC在数据库中的实现,就是为了解决读(快照读)写冲突,它的实现原理主要是依赖记录中的 3个隐式字段,undo日志 ,Read View 来实现的。MVCC可以为数据库解决以下问题:

  • 在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
  • 同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题

5. 总结

重做日志,回滚日志以及锁技术就是实现事务的基础。

  • 事务的 原子性 是通过 undo log 来实现的;
  • 事务的 持久性 是通过 redo log 来实现的;
  • 事务的 隔离性 是通过 (读写锁+MVCC)来实现的;
  • 事务的 一致性 是通过原子性,持久性,隔离性来共同实现的。

总之,ACID只是个概念,原子性,持久性,隔离性都是为了实现数据的一致性,事务的最终目的就是要保障数据的一致性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/61005.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ChatGPT会取代搜索引擎吗?BingChat、GoogleBard与ChatGPT区别

目前暂时不会,ChatGPT为代表的聊天机器人很可能会直接集成到搜索中,而不是取代它。微软已经通过Bing Chat和Bing做到了这一点,它将“聊天”选项卡直接放入Bing搜索的菜单中。Google、百度也分别开始尝试通过其AI生成技术将Google Bard、文心一…

DARPA-TC-engagement5-theia部分数据格式分析

转换出来的jsons数据主要分为四大类:Event、Subject、Object和Principal,分别代表系统事件、主体、客体和用户。各种大类中子类的数量,取决于CDM的版本。ShadeWatcher使用的是e3的数据,采用的是CDM18,而e5默认使用的是…

C语言:函数栈帧的创建和销毁(32位下观察)

一、寄存器(0:3:35) 1.寄存器有哪些?(6种)(0:38:50) 2.esp和ebp这两个寄存器中,存放的是什么?用来干嘛的?&a…

UDP简介

UDP 1. UDP格式2. UDP特点3. 差错检验 1. UDP格式 16位UDP长度,表示整个数据报(UDP首部UDP数据)的最大长度; 如果校验和出错,就会直接丢弃; 2. UDP特点 无连接: 知道对端的IP和端口号就直接进行传输,不需…

Vue——webpack

webpack 一、Install1.全局安装2.局部安装 二、总结1.打包2.定义脚本3.配置文件定义(webpack.config.js)4.项目重新加载依赖5.webpack打包Css6.style-loader 一、Install 1.全局安装 npm install webpack webpack-cli -g2.局部安装 以项目为单位,一个项…

git 报错 protocol ‘https‘ is not supported解决

报错原因:选择不了其他分支代码,甚至都看不到其他分支,我这边解决了两次报错,情况如下: 第一种报错: idea中刷新分支报错如下: Fetch Failed protocol https is not supported 话不多说&#…

爬虫013_函数的定义_调用_参数_返回值_局部变量_全局变量---python工作笔记032

然后再来看函数,可以避免重复代码 可以看到定义函数以及调用函数

HCIA---路由器--静态路由

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 一.路由器简介 二.路由器转发原理 三.骨干链路 四.路由分类 五.静态路由 总结 一.路由器简介 路由器是一种网络设备,用于将数据包从一个网络发送…

最大子数组和——力扣53

文章目录 题目描述解法一 动态规划题目描述 解法一 动态规划 int maxSubArray(vector<int>& nums){int pre=0, res=nums

探索ES高可用:滴滴自研跨数据中心复制技术详解

Elasticsearch 是一个基于Lucene构建的开源、分布式、RESTful接口的全文搜索引擎&#xff0c;其每个字段均可被索引&#xff0c;且能够横向扩展至数以百计的服务器存储以及处理TB级的数据&#xff0c;其可以在极短的时间内存储、搜索和分析大量的数据。 滴滴ES发展至今&#xf…

windows配置git公钥,读写远程git项目

首先Windows电脑需要下载并安装git&#xff1a; 从官网直接下载然后安装即可&#xff1a;https://git-scm.com/download/win 添加公钥 ssh-keygen -t rsa -C "xxxxxxx.com"注意&#xff1a;这个xxxxxxx.com与github注册的邮箱一致 然后一路回车&#xff0c;生成完…

uniapp支付宝微信支付功能实现

大纲&#xff1a; 具体实现逻辑如下&#xff1a; 页面初始化时&#xff0c;通过onLoad方法获取传入的钱包(wallet)信息。 用户输入充值金额&#xff0c;使用watch监听输入值的变化&#xff0c;并更新选中的充值金额选项。判断金额是否大于0&#xff0c;若是小于0&#xff0c;则…