MySQL的XA_prepare_event类型binlog的解析

为了支持新版的xa事务,MySQL新加了一种binlog event类型:XA_prepare

项目中使用的开源组件mysql-binlog-connector-java无法解析此种binlog event

分析源码后发现第一个问题:

MySQL中一共有39种binlog event

但是mysql-binlog-connector-java组件只写了38种binlog event,少了一种名为TRANSACTION_CONTEXT的binlog event,导致无法解析TRANSACTION_CONTEXT_EVENT/VIEW_CHANGE_EVENT/XA_PREPARE_LOG_EVENT类型的binlog event

修改完本地分支后,顺手向mysql-binlog-connector-java的作者提了一个issue,作者很友好也很迅速的修改了相关的代码

 

现在mysql-binlog-connector-java可以识别出XA_prepare的binlog event了,但是只是识别出来而已,我还要需要对这种binlog event进行反序列化

网上没有现成的资料,在MySQL的代码库里翻了一通后终于找到了关键代码

XA_prepare_event::
XA_prepare_event(const char* buf,
                 const Format_description_event *description_event)
 : Binary_log_event(&buf, description_event->binlog_version,
                    description_event->server_version)
{
  uint32_t temp= 0;
  uint8_t temp_byte;

  buf+= description_event->post_header_len[XA_PREPARE_LOG_EVENT - 1];
  memcpy(&temp_byte, buf, 1);
  one_phase= (bool) temp_byte;
  buf += sizeof(temp_byte);
  memcpy(&temp, buf, sizeof(temp));
  my_xid.formatID= le32toh(temp);
  buf += sizeof(temp);
  memcpy(&temp, buf, sizeof(temp));
  my_xid.gtrid_length= le32toh(temp);
  buf += sizeof(temp);
  memcpy(&temp, buf, sizeof(temp));
  my_xid.bqual_length= le32toh(temp);
  buf += sizeof(temp);
  memcpy(my_xid.data, buf, my_xid.gtrid_length + my_xid.bqual_length);
}
View Code

从源码中我们可以知道,XA_prepare类型的binlog event的数据部分结构如下:

one_phase : boolean, 1byte

formatID : int, 4byte

gtrid_length : int, 4byte

bqual_length : int, 4byte

data : String, gtrid + bqual, (gtrid_length + bqual_length)byte

 

例如[0, 123, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 103, 116, 114, 105, 100, 98, 113, 117, 97, 108]

就对应为:

one_phase:false

formatID : 123

gtrid_length : 5

bqual_length : 5

data : "gtridbqual"  ---> gtrid = "gtrid", bqual = "bqual"

于是可以很容易的写出XA_prepare类型的binlog event的解析器了

 

顺手提了个pr,已经被作者合进去了

posted @ 2017-05-10 17:34  qeDVuHG  阅读(896)  评论(0编辑  收藏  举报