先放一下两阶段提交的图,在后续问题中会用到:

问题

在MySQL 02中,讲到为什么要使用两阶段提交时用的是反证法,说明了如果不使用两阶段提交,会导致MySQL出现主备数据不一致等问题。

那么如果在两阶段提交的不同瞬间,MySQL如果发生异常重启,是怎么保证数据完整性的呢?

如果在图中时刻A,也就是写入redo log后、写binlog前发生了崩溃,由于此时binlog还没写,redo log也还没提交,所以崩溃恢复的时候,该事务会回滚。因为binlog还没写,也不会传到备库。

如果在图中时刻B,也就是binlog写完,redo log还没commit前发送崩溃,会怎么样呢?

先看一下崩溃恢复时的判断规则:

  • 如果redo log里的事务是完整的,也就是已经有commit标识,则直接提交;

  • 如果redo log里的事务只有完整的prepare,则判断对应的事务binlog是否存在并完整:

    • 是,则提交事务;

    • 否,回滚事务。

因此,时刻B崩溃恢复过程中事务会被提交。

追问1:MySQL怎么知道binlog是完整的?

一个事务的binlog有完整的格式:

  • statement格式的binlog,最后会有COMMIT语句;

  • row格式的binlog,最后会有一个XID event作为标识。

在MySQL 5.6.2 版本后,还引入了binlog-checksum参数,用来验证binlog内容的正确性。对于binlog日志由于磁盘原因可能在日志中间出错的情况,MySQL可以通过校验该参数的结果来发现。

追问2:redo log和binlog是怎么关联起来的?

两者有一个共同的数据字段XID。崩溃恢复的时候,会按顺序扫描redo log:

  • 如果碰到既有prepare,又有commit的redo log,就直接提交;

  • 如果碰到只有prepare,而没有commit的redo log,就拿着XID去binlog找对应的事务。

追问3:为什么设计为,prepare的redo log+完整binlog,重启就能恢复?

这个问题也与数据与备份的一致性有关。在时刻B,binlog已经写完,之后会被从库使用,因此在主库上也要提交这个事务,才能做到一致性。

追问4:如果这样为什么还要两阶段提交?为什么不先把redo log写完,再写binlog。而等崩溃恢复要求两个日志都完整?

两阶段提交是经典的分布式系统问题,并不是MySQL独有的。如果必须要说明这样设计的原因,那就是事务的持久性问题。

对于InnoDB来说,如果redo log提交完成,事务就不能回滚。而如果redo log直接提交,然后binlog写入失败,InnoDB又无法回滚,那么数据和binlog又不一致了。

追问5:只用binlog来支持崩溃恢复可以吗?

即把流程改为:… -> 数据更新到内存 -> 写binlog -> 提交事务。

答案是不可以的。

从历史原因说,InnoDB不是MySQL的原生存储引擎,而MyISAM设计之初就没有支持崩溃恢复。

从实现上说,如果只用binlog:

如图,假如在binlog2写完但整个事务还没有commit时,MySQL发生crash,重启后引擎内部事务2会回滚,但对于事务1来说,系统认为已经提交完成,不会再应用一次binlog1。

如果InnoDB使用的是WAL技术,执行事务的时候,写完内存和日志,事务就算完成。如果之后崩溃,要依赖日志来恢复数据页。那么这种情况下,由于不应用binlog1,事务1也可能丢失,而且是数据页级别的丢失。此时,binlog里没有记录数据页的更新细节,是补不回来的。

追问6:那能只用redo log,不要binlog吗?

如果只从崩溃恢复的角度来说是可以的。

使用binlog主要是它有着redo log无法替代的功能:

  • 归档。redo log是循环写,历史日志无法保留,起不到归档的作用。

  • MySQL高可用的基础就是binlog复制。

  • 很多公司有异构系统,这些系统靠消费MySQL的binlog来更新自己的数据。关掉binlog的话,这些下游系统就没法输入。

追问7:redo log一般设置多大?

如果redo log太小,会导致很快写满。

对于几个TB的磁盘,一般将redo log设置为4个文件,每个文件1GB。

追问8:正常运行的实例,数据写入后的最终落盘,是从redo log更新过来的还是从buffer pool更新过来的?

redo log并没有记录数据页的完整数据,所以它并没有能力自己去更新磁盘数据页,也就不存在“数据最终落盘,是由redo log更新过去”的情况。

  • 如果是正常运行的实例,数据页被修改以后,跟磁盘的数据页不一致,称为脏页。最终数据落盘,就是把内存中的数据页写盘;

  • 在崩溃恢复场景,如果一个数据页在崩溃恢复时丢失了更新,InnoDB会将其读到内存,然后让redo log更新内存内容。更新完成后,同上。

追问9:redo log buffer是什么?在写入时,是先修改内存,还是先写redo log文件?

redo log buffer是一块内存,是在事务还没commit时,先保存redo日志内容的。

真正把日志写到redo log文件(文件名为ib_logfile+数字),是在执行commit语句时候完成的。

