经过上一节的鉴权过后,程序已经受主库认可,并且可以像主库发起同步请求。在发起请求之前,还有一个可选的步骤:确认同步时间点。同步时间点由两个属性进行标识:Binlog文件名、偏移量。工具支持自定义时间点,如果没有指定,默认从主库的当前时间点开始同步。下面,介绍获取时间点协议,主要是向主库发起“SHOW MASTER STATUS”查询指令。
这是一个COM_QUERY类型的查询。COM_QUERY是基本的查询命令,服务器返回若干行,每行若干列,可能我们常见的select指令,也是COM_QUERY命令。他的格式非常简单。1 [03] COM_QUERY
string[EOF] the query the server shall execute
而解析服务器返回的结果可以说非常复杂,所以我们写数据库程序一般是使用客户端库,而不是自行解析。总体流程如下:
对于第一个字节是0xfb的情况,只在执行如下指令的时候才会发生。应用目前没有这种操作,所以暂时忽略之。LOAD DATA LOCAL INFILE '' INTO TABLE
EOF、ERR、OK包的格式上一节都有描述,下面给出列定义和行数据的解析方法。
列定义
主要是两个版本,一个是ColumnDefinition41和ColumnDefinition320这两种,后者应用于4.1以前版本的MySQL。这里只给出新版MySQL的格式。lenenc_str catalog
lenenc_str schema
lenenc_str table
lenenc_str org_table
lenenc_str name
lenenc_str org_name
lenenc_int length of fixed-length fields [0c]
2 character set
4 column length
1 type
2 flags
1 decimals
2 filler [00] [00]
if command was COM_FIELD_LIST {
lenenc_int length of default-values
string[$len] default values
}
行数据
每行可以包含多个列,每个列都是一个lenenc_str。
lenenc_xxx
这里简单说一下这种lenenc_xxx类型的东西到底是什么。lenenc_str由两部分组成,第一部分是一个lenenc_int类型、标记字串长度的整数,第二部分是字串本身。这个lenenc_int类型,保证了字串长度可以超过255。同时考虑到大部分数据都比较短,每次都用多个字节表示长度过于浪费,于是指定了编码规则,规则如下:
A. 如果第一个字节小于0xfb,那么他本身就是字串长度。
B. 如果第一个字节是0xfc,那么他后面的2个字节表示字串长度。
C. 如果第一个字节是0xfd,那么他后面的3个字节表示字串长度。
D. 如果第一个字节是0xfe,那么他后面的8个字节表示字串长度。需要注意,此时需要查看究竟他后面有没有8个字节,如果没有,可能这是一个EOF包。
E. 如果第一个字节是0xff,那么这意味着一个ERR包。
F. 如果第一个字节是0xfb,这只会出现在行数据中,意味着这个字段是个NULL。