跟面试官侃了半小时 MySQL 事务,把原子性、一致性、持久性的实现都讲完了

来源 | 阿丸笔记

封图| CSDN下载于视觉中国

提到MySQL的事务,我相信对MySQL有了解的同学都能聊上几句,无论是面试求职,还是日常开发,MySQL的事务都跟我们息息相关。

而事务的ACID(即原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability)可以说涵盖了事务的全部知识点,所以,我们不仅要知道ACID是什么,还要了解ACID背后的实现,只有这样,无论在日常开发还是面试求职,都能无往而不利。

本篇内容将介绍原子性、一致性、持久性相关实现,由于这部分内容可能很多人会相对陌生,因为日常业务开发可能不太会去接触和深究,但是了解完后,你对MySQL会有更深刻的认识。

基本概念

  • 原子性

整个事务是不可分割的最小单位,事务中任何一个语句执行失败,所有已经执行成功的语句也要回滚,整个数据库状态要恢复到执行事务前到状态。

  • 一致性

事务将数据库从一种状态转变为下一种一致的状态。在事务的前后,数据库的完整性约束没有被破坏。(事务的acid不是完全正交的,尤其是一致性,可能跟原子性、隔离性都有一定关系,后面会看到)

  • 持久性

事务一旦提交,那么就是永久性的,不会因为宕机等故障导致数据丢失(外力影响不保证,比如磁盘损害)。持久性是保证了数据库的高可靠性(High Reliability),而不是高可用性(Hign Availability)。高可用性并不能通过事务来保证。

持久性的实现

MySQL的innoDB存储引擎,使用Redo log保证了事务的持久性。

当事务提交时,必须先将事务的所有日志写入日志文件进行持久化,就是我们常说的WAL(write ahead log)机制(这个技术是保障持久性的关键技术,在HBase中也扮演重要角色,有兴趣的同学可以参考我之前的HBase文章)。这样才能保证断电或宕机等情况发生后,已提交的事务不会丢失,这个能力称为 crash-safe。

下面深入聊一聊redo log的机制,给大家更深刻的理解。

Redo log包括两部分,重做日志缓冲(redo log buffer)和重做日志文件(redo log file),前者是易失的缓存,后者是持久化的文件。

举一个事务的例子:

  • 步骤1:begin;

  • 步骤2:insert into t1 …r

  • 步骤3:insert into t2 …

  • 步骤4:commit;

这个事务的写入过程实际拆解如下:

innodb缓冲池的概念本文就不展开说明了,以后有机会可以展开说一下。

重点关注在这个事务提交前,将 redo log 的写入拆成了两个步骤,prepare 和 commit,这就是"两阶段提交”。

为什么要采用两阶段提交呢?

实际上,两阶段提交是分布式系统常用的机制。MySQL使用了两阶段提交后,也是为了保证事务的持久性。Redo log 和bingo 有一个共同的数据字段,叫 XID,崩溃恢复的时候,会按顺序扫描 redo log。

  • 假设在写入binlog前系统崩溃,那么数据库恢复后顺序扫描 redo log,碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务,而且binlog也没写入,所以事务就直接回滚了。

  • 假设在写入binlog之后,事务提交前数据库崩溃,那么数据库恢复后顺序扫描 redo log,碰到既有 prepare、又有 commit 的 redo log,就直接提交,保证数据不丢失。

这个事务要往两个表中插入记录,插入数据的过程中,生成的日志都得先写入redo log buffer ,等到commit的时候,才真正把日志写到 redo log 文件。(当然,这里不绝对,因为redo log buffer可能因为其他原因被迫刷新到redo log)。

而为了确保每次日志都能写入日志文件,在每次将重做日志缓冲 写入 重做日志文件 后,InnoDB存储引擎都需要调用一次fsync操作,确保写入了磁盘。

对于redo log的持久化,可以如下图所示。

1)先写入redo log buffer,在蓝色区域。

2)写入redo log file,但是还没有fsync,这时候是处于黄色的位置,处于系统缓存。

