事务原子性、一致性、持久性的实现原理

浅析分布式系统之体系结构 技术基本目标----一致性(单对象、单操作) 一致性的本质 一致性定义:逻辑层面,一致性(consistency)是指一個形式系統中不蕴含矛盾(wiki)。在计算机系统的范畴之内,一致性其实是一种人们对于系统的综合需求,人们往往需要计算机的运行结果或状态是确定的、正确的且与系统的需求不蕴含矛盾,而不蕴含矛盾本身是一种随着不同的系统环境以及业务需求而变化而变化的要求。也就是说,对所有的计算机系统来说,只要它们的运行状态或结果与某种业务需求所定义的状态或结果一致不矛盾都可以认为达到了满足了一致性需求。因此针对不同的业务需求以及不同分布式系统的「一致」的定 阅读详情

前言

大家都知道事务有四个特性:

  • 原子性(atomicity)

    原子性是指整个数据库事务是不可分割的工作单位。只有使事务中所有的数据库操作执行都成功,才算整个事务成功。如果事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行事务前的状态。

  • 一致性(consistency)

    一致性指事务将数据库从一种状态转变为下一种一致的状态。在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。

  • 隔离性(isolation)

    一个事务的影响在该事务提交前对其他事务都不可见——这通过锁来实现。

  • 持久性(durability)

    事务一旦提交,其结果就是永久性的。即使发生宕机等故障,数据库也能将数据恢复。

对于隔离性的实现,可以参考我的这篇文章:InnoDB锁与事务简析

本篇文章主要讲述其它三个特性是如何实现的:通过数据库的redo和undo来完成。本文如果不做特别说明,默认指的是mysql的InnoDB存储引擎。

实现

基础知识

  1. redo log记录的关于每个页(Page)的更改的物理情况
  2. undo log和redo log记录物理日志不一样,它是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。
  3. LSN称为日志的逻辑序列号(log sequence number),在innodb存储引擎中,lsn占用8个字节。LSN的值会随着日志的写入而逐渐增大。事务中更新操作会产生一个新的LSN。LSN不仅存在于redo log中,还存在于数据页中。
  4. checkpoint检查点,表示脏页写入到磁盘的时候
整体流程

在这里插入图片描述
无论是日志还是数据,都是现在buffer里修改,然后再同步到磁盘上的。

  1. 启动事务后,修改的数据如果没有在log buffer中,则会从磁盘读取到log buffer

  2. 对内存中数据修改之前,将原始数据记录到undo log

  3. 对内存中的数据页进行修改,在内存数据页中记录LSN,暂且称之为data_in_buffer_lsn

  4. 在修改数据页的同时(几乎是同时)向redo log in buffer中写入redo log,并记录下对应的LSN,暂且称之为redo_log_in_buffer_lsn;

  5. 日志刷盘和数据刷盘

    日志刷盘的规则为

    • 发出commit动作时

    • 每秒刷一次

    • 当log buffer中已经使用的内存超过一半时

    • 当有checkpoint时

    数据刷盘的规则为

    • 当有checkpoint时

    日志刷盘的次数比数据刷盘次数更多,另外即使在checkpoint时,innoDB也会**保证在写数据前,需要先写日志,这种方式称为预写日志方式(Write-Ahead Logging,WAL)。**InnoDB存储引擎通过预写日志的方式来保证事务的完整性。

    预写日志方式之所以能保证完整性,是因为日志和数据页中有LSN,通过LSN可以比较日志和数据页中数据记录的顺序。日志文件是真正的核心。

实例

来源于:详细分析MySQL事务日志(redo log和undo log)

在这里插入图片描述
上图中,从上到下的横线分别代表:时间轴、buffer中数据页中记录的LSN(data_in_buffer_lsn)、磁盘中数据页中记录的LSN(data_page_on_disk_lsn)、buffer中重做日志记录的LSN(redo_log_in_buffer_lsn)、磁盘中重做日志文件中记录的LSN(redo_log_on_disk_lsn)以及检查点记录的LSN(checkpoint_lsn)。

假设在最初时(12:0:00)所有的日志页和数据页都完成了刷盘,也记录好了检查点的LSN,这时它们的LSN都是完全一致的。

