再深入一点|binlog和relay-log到底长啥样?
上一篇mysql面试的文章之后收到不少朋友的意见,希望深入讲讲复制、日志的格式这些,今天,我们就来深挖一下mysql的复制机制到底有哪一些,以及binlog和relay-log的结构到底是什么样子的。
binlog作用
binlog的主要作用是记录数据库中表的更改,它只记录改变数据的sql,不改变数据的sql不会写入,比如select语句一般不会被记录,因为他们不会对数据产生任何改动。
用一个实际的场景看下binlog产生的过程,准备sql:
create table test(text varchar(20));
insert into test values ('test_text');
select * from test;
flush logs;
查看binlog
show binlog events in 'binlog.000029';
显示的结果如下:
另外,也可以使用mysqlbinlog工具来查看binlog的内容:
show variables like 'log_%'; #查看日志目录
mysqlbinlog --short-form --force-if-open --base64-output=never /usr/local/var/mysql/binlog.000029
从日志我们可以看到执行了创建表的语句以及一个Format_desc头和Ratate轮换事件,这个我们会在后面讲到,先看几个字段代表的含义。
Log_name代表日志文件的名称,比如我这里的查询是直接查询binlog.000029,默认的写法是show binlog events,但是这样只会查询到第一个binlog,并不是当前激活状态的binlog,如果你不知道binlog有哪些,可以用命令:
show binary logs; #查看binlog列表
show master status; #查看最新的binlog
Pos代表文件开始的位置。
Event_type代表事件的类型。
Server_id是创建事件的服务器ID。
End_log_pos代表事件在文件中的结束位置,以上面为例,第一次查询的结束位置是723,第二次insert之后文件的开始位置就是从723开始。
Info代表事件信息,是一段可读的文本内容。
binlog日志结构
binlog日志的结构大概是长这样的,它由索引文件和binlog文件组成,其中binlog事件又包含通用头、提交头和事件体3个部分组成。
首先说说索引文件,索引文件的每一行都包含了一个binlog文件的完整文件名(类似host-bin.001),一些命令比如flush logs将所有日志写入磁盘会影响到索引文件。
每个binlog文件以若干个binlog事件组成,以格式描述事件(Format_description)作为文件头(上面的binlog图片Format_desc事件),以日志轮换事件(rotate)作为文件尾。
Format_description包含binlog文件的服务器信息、文件状态的关键信息等。如果服务器关闭或者重启,则会创建一个新的binlog文件,同时写入一个新的format_description。他的格式大致如下。
2 binlog-version
string[] mysql-server version
4 create timestamp
1 event header length
string[p] event type header lengths
日志轮换事件则包含下一个binlog的文件名以及开始读取的位置,它由服务器写完binlog后添加到文件尾,轮换事件并不会每次都存在,格式如下。
if binlog-version > 1 {
8 position
}
string[p] name of the next binlog
binlog事件包含若干个事务组成的组(group),每个组对应一个事务,如果是create alter语句不属于事务语句的话,则他们本身就是一个组,每个组要么全部执行,要么都不执行。
binlog事件结构
每个binlog事件由3个部分组成:
- 通用头,包含binlog中所有事件具备的基本信息。
- 提交头,对于不同类型的事件来说,提交头的内容也不尽相同
- 事件体,存储事件的主要数据,同样对于不同类型事件也不同。
binlog轮换和清理
从上面的例子我们也可以看出来,binlog并非只有一个,而基于真实的场景来说,始终写一个binlog文件肯定也是不可取的,而binlog轮换主要有3个场景:
- 服务器启动,每次服务器启动都会生成一个新的binlog文件。
- 达到最大大小,可以通过binlog-cache-size控制大小,达到最大大小后将更换。
- 显示刷新,flush logs将所有日志写入磁盘,这时候会创建一个新的文件写入,从第一个例子也能看出来执行完之后生成了一个新的日志binlog.000030的文件并且开始的位置是4。
随着时间的推移,我们的binlog文件会越来越多,这时候有两种方式可以清除binlog:
- 通过设置expire-logs-days控制想保留的binlog日志文件天数,系统将会自动清理。
- 通过PURGE BINARY LOGS手动清理
relay-log结构
relay-log中继日志是连接master和slave的核心,我们来深入了解一下它的结构和使用。
relay-log的结构和binlog非常相似,只不过他多了一个master.info和relay-log.info的文件。
master.info记录了上一次读取到master同步过来的binlog的位置,以及连接master和启动复制必须的所有信息。
relay-log.info记录了文件复制的进度,下一个事件从什么位置开始,由sql线程负责更新。
上一篇文章我们提到了整个复制流程的过程大概是这个样子:
知道binlog和relay-log的结构之后,我们重新梳理一下整个链路的流程,这里我们假定master.info和relay-log.info都是存在的情况:
- Master收到客户端请求语句,在语句结束之前向二进制日志写入一条记录,可能包含多个事件。
- 此时,一个Slave连接到Master,Master的dump线程从binlog读取日志并发送到Slave的IO线程。
- IO线程从master.info读取到上一次写入的最后的位置。
- IO线程写入日志到relay-log中继日志,如果超过指定的relay-log大小,写入轮换事件,创建一个新的relay-log。
- 更新master.info的最后位置
- SQL线程从relay-log.info读取进上一次读取的位置
- SQL线程读取日志事件
- 在数据库中执行sql
- 更新relay-log.info的最后位置
- Slave记录自己的binlog日志
但是在这里IO和SQL线程有会产生重复事件的问题,举一个场景:
- 先记录中继日志,然后更新master.info位置
- 此时服务器崩溃,写入master.info失败
- 服务器恢复,再次同步从master.info获取到的是上一次的位置,会导致事件重复执行
既然会有这个问题还为什么要这样做呢?假设反过来,先更新master.info再记录中继日志,这样带来的问题就是丢失数据了。而mysql认为丢失比重复更严重,所以要先刷新日志,保大还是保小mysql帮你做了决定。
- END -
再深入一点|binlog和relay-log到底长啥样?的更多相关文章
- 漫画赏析:Linux 内核到底长啥样(转)
知乎链接:https://zhuanlan.zhihu.com/p/51679405 来自 http://TurnOff.us 的漫画 “InSide The Linux Kernel” 本文转载自: ...
- 【随笔】CLR:.net的类型,内部到底长啥样?
前言 一提到.net的类型,首当其冲的就是“引用类型”.“值类型”:我们在面试中,也会经常被问“来说说值类型和引用类型....”,这时候第一反应就是:“哎呀,这还不简单,值类型是传递的值的copy,值 ...
- 不知道Linux内核到底长啥样?这幅漫画让你秒懂!
下面给大家分享一个[超全2020Linux学习教程],点击链接免费领取哦~ https://www.magedu.com/?p=84301&preview=true
- Linux 内核到底长啥样
目录 一.简介 二.结构 地基 地面层 进程表 http进程 21进程 22进程 到文件系统 定时任务 管道 411进程 跃层 一.简介 今天,我来为大家解读一幅来自 TurnOff.us 的漫画 & ...
- 用漫画了解Linux内核到底长啥样
一个执着于技术的公众号 原文链接:http://985.so/hRL6 往期精彩 ◆ 干货 | 给小白的Nginx10分钟入门指南 ◆ 什么是集群?看完这篇你就知道啦! ◆ 干货 | Linux ...
- master log 与relay log的关系
--master log 与relay log的关系 -------------------------------2014/06/09 Just to clarify, there are thre ...
- 3000帧动画图解MySQL为什么需要binlog、redo log和undo log
全文建立在MySQL的存储引擎为InnoDB的基础上 先看一条SQL如何入库的: 这是一条很简单的更新SQL,从MySQL服务端接收到SQL到落盘,先后经过了MySQL Server层和InnoDB存 ...
- Slave SQL_THREAD如何重放Relay log
复制的介绍: 根据日志定义的模式不一样,可以分为:Statement(SBR)模式,Row(RBR)格式或者是MIXED格式,记录最小的单位是一个Event,binlog日志前4个字节是一个magic ...
- DM 源码阅读系列文章(六)relay log 的实现
2019独角兽企业重金招聘Python工程师标准>>> 作者:张学程 本文为 DM 源码阅读系列文章的第六篇,在 上篇文章 中我们介绍了 binlog replication 处理单 ...
随机推荐
- 【Java】JavaMail 554错误解决方法
一.解决连续发送多次 // 构件MimeMessage 对象,并设置在发送给收信人之前给自己(发送方)抄送一份 MimeMessage msg = mailSender.createMimeMessa ...
- 微博AnalysisQl动态数据视图元数据设计
前言 目前,AnalysisQl 数据视图的元数据(维度.指标.指标计算器)需要通过代码(API)或资源文件的形式硬编码,应用启动时,按照声明的顺序依次注册.这种模式下,数据视图是 静态 的,任何一项 ...
- github渗透测试工具库
本文作者:Yunying 原文链接:https://www.cnblogs.com/BOHB-yunying/p/11856178.html 导航: 2.漏洞练习平台 WebGoat漏洞练习平台: h ...
- Mybatis如何在插入(ID是后台生成的)后返回ID?
获得ID方法:
- Storm与SparkStreaming对比
Storm与SparkStreaming对比 ◆ Spark Streaming 批处理的性能比Storm高出几十倍.◆ Streaming采用小批量模式,Storm是一条消息一条消息的计算.◆ St ...
- dcoker 小应用(二)
sudo yum install epel-release vi /etc/yum.repos.d/epel.repo use base url instead of mirror url ...
- Spring MVC 的运行流程
1.用户发送请求到DispatcherServlet 2.DispatcherServlet调用处理器映射器(HanderMapping)找到处理器 3.处理器映射器(HanderMapping)返回 ...
- Dubbo直连方式改造
目录 一.dubbo 服务化最佳实践 1. 分包 2. 粒度 3. 版本 二.改造 dubbo 项目 三.link-interface 1. pom.xml 2. 实体类 3. 公共接口 四.提供者 ...
- Java中动态规则的实现方式
背景 业务系统在应用过程中,有时候要处理“经常变化”的部分,这部分需求可能是“业务规则”,也可能是“不同的数据处理逻辑”,这部分动态规则的问题,往往需要可配置,并对性能和实时性有一定要求. Java不 ...
- sql 游标(理论)
游标是处理结果集的一种机制 --声明游标 --ISO 语法 DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR FOR select_state ...