MySQL是怎么保证数据一致性的

小编 2026-07-14 阅读:393 评论:0
在《写数据库同时发mq消息事务一致性的一种解决方案》一文的方案中把分布式事务巧妙转成了数据库事务。我们都知道关系型数据库事务能保证数据一致性,那数据库到底是怎么设计事务这一特性的呢?一、MySQL事务模型ACIDMySQL是一个多引擎数据库...

在《写数据库同时发mq消息事务一致性的一种解决方案》一文的方案中把分布式事务巧妙转成了数据库事务。我们都知道关系型数据库事务能保证数据一致性,那数据库到底是怎么设计事务这一特性的呢?

一、MySQL事务模型ACID

MySQL是一个多引擎数据库,其中InnoDB支持数据库事务,也是最常用的引擎。下边就介绍InnoDB的事务模型

MySQL官方文档对事务是这么描述的“事务是可以提交或回滚的原子工作单元。当事务对数据库进行多个更改时,要么提交事务时所有更改都成功,要么回滚事务时撤消所有更改。”

“ACID模型是一组数据库设计原则,强调业务数据和关键应用程序的可靠性很重要。MySQL包含与ACID模型紧密结合的innodb存储引擎组件,确保数据不会被破坏,结果不会被软件崩溃和硬件故障等异常情况所篡改。当您依赖ACID的特性,就不再需要重新发明一致性检查和崩溃恢复机制。”

ACID模型按照字母拆解分为四大特性

A : atomicity 原子性。原子性是我们对事务最直观的理解:事务就是一系列的操作,要么全部都执行,要么全部都不执行。

C : consistency 一致性。数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNTS表中Tom和Jack的存款和不变。

I : isolation 隔离性。在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。

D : durability 持久性。只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

二、InnoDB存储引擎架构

下边这张图是InnoDB的架构,包括两大部分,内存结构(In-Memory Structures)和磁盘上的结构(On-Disk Structures)。

在这张图中,尤其要关注“Redo Log”和“Undo Tablespaces”这两个区域,它们跟事务息息相关。

内存结构(In-Memory Structures)更多的目的是在提高性能,因此本文不会过多关注。如果感兴趣,可以访问MySQL的官方网站www.mysql.com

“Undo Tablespaces”包含Undo Log(撤消日志),Undo Log是撤消日志记录的集合,其中包含如何撤消事务对聚集索引记录的最新更改的信息。Undo Log存在于撤消日志段中,这些日志段包含在回滚段中。

MySQL事务的四个特性中ACD三个特性是通过Redo Log(重做日志)和Undo Log 实现的,而 I(隔离性)是通过Lock(锁)来实现。

三、普及个概念MVCC

MVCC,Multi-Version Concurrency Control,多版本并发控制。这项技术使得InnoDB的事务隔离级别下执行一致性读操作有了保证,换言之,就是为了查询一些正在被另一个事务更新的行,并且可以看到它们被更新之前的值。这是一个可以用来增强并发性的强大技术,查询不用等待另一个事务释放锁。这项技术广泛应用于数据库,例如Oracle,PostgreSQL。当然也有一些数据库产品以及mysql的其它存储引擎不支持它。

看一看MVCC机制的示意图,图下边会给出文字解释

图中底部横轴是时间,纵向的箭头用来标记增、删、改、查发生的时刻。尤其注意时间轴上方两条色块,代表数据的两个版本V1、V2。为了醒目,我把V1、V2用红色方框圈了起来(多版本的体现)。从左向右解读这张图

1、T1事务插入数据a=3,然后提交,生成了数据对应的V1版本

2、T2事务开始读取a数据,读取会持续一段时间,由于开始读取的时刻,只有V1版本,所以最终T2读到a=3

3、T2读取过程中,T3对数据a进行修改,a=4,生成a数据的V2版本,但此时并未提交,因此生效的是V1版本数据。

4、T3修改提交之前,T4读取a数据,由于此时V1版本数据生效,因此,T4读到a=3

5、T3提交a=4的修改,V1版本数据失效,V2生效。a的值变为4

6、T5读取a的值,读到V2版本,a=4

至此,MVCC的概念就搞明白了,那么MySQL是怎么实现的呢?

四、InnoDB多版本的实现

1、三个隐藏字段

在内部,InnoDB向数据库中存储的每一行数据添加三个字段。

(1)DB_TRX_ID字段,6字节。表示插入或更新行的最后一个事务的事务标识符。此外,删除在内部被视为更新,其中行中的特殊位被设置为将其标记为已删除。

(2)DB_ROLL_PTR字段,7字节,叫做回滚指针(roll pointer)。回滚指针指向写入回滚段的撤消日志(Undo Log)。如果行已更新,则撤消日志包含重建更新前该行内容所需的信息。

(3)DB_ROW_ID字段,6字节。包含一个随着新行插入而单调增加的行ID,如果innodb自动生成聚集索引,则该索引包含行ID值。否则,DB_ROW_ID列不会出现在任何索引中。

2、多版本产生过程

以新增一条记录并对该记录进行2次修改来说明具体实现

这条记录有3个隐含字段(前面已经介绍),分别应对行的ID、事务号和回滚指针。

当插入的是一条新数据时,记录上对应的回滚段指针为NULL

这个过程做了以下几件事

  • 用排他锁锁定该行
  • 把该行修改前的值拷贝到Undo Log中
  • 修改当前行的值,填写事务编号,使回滚指针指向Undo Log中的修改前的行
  • 记录Redo Log,包括Undo Log中的变化

多次更新后,回滚指针会把不同版本的记录串在一起。在InnoDB中存在purge线程,它会查询那些比现在最老的活动事务还早的Undo Log,并删除它们,从而保证Undo Log文件不至于无限增长。

3、提交与回滚

当事务正常提交时,InnoDB只需要更改事务状态为commit即可,不需要做其他额外的工作

回滚(rollback)需要根据当前回滚指针从Undo Log中找出事务修改前的版本,并恢复。如果事务影响的行非常多,回滚则可能会很慢,根据经验值没提交的事务行数在1000~10000之间,InnoDB效率还是非常高的(唐成-数据库多版本实现内幕)。

commit效率高,rollback代价大

4、可见性

事务隔离是数据库处理的基础之一,隔离是缩写ACID中的I。隔离级别是当多个事务同时进行更改和执行查询时,微调性能、可靠性、一致性和结果再现性之间的平衡的设置。

InnoDB提供SQL1992标准定义的四个隔离级别,READ UNCOMMITTED(未提交读), READ COMMITTED(已提交读), REPEATABLE READ(可重复读), and SERIALIZABLE(可串行化)。默认的是REPEATABLE READ

每种隔离级别具体的意义可以百度查到,实现原理深入进去比较复杂。注意到每条数据隐藏的事务ID字段DB_TRX_ID有时序性,理论上可以根据一些策略,借助这个字段来实现与隔离级别相关的功能。事实上InnoDB也是这么做的。当然这个功能还涉及很多锁的问题,这里不再展开。

MySQL官方文档在“锁和事务模型”这一章节开始就介绍了InnoDB的锁,截个目录,感兴趣可以去读一下。

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
标签列表