写点什么

【故障处理】 统计信息收集失败, enconding failed

  • 2024-07-26
    北京
  • 本文字数:3072 字

    阅读完需:约 10 分钟

作者: 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 时左右


  1. 查看表元信息,可以看到表是一直在更新的,最后更新时间是 2024-07-08 row count 120 亿左右



  1. 查看索引统计信息,发现索引统计信息缺失,最后更新时间为 6 月 13 日。 经询问此集群为迁移升级的目标集群,6 月 13 日 为数据导入时间,也就是从数据进到集群之后统计信息就没有正常收集过。



到这里其实 执行计划 错误的原因已经找到 : 相关表统计信息缺失导致优化器无法正确预估 cost ,进而导致执行计划选择错误,走到了全表扫描,但是正常情况下集群是有自动统计信息收集的,为什么索引的统计信息一直没有收集成功呢?


那么尝试手动收集统计信息呢试试呢?手动收集没有成功,报错如下:


mysql> analyze table content_xxx_xxx index content_index;ERROR 1105 (HY000): other error: encoding failed
复制代码


根据如上报错基本可以判断 统计信息收集失败的原因是表中存在非法字符导致。


此时最直接的解决办法是重新将数据重新导出导入,并指定字符集,但是这张表数据量有 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


region 799953{  "id": 799953,  "start_key": "7480000000000000FF715F72800000003CFF6835E20000000000FA",  "end_key": "7480000000000000FF715F72800000003CFFA61F7F0000000000FA",  "epoch": {    "conf_ver": 155,    "version": 104105  },  "peers": [    {      "id": 800344,      "store_id": 11,      "role_name": "Voter"    },    {      "id": 800343,      "store_id": 20,      "role_name": "Voter"    },    {      "id": 1465083,      "store_id": 6,      "role_name": "Voter"    },    {      "id": 1960146,      "store_id": 1148820,      "role_name": "Voter"    },    {      "id": 3532222,      "store_id": 1147431,      "role_name": "Voter"    }  ],  "leader": {    "id": 800344,    "store_id": 11,    "role_name": "Voter"  },  "written_bytes": 0,  "read_bytes": 135,  "written_keys": 0,  "read_keys": 3,  "approximate_size": 86,  "approximate_keys": 107417}/ # ./tikv-ctl  --host 127.0.0.1:20160 raft region -r 799953{  "region_infos": {    "799953": {      "raft_apply_state": {        "applied_index": 24971,        "commit_index": 24971,        "commit_term": 7,        "truncated_state": {          "index": 24969,          "term": 7        }      },      "raft_local_state": {        "hard_state": {          "commit": 24971,          "term": 7,          "vote": 800344        },        "last_index": 24971      },      "region_id": 799953,      "region_local_state": {        "region": {          "end_key": "7480000000000000FF715F72800000003CFFA61F7F0000000000FA",          "id": 799953,          "peers": [            {              "id": 800344,              "role": "Voter",              "store_id": 11            },            {              "id": 800343,              "role": "Voter",              "store_id": 20            },            {              "id": 1465083,              "role": "Voter",              "store_id": 6            },            {              "id": 1960146,              "role": "Voter",              "store_id": 1148820            },            {              "id": 3532222,              "role": "Voter",              "store_id": 1147431            }          ],          "region_epoch": {            "conf_ver": 155,            "version": 104105          },          "start_key": "7480000000000000FF715F72800000003CFF6835E20000000000FA"        }      }    }  }}
复制代码

6. 根据 startkey 、 endkey 定位表中存在问题的数据范围

解析出来的数据范围为 1013462498 ~ 1017519999


MySQL [(none)]> SELECT TIDB_DECODE_KEY('7480000000000000FF715F72800000003CFF6835E20000000000FA');+---------------------------------------------------------------------------+| TIDB_DECODE_KEY('7480000000000000FF715F72800000003CFF6835E20000000000FA') |+---------------------------------------------------------------------------+| {"_tidb_rowid":1013462498,"table_id":"113"}                               |+---------------------------------------------------------------------------+

MySQL [(none)]> SELECT TIDB_DECODE_KEY('7480000000000000FF715F72800000003CFFA61F7F0000000000FA');+---------------------------------------------------------------------------+| TIDB_DECODE_KEY('7480000000000000FF715F72800000003CFFA61F7F0000000000FA') |+---------------------------------------------------------------------------+| {"_tidb_rowid":1017519999,"table_id":"113"} |+---------------------------------------------------------------------------+
复制代码

7. 根据上文解析出的 数据范围查询表中相关数据

  1. 可能存在异常的数据量为 109574 条

  2. 尝试通过 char_length() 函数定位异常数据,异常数据通过函数处理时会报错,以此来确定异常数据范围。


  经确认, 只有 char_length(error_msg) 作为筛选条件的时候会报错,说明异常数据存在于 error_msg 字段。


  1. 确认异常字段后,在通过对 id 1013462498 ~ 1017519999 的范围进行二分法查找,定位具体出错的行,进一步通过业务手段处理,或者针对性地对该段数据进行重新导入。

总结与建议:

  1. 此次故障版本为 v5.4.3 ,新版本对非法数据的校验和检查制度更为完善,升级到 v6.5+ 以上的新版本可以获得更好的使用体验。

  2. 数据迁移如何避免非法数据。

  3. 参数: tidb_skip_utf8_check 建议关闭此参数,避免跳过集群本身的 utf8-check

  4. 如使用 lightning 工具导入,注意 character-set 可手动指定为需要的字符集,避免自动识别。更多请参考链接:https://docs.pingcap.com/zh/tidb/stable/tidb-lightning-configuration

  5. 数据迁移之后检查恢复日志是否存在异常。

  6. 数据迁移到新集群后,第一时间收集统计信息,并检查统计信息收集状态。


发布于: 34 分钟前阅读数: 4
用户头像

TiDB 社区官网:https://tidb.net/ 2021-12-15 加入

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

评论

发布
暂无评论
【故障处理】 统计信息收集失败, enconding failed_故障排查/诊断_TiDB 社区干货传送门_InfoQ写作社区