加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL中常见的日志难题有哪些

发布时间:2022-02-19 14:15:28 所属栏目:MySql教程 来源:互联网
导读:小编给大家分享一下MySQL中常见的日志问题有哪些,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧! MySQL 里有两个日志,即:重做日志(redo log)和归档日志(binlog)。 这里,我要先和你解释一个误会式的问题:这个图不就是一个 update 语
       小编给大家分享一下MySQL中常见的日志问题有哪些,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!
 
      MySQL 里有两个日志,即:重做日志(redo log)和归档日志(binlog)。
 
      这里,我要先和你解释一个误会式的问题:这个图不就是一个 update 语句的执行流程吗,怎么还会调用 commit 语句?
 
       通常情况下,你会产生这个疑问的原因,在于把两个“commit”的概念混淆了:
 
问题中的“commit 语句”,是指 MySQL 语法中,用于提交一个事务的命令。一般跟 begin/start transaction 配对使用。
 
而我们图中用到的这个“commit 步骤”,指的是事务提交过程中的一个小步骤,也是最后一步。当这个步骤执行完成后,这个事务就提交完成了。
 
“commit 语句”执行的时候,会包含“commit 步骤”。
 
而我们这个例子里面,没有显式地开启事务,因此这个 update 语句自己就是一个事务,在执行完成后提交事务时,就会用到这个“commit 步骤”。
 
接下来,我们就一起分析一下在两阶段提交的不同时刻,MySQL 异常重启会出现什么现象。
 
如果在图中时刻 A 的地方,也就是写入 redo log 处于 prepare 阶段之后、写 binlog 之前,发生了崩溃(crash),由于此时 binlog 还没写,redo log 也还没提交,所以崩溃恢复的时候,这个事务会回滚。这时候,binlog 还没写,所以也不会传到备库。到这里,我们都可以理解。
 
而我们理解会出现问题的地方,主要集中在时刻 B,也就是 binlog 写完,redo log 还没 commit 前发生 crash,那崩溃恢复的时候 MySQL 会怎么处理?
 
我们先来看一下崩溃恢复时的判断规则。
 
1、如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;
 
2、如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整:
 
a.如果是,则提交事务;
 
b.否则,回滚事务。
 
这里,时刻 B 发生 crash 对应的就是 2(a) 的情况,崩溃恢复过程中事务会被提交。
 
现在,我们就针对两阶段提交再继续延展一下。
 
问题 1:MySQL 怎么知道 binlog 是完整的?
回答:一个事务的 binlog 是有完整格式的:
 
如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;
 
如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。
 
问题 3:处于 prepare 阶段的 redo log 加上完整 binlog,重启就能恢复,MySQL 为什么要这么设计?
 
回答:其实,这个问题还是跟我们在反证法中说到的数据与备份的一致性有关。在时刻 B,也就是 binlog 写完以后 MySQL 发生崩溃,这时候 binlog 已经写入了,之后就会被从库(或者用这个 binlog 恢复出来的库)使用。
 
所以,在主库上也要提交这个事务。采用这个策略,主库和备库的数据就保证了一致性。
 
问题 4:如果这样的话,为什么还要两阶段提交呢?干脆先 redo log 写完,再写 binlog。崩溃恢复的时候,必须得两个日志都完整才可以。是不是一样的逻辑?
 
回答:其实,两阶段提交是经典的分布式系统问题,并不是 MySQL 独有的。

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读