写点什么

都是空格惹的祸

  • 2022 年 7 月 11 日
  • 本文字数:1175 字

    阅读完需:约 4 分钟

作者: navyaijm2017 原文来源:https://tidb.net/blog/0b574914

背景

通过 DM 同步 Mysql 库到 Tidb 集群,在一个 DM-Worker 上启动两个 task,一个 task 同步到 3.0.14 的集群,另一个 task 同步到 4.0.4 的集群,两个集群分别给不同的业务部门使用


什么是 DM

问题

4.0 集群上的开发人员反馈有一个查询 SQLselect id,wo_id,delivery_code,vehicle_order_id FROM insurance_wo where vehicle_order_id = '184742761197489224';在 Tidb 上查到的数据不对,少数据了,这个少数据指的是和源头 Mysql 上的查询结果对比,在 Tidb 上的查询结果少一条数据。

复现

  • 我用上面 SQL 在源 Mysql 上查询结果有两条数据:

  • 我用上面 SQL 在 4.0 的 Tidb 上查询确实只查到了一条数据

  • 然后我又用上面 SQL 在 3.0 的 Tidb 上查询发现也是只有一条数据

排查

  • 第一个想到的是不是经过 DM 同步中间数据丢了呢,然后我把这个表从 Mysql 上通过 Mysqldump 导出来,导入到 Tidb 用上面 SQL 查询也是少一条数据,那么排除了 DM 的问题

  • 我把上面信息反馈给 PingCAP 的同学继续排查, 首先通过use index对比查询走索引和表查询的情况,发现走索引查询和表查询结果都一样,都是有问题的



强制走索引的用法


  • 至此 PingCAP 的技术支持小伙伴需要后端研发人员介入了,又收集了一下 Tidb 集群的排序规则

  • 用 Mysql 客户端登录 Tidb 的时候增加两个参数 --column-type-info--comments执行下面 SQL:


–column-type-info 在结果中显示元数据信息

–comments 是否在发送到服务器的语句中剥离或保留注释, 默认值为跳过注释 ; 在连接 Tidb 的时候最好加上这个参数,不然有注释的 SQL,比如强制走索引,设置会不生效


  • 通过下面 SQL 确认 where 条件 vehicle_order_id 这个字段值的长度, 发现有长度是 19 位的值,大部分都是 18 位的,说明 19 位的数据有点不正常

  • 在 Tidb 上通过hex函数查看 vehicle_order_id 的十六进制,看看上面两条数据有啥区别,发现在 Tidb 上少的这条数据的十六进制的值最后多了一个20,然后在 Mysql 上查询结果和 Tidb 上是是一样的。

  • 通过上面的验证,PingCAP 的后端技术人员基本推断这条 Tidb 上查询不到的数据vehicle_order_id这个字段内容里面应该是有一个空格,然后通过下面方法验证空格的 16 进制确实是20

  • OK,至此已经定位到问题的原因是数据内容里面有空格,Tidb 和 Mysql 对空格的处理逻辑不一样,那么如何解决问题呢,有两个方案:


  1. 数据里面有空格是不正常的,从 Mysql 源头定位到问题并修正,清洗库里面现在的数据把空格去掉, 清洗 SQL:

  2. 新建 4.0 的 Tidb 集群并开启新框架的排序规则new_collations_enabled_on_first_bootstrap,重新通过 DM 同步数据到新集群,业务切割到新集群。


新框架的排序规则目前只有在新建集群的时候才能开启,已经跑了业务的集群无法开启,官方后面会支持老集群开启这个功能

新框架下的排序规则文档

更多学习和交流可以关注我公众号:


发布于: 刚刚阅读数: 3
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
都是空格惹的祸_TiDB 社区干货传送门_InfoQ写作社区