假设此时开启了一个事务,并立刻执行了一个update操作,执行完成后,buffer中的数据页和redo log都记录好了更新后的LSN值,假设为110。这时候如果执行 show engine innodb status 查看各LSN的值,即图中①处的位置状态,结果会是:

log sequence number(110) > log flushed up to(100) = pages flushed up to = last checkpoint at

之后又执行了一个delete语句,LSN增长到150。等到12:00:01时,触发redo log刷盘的规则(其中有一个规则是 innodb_flush_log_at_timeout 控制的默认日志刷盘频率为1秒),这时redo log file on disk中的LSN会更新到和redo log in buffer的LSN一样,所以都等于150,这时 show engine innodb status ,即图中②的位置,结果将会是:

log sequence number(150) = log flushed up to > pages flushed up to(100) = last checkpoint at

再之后,执行了一个update语句,缓存中的LSN将增长到300,即图中③的位置。

假设随后检查点出现,即图中④的位置,正如前面所说,检查点会触发数据页和日志页刷盘,但需要一定的时间来完成,所以在数据页刷盘还未完成时,检查点的LSN还是上一次检查点的LSN,但此时磁盘上数据页和日志页的LSN已经增长了,即:

log sequence number > log flushed up to 和 pages flushed up to > last checkpoint at

但是log flushed up to和pages flushed up to的大小无法确定,因为日志刷盘可能快于数据刷盘,也可能等于,还可能是慢于。但是checkpoint机制有保护数据刷盘速度是慢于日志刷盘的:当数据刷盘速度超过日志刷盘时,将会暂时停止数据刷盘,等待日志刷盘进度超过数据刷盘。

等到数据页和日志页刷盘完毕,即到了位置⑤的时候,所有的LSN都等于300。

随着时间的推移到了12:00:02,即图中位置⑥,又触发了日志刷盘的规则,但此时buffer中的日志LSN和磁盘中的日志LSN是一致的,所以不执行日志刷盘,即此时 show engine innodb status 时各种lsn都相等。

随后执行了一个insert语句,假设buffer中的LSN增长到了800,即图中位置⑦。此时各种LSN的大小和位置①时一样。

随后执行了提交动作,即位置⑧。默认情况下,提交动作会触发日志刷盘,但不会触发数据刷盘,所以 show engine innodb status 的结果是:

log sequence number = log flushed up to > pages flushed up to = last checkpoint at

最后随着时间的推移,检查点再次出现,即图中位置⑨。但是这次检查点不会触发日志刷盘,因为日志的LSN在检查点出现之前已经同步了。假设这次数据刷盘速度极快,快到一瞬间内完成而无法捕捉到状态的变化,这时 show engine innodb status 的结果将是各种LSN相等。

恢复

mysql的恢复策略是:

  1. 恢复时,先根据redo重做所有事务,包括未提交的事务
  2. 再根据undo回滚未提交的事务。

通过这种策略,保证了事务的原子性、一致性和持久性。

另外,引入了checkpoint机制,在恢复的时候,只需要从checkpoint的位置往后恢复即可

感想

  1. 网络上很多的内容可能不准确,即使是我写的这篇文章,也可能有不准确的地方,解决这个问题的最好办法是读源码
  2. 不同的技术可能实现不同,但核心原理往往都是相通的,而这些核心原理一般建立在基础知识之上
  3. 学习知识可以学习到不同的深度,看完《MySQL技术内幕:InnoDB存储引擎》便能大体掌握mysql的使用,但是了解的不深入,随着写了这两篇文章,对Mysql的了解更加深入了一些,如果需要继续深入,真的需要看源码了,这个事情感觉得耗费更多的时间。所以需要知道自己需要了解到什么水平,用有限的时间去做性价比更高的事情,选择很重要。

资料

  1. 深入学习MySQL事务:ACID特性的实现原理
  2. 详细分析MySQL事务日志(redo log和undo log)
  3. https://blog.youkuaiyun.com/suerge_storm/article/details/90484944
  4. https://blog.youkuaiyun.com/qq_41151659/article/details/99559397

最后

大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)

往期文章回顾:

  1. 事务原子性、一致性、持久性的实现原理
  2. 如何锻炼自己的记忆力
  3. CDN请求过程详解
  4. 关于程序员职业发展的思考
  5. 记博客服务被压垮的历程
  6. 常用缓存技巧
  7. 如何高效对接第三方支付
  8. Gin框架简洁版
  9. 关于代码review的思考
  10. InnoDB锁与事务简析
  11. Markdown编辑器推荐-typora
