MySQL怎么实现原子性的流程详解(以UPDATE为例)

 更新时间:2025年08月18日 08:31:52   作者:一个儒雅随和的男子  
原子性是事务的其中一个特性,指的是要么全部执行完,要么全都不执行,这篇文章主要介绍了MySQL怎么实现原子性(以UPDATE为例)的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

首先,应该想到InnoDB存储引擎,因为它是MySQL默认支持事务的引擎。MyISAM不支持事务,所以可能不适用。实现原子性关键在于Undo log,Undo log记录了SQL执行之前的状态,以便回滚恢复数据。

另外,事务的提交和回滚机制也很重要。当用户执行一个事务时,所有的修改操作会先记录到undo log中,如果事务成功提交,这些修改才会被持久化到磁盘;如果事务回滚,系统会利用undo log将数据恢复到事务开始前的状态。

还需要考虑redo log,虽然redo log主要是保证持久性,但它在事务提交时也起到关键作用,确保即使系统崩溃,已提交的事务修改也不会丢失。但现在问题是原子性,所以可能更侧重于undo log和事务的回滚机制。

还有一方面,锁机制也可能有关联。比如,在事务执行期间,相关的数据会被加锁,防止其他事务干扰,这有助于保证事务的原子性,因为在一个事务未完成前,其他事务不能修改相同的数据,从而避免中间状态被看到。

undo的工作流程大致为,当事务开始时,InnoDB会生成一个undo log记录旧值。如果在事务中执行了INSERT、UPDATE或DELETE操作,这些操作的反向操作会被记录到undo log中。如果事务需要回滚,就利用这些undo log来撤销更改。

还有一个点是,原子性不仅包括回滚,还包括提交时的原子性。在提交时,所有修改必须一次性写入到redo log和binlog中,确保即使系统崩溃,也能通过日志恢复事务的状态。这里可能涉及到两阶段提交(2PC)协议,协调redo log和binlog的写入,保证两者的日志一致性,从而确保事务的原子性。

在此之前必须了解原子性的基本概念。

总结一下,MySQL实现原子性的关键点包括:undo log记录修改前的数据状态,用于回滚;事务提交时的两阶段提交机制,确保日志的原子性写入;以及锁机制保证事务执行期间的隔离性,间接支持原子性。

MySQL 通过 Undo Log(回滚日志)、事务提交机制 和 InnoDB 存储引擎的原子性设计 来实现事务的原子性,确保事务中的操作要么全部成功,要么全部回滚。下面章节是具体实现原理。

一、原子性的定义

原子性(Atomicity)要求事务是一个不可分割的操作单元,事务中的操作要么全部成功提交,要么全部失败回滚,不会停留在中间状态。

二、实现原子性的核心技术

2.1. Undo Log(回滚日志)

  • 作用:记录事务修改前的数据状态,用于事务回滚。

  • 实现细节:

    • 每个事务开始时,InnoDB 会为其生成一个 Undo Log Segment。
    • 对数据的增删改操作(INSERT/DELETE/UPDATE)会先记录到 Undo Log 中:
      • INSERT:记录新插入数据的主键,回滚时根据主键删除。
      • DELETE:记录删除前的完整数据,回滚时重新插入。
      • UPDATE:记录修改前的旧值,回滚时恢复旧值。
  • 生命周期:

    • 事务提交后,Undo Log 不会立即删除,而是等待可能存在的其他事务(如 MVCC 读)不再需要时,由后台线程清理。

2.2 事务提交与回滚机制

  • 事务提交(Commit):
    • 将事务的所有修改写入内存中的 Buffer Pool。
    • 将修改的 Redo Log(重做日志)写入磁盘(innodb_flush_log_at_trx_commit=1 时强制刷盘)。
      标记事务为已提交,释放相关锁资源。
  • 事务回滚(Rollback):
    • 根据 Undo Log 中的记录反向执行操作(如删除新增数据、恢复旧值)。
    • 清理事务相关的锁和 Undo Log。

2.3. 崩溃恢复(Crash Recovery)

  • 若事务未提交时 MySQL 崩溃:

    • 重启后,通过 Undo Log 回滚未提交的事务。
  • 若事务已提交但数据未持久化到磁盘:

    • 通过 Redo Log 重放已提交的事务操作,确保数据持久性。

三、原子性的实现流程(以 UPDATE 为例)

1.事务开始:

START TRANSACTION;

2.执行 UPDATE 操作:

UPDATE users SET balance = balance - 100 WHERE id = 1;

InnoDB 将旧值 balance = 200 写入 Undo Log。

3.事务提交:

COMMIT;

写入 Redo Log 并刷盘,标记事务完成。

