前言
最近一段时间一直再看mysql binlog相关的内容,也整理了几篇相关的文章,对mysql的事件以及通讯协议在理论上有了一个大概的了解,但是缺少实战;本文的目的就是从实战出发,了解binlog解析的整个过程。
解析思路
把binlog的解析过程大致分为以下几个步骤:
1.服务器启动首先获取上一次解析成功的位置(实例中存储在本地文件中);
2.和mysql服务器建立连接;
3.接受mysql发送来的binlog事件;
4.对不同的binlog事件进行解析;
5.将数据进行存储(实例中仅在日志中打印);
6.存储成功后,定时记录Binaly Log位置。
关于binlog相关的配置可以参考系列文章,里面有详解的介绍,下面对步骤进行详细的介绍;
1.服务器启动首先获取上一次解析成功的位置(实例中存储在本地文件中)
binlog的位置信息存储在文件namePosition,有更新也同样更新到namePosition中,部分代码如下:
public class NamePositionStore {
private static Logger log = LoggerFactory.getLogger(NamePositionStore.class);
public static final String BINLOG_NAME = "binlogName";
public static final String BINLOG_POSITIION = "binlogPosition";
private static Map binlogMap = new HashMap();
private static String lineSeparator = (String) System.getProperties().get("line.separator");
private static String localStoreUrl = "namePosition";
static {
loadNamePosition();
}
public static synchronized Map loadNamePosition() {
binlogMap = load();
return binlogMap;
}
public static synchronized Map getNamePosition() {
return binlogMap;
}
public static synchronized void putNamePosition(String binlogName, long binlogPosition) {
binlogMap.put(BINLOG_NAME, binlogName);
binlogMap.put(BINLOG_POSITIION, binlogPosition + "");
store(binlogMap);
}
public static synchronized void putNamePosition(long binlogPosition) {
binlogMap.put(BINLOG_POSITIION, binlogPosition + "");
store(binlogMap);
}
...以下代码省略,可参考码云完整代码...
}
namePosition中存储了两个字段分别是:binlogName和binlogPosition,这两个字段会在客户端请求mysql binlog的时候需要的参数;
2.和mysql服务器建立连接
在文章Mysql通讯协议分析中可以看到和mysql服务器建立连接的步骤:mysql发送握手包,客户端发送认证包,mysql发送认证的结果;
public class HandshakeHandler extends SimpleChannelInboundHandler {
private Logger logger = LoggerFactory.getLogger(HandshakeHandler.class)