浅析Mysql InnoDB存储引擎事务原理 innoDB存储引擎事务与日志,日志在系统恢复过程中的作用剖析 阅读详情

相关推荐

C语言编程规范 clean code

目的规则并不是完美的,通过禁止在特定情况下有用的特性,可能会对代码实现造成影响。但是我们制定规则的目的“为了大多数程序员可以得到更多的好处”, 如果在团队运作中认为某个规则无法遵循,希望可...

编程与实战的博客 3106

数据库事务一致性的理解

一致性的定义 百度百科-一致性: 一致性就是数据保持一致,在分布式系统中,可以理解为多个节点中数据的值是一致的。 百度百科-事务一致性: 一个或多个事务执行后,原来一致的数据和数据库仍然是一致的。它主要涉及事务的原子性。 维基百科-一致性(数据库) 一致性是数据库系统的一项要求:任何数据库事务修改数据必须满足定义好的规则,包括数据完整性(约束)、级联回滚、触发器等。 我对一致性的理解 “一致”是指数据库中的数据是正确的,不存在矛盾。事务的一致性是指事务执行前后,数据都是正确的,不存在

debugmyworld 1万+

STM32实战:如何快速移植野火PID调试助手协议到你的电机控制项目

本文详细解析了如何将野火PID调试助手协议快速移植到STM32电机控制项目中。通过深度剖析协议帧格式、数据解析逻辑及环形缓冲区应用,提供了从工程结构规划、核心函数适配到串口中断集成的完整移植步骤。文章还分享了协议健壮性增强、数据上报频率优化等高级调试技巧,帮助开发者构建稳定可靠的上位机调试通道,大幅提升PID参数整定效率。

weixin_29171129的博客 466

数据库中的一致性

系统的一致性在发展过程中产生的经典概念: ACID 原子性:事务的原子性是指事务必须是一个原子的操作序列单元。事务中包含的各项操作在一次执行过程中,要么全部执行,要么全部不执行。 任何一项操作失败都将导致整个事务失败,同时其他已经被执行的操作都将被撤销并回滚。只有所有的操作全部成功,整个事务才算是成功完成。 一致性:事务的一致性是指事务的执行不能破坏数据库数据的完整性和一致性,一个事务在执行前后...

乔的博客 8621

DeepSeek-R1模型+Dify实战:5步打造能读PDF的智能客服(附BGE-M3嵌入模型配置)

本文详细介绍了如何利用DeepSeek-R1大模型与Dify平台,结合BGE-M3嵌入模型,构建企业级智能文档问答系统。通过5个步骤,从环境准备到知识库构建,再到智能问答应用开发,帮助企业快速从PDF等文档中提取关键信息,提升工作效率。特别适合处理产品手册、内部规程等专业内容。

convnet3designer的博客 719

从零开始:用LabVIEW和ModbusTCP协议,像搭积木一样连接Delta PLC

本文详细介绍了如何利用LabVIEW的图形化编程环境和ModbusTCP工业协议,快速连接Delta PLC实现数据通信。通过模块化配置和实战案例,指导读者无需编写复杂代码即可完成寄存器读取、多数据类型处理及系统监控,显著提升工业自动化项目的开发效率与部署速度。

n8m7b6v5c4的博客 693

原子性和一致性的区别是什么?

重度参考了:https://www.zhihu.com/question/30272728/answer/72476703(讲的非常好,逻辑清晰)轻度参考了:https://www.cnblogs.com/fjdingsd/p/5273008.html(概念也比较清晰,只不过没有对比着这两个特性讲)概念原子性:一个事务内的操作,要么同时成功,要么同时失败一致性:一个事务必须使数据库从一个一致性状态变换到另一个一致性状态对于一致性,知乎链接中内容如下:从这段话的理解来看,所谓一致性,即,从实际的业务逻辑上来说

因热爱而执着,因执着而成功。 1285

AI写作:为AI人工智能领域赋能

