MySQL更新数据时,日志(redo log、binlog)执行流程
1:背景
项目需要做Es和数据库的同步,而手动在代码中进行数据同步又是Es的一些不必要的数据同步操作和业务逻辑耦合,所以使用的了读取mysql的binlog日志的方式进行同步Es的数据。
问题1:根据binlog同步数据的时候会不会出现业务逻辑利用事务操作数据的时候,当事务还没有提交的时候,是否能够读到binlog,也就是binlog的写入时机(是事务提交的之前写,还是事务提交后写)。
问题2:如果事务提交之前写入binlog,那么事务提交之前,事务回滚,那么binlog又会出现什么情况?
首先我们做一下实验(前提是必须要打开binlog),SQL初始化语句
create table user
(
id bigint not null auto_increment
primary key,
name varchar(64) null,
status tinyint(1) null
);
insert into user (name,status)values ('张三',1);
set autocommit = 0;
2.1:事务提交对binlog的影响
我们先确定一下MySQL执行更新SQL语句之后,执行commit命令前后,binlog会有什么变化。
然后我们先使用 show master status 看一下binlog的位置

然后我们执行一下更新语句
update user set status = status + 1;
再次使用 show master status 查看发现并没有Position并没有变,执行commit命令之后,发现Position由141169变为了141506,说明从库只有在主库提交之后才能读到主库写入的binlog日志。

2.2:事务回滚对binlog的影响
我们再确定一下MySQL执行更新SQL语句之后,执行rollback命令前后,binlog会有什么变化。
然后我们先使用 show master status 看一下binlog的位置

然后我们执行一下更新语句
update user set status = status + 1;
再次使用 show master status 查看发现并没有Position并没有变,执行rollback命令之后,发现Position仍然没有变化,说明事务回滚之后binlog并不会写入磁盘。

难道binlog是在事务提交之后才写入磁盘的嘛?那redo log 又是什么时候写入磁盘的呢?有上面的问题又引发一系列的问题,带着这些问题,我们来进行mysql日志的深入学习。
3:MySQL更新数据的执行流程
首先我们要先了解一下当我们做一条数据的更新操作的时候,数据库的底层到底是如何执行的?
MySQL更新数据执行流程:
1:判断数据页是否在内存中,若为否,则从磁盘读取数据到内存中,返回数据行
2:若是数据页在内存中,则直接返回数据行
3:执行数据更新操作
4:数据写入内存,同时redolog写入到内存
5:执行commit操作(此commit是SQL命令操作,而不是数据的commit状态)
6:执行commit命令之后,则进行两段提交操作。
6.1:写入内存中的redolog到磁盘中,此时redolog处于prepare状态
6.2:写入binlog到磁盘
6.3:提交事务,此时事务处于commit状态
7:结束。
注:以上操作为参数innodb_flush_log_at_trx_commit 为1和sync_binlog为1的时候。
对应MySQL的更新语句执行流程图,如图1-1。

redo log:被称之为重做日志,是在数据库发生意外时,进行数据恢复,redo log会备份是事务执行过程中的修改数据。
binlog: 被称为归档日志,是一个二进制格式的文件,用于记录用户对数据库更新的SQL语句信息,格式分为(statement、row、mixed)
redo log 和binlog的差异如下表:
| redo log | binlog |
|---|---|
| InnoDB引擎 | MySQL Serve |
| 物理日志 | 逻辑日志 |
| 循环写入 | 追加写入 |
MySQL执行commit命令之后是使用两段提交的办法来保证事物的原子行的,至于为什么使用两段提交,而不是其他的提交方式,由于篇幅有限,不做多余解释,请参考自行查询资料。
到目前为止,关于上面binlog的问题也就迎刃而解了,
对于问题一:MySQL中binlog在事务提交之前会写入redo log和binlog到内存中,在执行commit命令之后进行两段提交操作,将redo log和binlog写入磁盘,因此在事务提交之前不能读取到binlog日志(前提binlog没有进行被动刷盘)。
对于问题二:binlog是在执行commit命令之后进行的刷盘,但是是在事务在commit状态之前写入的磁盘。根据上面的实验可以看出,事务回滚对于binlog并没有什么影响。
小结:在执行commit命令前,执行更新数据到内存之后,那么就会写入redo log和binlog到 redo log buffer和binlog buffer中,当执行了commit命令之后,就是进行两段提交操作,然后进行redo log和binlog写入磁盘操作。
关于MySQL的日志刷盘机制是由参数innodb_flush_log_at_trx_commit 和sync_binlog控制的,具体请参考下一篇文章。
4:commit命令和commit状态区别解释
我们上面说的commit命令是指MySQL语法中的commit命令,用于提交事务,一般跟 begin/start transaction 配对使用。
而我们图中用到的这个“commit 步骤”,指的是事务提交过程中的一个小步骤,也是最后一步。当这个步骤执行完成后,这个事务就提交完成了。
“commit 命令”执行的时候,会包含“commit 步骤”。
MySQL更新数据时,日志(redo log、binlog)执行流程的更多相关文章
- mysql更新数据时:当想mysql某插入有某字段设置了unique且和之前相同时,会报错,并停止运行
这个在mysql5.7会报错: 如openid设为unique: 1062 - Duplicate entry 'oTfYq6PKne00IrcTqphmKqKnsahM' for key 'qx_w ...
- 详细分析MySQL事务日志(redo log和undo log) 表明了为何mysql不会丢数据
innodb事务日志包括redo log和undo log.redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作. undo log不是redo log的逆向过程,其实它 ...
- MySQL的两种日志类型,redo log,binlog
文章内容学习:极客时间-林晓彬老师-MySQL实战45讲 整理而得 我们知道MySQL数据库在发生意外宕机的情况下,可以将数据恢复到历史的某个时间点,能实现这个功能依靠的是日志,MySQL提供两种类型 ...
- 详细分析MySQL事务日志(redo log和undo log)
innodb事务日志包括redo log和undo log.redo log是重做日志,提供前滚操作,undo log是回滚日志,提供回滚操作. undo log不是redo log的逆向过程,其实它 ...
- 【Mysql】三大日志 redo log、bin log、undo log
@ 目录 redo log(物理日志\重做日志) binlog(逻辑日志/归档日志) update语句执行流程 Uodolog(回滚日志/重做日志) undo log+redo log保证持久性 re ...
- 数据库中的两个最重要的日志redo log和binlog
mysql整体来看其实只有两部分,一部分是server层,一部分是引擎层. 1.redo log(重做日志):当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写入redo log里面,并更新 ...
- MySQL(五)中的redo&undo&binlog
MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log).一 ...
- mysql报错Ignoring the redo log due to missing MLOG_CHECKPOINT between
mysql报错Ignoring the redo log due to missing MLOG_CHECKPOINT between mysql版本:5.7.19 系统版本:centos7.3 由于 ...
- mysql事务(一)——redo log与undo log
数据事务 即支持ACID四大特性. A:atomicity 原子性——事务中所有操作要么全部执行成功,要么全部执行失败,回滚到初始状态 C:consistency 一致性—— ...
随机推荐
- 【LeetCode】133. Clone Graph 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS BFS 日期 题目地址:https://le ...
- 【LeetCode】Pascal's Triangle II 解题报告
[LeetCode]Pascal's Triangle II 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/pascals-tr ...
- SOFA 通信
私有通信协议设计: 我们的分布式架构,所需要的内部通信模块,采用了私有协议来设计和研发. 可以有效地利用协议里的各个字段 灵活满足各种通信功能需求:比如 CRC 校验,Server Fail-Fast ...
- MongoDB基本介绍与安装(1)
MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功 ...
- 【优雅代码】03-optional杜绝空指针异常
[优雅代码]03-optional杜绝空指针异常 欢迎关注b站账号/公众号[六边形战士夏宁],一个要把各项指标拉满的男人.该文章已在github目录收录. 屏幕前的大帅比和大漂亮如果有帮助到你的话请顺 ...
- 分布式抽奖秒杀系统,DDD架构设计和实现分享
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.用大项目,贯穿知识体系 写CRUD.堆API.改屎山⛰,熬多少个996也只是成为重复的螺丝 ...
- 《Python核心编程第3版中文版》(高清).PDF,免费无需任何解压密码
链接:https://pan.baidu.com/s/18d3xinNX1oH5q8zpB10ABA 提取码:dx7h
- 移动端调试 - UC浏览器开发者版 - WIFI
Chrome 功能特性 支持PC或Pad设备,实时调试手机网页 DOM.CSS.JS调试 多功能面板满足多种调试需求 1 准备工作 保证手机与PC处于同一个无线网段. 下载Android平台的U ...
- v4l2数据获取流程
V4L2数据获取流程 整个过程相关的数据结构有如下几个: struct v4l2_capability m_cap; /* 驱动能力 */ struct v4l2_format m_fmt; /* 数 ...
- STM32新建模板之寄存器
创建寄存器的项目模板相对比较简单,这里是基于库文件的模板进行更改的,有不明白的小伙伴可以浏览STM32新建模板之库文件. 一.项目文件 拷贝库文件的工程模板重命名为"stm32f10x_re ...