3)调用fsync,真正写入磁盘。

为了控制 redo log 的写入策略,InnoDB 提供了 innodb_flush_log_at_trx_commit 参数,它有三种可能取值:

  • 设置为 0 的时候,表示每次事务提交时都只是把 redo log 留在 redo log buffer 中 ;

  • 设置为 1 的时候,表示每次事务提交时都将 redo log 直接持久化到磁盘;

  • 设置为 2 的时候,表示每次事务提交时都只是把 redo log 写到 page cache。

binlog的写入和redo log一样,也是包括bingo cache和bingo file,同样跟上面的三色层次类似(当然,binlog是server层的,不是存储引擎层的),包括log buffer、文件系统page cache、hard disk。

写入page cache 和 fsync到disk 的时机,是由参数 sync_binlog 控制的:

  • sync_binlog=0 的时候,表示每次提交事务都只 写入文件系统的page cache,不 fsync;

  • sync_binlog=1 的时候,表示每次提交事务都会执行 fsync;

  • sync_binlog=N(N>1) 的时候,表示每次提交事务都写入文件系统的page cache,但累积 N 个事务后才 fsync。(如果主机发生异常重启,会丢失最近 N 个事务的 binlog 日志)

通常我们说 MySQL 的“双 1”配置,指的就是 sync_binlog 和 innodb_flush_log_at_trx_commit 都设置成 1。也就是说,一个事务完整提交前,需要等待两次刷盘,一次是 redo log(prepare 阶段),一次是 binlog。

特别需要区分的是,redo log和binlog的不同。这也是经常在面试中可能会问到的两种日志的差异。

注意有这么几点不同:

  • 产生位置不同。

redo log是innodb的存储引擎产生的,而binlog是数据库的server层实现的。换句话说,如果你使用MySQL,换其他存储引擎,那么可能没有redo log,但是还是会有binlog。

  • 日志记录的内容形式不同。

binlog是一种逻辑日志,记录对应的SQL语句,而redo log记录了物理日志,是针对每个数据页的修改。

  • 日志写入时间不同。

binlog只有在事务提交后完成一次写入,对于一个事物而言,在binlog中只有一条记录。而redo log在事务进行中不断被写入,而且是并发写入的,不是顺序写入的。

  • 保存方式不同。

redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

原子性的实现

Undo log保证了事务的原子性。

在对数据库进行修改时,innoDB引擎除了会产生redo log,还会产生undo log。InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败导致事务需要回滚,就利用undo log中的信息将数据回滚到修改之前的样子。

有人认为undo log是redo log的逆过程,其实是不对的。两个日志文件其实都能看作是一种对数据的恢复操作,redo log恢复事务导致的数据页的修改,而undo log能够恢复数据记录到某个特定的版本。

所以redo log是一种物理日志(数据页的修改),而undo log是一种逻辑日志(数据记录)。

undo log还要另外一个重要作用,就是用于mvcc中,进行多版本控制,也就是实现事务隔离性的基础,当用户读取一行记录时,如果这个记录已接被其他事务占用,那么当前事务就可以通过undo读取之前的行版本信息,用来实现非锁定读取,就是“快照读”。(事务隔离性的问题,可以看我上一篇文章 跟面试官侃半小时MySQL事务隔离性,从基本概念深入到实现 )。

一致性的实现

就像一开始在定义的时候介绍的,事务的ACID性质不是完全正交的,尤其是一致性,我们可以认为原子性、持久性和隔离性都是为了实现事务的一致性。

当然,这里的一致性是指数据库层面的事务一致性。

如果说你在应用层面做一个操作,给转账者扣钱,没给接收者加钱,那么这个不一致跟事务的不一致是没有关系的,需要开发人员自己做业务逻辑一致性的保证。

同时,欢迎所有开发者扫描下方二维码填写《开发者与AI大调研》,只需2分钟,便可收获价值299元的「AI开发者万人大会」在线直播门票!