MySQL 15 日志相关问题追问的更多相关文章

  1. MySQL的日志相关内容

    本篇文章介绍一下mysql的备份和日志,由于备份时需要用到日志,所以在讲备份前,如果日志内容篇幅过长,将会把日志和备份分开单独来讲,先简单介绍一下mysql的日志相关内容. MySQL日志 日志是my ...

  2. MySQL重做日志相关

      Ⅰ.事务的实现 这里我们先抛出答案,通过答案再展开分析 特性 实现 A(原子性) redo C(一致性) undo I(隔离性) lock D(持久性) redo/undo 本节针对redo展开分 ...

  3. MySQL二进制日志总结

    二进制日志简单介绍 MySQL的二进制日志(binary log)是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的MySQL语句.二进制日志(binary log)中记录了对MySQL数据 ...

  4. mysql慢查询日志相关参数

    -- mysql慢查询日志相关参数 -- 慢查询日志时间 show variables like "long_query_time"; -- 将时间设置为2s ; -- 是否开启慢 ...

  5. MySQL各类日志文件相关变量介绍

    文章转自:http://www.ywnds.com/?p=3721 MySQL各类日志文件相关变量介绍 查询所有日志的变量   1 mysql> show global variables li ...

  6. MySQL的日志(一)

    本文目录:1.日志刷新操作2.错误日志3.一般查询日志4.慢查询日志5.二进制日志 5.1 二进制日志文件 5.2 查看二进制日志 5.2.1 mysqlbinlog 5.2.2 show binar ...

  7. MySQL的日志(二):事务日志

    本文目录:1.redo log 1.1 redo log和二进制日志的区别 1.2 redo log的基本概念 1.3 日志块(log block) 1.4 log group和redo log fi ...

  8. 详细分析MySQL的日志(一)

    官方手册:https://dev.mysql.com/doc/refman/5.7/en/server-logs.html 不管是哪个数据库产品,一定会有日志文件.在MariaDB/MySQL中,主要 ...

  9. 详细分析MySQL事务日志(redo log和undo log)

    innodb事务日志包括redo log和undo log.redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作. undo log不是redo log的逆向过程,其实它 ...

  10. 【MySQL (六) | 详细分析MySQL事务日志redo log】

    Reference:  https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html 引言 为了最大程度避免数据写入时 IO ...

随机推荐

  1. P7404题解

    分析题意: 题意就是让前半段序列呈上升趋势,后半段呈下降趋势. 解题方法: 考虑差分出序列的高度. xix_ixi​ 表示以 iii 为 kkk 的前半段需增加量. yiy_iyi​ 表示以 i−1i ...

  2. 一个Controller网关根据请求参数和版本号调用分发多个Service和方法

    一个Controller网关根据请求参数和版本号分发Service 公司原有项目就是根据请求参数进行分发逻辑的,这次想着通过反射加入了版本号的分发,减轻各种版本的业务代码逻辑耦合度. 在一个项目中需要 ...

  3. Windows 提权指南

    男儿若遂平生志,五经勤向窗前读. 导航 壹 - Se 特权 贰 - RunAs 叁 - 弱服务 肆 - Windows 内核 伍 - 密码搜寻 陆 - 杂项 AlwaysInstallElevated ...

  4. 代码随想录第一天 | Leecode 704 二分查找、27 移除元素、977 有序数组的平方

    前言 今天是我开始刷Leecode的第一天,同时这也是开通博客园第一篇博客.我希望能在每篇博客中记录下我做出每一道题的过程,为此我想先说明一下我的博客内容的结构. 题目描述:首先说明题目的要求以及测试 ...

  5. 【经验】Git|Linux终端git太慢,改hosts、复制文件夹、用镜像源?不不不不不

      有个同学问我Linux下想要克隆一个仓库怎么办,并给我发了一个word,记录了他的操作.看完之后我的血压都上来了,遂记之.   下文分成两种情况,克隆一两个仓库,和克隆一大堆仓库. 文章目录 一. ...

  6. 【HUST】网安|多媒体数据安全实验|LSB隐写和DCT域JSTEG+F4+F5隐写及检测

    文章目录 LSB空域隐写 原理 值对现象原理 实验内容 DCT域隐写 JSteg F4 F5 代码仓库:代码.嵌入提取使用的图像.jpeg_tool库.实验报告_Gitee. 实验环境:MATLAB ...

  7. IDEA设置之“代码提示不区分大小写”

    作用 代码提示不区分大小写 案例1 案例2

  8. vue3 基础-常用模板语法

    一个 vue 的单文件 SAP ( single page web application ) 即在一个 .vue 为后缀的文件中, 会包含3个部分. 模板: html 逻辑: javascript ...

  9. React-Native开发鸿蒙NEXT-本地与沙盒加载bundle

    React-Native开发鸿蒙NEXT-本地与沙盒加载bundle 来晚了来晚了,不是想偷懒,实在是一个图片问题没搞定导致效果出不来,今天刚靠工具查出了原因. RN的加载无非本地加载与沙盒加载两种方 ...

  10. 第6讲、全面拆解Encoder、Decoder内部模块

    全面拆解 Transformer 架构:Encoder.Decoder 内部模块解析(附流程图小测验) 关键词:Transformer.Encoder.Decoder.Self-Attention.M ...