1,dump协议:

根据数据库的ip+port创建socket,如果创建成功,说明链接建立成功,接下来是使用dump协议订阅binlog

链接建立成功之后,服务端会主动向客户端发送如下问候信息greeting(可以理解为经java转换后,是一个java对象),

在下面的代码中可以看到greeting中的信息:

this.context.setServerStatus(greeting.getServerStatus());//
this.context.setServerVersion(greeting.getServerVersion().toString());
this.context.setServerCollation(greeting.getServerCollation());
this.context.setServerCapabilities(greeting.getServerCapabilities());
this.context.setThreadId(greeting.getThreadId());
this.context.setProtocolVersion(greeting.getProtocolVersion());
this.context.setScramble(greeting.getScramble1().toString() + greeting.getScramble2().toString()); 然后如下:
将ctx=this.context;
final XSerializer s = new XSerializer(64);
s.writeInt(buildClientCapabilities(), 4);
s.writeInt(this.maximumPacketLength, 4);
s.writeInt(this.clientCollation > 0 ? this.clientCollation : ctx.getServerCollation(), 1);
s.writeBytes((byte)0, 23); // Fixed, all 0
s.writeNullTerminatedString(StringColumn.valueOf(this.user.getBytes(this.encoding)));
s.writeInt(20, 1); // the length of the SHA1 encrypted password
s.writeBytes(MySQLUtils.password41OrLater(this.password.getBytes(this.encoding), ctx.getScramble().getBytes(this.encoding)));
if(this.initialSchema != null) s.writeNullTerminatedString(StringColumn.valueOf(this.initialSchema.getBytes(this.encoding))); //transport可以理解为是一个socket的包装后的东西
final RawPacket request = new RawPacket();
request.setSequence(1);
request.setPacketBody(s.toByteArray());
request.setLength(request.getPacketBody().length);
transport.getOutputStream().writePacket(request);
transport.getOutputStream().flush(); 然后可以在下面的代码中得到mysql的相应:
final Packet response = transport.getInputStream().readPacket();
if(response.getPacketBody()[0] == ErrorPacket.PACKET_MARKER) {
final ErrorPacket error = ErrorPacket.valueOf(response);
LOGGER.info("login failed, user: {}, error: {}", this.user, error);
throw new TransportException(error);
} else if(response.getPacketBody()[0] == OKPacket.PACKET_MARKER) {
final OKPacket ok = OKPacket.valueOf(response);
LOGGER.info("login successfully, user: {}, detail: {}", this.user, ok);
} else {
LOGGER.warn("login failed, unknown packet: ", response);
throw new RuntimeException("assertion failed, invalid packet: " + response);
} 2,dump报文格式:

下方表格来自mysql官网链接:http://dev.mysql.com/doc/internals/en/mysql-packet.html

Type Name Description
int<3> payload_length Length of the payload. The number of bytes in the packet beyond the initial 4 bytes that make up the packet header.
int<1> sequence_id Sequence ID
string<var> payload [len=payload_length] payload of the packet
报文对超大packet的支持方式如下:

当一个packet过大 (超过1<<24-1byte ~= 16 MB) 时, 传输需要对packet进行切割, 参看这里

注意, 在A上生成binlog时, 是可以容纳大于16MB的packet的, 也就是原binlog里存在超大的event, 需要在传输时加以限制

切割packet没什么特别之处, 仅需要注意包格式, 一个20MB的event的传输packet格式举例为 (此处用16MB便于描述, 应为1<<24-1byte):

    packet 1
4字节 packet header
1字节 值为[00], 是binlog event的特征标志
16MB-1字节 为第一段数据 packet 2
4字节 packet header
20MB-16MB+1字节 为第二段数据

需要注意的是之后的packet时不带有[00]特征位的. 而包的大小计算范围为除去前4字节的全部字节

上面的讲解对应的代码为:

// Parse packet
final int packetLength = is.readInt(3);
final int packetSequence = is.readInt(1);//超大数据包切割后的顺序
is.setReadLimit(packetLength); // Ensure the packet boundary //
final int packetMarker = is.readInt(1);//特征位
if(packetMarker != OKPacket.PACKET_MARKER) { // 0x00
if((byte)packetMarker == ErrorPacket.PACKET_MARKER) {
final ErrorPacket packet = ErrorPacket.valueOf(packetLength, packetSequence, packetMarker, is);
throw new RuntimeException(packet.toString());
} else if((byte)packetMarker == EOFPacket.PACKET_MARKER) {
final EOFPacket packet = EOFPacket.valueOf(packetLength, packetSequence, packetMarker, is);
throw new RuntimeException(packet.toString());
} else {
throw new RuntimeException("assertion failed, invalid packet marker: " + packetMarker);
}
}

接下来直接解析mysql binlog即可,header获取如下:

