# [Know Issue] sync-diff-inspector 执行报错 err="runtime error: index out of range [86] with length 86"

## Key Words

index out of range,sync-diff-inspector

## Description

TiDB 版本：v6.1.1 

sync-diff-inspector 版本：v6.5.0

使用 sync-diff-inspector 对比 MySQL 到 TiDB 的数据，sync-diff-inspector 报错，stack 信息：

```log
[err="runtime error: index out of range [86] with length 86"] [stack="github.com/pingcap/tidb/server.(*clientConn).Run.func1\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/server/conn.go:1059\nruntime.gopanic\n\t/usr/local/go/src/runtime/panic.go:838\nruntime.goPanicIndex\n\t/usr/local/go/src/runtime/panic.go:89\ngithub.com/pingcap/tidb/util/collate.decodeRune\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/collate/collate.go:297\ngithub.com/pingcap/tidb/util/collate.(*unicodeCICollator).KeyWithoutTrimRightSpace\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/collate/unicode_ci.go:99\ngithub.com/pingcap/tidb/util/collate.(*unicodeCICollator).Key\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/collate/unicode_ci.go:88\ngithub.com/pingcap/tidb/util/codec.encodeString\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/codec/codec.go:208\ngithub.com/pingcap/tidb/util/codec.encode\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/codec/codec.go:97\ngithub.com/pingcap/tidb/util/codec.EncodeKey\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/codec/codec.go:295\ngithub.com/pingcap/tidb/util/ranger.validInterval\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/ranger.go:42\ngithub.com/pingcap/tidb/util/ranger.points2Ranges\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/ranger.go:72\ngithub.com/pingcap/tidb/util/ranger.(*rangeDetacher).buildCNFIndexRange\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/ranger.go:403\ngithub.com/pingcap/tidb/util/ranger.(*rangeDetacher).detachCNFCondAndBuildRangeForIndex\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/detacher.go:368\ngithub.com/pingcap/tidb/util/ranger.(*rangeDetacher).detachCondAndBuildRangeForCols\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/detacher.go:794\ngithub.com/pingcap/tidb/util/ranger.DetachCondAndBuildRangeForIndex\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/detacher.go:759\ngithub.com/pingcap/tidb/util/ranger.extractIndexPointRangesForCNF\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/detacher.go:205\ngithub.com/pingcap/tidb/util/ranger.(*rangeDetacher).detachCNFCondAndBuildRangeForIndex\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/detacher.go:317\ngithub.com/pingcap/tidb/util/ranger.(*rangeDetacher).detachCondAndBuildRangeForCols\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/detacher.go:794\ngithub.com/pingcap/tidb/util/ranger.DetachCondAndBuildRangeForIndex\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/util/ranger/detacher.go:759\ngithub.com/pingcap/tidb/planner/core.(*DataSource).fillIndexPath\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/core/logical_plans.go:1443\ngithub.com/pingcap/tidb/planner/core.(*DataSource).DeriveStats\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/core/stats.go:399\ngithub.com/pingcap/tidb/planner/core.(*baseLogicalPlan).recursiveDeriveStats\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/core/stats.go:131\ngithub.com/pingcap/tidb/planner/core.(*baseLogicalPlan).recursiveDeriveStats\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/core/stats.go:124\ngithub.com/pingcap/tidb/planner/core.(*baseLogicalPlan).recursiveDeriveStats\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/core/stats.go:124\ngithub.com/pingcap/tidb/planner/core.physicalOptimize\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/core/optimizer.go:480\ngithub.com/pingcap/tidb/planner/core.DoOptimize\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/core/optimizer.go:291\ngithub.com/pingcap/tidb/planner.optimize\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/optimize.go:397\ngithub.com/pingcap/tidb/planner.Optimize\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/planner/optimize.go:227\ngithub.com/pingcap/tidb/executor.(*Compiler).Compile\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/executor/compiler.go:81\ngithub.com/pingcap/tidb/session.(*session).ExecuteStmt\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/session/session.go:1916\ngithub.com/pingcap/tidb/server.(*TiDBContext).ExecuteStmt\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/server/driver_tidb.go:230\ngithub.com/pingcap/tidb/server.(*clientConn).handleStmt\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/server/conn.go:2022\ngithub.com/pingcap/tidb/server.(*clientConn).handleQuery\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/server/conn.go:1876\ngithub.com/pingcap/tidb/server.(*clientConn).dispatch\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/server/conn.go:1371\ngithub.com/pingcap/tidb/server.(*clientConn).Run\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/server/conn.go:1121\ngithub.com/pingcap/tidb/server.(*Server).onConn\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/tidb/server/server.go:559"]
```

## Root Cause

为了加速校验过程，sync-diff-inspector 会将一个表拆分为多个 chunks 并行去工作，如果目标库是 TiDB，那么拆分 range 会使用 STATS_BUCKETS 的结果，但是返回的是 [WEIGHT_STRING](https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_weight-string)处理后的结果。而 sync-diff-inspector 暂时不支持 WEIGHT_STRING，因此会出现 Index out of range 的报错。

```sql
$ mysql -u xxxx -h 123.45.67.89 -P 4000 --binary-as-hex
MySQL [ums]> SHOW STATS_BUCKETS WHERE ...
```

## Diagnostic Steps

1.从 Panic 的错误堆栈看 github.com/pingcap/tidb/util/collate.(*unicodeCICollator).KeyWithoutTrimRightSpace, 所以是 collation 相关的 bug,确认表结构中列的数据类型

2.目标库是 TiDB 时，会使用 SHOW STATS_BUCKETS 取平均分布的边界值。确认 SHOW STATS_BUCKETS 中
Lower_Bound 和 Upper_Bound 的值

## Resolution

在 sync-diff-inspector 的 config 配置中添加 range 参数，同时需要指定 table-configs.*.target-tables。

sync-diff-inspector 会先判断 range 是否「trivial」的, 只有 trivial range 才会用 SHOW STATS_BUCKETS, 否则会用随机 sample 方法. 而我们指定 range = "(TRUE)" 就是告诉 sync-diff-inspector 这个是 non-trivial range，采用随机 sample 的方式加快比较。

示例：

```toml
...
[task]
...
target-configs = ["config1"]

[table-configs]
[table-configs.config1]
target-tables = ['test.test1']
range = "(TRUE)" # 使用 Non-Trivial Range 强行让 sync-diff-inspector 不使用 show stats_buckets
```
