# [Critical-bug]-关于-当关闭-GC-compaction-filter-时，TiDB-集群运行变慢的问题

## Description

在关闭 GC compaction filter 的情况下发现一个Bug。该 Bug 是由于 idle connection 的代码判定错误，导致 GC 过程的 unsafe destroy range 异常缓慢，进而 MVCC deletion 版本没有被及时删除，影响了 scan 的性能。

### Phenomenon

1. TiDB 侧经常出现分钟级的 duration 尖刺，可见于 Grafana 上的指标 TiDB --> KV Request Duration。

2. 简单查询耗时非常高,  cop 扫描类型的查询，可见于 Grafana 上的指标 "Coprocessor Executor Time”。

3. 系统执行一些查询，偶尔卡住，且几分钟之后也无法得到响应。尝试执行 create database 卡住。

## Root Cause

在关闭 GC compaction filter 后，TiKV 的 GC woker 开始持续工作，GC worker 的线程非常繁忙， unsafe destroy range （主要是 truncate\drop 操作后需要清理的数据）需要在 GC worker 线程排队。

由于 unsafe destroy range 运行时间长导致触发了 batch client 层的 bug（[https://github.com/pingcap/tidb/pull/27678](https://github.com/pingcap/tidb/pull/27678) TiDB 会错误地回收了不活跃的连接），最终造成 TiDB 层面的响应出现极度缓慢的情况。

 **注意** ：这个问题跟 GC worker 繁忙程度有关，在 ARM 平台上更加容易触发。

## Diagnostic Steps

1. TiDB 一侧 duration 经常出现分钟级的 duration 尖刺，并且和 GC 使用 unsafe destroy range 的时间高度重合。这些尖刺可以在 TiDB 端的 KV Request Duration 看到（主要是 cop, get, batch_get），但是在 TiKV 看不到，gRPC duration 调到 6 个 9 或者调成 1 都看不到

2. unsafe destroy range 单个 task 的耗时通常较久，也经常在 TiDB 发生 Deadline Exceeded 错误

3. GC worker cpu 指标始终是 100%

## Resolution

### 1. 升级到修复版本 v5.1.2

该版本只是修复了 batch client 层的 bug [https://github.com/pingcap/tidb/pull/27678](https://github.com/pingcap/tidb/pull/27678) ，可以避免出现 tidb 分钟级时延的异常，不能避免 TiKV compaction filter GC 不能正常对 MVCC deletion 版本进行回收的问题(详见KB [https://kb.pingcap.com/post/solutions/427?locale=zh](https://kb.pingcap.com/post/solutions/427?locale=zh))。

### 2. 升级到修复版本

v5.1.3 v5.2.3 v5.3.0 版本修复了 TiKV compaction filter GC 工作机制和 batch client 层的多个 Bug ，详见 [https://github.com/tikv/tikv/pull/11423](https://github.com/tikv/tikv/pull/11423)

## Workaround

方法1：对业务限流，等待 GC 完成 。即持续观察 gc_delete_region 和 gc_delete_region_done 数据应持续下降。

方法2：先设置 [tikv-client.ma](https://kb.pingcap.cn/tikv-client.ma)x-batch-size = 0 再关 compaction filter。原理是避免了慢速的 unsafe destroy range 请求卡住其它普通请求。

```markdown
tiup cluster edit-config {$cluster-name}
在配置文件中加入以下内容：
tidb:
  tikv-client.max-batch-size: 0
tikv:
  gc.enable-compaction-filter: false

按照以下顺序执行执行reload操作，确保 tikv-client.max-batch-size: 0 优先生效
 tiup cluster reload {$cluster-name} -R tidb
 tiup cluster reload {$cluster-name} -R tikv
```
