跳到主要内容

TiFlash 批量删除场景可能出现数据不一致

作者:Wan Wei,更新于 2022.05.25

Issue

  • 从 TiFlash 的查询结果数据量多于 TiKV 的结果
  • 如果有多份 TiFlash 副本,从 TiFlash 查询结果不稳定

Triggering condition:

  • 顺序写入的表,然后批量删除大量数据的场景有较大概率出现。这样的表需要是没有设置 auto random,且没有设置 SHARD_ROW_ID_BITS ,且无主键的表。
  • 随机写入的表,极小概率触发这个问题

影响版本:

  • v6.0.0
  • [v5.4.0 ~ v5.4.1]
  • [v5.3.0 ~ v5.3.1]
  • [v5.2.0 ~ v5.2.4]
  • [v5.1.0 ~ v5.1.4]
  • [v5.0.0 ~ v5.0.6]
  • [v4.0.0 ~ v4.0.16]

修复版本:

  • v6.1.0
  • v5.4.2
  • v5.3.2
  • v5.2.5
  • v5.1.5
  • v5.0.7
  • v4.0.17

Root Cause

TiFlash 存储引擎内部在做 Segment 的 Split、Merge 的过程中,没有落盘的 Delta 数据只有在查询过程中才会被 range 所限制,在数据整理阶段不会被 Segment 的 range 限制。在一个 Segment Split 完之后,中间没有 Flush 操作,然后 Merge,会导致 Merge 操作无法过滤掉一些已经删除的数据,从而出现多余数据。

Diagnostic Steps

对于一张表,对比 TiKV 和 TiFlash 副本的总行数。如果 TiFlash 总行数大于 TiKV,则可能是触发了这个问题。注意 TiFlash 需要查 2 次。

begin;

set tidb_isolation_read_engines = 'tikv';
select count(*) from T;

set tidb_isolation_read_engines = 'tiflash';
# Run twice queries on TiFlash replicas
select count(*) from T;
select count(*) from T;

commit;

Resolution

升级到对应的修复版本,然后重新同步出现问题的表的 TiFlash 副本。

Workaround

  • 如果数据删除业务是整个表删除,可以考虑用 drop table 或者 truncate table 代替 delete SQL;否则没有其他措施。
  • 通过重新同步 TiFlash 副本可以暂时解决这个问题 即删除 TiFlash replica,等待 TiFlash 真正删除副本数据,然后再加回 TiFlash replica