前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL架构(三)mysql的两阶段提交

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

作者头像
鳄鱼儿
发布2024-05-21 17:15:47
930
发布2024-05-21 17:15:47
举报

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 会提交事务恢复数据。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Mysql 的两阶段提交
    • 情况1: 先写入 redo log 日志;再写入 binlog 日志
      • 情况 2: 先写入 binlog 日志;再写入 redo log 日志
      • 两阶段过程异常崩溃处理
      相关产品与服务
      云数据库 MySQL
      腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档