MySQL架构(三)mysql的两阶段提交

Mysql 的两阶段提交

在 MySQL架构(二)SQL 更新语句是如何执行的?中说到了 redo log 和 binlog 日志文件,在事务执行过程中,会分两个阶段写入这两份日志文件中,这也是为了保证两份日志之间的一致性,即维护 mysql 的数据一致性。

试想,如果不采用两阶段提交,会发生哪些情况?

由于 redo log 和 binlog 是两个独立的逻辑,不采用两阶段提交,有两种情况。

  • 情况 1:先写入 redo log 日志;再写入 binlog 日志。
  • 情况 2:先写入 binlog 日志;再写入 redo log 日志。

接下来我们用 MySQL架构(二)SQL 更新语句是如何执行的?中的例子来看看这两种方式会存在什么问题。

例子:update T set age = age+1 where ID = 2;

假设 ID=2 的行,字段 age=0 ,当执行该 update 语句时,第一个日志已经完成写入,但是第二个日志还没有写,或者还没有写完,在这个期间程序发生了异常奔溃(crash),这时该条更新的数据会出现怎样的情况呢?

情况1: 先写入 redo log 日志;再写入 binlog 日志

如果 redo log 写完,binlog 还没有写,或者还没有写完的时候,MySQL 进程突发异常崩溃。由于 redo log 已经写完,即便 mysql 崩溃,数据仍然能够恢复,所以恢复后该行数据中 age=1。

但 binlog 日志并没有完成写入,并没有记录这个更新语句。因此,在我们进行备份日志的时候,导出的 binlog 日志中没有这条更新语句。当我们需要用这个 binlog 日志去恢复临时库时,由于日志中缺失这个更新语句,那么本次恢复的临时库就少了一次更新,得到的值为 age=0 ,如此就与原库 age=1 的值不同。

情况 2: 先写入 binlog 日志;再写入 redo log 日志

如果 binlog 日志写完, redo log 日志还没写,或者还没有写完的时候,mysql 发生异常崩溃。在恢复数据以后,由于 redo log 没有更新记录,所以这个事务无效,所以 age=0,没发生更新。

但是 binlog 日志里面已经完整记录了 age=1,在之后使用 binlog 日志恢复临时库时就多了一个更新事务,恢复后得到的值为 age=1,这时也与原库的值不同。

由上述情况我们可以看到,如果不采用"两阶段提交"的方式,数据库在发生异常需要恢复数据的时候,采用两种日志恢复的数据就不一致了。

两阶段过程异常崩溃处理

如果在两阶段提交的方式下,在 binlog 日志写完,事务在没有 commit 前,即 redo log 日志还没记录 commit 前,mysql 进程发生异常崩溃,MySQL 恢复数据的流程如下。

首先,我们看一下完整的两阶段提交流程,分为准备阶段和提交阶段。

  1. 在准备阶段,MySQL 先将数据修改写入 redo log 日志,并将其标记为 prepare 状态,即事务还处于未提交状态。再将对应的 SQL 语句写入 bin log 日志。
  2. 在提交阶段,事务完成提交,MySQL 将 redo log 日志标记为 commit 状态。然后根据 sync_binlog 参数,决定是否将 bin log 刷入磁盘。
    1. sync_binlog=1 时,将 bin log 刷入磁盘。

知道了两阶段提交流程后,我们再来看一下异常崩溃后,mysql 是如何恢复数据的。

  • 若 redo log 日志里记录了完整的事务,即已经处于 commit 状态,则直接提交恢复。
  • 若 redo log 日志里只记录了 prepare 状态的事务,则需要再判断对应的事务 binlog 日志是否存在并日志是否完整:
    • 如果 binlog 存在该事务日志并且是完整的,则提交事务恢复数据。
    • 否则,则回滚事务。

由上诉可知,在 binlog 日志写完,事务在没有 commit 前,mysql 进程发生异常崩溃,此时 mysql 会提交事务会恢复数据。

相关推荐
北城笑笑2 小时前
Server 18 ,Nginx 双服务器 HTTP转HTTPS 代理实战( HTTP 地址换 HTTPS 域名 )
运维·服务器·前端·后端·nginx·http·https
紫洋葱hh2 小时前
Go 入门基础:类型、变量与运算符
开发语言·后端·ai·golang
打工仔折腾 AI2 小时前
Qt网络编程实战:UDP、TCP到HTTP的落地经验与选型
网络·人工智能·后端·python·qt·udp·ai agent 实战
打工仔折腾 AI2 小时前
SQL 编辑器不是高级记事本:KStudio 与 KSQL Developer 的建表与增删改查手法
数据库·人工智能·后端·python·sql·编辑器·ai agent 实战
拖孩3 小时前
# AI 帮我写的小程序,上线不到一个月流量主突然爆了
前端·后端·微信小程序
考虑考虑3 小时前
JFROG手动上传包
运维·后端·自动化运维
Java爱好狂.4 小时前
挑战一周速通Spring+SpringBoot+SpringCloud!
java·后端·spring·springboot·架构师·java面试·java程序员
柠檬味拥抱4 小时前
基于 YOLO11 的 18 类户外生活垃圾智能检测系统:从模型到 Streamlit 全流程实战
后端
得物技术4 小时前
动态规则的 Agent 实践:用确定性工程驾驭 LLM 的资产智能验收
人工智能·后端·llm
柠檬味拥抱4 小时前
基于 YOLO11 的低空空域反无人机预警系统:红外热成像 + Streamlit 全流程实战
后端