首页 >> 基础教程

mysql怎么保证ACID

    MySQL 的 ACID 特性主要通过 InnoDB 存储引擎的核心机制来保证,具体实现如下:

  1. 原子性 (Atomicity)

    • 保证机制:Undo Log

    • 原理:

      • 事务开始前或修改数据时,InnoDB 会将被修改数据的旧版本(修改前的值) 记录到 Undo Log 中。

      • 如果事务需要回滚(例如遇到错误或显式执行 ROLLBACK),InnoDB 会利用 Undo Log 中的数据将修改过的数据恢复到事务开始前的状态

      • 如果事务成功提交,相关的 Undo Log 记录并不会立即删除,而是在不再需要时(例如没有其他事务需要访问这些旧版本来保证一致性视图时)才被清理。

    • 作用: 确保事务内的所有操作要么全部完成,要么全部不执行,没有中间状态。

  2. 一致性 (Consistency)

    • 保证机制: 这是一个结果性的特性,由数据库的完整性约束(主键、外键、唯一索引、数据类型、NOT NULL等)以及应用程序的业务逻辑共同保证。原子性、隔离性、持久性是实现一致性的基础手段。

    • 原理:

      • 事务执行前,数据库处于一致状态。

      • 事务执行过程中,数据库可能处于不一致的中间状态(这是允许的)。

      • 事务执行完成后(无论提交还是回滚),数据库必须再次回到一致状态。

      • InnoDB 通过强制执行约束(如插入违反唯一索引会报错)和利用原子性、隔离性、持久性机制来确保事务结束时的一致性。

    • 作用: 确保数据库从一个有效的状态转换到另一个有效的状态,不会破坏预定义的规则。

  3. 隔离性 (Isolation)

    • 保证机制:锁机制 (Locking) 和 多版本并发控制 (MVCC - Multi-Version Concurrency Control)

    • 原理:

      • 锁机制 (Locking):

        • 行级锁: InnoDB 默认使用行级锁(共享锁 S Lock 用于读,排他锁 X Lock 用于写),大大减少了锁冲突,提高了并发度。

        • 表级锁 (意向锁): 在获取行锁之前,需要先获取表级的意向锁 (IS Lock / IX Lock),用于快速判断表上是否有冲突的锁存在。

        • 锁的兼容性: 锁机制通过定义锁之间的兼容性(例如,多个事务可以同时持有同一行的共享锁 S Lock,但一个事务持有排他锁 X Lock 时,其他事务不能获得该行的任何锁)来隔离并发事务的读写操作。

      • 多版本并发控制 (MVCC):

        • 这是 InnoDB 实现高并发读写的关键。

        • InnoDB 在修改数据行时,会为该行生成一个新版本(存储在表空间中),并保留旧版本(通过 Undo Log 链访问)。

        • 每个事务启动时(或在执行第一个读操作时,取决于隔离级别),InnoDB 会为该事务生成一个一致性读视图 (Read View)

        • Read View 定义了该事务能看到哪些版本的数据行:

          • 能看到事务自身修改的数据。

          • 能看到在 Read View 创建时已经提交的事务所做的修改。

          • 看不到在 Read View 创建时尚未提交的事务所做的修改。

          • 看不到在 Read View 创建之后才提交的事务所做的修改(在可重复读 REPEATABLE READ 级别下

        • 通过读取符合其 Read View 的数据行版本(可能是最新版本,也可能是旧版本),不同事务可以在很大程度上避免读写冲突,实现非锁定读 (Consistent Nonlocking Reads)。

    • 作用: 确保并发执行的事务之间互不干扰,每个事务感觉不到其他事务在同时执行。不同的隔离级别(读未提交 READ UNCOMMITTED, 读已提交 READ COMMITTED, 可重复读 REPEATABLE READ, 串行化 SERIALIZABLE)通过调整锁的使用策略和 Read View 的生成规则来实现不同程度的隔离性(以及并发性能)。

  4. 持久性 (Durability)

    • 保证机制:Redo Log 和 Double Write Buffer (部分场景)

    • 原理:

      • Redo Log (重做日志):

        • 这是持久性最核心的保证。

        • 事务提交时,InnoDB 会先将事务产生的 Redo Log 记录(记录的是对数据页的物理修改)按顺序写入 Redo Log Buffer

        • 关键步骤: InnoDB 通过调用 fsync() 或类似机制,确保 Redo Log Buffer 中的内容强制刷新 (Force Log at Commit) 到磁盘上的 Redo Log 文件中(通常是 ib_logfile0ib_logfile1)。只有这个刷盘操作完成,事务才被认为真正提交成功。

        • 即使此时修改的数据页本身还没有写回磁盘(脏页),数据库发生崩溃,重启后 InnoDB 可以根据 Redo Log 文件中的记录重放 (Redo) 所有已提交事务的修改,将数据恢复到崩溃前的状态。

        • Redo Log 是顺序写入的,比随机写入数据文件快得多,并且大小固定,循环使用(写满后覆盖最旧的日志)。

      • Double Write Buffer (双写缓冲区):

        • 主要解决 Partial Page Write (部分页写入) 问题。

        • 在将内存中修改过的脏数据页刷回磁盘上的数据文件之前,InnoDB 会先将这些页按顺序写入磁盘上一个共享表空间中的连续区域(Double Write Buffer)。

        • 然后再将这些页写入它们在数据文件中的实际位置(可能是随机位置)。

        • 如果在写入实际位置时发生崩溃(比如只写了一部分),重启恢复时,InnoDB 可以从 Double Write Buffer 中找到该页的一个完整副本,用它来覆盖损坏的页,然后再应用 Redo Log。这确保了数据页本身的完整性和一致性。

    • 作用: 确保一旦事务成功提交,它对数据库所做的修改就是永久性的,即使发生系统崩溃、断电等故障,数据也不会丢失。

     InnoDB 通过精心设计的 Undo Log、Redo Log、锁协议、MVCC 等机制协同工作,共同确保了 MySQL 数据库事务的 ACID 特性。


最新文章
mysql分页问题2025-08-04
千万数据先insert和先建索引哪个快2025-08-04
MySQL 中大小表关联查询如何优化2025-08-04
sql技巧-每个班年龄排前两名的人2025-08-03
MySQL 导致 cpu 飙升的话,要怎么处理呢?2025-07-29
MySQL 中为千万级大表添加字段2025-07-29
mysql中百万级别以上的数据如何删除2025-07-29
分库分表带来的问题2025-07-29
mysql中常用的分库分表中间件有哪些2025-07-29
mysql不停机扩容2025-07-29
备案号:蜀ICP备2023042032号-1