上一篇mysql面试的文章以后收到很多朋友的意见,但愿深刻讲讲复制、日志的格式这些,今天,咱们就来深挖一下mysql的复制机制到底有哪一些,以及binlog和relay-log的结构究竟是什么样子的。mysql
binlog的主要做用是记录数据库中表的更改,它只记录改变数据的sql,不改变数据的sql不会写入,好比select语句通常不会被记录,由于他们不会对数据产生任何改动。面试
用一个实际的场景看下binlog产生的过程,准备sql: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表明事件的类型。ui
Server_id是建立事件的服务器ID。spa
End_log_pos表明事件在文件中的结束位置,以上面为例,第一次查询的结束位置是723,第二次insert以后文件的开始位置就是从723开始。
Info表明事件信息,是一段可读的文本内容。
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[50] 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事件由3个部分组成:
从上面的例子咱们也能够看出来,binlog并不是只有一个,而基于真实的场景来讲,始终写一个binlog文件确定也是不可取的,而binlog轮换主要有3个场景:
随着时间的推移,咱们的binlog文件会愈来愈多,这时候有两种方式能够清除binlog:
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都是存在的状况:
可是在这里IO和SQL线程有会产生重复事件的问题,举一个场景:
既然会有这个问题还为何要这样作呢?假设反过来,先更新master.info再记录中继日志,这样带来的问题就是丢失数据了。而mysql认为丢失比重复更严重,因此要先刷新日志,保大仍是保小mysql帮你作了决定。
- END -