A-A+

TenDB Cluster集群Spider引擎在update语句中set值为16进制bug

2015年05月04日 bug fixed, TenDBCluster 评论 1 条

spider bug fixed: update table set X''

现象:TenDB Cluster集群的业务中使用类似update spider_test set info=x'aabbcc112233445566' where id=1的语句,其中id为分区键。 select length(info) from spider_test where id=1; 得出来的长度为8。 事实上无论set info =x'... ...'的内容长度是多少,只有长度大于8, select length(info)得到的结果都是8,即info的长度被截取了。

而在insert语句中info字段不会出现字段被截取。

spider的update是有特殊处理的direct_update,猜测该出错与direct_update有关。因此测试update spider_test set id=2, info= x'aabbcc112233445566' where id=1,更新的结果属正常。基本断定spider的direct update逻辑存在bug。

普通存储引擎的update的处理是将数据select到server层后进行update,再写入到磁盘。spider是一个存储引擎,正常的update逻辑也是这样。但spider是一个分布式的存储引擎,数据存储在remote mysql实例,那么spider先需要将select 语句发送到remote mysql,读取结果到spider本地,进行数据更新后,再将update语句发送到remote层。这样会有2次与remote mysql的SQL交互,影响性能。

spider对update进行了特殊的处理,即使用了direct_update。 direct_update将满足条件的update语句直接发送到remote mysql,而不需要先select 再update,从而提高性能。但是,若更新的分区键,再无法走direct_update逻辑。

回到上述bug,为什么正常逻辑的的update没有问题,而direct_update会出现数据丢失呢?根源在于spider与remote mysql交互需要自己接接SQL语句,而读取info值的接口不同。

正常逻辑的update会将数据select到server层,并通过file_record保存到record[0]与record[1]中。spider对这类SQL语句拼update语句,接update语句值的函数append_update-->append_update_set是从field字段读取出来。 这种逻辑下,从record读取的数据是正常的。

而spider的direct_update则需要不需要走select到本地,并将update前后值保存到record的逻辑,而是直接拼接update语句发送到remote。拼接update的代码逻辑是spider_db_append_update_columns --> spider_db_print_item_type。 在spider_db_print_item_type处理中,针对X'' 这种16进制格式的内容读取是存在bug的,该逻辑调用了Item_hex_string::print方法,这个方法限定仅读取前面8个字节。因此,update test set info =X'' set的实际内容会被截取。

通过修复direct_update对spider_db_append_update_columns的处理即可解决该bug。

原创文章,转载请注明: 转载自腾讯游戏DBA团队

本文链接地址: TenDB Cluster集群Spider引擎在update语句中set值为16进制bug

文章的脚注信息由WordPress的wp-posturl插件自动生成

Copyright © 腾讯游戏DBA团队 保留所有权利.  

用户登录

分享到: