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)执行流程的更多相关文章

  1. mysql更新数据时:当想mysql某插入有某字段设置了unique且和之前相同时,会报错,并停止运行

    这个在mysql5.7会报错: 如openid设为unique: 1062 - Duplicate entry 'oTfYq6PKne00IrcTqphmKqKnsahM' for key 'qx_w ...

  2. 详细分析MySQL事务日志(redo log和undo log) 表明了为何mysql不会丢数据

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

  3. MySQL的两种日志类型,redo log,binlog

    文章内容学习:极客时间-林晓彬老师-MySQL实战45讲 整理而得 我们知道MySQL数据库在发生意外宕机的情况下,可以将数据恢复到历史的某个时间点,能实现这个功能依靠的是日志,MySQL提供两种类型 ...

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

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

  5. 【Mysql】三大日志 redo log、bin log、undo log

    @ 目录 redo log(物理日志\重做日志) binlog(逻辑日志/归档日志) update语句执行流程 Uodolog(回滚日志/重做日志) undo log+redo log保证持久性 re ...

  6. 数据库中的两个最重要的日志redo log和binlog

    mysql整体来看其实只有两部分,一部分是server层,一部分是引擎层. 1.redo log(重做日志):当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写入redo log里面,并更新 ...

  7. MySQL(五)中的redo&undo&binlog

    MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log).一 ...

  8. 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 由于 ...

  9. mysql事务(一)——redo log与undo log

    数据事务 即支持ACID四大特性. A:atomicity          原子性——事务中所有操作要么全部执行成功,要么全部执行失败,回滚到初始状态 C:consistency     一致性—— ...

随机推荐

  1. 【九度OJ】题目1475:IP数据包解析 解题报告

    [九度OJ]题目1475:IP数据包解析 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1475 题目描述: 我们都学习过计算机网络, ...

  2. 【LeetCode】478. Generate Random Point in a Circle 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/generate ...

  3. hdu 5592 ZYB's Premutation(线段树优化)

    设f_if​i​​是第ii个前缀的逆序对数,p_ip​i​​是第ii个位置上的数,则f_i-f_{i-1}f​i​​−f​i−1​​是ii前面比p_ip​i​​大的数的个数.我们考虑倒着做,当我们处理 ...

  4. mac学习Python第一天:安装、软件说明、运行python的三种方法

    一.Python安装 从Python官网下载Python 3.x的安装程序,下载后双击运行并安装即可: Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的. MAC 系统一般 ...

  5. 分布式系统(二)——GFS

    分布式存储系统的难点 在存储系统中,为了获得巨大的性能加成,一个很自然的想法就是采用分片(sharding),将数据分割存储到多台服务器上,这样获得了更大的存储容量,而且可以并行地从多台服务器读取数据 ...

  6. ACE_Get_Opt函数笔记

    #include "ace/OS_NS_string.h" #include "ace/Configuration.h" #include "ace/ ...

  7. html简单随机抽奖页面(在线抽奖、随机选取、自动挑选)

    下载: https://download.csdn.net/download/weixin_44893902/20366745 效果: 代码: <!doctype html> <ht ...

  8. Linux_接收文件(rz)和发送文件(sz)

    我们连接linux通常是使用一些ssh工具进行远程访问连接的,在使用过程中,少不了将本地文件上传到linux或将linux上的文件下载到本地,每次使用ftp比较繁琐而且浪费时间.我们可以使用linux ...

  9. react中使用react-transition-group(CSSTransition)

    https://blog.csdn.net/sophie_u/article/details/80093876

  10. python2.7发送邮件失败之——SMTPAuthenticationError问题

    使用python2.7发送邮件,代码如下: from email.header import Headerfrom email.mime.text import MIMETextimport smtp ...