binary log解析(一)

目前的解析是针对mysql 5.1.45, 其它版本很可能会有不一样, 所以不适合其它版本, 但基本思想应当是差不多的,所以可以借鉴;

Query_log_event: insert/delete/update语句都是这种类型;它的binary log structure是:

event header and data header are fixed format; 
event header is: timestamp(4), eventtype(1), serverid(4), eventLength(4), nextPos(4), flags(2)
fixed data header: threadID(4), timestamp(4), databaseid(1),errorCodeID(2), varStatusLength(2);
variabled data header: Because above parts are fixed length, so we should not know each part length from binary log. But in variable data header,
variabled data header: each item length is unfixed, and which item is needed and which not exist, it vary; so in order to parse each item, mysql define a ID for each item, and store the item ID in one byte at first and then store the data, and if the data is variable, such as timezone name, the structure is:

05 06 53 59 53 54 45 4d: 每一位对应的意思是: 05: 表示当前的item是timezone name, 06: 表示这个timezone name的长度, 53 59 53 54 45 4d: 合起来就是SYSTEM, 并且当前timezone name是SYSTEM;

这些存的方式其实以前在做C++的时候也经常用到, 不过好久不做C++了, 全忘了

如果表上面有auto_increment, 那该如何保证两边数据的一致呢?

如果仅仅把SQL从primary DB拷贝到GSB上去运行, 那么在GSB上必定会重新生成一个新的ID值, 这样两个DB的数据就不一致了. 在binary log里, mysql先调用了set insert_id=, 然后再执行那个insert SQL. 呵呵, 学了一招;

每调用一个auto_increment或last_insert_id()都会产生一个这样的auto_increment log event, 叫INTVAR_EVENT(5),对应的类Intvar_log_event;

如果insert/update/delete里有rand()函数呢? 这个函数产生的是随机数, 并且每次产生的数据是不一样的. 呵呵, mysql也想办法解决了. 其实rand()函数是根据不同的randseed来产生的, 所以只要能把每次执行rand()时的randseed也放入binary log, 那就不会有问题了;以下是binary log的节选:

SET @@RAND_SEED1=326269549, @@RAND_SEED2=1037133929/*!*/;

insert into test(name,age) values('alex',ceil(rand()* 100));

不过要注意了, rand也是一个log_event,是Rand_event(13的类Rand_log_event;

如果表上有trigger呢? 例如像我们经常用的create trigger before insert, create trigger before update. 在binlog里会有一个set timestamp=?, 但是实际上我在GSB上跑过这个set timestamp后再跑insert/update/delete语句, trigger仍然会触发, 并且时间跟set timestamp指定的时间不一致. 所以mysql使用的方法是在GSB端禁止trigger. 如果我们自己写tool的话, 可以通过过滤user来间接禁止trigger.

整个structure的拼装是在bool Query_log_event::write(IO_CACHE* file)函数里, 而这个函数是在log_event.cc文件里;
    

XID_LOG_EVENT(16): 在mysql里这仅仅表示commit. 它结构比较简单, event header部分, fixed data header部分是空的,  variable data header部分也是空的, 只有一个8 bytes的xid值;  所以如果碰到一个XID,那也就意味着这里是一个commit SQL;

 

所有这些信息都可以在这里找到: http://forge.mysql.com/wiki/MySQL_Internals_Binary_Log#Event_Flags

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7682812/viewspace-675013/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7682812/viewspace-675013/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值