什么是ACID

ACID是衡量事务的四个特性:

  • 原子性(Atomicity,或称不可分割性)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

原子性:原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中一个sql语句执行失败,则已执行的 语句也必须回滚,数据库退回到事务前的状态。

实现原理:undo log

在说明原子性原理之前,首先介绍一下MySQL的事务日志。MySQL的日志有很多种,如二进制日志、错误日志、查询日志、慢查询日志等,此外InnoDB存储引擎还提供了两种事务日志:redo log(重做日志)和undo log(回滚日志)。其中redo log用于保证事务持久性;undo log则是事务原子性和隔离性实现的基础。

下面说回undo log。实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。InnoDB实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB会生成对应的undo log;如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。

undo log属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB会根据undo log的内容做与之前相反的工作:对于每个insert,回滚时会执行delete;对于每个delete,回滚时会执行insert;对于每个update,回滚时会执行一个相反的update,把数据改回去。

以update操作为例:当事务执行update时,其生成的undo log中会包含被修改行的主键(以便知道修改了哪些行)、修改了哪些列、这些列在修改前后的值等信息,回滚时便可以使用这些信息将数据还原到update之前的状态。

持久性:持久性是指事务一旦提交,它对数据库的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

实现原理:redo log

redo log和undo log都属于InnoDB的事务日志。下面先聊一下redo log存在的背景。

InnoDB作为MySQL的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘IO,效率会很低。为此,InnoDB提供了缓存(Buffer Pool),Buffer Pool中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲:当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool;当向数据库写入数据时,会首先写入Buffer Pool,Buffer Pool中修改的数据会定期刷新到磁盘中(这一过程称为刷脏)。

Buffer Pool的使用大大提高了读写数据的效率,但是也带了新的问题:如果MySQL宕机,而此时Buffer Pool中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。

于是,redo log被引入来解决这个问题:当数据修改时,除了修改Buffer Pool中的数据,还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。如果MySQL宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是WAL(Write-ahead logging,预写式日志),所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因MySQL宕机而丢失,从而满足了持久性要求。

既然redo log也需要在事务提交时将日志写入磁盘,为什么它比直接将Buffer Pool中修改的数据写入磁盘(即刷脏)要快呢?主要有以下两方面的原因:

(1)刷脏是随机IO,因为每次修改的数据位置随机,但写redo log是追加操作,属于顺序IO。

(2)刷脏是以数据页(Page)为单位的,MySQL默认页大小是16KB,一个Page上一个小修改都要整页写入;而redo log中只包含真正需要写入的部分,无效IO大大减少。

隔离性:与原子性、持久性侧重于研究事务本身不同,隔离性研究的是不同事务之间的相互影响。隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。严格的隔离性,对应了事务隔离级别中的Serializable (可串行化),但实际应用中出于性能方面的考虑很少会使用可串行化。

隔离性追求的是并发情形下事务之间互不干扰。简单起见,我们仅考虑最简单的读操作和写操作(暂时不考虑带锁读等特殊操作),那么隔离性的探讨,主要可以分为两个方面:

  • (一个事务)写操作对(另一个事务)写操作的影响:锁机制保证隔离性
  • (一个事务)写操作对(另一个事务)读操作的影响:MVCC保证隔离性

2. 锁机制

首先来看两个事务的写操作之间的相互影响。隔离性要求同一时刻只能有一个事务对数据进行写操作,InnoDB通过锁机制来保证这一点。

锁机制的基本原理可以概括为:事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。

行锁与表锁

按照粒度,锁可以分为表锁、行锁以及其他位于二者之间的锁。表锁在操作数据时会锁定整张表,并发性能较差;行锁则只锁定需要操作的数据,并发性能好。但是由于加锁本身需要消耗资源(获得锁、检查锁、释放锁等都需要消耗资源),因此在锁定数据较多情况下使用表锁可以节省大量资源。MySQL中不同的存储引擎支持的锁是不一样的,例如MyIsam只支持表锁,而InnoDB同时支持表锁和行锁,且出于性能考虑,绝大多数情况下使用的都是行锁。

一致性:一致性是指事务执行结束后,数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态。数据库的完整性约束包括但不限于:实体完整性(如行的主键存在且唯一)、列完整性(如字段的类型、大小、长度要符合要求)、外键约束、用户自定义完整性(如转账前后,两个账户余额的和应该不变)。

实现

可以说,一致性是事务追求的最终目标:前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。此外,除了数据库层面的保障,一致性的实现也需要应用层面进行保障。

实现一致性的措施包括:

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