AI写作技术作为自然语言处理(NLP)领域的重要应用方向,正在深刻改变内容创作的方式。系统介绍AI写作的技术原理分析主流AI写作模型的架构特点提供实践性的代码示例探讨实际应用中的关键问题展望未来发展趋势本文涵盖从基础理论到高级应用的完整知识体系,适用于希望深入了解AI写作技术的开发者和研究人员。背景介绍:建立基本概念框架核心概念:解析关键技术原理算法实现:通过代码演示具体实现数学原理:深入底层数学模型实践应用:展示真实场景案例资源推荐:提供学习路径和工具。

AI天才研究院 3052

MySQL事务的四大特性及实现原理解析

MySQL事务的四大特性(原子性、一致性、隔离性和持久性)保证了数据库操作的可靠性和一致性。事务的实现原理包括日志系统、锁机制和并发控制。隔离级别定义了事务的隔离程度,不同的隔离级别对并发性和数据一致性有不同的要求。在使用事务时,需要注意事务的使用场景、边界和最佳实践,以提高性能和保证数据的完整性。

博客 2521

Windows下Python安装geopandas全攻略:解决GDAL依赖问题的5个关键步骤

本文详细解析了在Windows系统下安装Python地理空间分析库geopandas时,如何有效解决其核心依赖GDAL的编译难题。文章提供了五个关键步骤,包括理解依赖关系、获取预编译wheel文件、顺序安装及环境验证,旨在帮助用户绕过复杂的C++编译环境,顺利完成geopandas的安装部署。

weixin_28221501的博客 283

Framelet Transform

需要定义 Framelet 的基函数。Framelet 基函数可以是通过组合不同的小波函数生成的。# 这里可以定义 Framelet 基函数,例如一些小波基函数的线性组合# 这是一个示例函数,具体实现需要根据具体的 Framelet 设计# 示例:正弦函数。

qq_33009429的博客 1210

Mysql进阶(事务)

数据库事务是访问并可能操作数据项的一个数据库操作序列,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作完成·。,就是一次对数据库操作过程,这个过程由多条sql执行,这么多条sql在一次执行过程中要么都成功执行么都不执行,保证数据完整性。mysql中只有innodb引擎支持事务。

m0_68821222的博客 874

飞行器坐标转换

本文定义的是右手直角坐标系,x−y−zx-y-zx−y−z轴分别为北-天-东。从AAA坐标系到BBB坐标系是分别绕y−z−xy-z-xy−z−x轴,即天-东-北旋转ψ−θ−γψ−θ−γ。如果AAA是惯性系,BBB是机体系,则这三个角度分别为偏航角、俯仰角、横滚角。图1 惯性系到机体系。

gongfuyd的博客 1354

跟面试官侃半小时MySQL事务,一口气说完原子性、一致性、持久性的实现

提到MySQL的事务,我相信对MySQL有了解的同学都能聊上几句,无论是面试求职,还是日常开发,MySQL的事务都跟我们息息相关。 而事务的ACID(即原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability)可以说涵盖了事务的全部知识点,所以,我们不仅要知道ACID是什么,还要了解ACID背后的实现,只有这样,无论在日常开发还是面试求职,都能无...

阿丸笔记 1404

Python内置函数zip()——《Python内置函数手册》Python老吕编著

zip()函数是 Python 中的一个内置函数,用于将多个可迭代对象(如列表、元组、字符串等)中对应的元素打包成一个个元组,然后返回由这些元组组成的迭代器。zip()函数常用于将多个序列并行迭代,或者用于数据对齐。zip()它返回一个迭代器,这意味着你可以逐个获取打包后的元素,而不是一次性将所有元素加载到内存中。如果输入的可迭代对象长度不一致,zip()会以最短的可迭代对象为准,只打包到最短对象的末尾。它可以用来并行迭代多个序列,使得代码更加简洁和高效。在接下来的章节中,我们将详细介绍。

Python老吕的博客 680

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

mysql的原子性的意思_MySQL事务,说完原子性、一致性、持久性的实现【转】

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

weixin_29901323的博客 2853

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

mysql 原子性_MySQL事务,说完原子性、一致性、持久性的实现【转】

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

weixin_29733427的博客 212

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【数据库】ACID底层实现原理

前言 我们在学MySQL的时候事务是必须要知道的部分,也就是原子性(Atomic)、一致性(Consistency)、隔离性(isolation)和持久性(Persistence)。知道他的概念其实是远远不够的,现在越来越卷,那么就必须知道的他的原理什么?怎么是实现的。 原理 原子性: 概念 是指事物是一个不可分割的工作单位,事物中的操作要么都发生,要么都不发生。最经典的就是转账案例,我们把转入和转出当做一个事物的话,就需要在SQL中显式指定开启事务。 实现原理:undo log undo log 是 回滚