4.事务回滚:

ROLLBACK;
  • 根据 Undo Log 将 balance 恢复为 200。

四、关键设计与优化

  1. 两阶段提交(2PC)
  • 协调 Redo Log 和 Binlog:
    • Prepare 阶段:写入 Redo Log,标记为 Prepare 状态。
    • Commit 阶段:写入 Binlog,标记 Redo Log 为 Commit 状态。
  • 作用:确保事务日志的一致性,即使崩溃也能通过日志恢复原子性
  1. MVCC(多版本并发控制)
  • 依赖 Undo Log:为每个读操作提供事务开始时的数据快照。
  • 实现原子性隔离:确保事务回滚时,其他事务不会看到中间状态。
  1. 锁机制
  • 行锁、表锁:在事务执行期间锁定资源,防止其他事务干扰。
  • 隐式锁:通过 Undo Log 的可见性判断实现非阻塞读。

五、原子性与其他 ACID 属性的协作

六、验证原子性的示例

  • 场景:转账操作(A 转 100 给 B)
START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE user = 'A';
UPDATE accounts SET balance = balance + 100 WHERE user = 'B';
COMMIT;
  • 原子性保证:
    • 若执行到第 2 步后崩溃,事务未提交,Undo Log 会回滚 A 的余额。
    • 若执行到 COMMIT 时崩溃,重启后通过 Redo Log 重放完整事务。

七、总结

MySQL 通过以下机制实现原子性:

1.Undo Log:记录事务前的数据状态,支持回滚。

2.Redo Log 和两阶段提交:确保已提交事务的持久性和日志一致性。

3.崩溃恢复机制:通过日志回滚未完成事务或重放已提交事务。

4.锁与 MVCC:隔离事务操作,避免中间状态被其他事务读取。

这些机制共同保障了事务的原子性,使得 MySQL 在高并发和数据一致性场景下表现可靠。

到此这篇关于MySQL怎么实现原子性流程(以UPDATE为例)的文章就介绍到这了,更多相关MySQL实现原子性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • php中关于mysqli和mysql区别的一些知识点分析

    php中关于mysqli和mysql区别的一些知识点分析

    看书、看视频的时候一直没有搞懂mysqli和mysql到底有什么区别。于是今晚“谷歌”一番,整理一下。需要的朋友可以参考下。
    2011-08-08
  • MySQL 常见时间字段设置小结

    MySQL 常见时间字段设置小结

    本文详细探讨了MySQL中常见时间字段的设置和处理,包括DATETIME、DATE、TIME和TIMESTAMP等类型的介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • mysqlhotcopy 正则使用小技巧

    mysqlhotcopy 正则使用小技巧

    mysqlhotcopy 是MySQL的热备工具,详细请看手册 ,为了安全起见我们给热备分配个用户
    2011-08-08
  • Mybatis中的动态SQL语句解析

    Mybatis中的动态SQL语句解析

    这篇文章主要介绍了Mybatis中的动态SQL语句解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • MySQL大小写敏感导致的问题分析

    MySQL大小写敏感导致的问题分析

    在本篇内容里小编给大家整理了关于MySQL大小写敏感导致的问题的详细分析,有兴趣的朋友们可以学习参考下。
    2019-06-06
  • SQL中的distinct的使用方法

    SQL中的distinct的使用方法

    这篇文章主要介绍SQL中的distinct的使用方法,distinct用来查询不重复记录的条数,即用distinct来返回不重复字段的条数,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • SQL慢查询优化方案详解

    SQL慢查询优化方案详解

    这篇文章主要介绍了SQL慢查询优化方案详解,如果你的项目中出现了一些查询超时情况,很可能是项目中有了一些慢查询的情况产生,下面就慢查询的排查和解决方案进行一番分析,需要的朋友可以参考下
    2023-07-07
  • 让MySQL数据库跑的更快 为数据减肥

    让MySQL数据库跑的更快 为数据减肥

    在MySQL数据库优化工作中,使数据尽可能的小,使表在硬盘上占据的空间尽可能的小,这是最常用、也是最有效的手段之一。
    2011-03-03
  • 把MySQL卸载干净的超详细步骤

    把MySQL卸载干净的超详细步骤

    这篇文章主要介绍了把MySQL卸载干净的超详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考价值,需要的朋友们下面跟着小编来一起学习吧
    2024-02-02
  • MySQL 5.5的max_allowed_packet属性的修改方法

    MySQL 5.5的max_allowed_packet属性的修改方法

    今天在部署一个实验系统的时候,报错提示需要修改一下MySQL的配置文件,在修改的时候是有技巧的,大家可以参考下本文尝试操作下
    2013-08-08

最新评论