一、msyql内部指令操作
1)接收msyql发送过来的报文,先获取头部。
header = PacketManager.readHeader(connector.getChannel(), 4);
public static HeaderPacket readHeader(SocketChannel ch, int len) throws IOException { HeaderPacket header = new HeaderPacket(); header.fromBytes(ch.read(len)); return header; }
public void fromBytes(byte[] data) { if (data == null || data.length != 4) { throw new IllegalArgumentException("invalid header data. It can't be null and the length must be 4 byte."); } this.packetBodyLength = (data[0] & 0xFF) | ((data[1] & 0xFF) << 8) | ((data[2] & 0xFF) << 16); this.setPacketSequenceNumber(data[3]); }
只取了data的前四个字节
2)根据头部大小判断body长度

开始获取body
byte[] body = PacketManager.readBytes(connector.getChannel(), header.getPacketBodyLength());
public static byte[] readBytes(SocketChannel ch, int len) throws IOException { return ch.read(len); }若body长度为7,则从input里获取0-7字节放入data
public byte[] read(int readSize) throws IOException { InputStream input = this.input; byte[] data = new byte[readSize]; int remain = readSize; if (input == null) { throw new SocketException("Socket already closed."); } while (remain > 0) { try { int read = input.read(data, readSize - remain, remain); if (read > -1) { remain -= read; } else { throw new IOException("EOF encountered."); } } catch (SocketTimeoutException te) { if (Thread.interrupted()) { throw new ClosedByInterruptException(); } } } return data; }
3)获得data为
,根据msyql协议里ok报文的特性(如下,)

4)获得ok后,进行下一步操作

二、msyql 日常指令(dml,ddl)操作:
1)先初始化一个buff,new buffer(32)和chanel,

接收msyql发送过来的data
public boolean fetch() throws IOException { try { // Fetching packet header from input. if (!fetch0(0, NET_HEADER_SIZE)) { logger.warn("Reached end of input stream while fetching header"); return false; } // Fetching the first packet(may a multi-packet). int netlen = getUint24(PACKET_LEN_OFFSET);//body长度 int netnum = getUint8(PACKET_SEQ_OFFSET);// if (!fetch0(NET_HEADER_SIZE, netlen)) {//获取body logger.warn("Reached end of input stream: packet #" + netnum + ", len = " + netlen); return false; } // Detecting error code. final int mark = getUint8(NET_HEADER_SIZE); if (mark != 0) { if (mark == 255) // error from master {

本文详细介绍了Canal在接收到MySQL内部指令和日常DML、DDL操作时的数据处理流程。从解析MySQL报文头部、获取body、到根据不同事件类型进行过滤和分发,如binlog事件的确认、格式描述等。文中还列出了不同event类型的过滤规则,如插入、更新、删除等。
最低0.47元/天 解锁文章
1094

被折叠的 条评论
为什么被折叠?