聪明不喝牛奶的博客 2379

MySQL事务

MySQL数据库事务概述,事务有哪些特征,MySQL如何开启事务,MySQL事务如何设置保存点,如何回滚到指定保存点。MySQL事务隔离级别,读已提交,读未提交,可重复读,串行化,MySQL事务持久性实现原理,原子性实现原理,隔离性实现原理,一致性实现原理。 什么是脏读、不可重复读、幻读,如何解决脏读,如何解决不可重复读,如何解决幻读,MySQL采用的默认隔离级别是什么。如何关闭MySQL的自动提交事务

2301_77713282的博客 1228

mysql boolean_redis┃面试官问我redis事务和mysql事务的区别,我。。。。。

​本文共:3889字 预计阅读时间:9分钟原文在我的微信公众号中redis┃面试官问我redis事务和mysql事务的区别,我。。。。。1. 前言 面试官:我看你简历上写了熟悉redis,看来工作中用的很多吧?我:是的,我们项目中经常用到redis(来,随便问,看我分分钟秒杀你) 面试官:那你给我说说redis的事务和mysql的事务有什么区别吧我:额。。。事务还有区别????面试官:比如说red...

weixin_39546092的博客 104

mysql 事务的实现原理

开篇 相信大家都用过事务以及了解他的特点,如原子性(Atomicity),一致性(Consistency),隔离型(Isolation)以及持久性(Durability)等。今天想跟大家一起研究下事务内部到底是怎么实现的,在讲解前我想先抛出个问题:事务想要做到什么效果? 按我理解,无非是要做到可靠性以及并发处理 可靠性:数据库要保证当insert或update操作时抛异常或者数据库crash的时候需要保障数据的操作前后的一致,想要做到这个,我需要知道我修改之前和修改之后的状态,所以就有了undo lo

Geek Cui 255

【MySQL】MySQL实现ACID的原理(MySQL专栏启动)

MySQL实现事务四大特性(ACID,原子性,隔离性,一致性,持久)的原理解析,主要为Undo Log、Redo Log、mvcc、锁的运用

小明的Java问道之路 7744

MySQL事务实现原理

前言:在说事务 事务的特点 在事务的四个特点中,一致性是事务根本追求,而在某些情况下对事务的一致性造成破坏; 事务的并发执行 事务故障或系统故障 数据库系统通过并发控制技术和日志恢复技术来避免这种情况的发生 并发控制技术保证了事务的隔离性,是数据库的一致性状态不会因为并发执行的操作被破坏。 日志恢复技术保证了事务的原子性,使一致性状态不会因事务或系统故障被破坏。同时使已提交的对数据的修改不会因系统崩溃而失去,保证了事务的持久性。 持久性 数据库总能保持一致性状态。事务一旦提交,其对数据库.

似水流年,是谁苍白了等待 2567

深入理解 MySQL 事务:隔离级别、ACID 特性及其实现原理

什么是事务? 事务(`Transaction`),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元。事务通常由高级数据库操作语言或编程语言(如 SQL,C++ 或 Java)书写的用户程序的执行所引起,并用形如`begin transaction`和`end transaction`语句(或函数调用)来界定。事务由事务开始(`begin transaction`)和事务结束(`end transaction`)之间执行的全部操作组成。

安正勋的博客 13万+

MySQL事务机制深度解析:从原理到应用

本文深入探讨了MySQL事务的基本概念和实现原理,重点分析了ACID原则、事务的隔离级别、以及InnoDB存储引擎如何通过MVCC、多版本并发控制、锁机制和日志文件保障事务的原子性、一致性、隔离性和持久性。通过对MySQL事务底层实现的详细解析,本文帮助读者理解事务管理在数据库设计和优化中的重要性,并为开发者提供了在高并发环境中保证数据一致性和可靠性的实用知识。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 87万+
上一篇: Markdown编辑器推荐-Typora
下一篇: 如何锻炼自己的记忆力
程序员麻辣烫
博客等级 码龄17年 2万+粉丝 351原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员麻辣烫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值