> ## Content Index
> Fetch the complete content index at: https://www.richarvin.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 如何保证MySQL的原子性？
- URL: https://www.richarvin.com/ru-he-bao-zheng-mysql-de-yuan-zi-xing/
- Published: 2023-12-02T05:55:37.000Z
- Updated: 2024-05-22T01:43:52.000Z
- Author: Richarvin
- Tags: 编程技术

在MySQL中，保证原子性是指一个事务（Transaction）要么完全执行，要么完全不执行，不会出现部分执行的情况。如果在事务执行过程中发生了异常，那么事务中的所有操作都应该回滚到修改之前的样子。

MySQL 使用回滚日志来记录事务中的所有操作。当事务开始执行时，MySQL 会先将事务中的操作记录到回滚日志中。然后，MySQL 才会执行这些操作。如果在执行过程中发生了异常，那么 MySQL 可以利用回滚日志中的信息来回滚事务。

具体来说，MySQL 中的回滚日志分为两部分：

- 内存中的回滚日志缓冲区（redo log buffer）：这部分日志是易失性的，如果数据库发生宕机，内存中的回滚日志缓冲区中的数据可能会丢失。
- 磁盘上的回滚日志文件（redo log file）：这部分日志是持久性的，即使数据库发生宕机，磁盘上的回滚日志文件中的数据也不会丢失。

那么是先写redo log还是先修改数据呢？

MySQL使用的是WAL（Write-Ahead Logging）技术，即先写日志，后写数据。

- 但在执行 DML 操作时，MySQL会先将操作记录到内存中的 Redo Log Buffer 中。
- 在事务提交时，将 Redo Log Buffer 中的数据刷新到磁盘上的 Redo Log File 中。这确保了即使在事务提交时发生异常，Redo Log 中的数据已经持久化到磁盘，可以用于恢复。
- 如果在事务执行过程中发生异常，MySQL会根据 Redo Log 中的信息将事务回滚到修改之前的状态。这是因为 Redo Log 记录了事务的变更操作。

因此，在MySQL中，先写Redo Log，后写数据。这样的设计可以确保事务的原子性和持久性，即使在发生异常时也能通过Redo Log 来进行数据的恢复。

💡

也就是说如果在事务执行过程中发生了异常，那么 MySQL 会将事务回滚到修改之前的样子。回滚的过程应该是下面这样：

1. 清空内存中的Redo Log Buffer中的数据。。
2. 将磁盘上的Redo Log File中的数据读取到内存中。
3. 按照Redo Log中的信息对数据进行回滚。

由于回滚日志会先于数据持久化到磁盘上，因此即使数据库发生宕机，当用户再次启动数据库的时候，数据库还能够通过查询回滚日志来回滚之前未完成的事务。

具体来说，当数据库发生宕机时，数据库会丢失内存中的数据，包括内存中的回滚日志缓冲区中的数据。但是，磁盘上的回滚日志文件中的数据仍然存在。当用户再次启动数据库时，数据库会先将磁盘上的回滚日志文件中的数据读取到内存中。然后，数据库会按照回滚日志中的信息对数据进行回滚。这样，就可以保证即使数据库发生宕机，之前未完成的事务也会被回滚。