Mysql ACID详解

article/2025/9/29 19:25:24

ACID简述
Atomicity、Durability实现之 (WAL+redo log)
Atomicity 、Isolation实现之 (锁 OR undo log+MVCC)

一、前言
主要是后台程序员都会和数据库打交道,最常用的关系型数据库是MySQL,最常用的存储引擎是InnoDB。InnoDB又以其支持事务而大量应用,事务的核心就是ACID。网上也有很多关于ACID的文章,但关于实现原理的较少,希望简述一下数据库事务的实现机制,对今后的应用有更大的启发。

二、ACID简述

  • 原子性保证每个事务都是最小不可分割的单元,要么全部成功,要么全部失败并恢复至事务未开始的样子。
  • 一致性指事务总是能使得数据库从一个一致性状态转移到另一种一致性状态
  • 隔离性指即使在并发的执行事务时,事务之间不会造成相互影响
  • 持久性是一旦事务提交,那么这个事务一定是生效的,即使后续遇到系统崩溃

网上很多文章提到数据库的乐观锁、悲观锁。而在我看来,这种分类过于浅显,没有触及到问题的本质核心。锁只是数据库为了达到ACID的一小部分,除此之外MVCC(多版本并发控制)及WAL(write ahead log)才是数据库事务的核心。一个数据系统中,数据应该是其次的,最重要的是记录数据的变更,即log。

三、WAL、redo log与Durability
数据库的最终数据是要落盘的,试想如果我想修改100张表里的10000条数据,如果每次修改都直接以落盘的形式处理,那么必定有大量的随机IO,如果使用机械磁盘那么一定存在大量的disk seek时间,数据库性能极低(我的另一篇文章:从磁盘到文件系统 很清晰的描述了为什么随机IO性能低)。为了能提高性能,我们希望能将这些改动缓存下来,统一处理,但问题是:如果这期间数据库崩溃了,那么这部分修改就丢失了,Durability就无法得到满足。

针对于此问题,InnoDB存储引擎引入了WAL技术(write-ahead logging)和redo log。

1、每次commit事务之前,先将要修改的数据信息存入redo log buffer,然后根据innodb_flush_log_at_trx_commit 的设置将redo log刷新至磁盘,写redo log至磁盘属于磁盘顺序写(因为只需append log到下一位置),因此redo log的落盘速度是非常快的。

2、MySQL在内存中执行此次update操作,即修改数据。

3、MySQL会周期或不周期性的刷新内存值到磁盘。

可以看到,一次update事务并不会立刻修改磁盘中的数据,而是记录修改信息,后期刷新至磁盘。所以步骤一以后,即使数据库崩溃,还可以根据落盘的redo log恢复已执行的事务,使得我们能获得Durability。
在这里插入图片描述

MySQL update事务

四、Isolation实现之 (锁 OR undo log+MVCC)
总是能在各种数据库事务文章中看到 未提交读、提交读、可重复读等字眼,而大部分文章将这个功能的实现归功于读写锁。锁是一种实现方式,但熟悉操作系统就会知道,锁是一种开销很大的并发控制手段,如无必要,尽量采用其他方式实现。

1)锁实现的Isolation
未提交读:一个update事务A只有在对数据修改时才加write lock,一旦写完马上释放write lock,即使事务A还没有提交。因此事务B在读取同一行时,才能读到事务A修改过的数据。

提交读:一个update事务A只有在对数据修改时才加write lock,但直到事务A commit时才释放写锁。因此,同时进行的事务B希望读取同一行数据时,会被事务A的write lock堵塞,所以解决了脏读的问题。

可重复读:这个隔离等级的条件下,除了执行提交读的写锁方式,还会在读取一行数据后,为这行数据添加read lock直至事务commit。例如,事务A读取ID=1这一行数据,然后为ID=1添加read lock。事务B同时希望update ID=1,此时获取写锁失败,因此在事务A执行完之前,没有其他任何事务可以对ID=1这一行做修改,因此解决了重复读的问题

虽然读写锁解决了Isolation问题,但锁会导致大量的堵塞,性能下降。某些时候会造成死锁,为了解决死锁,还要添加死锁探测机制,性能进一步下降,因此需要更高效的方式实现Isolation。

2)MVCC实现的Isolation
MVCC,多版本并发控制,的思路是:对每一行数据用log记录多个版本,每个版本的数据可能都不相同,然后根据事务的ID去寻找到适合他的那个版本数据,以此达到不同事务之间的隔离性。

InnoDB行数据结构:
在这里插入图片描述

如图所示,InnoDB每行数据除了用户定义的数据外,还包括TRX_ID(当前数据属于哪个事务ID)、ROLL_PTR(指向这一行数据undo log的指针)、delete bit(删除标记)。
在这里插入图片描述

ROLL_PTR指向的undo log链
如图,MVCC的前提下,事务A读取ID=1的行,数据库会检测事务A的事务ID,并在ROLL_PTR指向的undo log链中寻找合适的数据版本,并提取数据。通过MVCC,数据库可以使得事务的读取不需要很多读锁,提升了数据库的性能。当一个事务完成时,数据库会删除关于这条事务所有的undo log,若未完成事务数据库崩溃则根据undo log回滚,实现Atomicity。

新的问题来了:数据库是如何知道哪个版本是事务A可见的呢?
在实现上, InnoDB 为每个事务构造了一个数组,用来保存这个事务启动瞬间,所有活跃的事务ID。

1、如果undo log指向的是绿色部分的trx_id,说明该事务在事务A启动前已commit,那么其修改一定是事务A可见的数据

2、如果undo log指向的是红色部分的trx_id,说明该事务在事务A启动前还未开启,那么其修改一定是事务A不可见的。

