MySQL - 事务原理
<h3 id="一概述">一、概述</h3><h4 id="11-什么是事务">1.1 什么是事务?</h4>
<p>事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作:要么同时成功,要么同时失败</p>
<h4 id="12-事务的特性acid">1.2 事务的特性:ACID</h4>
<ul>
<li>原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全部失败</li>
<li>一致性(Consistency):事务完成时候,必须使所有的数据都保持一直状态</li>
<li>隔离性(Isolation):数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行</li>
<li>持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的</li>
</ul>
<h4 id="13-事务四大特性的实现">1.3 事务四大特性的实现</h4>
<p><img src="https://img2024.cnblogs.com/blog/3573751/202508/3573751-20250819162211145-241632958.png" alt="image" loading="lazy"></p>
<blockquote>
<p>原子性/一致性/持久性:通过Redo Log和Undo Log实现<br>
隔离性:通过锁+MVCC实现</p>
</blockquote>
<h3 id="二redo-log重做日志">二、Redo Log(重做日志)</h3>
<p>Redo Log主要用来实现四大特性中的"持久性"</p>
<blockquote>
<p>重做日志,记录的是事务提交时数据页的物理修改,该日志文件由两部分组成:<code>重做日志缓冲(redo log buffer)</code>以及<code>重做日志文件(redo log file)</code>,前者是在内存中,后者在磁盘中,当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘,发生错误时,进行数据恢复使用</p>
</blockquote>
<p><img src="https://img2024.cnblogs.com/blog/3573751/202508/3573751-20250819162501057-1642010186.png" alt="image" loading="lazy"></p>
<ol>
<li>客户端发起UPDATE/DELETE请求到InnoDB存储引擎 Buffer Pool缓冲池</li>
<li>判断缓冲池中是否存在数据,如果有,则直接进行修改,如果没有,则通过后台线程读取磁盘中的数据文件到缓冲池</li>
<li>在缓冲池直接进行SQL操作,这时候Buffer Pool中是更新好的数据,数据文件中是老的数据,我们称Buffer Pool中的页为脏页</li>
<li>将增删改的数据现记录到Redo Log Buffer中,里面记录的是数据页的物理变化</li>
<li>事务提交时,将Redo Log Buffer中的变化刷新到磁盘当中,生成Redo Log日志文件</li>
<li>过一定时间,进行脏页刷新</li>
</ol>
<h4 id="21-redo-log的实现">2.1 Redo Log的实现</h4>
<ul>
<li><strong>物理日志:</strong> Redo Log 是物理日志,记录的是物理数据页的更改,而不是 SQL 操作或逻辑操作。它记录了数据库物理块的变更,比如某个数据页上某条记录的修改。</li>
<li><strong>WAL(Write-Ahead Logging)机制:</strong> InnoDB 采用 WAL 机制,即先写日志,再写磁盘。每次事务提交时,InnoDB 会将 Redo Log 先写入磁盘,而后再慢慢将实际修改的数据写入磁盘。</li>
<li><strong>循环写机制:</strong> Redo Log 采用固定大小的循环写机制。当日志写满时,会从头开始重新写。因此,在系统运行时,InnoDB 会定期将日志应用到数据页,并将脏页(即被修改但还未写入磁盘的数据页)刷新到磁盘。</li>
</ul>
<h4 id="22-为什么要先把redo-log刷新到磁盘当中">2.2 为什么要先把Redo Log刷新到磁盘当中?</h4>
<p>分为两种场景:<br>
场景一:如果过一定时间在刷新脏页,如果刷新失败,则无法保证数据的持久性<br>
场景二:如果每次写入都直接刷新到磁盘,这样存在严重的性能问题</p>
<blockquote>
<p>如果直接刷新,涉及大量的随机磁盘IO,性能比较低,如果用到Redo Log,不会直接刷新脏页,Redo Log日志文件是追加写入,顺序磁盘IO</p>
</blockquote>
<h4 id="23-redo-log的使用场景">2.3 Redo Log的使用场景</h4>
<ul>
<li><strong>崩溃恢复:</strong> 当数据库崩溃后,通过重启,MySQL 可以根据 Redo Log 恢复所有已提交的事务。这是 MySQL 保证事务持久性的关键机制。</li>
<li><strong>提高性能:</strong> 因为 Redo Log 可以先于数据页写入磁盘,数据库无需每次事务提交时都立即写入数据页,从而显著提高了写操作的性能。数据页的写入可以在稍后的时间由后台线程异步完成。</li>
</ul>
<h3 id="三undo-log回滚日志">三、Undo Log(回滚日志)</h3>
<p>Undo Log主要用来实现四大特性中的"原子性"</p>
<blockquote>
<p>回滚日志,用于记录数据被修改前的信息,作用包含两个:提供回滚和MVCC(多版本并发控制),undo log和redo log记录物理日志不一样,它是逻辑日志</p>
</blockquote>
<p><strong>undo log销毁:</strong> undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC<br>
<strong>undo log存储:</strong> undo log采用段的方式进行管理和记录,存存放在前面介绍的rollback segment回滚段中,内部包含1024个undo log segment</p>
<h4 id="31-undo-log的实现">3.1 Undo Log的实现</h4>
<ul>
<li><strong>逻辑日志:</strong> Undo Log是一种逻辑日志,记录的是逻辑上的修改操作,它并不会直接记录每次操作的物理存储修改,而是记录修改前的数据</li>
<li><strong>链表结构:</strong> InnoDB存储引擎会为每条记录维护一条Undo Log记录,并以链表的方式串联起来,如果事务需要回滚,MySQL会沿着Undo Log链表进行逐条回滚,直至恢复到事务开始时的状态</li>
<li><strong>Undo Log记录类型:</strong>
<ul>
<li><strong>对于<code>INSERT</code>操作:</strong> Undo Log记录的是“删除”操作,因为如果事务回滚,需要撤销插入的数据</li>
<li><strong>对与<code>DELETE</code>操作:</strong> Undo Log记录的是“插入”操作,用来恢复被删除的数据</li>
<li><strong>对于<code>UPDATE</code>操作:</strong> Undo Log记录的是修改前的旧值,用来恢复原来的值</li>
</ul>
</li>
</ul>
<h4 id="32-使用场景">3.2 使用场景</h4>
<ul>
<li><strong>事务回滚:</strong> 当事务执行失败或用户显式要求回滚时,Undo Log 会将所有修改的数据恢复到事务开始前的状态</li>
<li><strong>MVCC(多版本并发控制):</strong> Undo Log 也用于实现 MVCC 机制,不同事务可能在不同时间看到不同版本的数据,这些版本的数据就是由 Undo Log 提供的。这样,未提交的事务修改对其他事务是不可见的,帮助实现隔离性</li>
</ul>
<h3 id="四redo-log和undo-log的区别">四、Redo Log和Undo Log的区别</h3>
<table>
<thead>
<tr>
<th><strong>对比项</strong></th>
<th><strong>Undo Log</strong></th>
<th><strong>Redo Log</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>作用</strong></td>
<td>记录数据的旧值,用于回滚事务</td>
<td>记录数据的修改,用于恢复已提交的事务</td>
</tr>
<tr>
<td><strong>日志类型</strong></td>
<td>逻辑日志,记录逻辑操作</td>
<td>物理日志,记录数据页的物理修改</td>
</tr>
<tr>
<td><strong>实现机制</strong></td>
<td>链表结构,逐条回滚</td>
<td>固定大小的循环写机制,WAL 策略</td>
</tr>
<tr>
<td><strong>使用场景</strong></td>
<td>事务回滚、多版本并发控制(MVCC)</td>
<td>崩溃恢复、保证数据持久性</td>
</tr>
<tr>
<td><strong>何时写入磁盘</strong></td>
<td>修改数据时记录,但无需立即写入磁盘</td>
<td>事务提交时必须写入磁盘</td>
</tr>
<tr>
<td><strong>涉及的 ACID 特性</strong></td>
<td>原子性、隔离性</td>
<td>持久性</td>
</tr>
</tbody>
</table><br><br>
来源:https://www.cnblogs.com/jiamiing/p/19046987
頁:
[1]