// Parse the event header
final BinlogEventV4HeaderImpl header = new BinlogEventV4HeaderImpl();
header.setTimestamp(is.readLong(4) * 1000L);//timestamp
header.setEventType(is.readInt(1));//type_code
header.setServerId(is.readLong(4));//server_id
header.setEventLength(is.readInt(4));//event_length
header.setNextPosition(is.readLong(4));//next_position
header.setFlags(is.readInt(2));//flags
header.setBinlogFileName(this.binlogFileName);
header.setTimestampOfReceipt(System.currentTimeMillis()); body的解析不同事件格式不一样,类似header那样取值 注:代码来自开源项目open replicator

mysql binlog解析概要的更多相关文章

  1. MySQL Binlog 解析工具 Maxwell 详解

    maxwell 简介 Maxwell是一个能实时读取MySQL二进制日志binlog,并生成 JSON 格式的消息,作为生产者发送给 Kafka,Kinesis.RabbitMQ.Redis.Goog ...

  2. MySQL Binlog解析

    https://yq.aliyun.com/articles/238364?spm=5176.8067842.tagmain.52.73PjU3 摘要: 概述 MySQL的安装可以参考:Linux(C ...

  3. MySQL Binlog解析(1)

    一.Binlog File Binlog files start with a Binlog File Header followed by a series of Binlog Event Binl ...

  4. MySQL Binlog解析(2)

    一.TABLE_MAP_EVENT Used for row-based binary logging beginning with MySQL 5.1.5.The TABLE_MAP_EVENT d ...

  5. 采用OpenReplicator解析MySQL binlog

    Open Replicator是一个用Java编写的MySQL binlog分析程序.Open Replicator 首先连接到MySQL(就像一个普通的MySQL Slave一样),然后接收和分析b ...

  6. MySQL Binlog 介绍

    Binlog 简介 MySQL中一般有以下几种日志: 日志类型 写入日志的信息 错误日志 记录在启动,运行或停止mysqld时遇到的问题 通用查询日志 记录建立的客户端连接和执行的语句 二进制日志 记 ...

  7. Mysql binlog日志解析

    1. 摘要: Mysql日志抽取与解析正如名字所将的那样,分抽取和解析两个部分.这里Mysql日志主要是指binlog日志.二进制日志由配置文件的log-bin选项负责启用,Mysql服务器将在数据根 ...

  8. MySQL binlog的格式解析

    我搜集到了一些资料,对理解代码比较有帮助. 在头文件中binlog_event.h中,有描述 class Log_event_header class Log_event_footer 参见[Myst ...

  9. 腾讯工程师带你深入解析 MySQL binlog

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 本文由 腾讯云数据库内核团队 发布在云+社区 1.概述 binlog是Mysql sever层维护的一种二进制日志,与innodb引擎中的red ...

随机推荐

  1. Unsupported Media Type 415问题解决办法(Ajax)

    场景:Ajax传一个json对象到服务器,让参数自动封装至与json对象匹配的java对象中. 错误类型 错误类型1: "status":415 "error" ...

  2. JSP中的include的两种用法

    1.两种用法 <%@ include file=” ”%> <jsp:include page=” ” flush=”true”/> 2.用法区别 (1)执行时间上区别 < ...

  3. Google Go 语言从入门到应用必备开源项目

    Go 语言于 2009 年 11 月正式宣布推出,成为开放源代码项目,发展至今已经具有越来越广泛的影响力,今年更是在 TIOBE 编程语言排行榜中跻身 20 强.很多开发者也逐渐将目光投向这门语言,本 ...

  4. Swift继承的用法

    一个类可以继承另一个类的方法,属性和其它特性.当一个类继承其它类,继承类叫子类,被继承类叫超类(或父类).在Swift中,继承是区分「类」与其它类型的一个基本特征. 在Swift中,类可以调用和访问超 ...

  5. 【计算几何初步-判断是否凸多边形】【HDU2108】Shape of HDU

    Shape of HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tot ...

  6. 在EasyUI中统一判断是否有选中行,如果有则将选中行数据传入回调函数

    function procossWithSeletedData(func) { var rowData = $("#tbGrid").datagrid("getSelec ...

  7. 关于String字符串反转

    这是网上看到的一篇java面试题中的问题: 问题是: 如何将一个String字符串反转. String str = "1234567"; int length = str.leng ...

  8. RelativeLayout与LinearLayout的区别

    1.LinearLayout是线性布局控件,它包含的子控件将以横向或竖向的方式排列,按照相对位置来排列所有的widgets或者其他的 containers,超过边界时,某些控件将缺失或消失.因此一个垂 ...

  9. [Math]Reverse Integer

    Total Accepted: 111287 Total Submissions: 474471 Difficulty: Easy Reverse digits of an integer. Exam ...

  10. T - 阿牛的EOF牛肉串(第二季水)

    Description          今年的ACM暑期集训队一共有18人,分为6支队伍.其中有一个叫做EOF的队伍,由04级的阿牛.XC以及05级的COY组成.在共同的集训生活中,大家建立了深厚的 ...