推荐阅读:你公司的虚拟机还闲着?基于 Jenkins 和 Kubernetes 的持续集成测试实践了解一下!
北京四环堵车引发的智能交通大构想
400 多行代码!超详细中文聊天机器人开发指南 | 原力计划
三大运营商将上线 5G 消息;苹果谷歌联手,追踪 30 亿用户;jQuery 3.5.0 发布 | 极客头条比特币当赎金,WannaRen 勒索病毒二度来袭!从 Web 1.0到Web 3.0:详析这些年互联网的发展及未来方向真香,朕在看了!

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

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

相关文章

阿里云Link TEE获得全球首款GlobalPlatform TEE全配置安全认证

2019年7月12日,阿里云Link TEE正式获得由国际标准组织GlobalPlatform(以下简称GP)颁发的TEE安全评估认证证书,也成为全球首款获得GP TEE全配置(支持TEE Time and Rollback PP-Module和TEE Debug PP-Module)…

阿里云 EMAS HTTPDNS 联合函数计算重磅推出 SDNS 服务,三大能力获得突破

阿里云 EMAS HTTPDNS 联合函数计算重磅推出 SDNS 服务,三大能力获得突破 1. 什么是 HTTPDNS ? 传统的 DNS(Domain Name System)使开发者常面临着域名劫持、调度不精准的问题。 HTTPDNS 使用 HTTP 协议替换常用的 UDP 协议&#…

是!“用Python的,全是假程序员”!HR:太真实……

某热门网站最近有一个话题引起热议:“用Python的,全是假程序员!”题主觉得,Python程序员写代码量太少!论编程能力,根本打不过其他程序员。那么,各类编程语言的程序员到底谁更强?我们…

【译】用SQL统一所有:一种有效的、语法惯用的流和表管理方法

现在还没有一个统一的流式SQL语法标准,各家都在做自己的。本文在一些业界应用的基础上提出了一个统一SQL语法的建议。Spark同样存在这个问题,社区版本在流式SQL上迟迟没有动作。EMR Spark在今年上半年提供了自己设计版本的流式SQL支持,也会在…

透过 In-memory Channel 看 Knative Eventing 中 Broker/Trigger 工作机制

In-memory Channel是当前Knative Eventing中默认的Channel, 也是一般刚接触Knative Eventing首先了解到的Channel。本文通过分析 In-memory Channel 来进一步了解 Knative Eventing 中Broker/Trigger事件处理机制。 事件处理概览 我们先整体看一下Knative Eventing 工作机制示…

css-三种基本选择器

一、标签选择器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 标签选择器&#xff0c;会选择到页面上所有的这个标签的元素 */h1{color: #12ec4e;background: …

你知道吗?其实 Oracle 直方图自动统计算法存在这些缺陷!(附验证步骤)

作者 | 吴海存责编 | Carol出品 | CSDN 云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国在某些场景下&#xff0c;表中某一列的数据分布会比较崎岖&#xff0c;使得CBO(cost base optimizer)在评估执行计划的时候可能会出现误差&#xff0c;从…

开源软件 Apache Dubbo 牵手 IDE 插件,开发部署提速不止 8 倍

自从产品经理银时小伙和他的团队在去年11月发布 Cloud Toolkit&#xff08;一款 IDE 插件&#xff09;以来&#xff0c;已帮助数以万计的开发者们提高了开发、测试、诊断以及应用部署效率。期间&#xff0c;他们还发布了 Contributor Ranking List&#xff0c;和开发者们一同定…

css-层次选择器

一、后代选择器 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* 后代选择器 */body ul p{background: red;}body p{background: yellow;}</style> </he…

技术人具备“结构化思维”意味着什么?

阿里妹导读&#xff1a;在日常工作中&#xff0c;我们时常会碰到这样的情况&#xff0c;有的人讲事情逻辑非常混乱&#xff0c;罗列了很多事项&#xff0c;却把握不到重点&#xff0c;无法把一件事情说清楚。这种思维混乱是典型的缺少结构化思维的表现。结构化思维非常重要&…