3、如果undo log指向的是黄色部分的trx_id且这个trx_id在事务A启动时创建的活跃事务中,那么这个版本是事务A不可见的

MVCC 事务可见版本范围:
在这里插入图片描述

通过以上的步骤可以取得适合事务A的版本数据(undo log),取出数据并返回,此时实现了事务的Isolation。

提交读:事务A执行每一条语句时,生成一份活跃事务表,根据这份表去获取数据,因此不会获取到脏数据(未提交事务引起的),但会有重复读问题(因为可以读取到commit的事务数据)

可重复读:事务A只有在事务开始时才生成一份活跃事务表,因此不会读取到事务A执行中commit的其它事务引起的数据变更,也就不存在重复读问题。


http://chatgpt.dhexx.cn/article/UDVPj41I.shtml

相关文章

数据库acid实现原理(二)

一、基础概念 事务(Transaction)是访问和更新数据库的程序执行单元;事务中可能包含一个或多个sql语句,这些语句要么都执行,要么都不执行。作为一个关系型数据库,MySQL支持事务,本文介绍基于MyS…

什么是 ACID

MySQL ACID及四种隔离级别的解释 脏读、非重复读、幻读 ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性…

MySQL的ACID是如何实现的?

写在前面 本文主要探讨MySQL InnoDB 引擎下ACID的实现原理,对于诸如什么是事务,隔离级别的含义等基础知识不做过多阐述。 ACID MySQL 作为一个关系型数据库,以最常见的 InnoDB 引擎来说,是如何保证 ACID 的。 (Atomi…

数据库的ACID原则

一、 事务的ACID属性 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 一致性(Consistency) 事务必须使数据库从一个一致性状态变换到另外一个一致性状…

ACID理论

ACID 理论是对事务特性的抽象和总结,方便我们实现事务。可以理解成:如果实现了操作的 ACID 特性,那么就实现了事务。 1. 事务是什么 事务可以看成是一个或者多个操作的组合操作,并且它对这个组合操作提供一个保证,如果…

mysql acid

本文实验的测试环境:Windows 10cmdMySQL5.6.36InnoDB 一、事务的基本要素(ACID) 1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间…

数据库ACID四大特性到底为了啥,一文带你看通透

小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL江湖路 | 专栏目录 说起数据库四大特性,同学们张口就来,ACID!那为什么要ACID?每种特性的原理又是什么?如何实现的?废话少说,哈哥今…

ACID是靠什么来保证的?

首先,什么是ACID? 原子性(A): 原子性就是一个事务内的操作,要么全部成功,要么全部失败。一致性(C) 一致性就是一个正确的结果到另一个正确的结果。换句话说就是一个事…

mysql的ACID

ACID是衡量事务的四个特性: 原子性(Atomicity,或称不可分割性)一致性(Consistency)隔离性(Isolation)持久性(Durability) 原子性:语句要么全执行&…

ACID

细节其实很多。。。 1 到底什么是ACID 首先需要说明的是,在IT领域,很多名词在不同的上下文环境中的语义是不同的。例如某些产品宣称支持“100% ACID”和“强一致性”等。那么,这些名词到底指的是什么?如果不结合具体的语境&#x…

[MySQL]事务ACID详解

专栏简介 :MySql数据库从入门到进阶. 题目来源:leetcode,牛客,剑指offer. 创作目标:记录学习MySql学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 1. 事务的概念 2. 事务的特性 3.事务控制语法…

数据库的ACID是什么

欢迎大家关注我的公众号【老周聊架构】,Java后端主流技术栈的原理、源码分析、架构以及各种互联网高并发、高性能、高可用的解决方案。 事务在当今的企业系统无处不在,即使在高并发环境下也可以提供数据的完整性。一个事务是一个只包含所有读/写操作成功…

谈谈数据库的ACID

谈谈数据库的ACID 帅宏军 一.事务 定义:所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。 准备工作:为了说明事务的ACID原理,我们使用银行账户及资金…

数据库中的 ACID 属性

💂 个人网站:【海拥】【摸鱼游戏】【神级源码资源网】🤟 前端学习课程:👉【28个案例趣学前端】【400个JS面试题】💅 想寻找共同学习交流、摸鱼划水的小伙伴,请点击【摸鱼学习交流群】 大多数使用数据库的程…

什么是ACID?它的特性是什么?

https://baijiahao.baidu.com/s?id1743501877867119042&wfrspider&forpc ACID是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性&…

事务ACID理解

事务管理(ACID) 谈到事务一般都是以下四点 原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。 一致性(Consistency) 事务前后数据…

vue页面刷新 reload()

首先在vue里配置 在所想添加reload的vue里直接如下: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190610082256841.png?x-oss-processimage/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NTAxMTkxMA…

重识Nginx - 16 Nginx reload流程浅析

文章目录 图解reload流程1.向master程发送HUP号( reload命令)2.master进程校验配置语法是否正确3.master进程打开新的监听端口4.master进程用新配置启动新的worker 进程5.master进程向老worker 进程发送QUIT号6.老worker进程关闭监听句柄,处理完当前连接后结束进程 图解reload流…

vue this.reload 方法 配置, 优于window.reload()的页面刷新

相关网址: https://www.cnblogs.com/yinn/p/9056731.html 1.场景 在处理列表时,常常有删除一条数据或者新增数据之后需要重新刷新当前页面的需求。 2.遇到的问题 1. 用vue-router重新路由到当前页面,页面是不进行刷新的 2.采用window.re…

Nginx reload

解释 /usr/local/nginx/sbin/nginx -s reload 用过多次这条命令,一直以为是重启Nginx,今天有幸看了下Nginx官方文档介绍这条命令 Nginx服务不会终止,主进程检查配置,应用配置的过程。主进程会启动一个新的工作进程处理新来的请求…