# [Critical bug] GC worker 误报 busy 导致 drop:truncate table 空间不回收

## Issue

在 TiKV GC worker CPU 使用率 100% 期间内，执行 drop table 或 truncate table 命令，可能遇到删除表后 TiKV 空间不回收的问题。且 GC worker CPU 下降后，后续执行 drop table 或 truncate table 依然不会回收空间。

## Root Cause

TiDB 的 drop table 和 truncate table 命令会发送 unsafe destroy range 请求给 TiKV 删除一个范围的数据。

在 TiKV GC worker 繁忙时，GC worker 的 pending task 数量可能达到上限。此时如果继续向其中添加 unsafe destroy range 任务时，会错误地增加任务数量的计数器但最终没有减小。

多次这样的操作后，该计数器的值会永久性地高于 GC worker 繁忙的阈值。之后所有的 unsafe destroy range 请求都会被 TiKV 拒绝，造成 drop/truncate table 后删除数据不成功。

GitHub issue: <https://github.com/tikv/tikv/issues/11903>

## Diagnostic Steps

TiDB 监控的 GC - Delete Range Failure OPM 中有持续的 send 失败，如图：

![critical-bug-tikv-gc-worker-busy](../images/TiKV/critical-bug-tikv-gc-worker-busy.png)

TiDB 日志中确认 Delete Range 错误原因是 "gc worker is too busy"

从原理上再次确认，检查 TiKV 曾经出现过 GC worker 持续 CPU 100% 的状况。

## Resolution

Bugfix PR: [https://github.com/tikv/tikv/pull/11904](https://github.com/tikv/tikv/pull/11904)

修复版本: 5.0.7, 5.1.4, 5.3.1, 5.4.0

## Workaround

1. 如果当前 TiKV GC worker CPU 使用率不高，可以重启 TiKV 实例重置错误的计数器，暂时规避问题。
2. 避免在 TiKV GC worker CPU 使用率高的时候执行 drop table/truncate table 操作。