奇奇怪怪的知识增加了,大括号的历史你知道吗?

作者 | Michael McMillan译者 | 弯月&#xff0c;责编 | 夕颜封图 | CSDN下载自视觉中国出品 | CSDN&#xff08;ID:CSDNnews&#xff09;众所周知的标志代码块起始和结尾的大括号是什么时候开始成为编程语言的一部分的呢&#xff1f;或者更重要的是&#xff0c;代码块何时成了…

5年时间,我从开发做到总裁的秘籍--如何提升技术型管理者的领导力

对于深耕技术的一线开发者而言&#xff0c;大多数都希望把技术工作进行到底&#xff0c;或者一直从事和技术技术相关性更高的工作。但随着年龄和经验的增长&#xff0c;我对管理和技术的思考越来越多、越来越深入&#xff0c;和大多数人一样&#xff0c;站在这个路口——到底继…

css-结构伪类选择器

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>/* ul的第一个子元素 */body ul li:first-child{background: #12ec4e;}/* ul的最后一个子元素 */ul li:last-child…

闲鱼无障碍是怎么在端侧实现的

Hi&#xff0c;小伙伴们还记得之前刷屏的“闲鱼为1700万人&#xff0c;打造了一条盲道”的文章吗&#xff1f; 在今年4月&#xff0c;闲鱼和深圳市信息无障碍研究会取得了联系。在沟通过程中&#xff0c;我们了解到在移动互联网时代&#xff0c;视障人士同样可以通过手机&#…

面试造飞机系列:看架构师如何设计微服务接口

来源 | 后端技术学堂责编 | Carol封图| CSDN下载于视觉中国 在微服务设计中&#xff0c;服务间接口通信设计常见的有两种方式&#xff1a;RPC 和 REST&#xff0c;关于微服务和 RPC 的更多细节&#xff0c;可以参考我上一篇文章 面试都在问的微服务&#xff0c;一文带你彻底搞…

日均处理万亿数据!Flink在快手的应用实践与技术演进之路

董亭亭&#xff0c;快手大数据架构实时计算引擎团队负责人。目前负责 Flink 引擎在快手内的研发、应用以及周边子系统建设。2013 年毕业于大连理工大学&#xff0c;曾就职于奇虎 360、58 集团。主要研究领域包括&#xff1a;分布式计算、调度系统、分布式存储等系统。 本次的分…

css-字体样式

字体样式 <!--font-family: 字体font-size: 字体大小font-weight: 字体粗细color: 字体颜色--><style>body{font-family: "Arial Black", 楷体,serif;color: #cdbb21;}h1{font-size: 50px;}.p1{font-weight: bolder;}</style><!--字体风格 ob…

小网站的容器化(下):网站容器化的各种姿势,先跟着撸一波代码再说!

作者 | 王洪鹏责编 | Carol出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcloud&#xff09;封图| CSDN下载于视觉中国 上篇文章&#xff1a;小网站的容器化(上) 中我们大致描述了下个人网站在日常维护中的痛点&#xff0c;文章的后半部分我们添加了一个纯静态网站容器化的简…

阿里云应用高可用 AHAS 正式商用,可一键提升云上应用可用性

在分布式架构环境下&#xff0c;服务间的依赖日益复杂&#xff0c;可能没有人能说清单个故障对整个系统的影响&#xff0c;构建一个高可用的分布式系统面临着很大挑战。 7月17日&#xff0c;阿里云应用高可用服务AHAS 正式商用&#xff0c;包含架构感知、流控降级和故障演练三…

机器学习在高德起点抓路中的应用实践

导读&#xff1a;高德地图作为中国领先的出行领域解决方案提供商&#xff0c;导航是其核心用户场景。路线规划作为导航的前提&#xff0c;是根据起点、终点以及路径策略设置&#xff0c;为用户量身定制出行方案。 起点抓路&#xff0c;作为路线规划的初始必备环节&#xff0c;…