背景:
公司自研同步服務(wù)拙泽,先執(zhí)行全量同步淌山,補(bǔ)充增強(qiáng)數(shù)據(jù),達(dá)到同步數(shù)據(jù)的目的顾瞻。
問題:
用戶消費(fèi)的時候泼疑,發(fā)現(xiàn)這個字段(列)的數(shù)據(jù)有問題;
說增量的消費(fèi)沒有問題荷荤,奇怪退渗。
原因:
全量遇到bit字段,導(dǎo)出的時候當(dāng)做varchar處理了蕴纳,轉(zhuǎn)成base64格式的字符串会油;用戶解析遇到非數(shù)字字符串。
而增量數(shù)據(jù)解析的binlog返回的bit列古毛,對應(yīng)的類型是mysql_type_longlong
處理:
弄了一下拉取的數(shù)據(jù)翻翩,都是會處理string。
本來以為直接翻譯成mysql_type_longlong類型就可以了稻薇,然后緊急發(fā)布嫂冻,發(fā)現(xiàn)總是有問題。
無法解析的字符串"\x00\x01"塞椎。
服務(wù)器返回的類型是特殊字符串桨仿;
思路1:
后面就一致想著把返回的"\x00\x01"字符串,翻譯成"01",在轉(zhuǎn)成uint64案狠;
調(diào)試了半天出不來服傍,后續(xù)輸出單步調(diào)試暇昂,發(fā)現(xiàn)出現(xiàn)"\x00\x07",納尼伴嗡。。从铲。
此路不通瘪校。
復(fù)盤
最后發(fā)現(xiàn)弄了半天的東西,原來是最簡單名段,服務(wù)器返回的就是uint64的字節(jié)序阱扬;而且是按照bit的順序,中間轉(zhuǎn)義
處理的時候伸辟,依然是原始的[]byte字節(jié)序麻惶。
思路2:
自己去解析uint64值,不用走彎彎繞繞信夫。踏破鐵鞋無覓處窃蹋,得來全不費(fèi)工夫。原來是如此簡單静稻,我搞了半天警没。
func bytes2uint64Special(bs []byte) uint64 {
var v uint64 = 0
for _, b := range bs {
v = v * 256 + uint64(b)
}
return v
}
然后再編碼輸出的Queue中,供消費(fèi)振湾;
最終代碼
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
}