【故障处理】 统计信息收集失败, enconding failed
作者: Jasper 原文来源:https://tidb.net/blog/a9d3ce36
问题背景
集群版本 :v5.4.3
问题现象:集群 cpu 资源使用率飙高,集群整体 duration 上升,造成部分业务收到影响
问题处理
1. sql 定位
根据 dashboard top sql ,以及慢查询 定位到相关 sql ,为 120 亿 表全表扫描
2. 临时解决
sql 相关查询条件在表中是有索引的,临时通过 sql binding 的方式 绑定走索引的执行计划,集群资源使用率恢复正常。
3. 查询条件有对应索引为什么要走全表?
注: 查看时间点 7 月 8 日 11 时左右
查看表元信息,可以看到表是一直在更新的,最后更新时间是 2024-07-08 row count 120 亿左右
查看索引统计信息,发现索引统计信息缺失,最后更新时间为 6 月 13 日。 经询问此集群为迁移升级的目标集群,6 月 13 日 为数据导入时间,也就是从数据进到集群之后统计信息就没有正常收集过。
到这里其实 执行计划 错误的原因已经找到 : 相关表统计信息缺失导致优化器无法正确预估 cost ,进而导致执行计划选择错误,走到了全表扫描,但是正常情况下集群是有自动统计信息收集的,为什么索引的统计信息一直没有收集成功呢?
那么尝试手动收集统计信息呢试试呢?手动收集没有成功,报错如下:
根据如上报错基本可以判断 统计信息收集失败的原因是表中存在非法字符导致。
此时最直接的解决办法是重新将数据重新导出导入,并指定字符集,但是这张表数据量有 120 亿,这个操作动作太大。且业务没有反馈数据查询存在问题,说明有异常数据的部分占比较小,那下一步就是通过日志信息尝试定位具体异常数据范围。
4. 查看 tikv 、 tidb 日志 定位 analyze 异常信息:
07/08 11:07:37 tidb 日志显示 content 表统计信息收集失败
查看对应时间点 tikv 日志,定位到报错的表的 region 信息,报错 region id 为 799953
5. 通过 region id 799953 查询 region 详细信息
得到 startkey : 7480000000000000FF715F72800000003CFF6835E20000000000FA
endkey: 7480000000000000FF715F72800000003CFFA61F7F0000000000FA
6. 根据 startkey 、 endkey 定位表中存在问题的数据范围
解析出来的数据范围为 1013462498 ~ 1017519999
7. 根据上文解析出的 数据范围查询表中相关数据
可能存在异常的数据量为 109574 条
尝试通过 char_length() 函数定位异常数据,异常数据通过函数处理时会报错,以此来确定异常数据范围。
经确认, 只有 char_length(error_msg) 作为筛选条件的时候会报错,说明异常数据存在于 error_msg 字段。
确认异常字段后,在通过对 id 1013462498 ~ 1017519999 的范围进行二分法查找,定位具体出错的行,进一步通过业务手段处理,或者针对性地对该段数据进行重新导入。
总结与建议:
此次故障版本为 v5.4.3 ,新版本对非法数据的校验和检查制度更为完善,升级到 v6.5+ 以上的新版本可以获得更好的使用体验。
数据迁移如何避免非法数据。
参数: tidb_skip_utf8_check 建议关闭此参数,避免跳过集群本身的 utf8-check
如使用 lightning 工具导入,注意 character-set 可手动指定为需要的字符集,避免自动识别。更多请参考链接:https://docs.pingcap.com/zh/tidb/stable/tidb-lightning-configuration
数据迁移之后检查恢复日志是否存在异常。
数据迁移到新集群后,第一时间收集统计信息,并检查统计信息收集状态。
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/93dae26f695efca507e1888b1】。文章转载请联系作者。
评论