# [Critical bug] Region 迁移导致TiFlash副本比TiKV副本包含更多行

## Issue

我们在用户环境中发现，TiFlash 副本的总行数多于 TiKV，并在后来的模拟测试中复现了这个现象。

### 问题现象

问题发现于：[ONCALL-2901](https://internal.pingcap.net/jira/browse/ONCALL-2901) ,[ONCALL-3678](https://internal.pingcap.net/jira/browse/ONCALL-3678)

修复于 ##1789(4.0) 以及 ##1783 (5.0)，但是当时修复的时候，没有预测到它会导致数据不一致。用户侧出现问题后，在测试环境复现不一致，并确认这个修复已经解决问题。

select count(*) from table，从 TiFlash 副本读的结果多于 TiKV 副本

### 触发条件

1. 集群存在 2 个及以上 TiFlash 节点，且开启了 TiFlash 副本

2. region 副本在 TiFlash 节点间有来回调度

3. 通常较小的表，才有较高触发概率

## Root Cause

### 具体原因

1. region 副本在从 tiflash 迁移走，以及迁移进来，这两个操作都会写入 delete_range 来清除遗留的旧数据。

2. tiflash 内部存在一个 bug，在这两个操作结束之后，立刻对另外一个 region 发起查询，可能会导致 delete_range 不完全生效。

3. 如果 delete_range 在两个操作中都触发了 2 的问题，就会导致 region 副本之前的旧数据没有正确删掉，从而导致 TiFlash 副本的行数比 TiKV 副本的行数更多。

## Diagnostic Steps

Oncall issue:

1. [ONCALL-2901](https://internal.pingcap.net/jira/browse/ONCALL-2901)

2. [ONCALL-3678](https://internal.pingcap.net/jira/browse/ONCALL-3678)

## Resolution

影响版本： v4.0.0 ~ v4.0.13 的版本，以及 v5.0.0
修复版本： v4.0.13, v5.0.1

## Workaround

规避/解决方案：

- 如果用户 TiDB 版本为受影响版本，并且带有 TiFlash 副本，应尽快升级到 v4.0.13 或者 v5.0.1

- 如果用户已经触发了此问题，首先需要将集群升级至修复版本，然后：

    - 使用 ALTER TABLE {table_name} SET TIFLASH REPLICA 0 去除 TiFlash 副本，等一个 GC lifetime 的时间以清理旧的 TiFlash 副本数据，再重新设置 TiFlash 的副本