该文章转载于:

https://www.cnblogs.com/xiaozhaung/p/11083028.html

这是我看到的讲的特别清晰的一篇,分享给大家~

什么是ACID(转载)相关推荐

  1. 数据库事务ACID详解(转载)

    转载自:http://blog.csdn.net/shuaihj/article/details/14163713 谈谈数据库的ACID 一.事务 定义:所谓事务,它是一个操作序列,这些操作要么都执行 ...

  2. 谈谈对数据库中ACID、CAP、BASE的认识

    2019独角兽企业重金招聘Python工程师标准>>> ACID.CAP.BASE的区别与联系 这得从关系型数据库关系型数据库(RDBMS)和非关系型数据库(NoSQL)说起. RD ...

  3. 数据库 事务的特性ACID

    事务(Transaction)是并发控制的基本单位. 所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位.例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这 ...

  4. 数据库设计的酸(ACID)碱(BASE)原则

    数据库设计的酸(ACID)碱(BASE)原则 转载于:https://www.cnblogs.com/gotodsp/p/6517481.html

  5. 分布式系统开发的一些相关理论基础——CAP、ACID、BASE

    本文主要讲述分布式系统开发的一些相关理论基础. 一.ACID 事务的四个特征: 1.Atomic原子性 事务必须是一个原子的操作序列单元,事务中包含的各项操作在一次执行过程中,要么全部执行成功,要么全 ...

  6. [转载]C++ 面试

    原文地址:C++ 面试作者:老徐 1.new.delete.malloc.free关系 delete会调用对象的析构函数,和new对应free只会释放内存,new调用构造函数.malloc与free是 ...

  7. [转载]C#写的NoSQL开源项目/系统(系列)

    闲扯 好久没写开源项目了,也没写对新开源项目的介绍,今晚看了几个项目,写一下. 前言 一直推崇纯C#的解决方案,无论是多年写的各种文件格式的读写(如office系列的xls/xlsx/doc/docx ...

  8. Base:一种 Acid 的替代方案

    原文链接: BASE: An Acid Alternative 数据库 ACID,都不陌生:原子性.一致性.隔离性和持久性,这在单台服务器就能搞定的时代,很容易实现,但是到了现在,面对如此庞大的访问量 ...

  9. MySQL配置文件my.cnf中文版(转载)

    mysql的DBA必看的内容,这个选取my-innodb-hurge的那个配置文件的内容,为以后方便查阅. MySQL配置文件my.cnf中文版 #BEGIN CONFIG INFO #DESCR: ...

最新文章

  1. 北大燕博南:下一代AI芯片— 存内计算的硬核与软着陆 | 报告详解
  2. mysql连接出现Unknown system variable ‘tx_isolation‘异常
  3. linux php ldap扩展,php_ldap域集成模块安装-159
  4. idea代码提示插件_IDEA 插件推荐 —— 让你写出好代码的神器!
  5. 如何找出SAP Fiori launchpad URL start_up请求发起的具体位置
  6. sulin Python3.6爬虫+Djiago2.0+Mysql --实例demo
  7. .Net Core功能开关实战
  8. 分享一个Go项目的整洁架构模板
  9. fpga结构主体_两大FPGA公司的“AI技术路线”
  10. 欢迎来到,数据库联盟!
  11. 【Codeforces 1344 A】Hilbert‘s Hotel,哈希表,set维护
  12. 【原创】PDA 实现DataGrid可编辑
  13. Leetcode 刷题笔记(一) —— 数组类型解题方法一:二分法
  14. .NET技术(Path)
  15. centos www服务器文件unable create,Centos Vsftpd 无上传权限 (553 Could not create file)
  16. IIS无法启动:存储空间不足解决办法
  17. 数据可视化:大屏可视化设计全流程教程
  18. Spark Streaming简单入门(示例+原理)
  19. thinkphp使用paypal进行支付的做法详细步骤
  20. 哪家python培训最好

热门文章

  1. 体面 用计算机弹调子,怎么把计算器调成音符
  2. USB host关于收到STALL处理
  3. XGBRegressor参数详解以及调参过程
  4. day14 方法原则 方法命名 方法组成 方法重载
  5. Naoqi机器人学习
  6. uin-app安卓打包流程
  7. 结构光逆相机法重建详解+代码
  8. 洛谷CF1303A Erasing Zeroes 题解
  9. STM32物联网项目-通过ESP12S模块连接TCP服务器
  10. 【STM32G431RBT6】蓝桥杯嵌入式 ADC采样DMA传输配置