背景:
公司自研同步服务,先执行全量同步,补充增强数据,达到同步数据的目的。
问题:
用户消费的时候,发现这个字段(列)的数据有问题;
说增量的消费没有问题,奇怪。
原因:
全量遇到bit字段,导出的时候当做varchar处理了,转成base64格式的字符串;用户解析遇到非数字字符串。
而增量数据解析的binlog返回的bit列,对应的类型是mysql_type_longlong
处理:
弄了一下拉取的数据,都是会处理string。
本来以为直接翻译成mysql_type_longlong类型就可以了,然后紧急发布,发现总是有问题。
无法解析的字符串"\x00\x01"。
服务器返回的类型是特殊字符串;
思路1:
后面就一致想着把返回的"\x00\x01"字符串,翻译成"01",在转成uint64;
调试了半天出不来,后续输出单步调试,发现出现"\x00\x07",纳尼。。。
此路不通。
复盘
最后发现弄了半天的东西,原来是最简单,服务器返回的就是uint64的字节序;而且是按照bit的顺序,中间转义
处理的时候,依然是原始的[]byte字节序。
思路2:
自己去解析uint64值,不用走弯弯绕绕。踏破铁鞋无觅处,得来全不费工夫。原来是如此简单,我搞了半天。
func bytes2uint64Special(bs []byte) uint64 {
var v uint64 = 0
for _, b := range bs {
v = v * 256 + uint64(b)
}
return v
}
然后再编码输出的Queue中,供消费;
最终代码
func bytes2uint64(bs []byte) uint64 {
var data uint64
switch len(bs) {
case 2:
data = uint64(binary.BigEndian.Uint16(bs))
case 4:
data = uint64(binary.BigEndian.Uint32(bs))
case 8:
data = binary.BigEndian.Uint64(bs)
default:
data = bytes2uint64Special(bs)
}
return data
}