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实现原子性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • MySQL核心参数优化文件my.ini实现

    MySQL核心参数优化文件my.ini实现

    本文主要介绍了MySQL核心参数优化文件my.ini实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-01-01
  • mysql的校对规则引起的问题分析

    mysql的校对规则引起的问题分析

    在以前用oracle的时候,很少关于它的collation方法,但是在mysql中,这点不加注意的话,却有可能会出现问题。
    2008-10-10
  • MySQL自增ID用完了的四种解决方式

    MySQL自增ID用完了的四种解决方式

    这篇文章主要介绍了MySQL自增ID用完了的四种解决方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • MYSQL 批量替换之replace语法的使用详解

    MYSQL 批量替换之replace语法的使用详解

    本篇文章是对MYSQL中replace语法的使用进行了详细的分析介绍,需要的朋友参考下
    2013-07-07
  • Navicat Premium15连接云服务器中的数据库问题及遇到坑

    Navicat Premium15连接云服务器中的数据库问题及遇到坑

    这篇文章主要介绍了Navicat Premium15连接云服务器中的数据库问题及遇到坑,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Mysql中常用的几种join连接方式总结

    Mysql中常用的几种join连接方式总结

    join语句是面试中经常会让你现场写出来的语句,下面这篇文章主要给大家介绍了关于Mysql中常用的几种join连接方式,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • MySQL索引失效原因以及SQL查询语句不走索引原因详解

    MySQL索引失效原因以及SQL查询语句不走索引原因详解

    今天领导在查询报表时,发现特别慢,于是引发一系列关于sql优化的工作,下面这篇文章主要给大家介绍了关于MySQL索引失效原因以及SQL查询语句不走索引原因的相关资料,需要的朋友可以参考下
    2023-03-03
  • win10下mysql 8.0.11 压缩版安装教程

    win10下mysql 8.0.11 压缩版安装教程

    这篇文章主要为大家详细介绍了win10下mysql 8.0.11 压缩版安装教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • Mysql文件存储图文详解

    Mysql文件存储图文详解

    文件存储是我们日常开发中经常遇到的一个功能,下面这篇文章主要给大家介绍了关于Mysql文件存储的相关资料,需要的朋友可以参考下
    2021-06-06
  • MySQL8.0临时表空间的使用及解读

    MySQL8.0临时表空间的使用及解读

    MySQL 8.0+引入会话级(temp_N.ibt)和全局(ibtmp1)InnoDB临时表空间,用于存储临时数据及事务日志,自动创建与回收,重启释放,管理高效
    2025-09-09

最新评论