TiDB Bug List=

【本贴用于记录TIDB中遇到的bug ,方便大家查阅,内容来源于tug的问题整理,除bug 类信息请不要回复,内容补充需考的大家一起维护】

1、bug-11217: 多key GC调用导致GC不工作,大量历史版本残留

2、bug-11903: 计数器错误导致drop/truncate后GC delete range不工作,报gc work is too busy

3、bug-12934: [Critical bug] 切换 PD Leader 或重启 PD 可能导致 SQL 执行持续报错

4、bug-5687: [Critical bug] TiFlash 在开启 Profiling 以后偶发崩溃

5、 bug-37238: [Critical bug] Outer join 的结果可能执行不正确

6、 tiflash 6.2 无大查询时 内存突增导致oom

7、 6.x版本设置新的tiflash副本后,progress同步进度不更新。

8、6.4版本BR在分区表恢复后使用有问题的partitionID。

9、 v6.3.0-v6.5.0 使用 Multi-schema change 添加唯一索引导致数据索引不一致。

6 个赞

bug-11217: 多key GC调用导致GC不工作,大量历史版本残留

影响版本

  • v5.0.0-v5.0.4
  • v5.1.0-v5.1.2
  • v5.2.0-v5.2.2

issue: https://github.com/tikv/tikv/issues/11217
TiKV GcKeys task doesn’t work when called with multiple keys (at least in 5.1 but I think for everything)

现象和确认方法

  • 部分 scan 相关操作执行慢,集群中有比较多的 UPDATE/DELETE 语句执行
  • EXPLAIN ANALYZE 的 scan detail 中显示 key_skipped_count 远远多于 total_process_keys 或者 slow log 中 key_skipped_count 远远多于 total_process_keys

解决方案

  • 设置 gc.enable-compaction-filter: false 以关闭 TiKV 的 compaction filter GC,使用旧的 GC 模式进行多版本 GC
  • 升级到新版本,如上所述选择发行版最新的发布版本
1 个赞

bug-11903: 计数器错误导致drop/truncate后GC delete range不工作,报gc work is too busy

问题

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

问题原因

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
– False GcWorkerTooBusy caused by incorrect scheduled_tasks

排查确认

  1. TiDB 监控的 GC - Delete Range Failure OPM 中有持续的 send 失败,如图:

image.png

  1. TiDB 日志中确认 Delete Range 错误原因是 “gc worker is too busy”
  2. 从原理上再次确认,检查 TiKV 曾经出现过 GC worker 持续 CPU 100% 的状况。

解决方案

Bugfix PR: https://github.com/tikv/tikv/pull/11904

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

临时解决措施

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

bug12934: [Critical bug] 切换 PD Leader 或重启 PD 可能导致 SQL 执行持续报错

产品 TiDB
组件 PD TiKV
版本 5.4.2 5.3.2
分类 Troubleshoot
标签 KnowIssue
来源

Issue

在对 PD 进行 Transfer Leader 或重启操作后,集群出现 SQL 执行持续报错的现象。

6.2.0 测试中发现了该问题:https://github.com/tikv/tikv/issues/12934

受到该 bug 影响的版本:v5.3.2, v5.4.2

Diagnostic Steps

  1. TiDB 监控观察到 SQL 执行持续报错,报错为 Region Unavailable / Region Epoch not match 等

  2. TiKV 监控中 TiKV Details - PD - PD heartbeats 中观察到持续快速上涨的 pending

image

Resolution

升级 TiKV 至修复了该 Bug 的版本。

Bug Fix PR: https://github.com/tikv/tikv/pull/13094

预期修复版本:v5.3.3, v5.4.3

bug-5687: [Critical bug] TiFlash 在开启 Profiling 以后偶发崩溃

产品 TiDB
组件 TiFlash
版本 6.1.0
分类 Troubleshoot
标签 KnowIssue
来源

Issue

TiFlash 在运行中偶尔出现某些系统调用(诸如 write())返回非法的 errno,由于程序无法处理非法 errno,所以最终会导致进程崩溃。由于仅在开启 Profiling 期间复现出该问题,因此怀疑与 Profiling 相关。

Github issue: https://github.com/pingcap/tiflash/issues/5687

Diagnostic Steps

  1. 观察 TiFlash 崩溃时的日志和 stack trace,判断它们是否是非法 errno 导致的。
  2. 判断当前是否存在 Profiling 动作(包括 Continuous Profiling,Manual Profiling,调用 /debug/pprof/profile 接口)

Workaround

在 TiDB Dashboard 关闭 Continuous Profiling,并且暂时不要在对 TiFlash 进行 Manual Profiling。

NOTE: 目前只有 v6.1.0 和 v6.2.0 版本默认开启 Continuous Profiling,我们从 v6.1.1 版本开始默认关闭 Continuous Profiling。

1 个赞

bug-37238: [Critical bug] Outer join 的结果可能执行不正确

产品 TiDB
组件 TiDB
版本 6.1.0
分类 Troubleshoot
标签 KnowIssue
来源

Issue

https://github.com/pingcap/tidb/issues/37238

Root Cause

当 tidb_enable_outer_join_reorder 设置为 true 时,

join reorder 处理过程中对 join 的 ON condition 处理有误

Diagnostic Steps

当存在多个 outer join,各自的 ON condition 中的条件比较简单,只涉及不多于两个表,而且涉及了多个 outer join 的公共外表时,其结果有可能出错。

  • A left join B_1 on F_1 left join B_2 on F_2 left join B_3 on F_3 left join B_i on F_i
  • 所有的连接条件 F_i 都各自只涉及两个表。其中有两个 join 的连接条件 F_i, F_j,F_i 涉及的表是 A 和 B_i,F_j 涉及的表示 A 和 B_j。而且此时有在 F_i 和 F_j 中有一个连接条件只涉及表 A。
  • 这时可能因为 join reorder 的一些处理不当导致结果可能出错

Resolution

修复 pr https://github.com/pingcap/tidb/pull/37245

修复版本 6.1.1 6.2.1

1 个赞

问题
升级到tiflash6.2 后非大查询、压力不大情况下出现oom

影响版本
v6.2 及以后

问题原因:
tiflash 从 6.2 开始引入 PageStorage v3 作为底层存储,可以显著减少写放大和提高写入性能,同时避免后台 gc 的高 cpu 使用。不过也引入了一个 bug,即 PageStorage 在 gc 的,page 的 删除标记 不会被真正回收,导致 wal 文件越滚越大,导致 GC 占用的内存也越来越大。
相关issue:
https://github.com/pingcap/tiflash/issues/6159
https://github.com/pingcap/tiflash/issues/6163

检查确认方式:
1、 无大查询 情况下 tfilash 出现内存突增 导致oom
2、<tiflash_data_dir>/data/page/log/wal/ 目录下,log_xxxx_1 文件持续变大

临时解决措施
使用 ALTER TABLE xxx COMPACT TIFLASH REPLICA 手工进行碎片整理,减少内存占用

修复版本
预计6.4版本修复

可参考:
https://asktug.com/t/topic/994062/41

1 个赞

问题
6.x版本设置新的tiflash副本后,progress同步进度不更新。

影响版本
6.0 - 6.2

问题原因:
region_id 上限值为int64,tiflash中错误的将region_id 解析为int32,导致region_id 达到 int32的值后,后续的新表设置的tiflash副本不能同步,已经设置tiflash的表不影响
相关issue:
https://github.com/pingcap/tidb/issues/37862

检查确认方式:
1、 检查PD 监控中alloc_id 或information_schema.tikv_region_peers中 region_id是否超过int32的最大值。

临时解决措施
应用hot fix : https://github.com/pingcap/tidb/issues/37862。 升级到修复版本

修复版本
预计6.5、6.1.4版本修复

可参考:
https://asktug.com/t/topic/996666/29

2 个赞

我们新发现了一个TiDB 的“BR”组件相关 critical bug,详细见下:

产品 TiDB
组件 BR
版本 6.4.0
分类 Troubleshoot
标签 KnowIssue
来源

Issue

BR v6.4.0 的一个优化意外地引入了一个 BUG (https://github.com/pingcap/tidb/issues/40177),这个 BUG 可能导致某些分区表在恢复之后使用有问题的 Partition ID。

“有问题”体现在:那些 Partition ID 在日后还可能会被其他 Table 用作 Table ID。

Root Cause

BR v6.4.0 引入了在恢复的时候尝试保持旧集群的 Table ID 不变的优化,这个优化的基本流程如下:

  1. 在备份档案使用的所有 Table ID 中找到最大的 ID。
  2. 将 TiDB 的 Global ID(可以理解成 Table ID 所使用的的自增 ID)给 rebase 到这个最大的 ID。

在执行了 (2) 之后,理论上我们就可以安全地使用旧集群的 Table ID 了(因为这些 ID 并不会被再度使用)。

但是现有的实现在步骤 (1) 中,意外地忽略了分区表中的 Partition:Partition ID 也来自 Global ID,并且可能大于 Table ID。我们只把 Global ID rebase 到了 Max(TableID) 的话,无法保障这些 Partition ID 也能被安全地使用。

当任意一个 Partition ID 大于最大的 Table ID 的时候,问题就会出现了。

Diagnostic Steps

取决于这些“有问题”的 Partition 日后被如何使用,这个 bug 具体的的表现形式非常多,绝大多数表现形式都是毁灭性的,例如:

  • 分区表的数据被意外 GC。
  • 分区表的数据被意外覆盖。
  • 某些新表出现不该存在的记录。

另一种方法能更精确地判断这个 bug 有没有触发:

首先,在 BR 日志中查询 “registering the table IDs”,你会得到这样的日志:

[INFO] [client.go:244] ["registering the table IDs"] [ids="ID:[79,153)"]

这里,ids 表示了 BR 已经认为可以“安全使用”的 Global ID 区间,接下来,使用这个 SQL 查询。

SELECT T.`TIDB_TABLE_ID`, P.`TIDB_PARTITION_ID`, T.table_schema, T.`table_name`, partition_name FROM 
  INFORMATION_SCHEMA.`PARTITIONS` P INNER JOIN 
    INFORMATION_SCHEMA.`TABLES` T 
      ON (T.TABLE_NAME = P.TABLE_NAME and T.`TABLE_SCHEMA` = P.TABLE_SCHEMA) 
  WHERE T.`TIDB_TABLE_ID` BETWEEN @lower AND @higher;

将上面的 @lower@higher 替换成上面日志中 ids 表示的区间即可。

如果出现了某个 TIDB_PARTITION_ID 不在 ids 的区间内,那么这个 bug 大概率已经被触发,请参考下文 “Workaround”。

Resolution

我们在 v6.5.0 LTS 中发现并修复了这个问题。现在 BR 会将 Global ID 给 rebase 到 Max(TableID ∪ PartitionID)以避免该问题的发生。

Workaround

建议不要使用 v6.4.0 的 BR 进行分区表的恢复,可以使用 v6.5.0 LTS

如果一定要使用 v6.4.0 进行恢复,那么在该 bug 触发之后,可以通过 DROP 掉所有已经恢复的库表,并重新执行恢复来 workaround。

[Critical bug] v6.3.0-v6.5.0 使用 Multi-schema change 添加唯一索引导致数据索引不一致

产品 TiDB
组件 TiDB
版本 6.3.0 6.4.0 6.5.0

Issue

使用 multi-schema change 添加唯一索引后,唯一索引的状态未能正确设置,导致后续执行 INSERT IGNORE 语句时会不正确地插入了重复的行,破坏了索引的唯一性约束。例如:

create table t (a int, b int);
insert into t values (1, 1);
insert into t values (2, 2);
alter table t add unique index idx(b), ...[any other schema changes];
insert ignore into t values (2, 2);
admin check table t;

ERROR 8223 (HY000): data inconsistency in table: t, index: idx, handle: 2, index-values:"handle: 3, values: [KindInt64 2]" != record-values:"handle: 2, values: [KindInt64 2]"

目前仅在 INSERT IGNORE 语句上发现此类违反唯一性约束的 bug。使用 INSERT、UPDATE 和 REPLACE 语句来插入唯一索引重复值,都会按照预期报 “duplicate entry” 的错误。

Root Cause

TiDB 从 6.3.0 起,支持使用 ingest 模式 (@@tidb_ddl_enable_fast_reorg) 添加索引。在增量数据合并回原索引的步骤完成后,multi-schema change 对目标索引的状态的更改未持久化到 TiKV,而执行下一个 schema 变更时丢弃了这个更改。在整个 multi-schema change 的 DDL 完成后,目标索引始终处于不正确的状态。

假如应用后续执行 INSERT IGNORE 语句,TiDB 在判断索引值是否重复时,该索引的状态影响了判断逻辑,导致检查被忽略,插入了重复的值(正常情况是不插入重复值并报 warning)。

Diagnostic Steps

出现数据索引不一致后,如果同时符合以下几种条件就可以确认是同一问题:

  • TiDB 版本为 6.3.0、6.4.0 或 6.5.0。
  • 检查该表的 DDL 历史记录,使用过 multi-schema change 添加唯一索引。
  • 数据索引不一致涉及到的索引和 multi-schema change 添加的索引是同一个索引。
  • 搜索 TiDB 添加唯一索引时间段的日志,包含 “[ddl-ingest]” 关键字。

Resolution

我们将在 v6.5.1 LTS 中修复这个问题。

Workaround

建议不要使用 multi-schema change 添加唯一索引。如果已经添加,最好重建索引以避免日后出现数据索引不一致。

[Critical Bug] The the update could not read the latest data if read committed is used

产品 TiDB
组件 TiDB
版本 6.0.0 6.1.1 6.1.2 6.1.3 6.1.4

Issue

https://github.com/pingcap/tidb/issues/41581

Root Cause

TiDB 使用 RC 隔离时,point get executor 读取的时间戳没有按预期刷新,取不到最新的值。使用RC隔离级别时,执行者不会获取不存在的key的悲观锁,更新可能不会对新插入的行生效。

Diagnostic Steps

如果更新结果出乎意料,例如不会更新最新值。尝试确认:

  • TiDB 版本为 v6.0、v6.1.1 -v6.1.4
  • 使用 RC 隔离级别
  • 使用并发插入和更新事务,更新/删除事务期望看到最新的插入结果使用pointGetExecutor读取

Resolution

  • 避免使用版本
    • v6.0
    • v6.1.1 -v6.1.4
  • v6.1.x版本,升级到v6.1.5版本

Workaround

  • 在update/delete语句之前使用select for update锁定row key

  • 禁用 RC 隔离级别,改用默认的 RR

1 个赞

这个帖子很相近
集群版本:5.0.4

:+1: :+1: :+1: :+1:

[Critical bug] Log Backup 在遇到 TiKV 重启后可能会遗落数据

大家好,

我们新发现了一个TiDB 的“TiKV BR”组件相关 critical bug,详细见下:

产品 TiDB
组件 TiKV BR
版本 6.5.4 7.1.0 7.1.1 7.4.0 7.2.0 7.3.0 7.1.2 7.5.0 6.5.6 7.1.3 6.5.5 7.1.4 7.5.1 7.6.0 6.5.7 6.5.8 8.0.0 6.5.9
分类 Developer
标签 KnowIssue
来源

Issue

Root Cause

TiKV 在日志备份的时候会启动两个并行的进程:

  1. 一个用于将文件推送到下游,这个进程会监听 raftstore 的变更,并将其缓存到本地。
  2. 一个用于推进备份的进度,这个进程会从 PD 不断地获取最新的 TSO,并且用它计算备份最新的进度。

在进程 (1) 积攒了足够多的文件之后,它会将当前缓存的文件上传到外部存储。在此之后,它会从 (2) 中获得当前的进度,并且更新到 PD 上。

但是,在 (1) 将文件上传到外部存储的过程中,新的写入将会持续进入,并且被计入进度计算;问题出现在这里:**这些新的写入不会在当前批次中被上传到外部存储。**因此,假如 (2) 在 (1) 上传文件的过程中,计算了最新的进度,那么这个进度其实是“超前”的。

一般情况下,这些写入会和下一批一起被上传,此时这个“超前”的进度并不会造成严重的后果。但是,如果 TiKV 此时因故重启,这批数据就会丢失。如果此时全局 Checkpoint 已经推进,其他 TiKV 在成为 Leader 之后会从这个“超前”的进度开始日志备份。此时前面提到那些未被备份的数据将永远不会被备份。

[1,Flush] [2,calculate progress]

TS --------------|----------|-------->

^ ^

| ± …but the log backup believes we have backed up to here

± Writes was actually backed up to here…

目前触发概率没有很精准的方式估算,但是总体上看,触发概率:

  • 随着 Flush 花费时间的上升上升
  • 随着 TiKV 数量上升下降。(因为有更多 TiKV 的时候,全局 checkpoint 被某个 TiKV 卡住的概率会变大。)

考虑到 TiKV 重启并不常见,而且目前 PiTR 本身也要求周期性重新全量备份,总体上看这个 bug 触发概率并不算高。

Diagnostic Steps

目前在备份集群没有很好的手段来发现这个问题。

这个问题遗失数据一个比较明显的特征是,那些被遗失的数据在某次进度更新之前,大约几百毫秒内的写入的。可以通过检查数据行的时间戳或者通过 TiDB HTTP API 查询 MVCC 版本确认。

Resolution

触发之后增量备份的部分数据会丢失,目前无法找回。

建议参考 workaround 部分或者升级到不受影响的版本。(6.5.10, 7.1.5, 7.5.2, 或者更高的 LTS 版本。)

以下 LTS 版本受到了影响:

  • Release 6.5: 6.5.4~6.5.9
  • Release 7.1: 7.1.0~7.1.4
  • Release 7.5: 7.5.0~7.5.1

Workaround

在上游集群,可以设置 log-backup.min-ts-interval (这个配置项没有文档)到大于全量备份间隔的值(例如,365d)来解决这个问题;但代价是 RPO 可能在 Leader Transfer 比较频繁的情况下会低于预期。

1 个赞

[Critical bug] 使用 restore 恢复带 auto random 字段的表, 可能导致数据修改错误

大家好,

我们新发现了一个TiDB 的“BR”组件相关 critical bug,详细见下:

产品 TiDB
组件 BR
版本 6.4.0 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 7.1.0 7.1.1 6.1.5 6.1.6 6.1.7 7.0.0 7.4.0 6.6.0 7.2.0 7.3.0 7.1.2 7.5.0 6.5.6 7.1.3 6.5.5 7.1.4 7.5.1 7.6.0 6.5.7 6.5.8 8.0.0
分类 Troubleshoot
标签 KnowIssue
来源

Issue

使用 br restore 恢复出来的集群上, 执行 insert on duplicate key update 语句, 可能会遇到错误的目标记录被修改的情况.

Root Cause

如果表的主键是一个包含 auto random id 在内的组合索引, 这个表在 br 恢复后的集群上, auto random id 字段不会被 rebase. 后续对这张表的 insert on duplicate key update 语句会因为生成的 id 与已经存在记录的 id 重复, 产生非预期的对老记录的更新, 导致数据出错.

Github Issue br doesn't rebase auto random if table's PKIsHandle is false · Issue #52255 · pingcap/tidb · GitHub 参看这个 issue 里面的复现的例子.

Diagnostic Steps

可以通过下面的方法来诊断这个问题的存在

  1. 检查集群中是否有表的主键是包含 auto random id 的组合索引,并且该表的数据是通过 BR restore 生成的。没有就跳过, 否则, 执行步骤 2

  2. 对包含 auto random id 字段的复合主键的表, 执行 show create table 语句, 观察输出结果 AUTO_RANDOM_BASE 的值是否正常

Resolution

该问题在最新的版本中已经修复,以下是受到该问题影响的 LTS 版本,可以考虑升级到 6.1.8, 6.5.9, 7.1.5, 7.5.2 及之后的版本以避免该问题。

  1. v6.1.5-v6.1.7

  2. v6.5.0-v6.5.8

  3. v7.1.0-v7.1.4

  4. v7.5.0-v7.5.1

Workaround

参照源集群, 使用 alter table auto_random_base 语句修复受影响的表

3 个赞

[Critical bug] 从低于 v6.5 版本的集群升级到不低于 v6.5 版本的集群,TiFlash 元数据可能损坏的问题

大家好,

我们新发现了一个TiDB 的“TiFlash”组件相关 critical bug,详细见下:

产品 TiDB
组件 TiFlash
版本 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 7.1.0 7.1.1 7.0.0 7.4.0 6.6.0 7.2.0 7.3.0 7.1.2 7.5.0 6.5.6 7.1.3 6.5.5 7.1.4 7.5.1 7.6.0 6.5.7 6.5.8 8.0.0 6.5.9
分类 Upgrade
标签 kbBug
来源

Issue

https://github.com/pingcap/tiflash/issues/9039

当集群中有 TiFlash 副本的情况下,从 v6.5 版本以下升级到不低于 v6.5 后,可能会导致 TiFlash 元数据损坏无法启动的问题。

具体影响的版本:将集群从低于 v6.5 升级到以下 LTS 版本时,TiFlash 可能会遇到此问题:v6.5.0~v6.5.9,v7.1.0~v7.1.5,v7.5.0~v7.5.1。

Root Cause

从低于 v6.5 版本的集群升级到不低于 v6.5 版本,TiFlash 会在内部把存储格式逐步地升级到 PageStorage V3,来提升写性能。

如果表的数据符合一定分布(在升级前 TiFlash 该表的 DeltaTree 存储引擎中 Delta 层没有新写入的数据),那么升级后 “已分配的文件 ID” 会获取到错误的值,导致在后续 TiFlash 运行过程中随着新数据写入,TiFlash 会对元数据进行错误的覆盖。但该问题在 TiFlash 实例重启之前不一定会表现出来。而是在下一次 TiFlash 实例重启的时候,在启动期间因为损坏的元数据导致检查失败,TiFlash 实例启动失败。

Diagnostic Steps

确认集群近期是否有从低于 v6.5 的版本升级操作。

启动失败时,tiflash 的日志报错信息类似:

["Code: 10017, e.displayText() = DB::Exception: try to create external version with invalid state [ver=23783.0] [state={type:VAR_REF, create_ver: 1653.0, is_deleted: true, delete_ver: 21767.0, ori_page_id: 22935.100, being_ref_count: 1, num_entries: 0}]: [type=PUT_EXTERNAL] [page_id=22935.106] [ver=23783.0] …

或者

["Code: 10015, e.displayText() = DB::Exception: Invalid page id, entry not exist [page_id=69.2] [resolve_id=69.2]: keyspace=4294967295 physical_table_id=-1: (while preHandleSnapshot region_id=100, index=3246, term=7) …

Resolution

将集群从低于 v6.5 升级到以下 LTS 版本时,tiflash 可能会遇到错误:v6.5.0~v6.5.9,v7.1.0~v7.1.5,v7.5.0~v7.5.1。

如果需要将集群低于 v6.5.0 升级版本时,建议至少选择 v6.5.10/v7.1.6/v7.5.2/v8.1.0 作为升级后的版本。另外如果用户在升级前没有 TiFlash 实例,在升级到 v6.5 后才部署 TiFlash 实例,则不涉及到 TiFlash 内的数据格式升级,不会遇到此错误。

Workaround

【已经升级后 TiFlash 遇到该问题】

如果遇到了该问题引起的 TiFlash 元数据损坏,则将出现数据损坏的 TiFlash 实例下线,然后重新部署 TiFlash 实例,等待数据重新从 TiKV 同步。

【升级集群版本前如何避免】

如果必须从低于 v6.5 升级到上述受影响的版本,有一种 workaround 可以避免此错误:

  1. 在升级前将表的 TiFlash 副本设置为 0,并且缩容所有 TiFlash 实例
  2. 升级集群至目标版本
  3. 重新部署 TiFlash 实例并添加 TiFlash 副本

[Critical bug] TiFlash 开启 async grpc server 时会随机 crash

版本

6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6

Issue

https://github.com/pingcap/tiflash/issues/7325

Root Cause

Async grpc server 的实现中存在 data race

Diagnostic Steps

TiFlash 在开启 async grpc server 时遇到随机 crash,其 crash 的 stack 中可以看到 EstablishCallData 相关的信息。例如
[2024/01/19 19:06:28.901 +08:00] [ERROR] [BaseDaemon.cpp:570] [“BaseDaemon:\n 0x1bf3ca4\tfaultSignalHandler(int, siginfo_t*, void*) [tiflash+29310116]\n \tlibs/libdaemon/src/BaseDaemon.cpp:221\n 0xfffc96c207c0\t [linux-vdso.so.1+1984]\n 0x648fc54\tDB::EstablishCallData::proceed() [tiflash+105446484]\n \tdbms/src/Flash/EstablishCall.cpp:151\n 0x1ab2280\tDB::handleRpcs(grpc_impl::ServerCompletionQueue*, Poco::Logger*) [tiflash+27992704]\n \tdbms/src/Server/Server.cpp:546\n 0x1afe6b0\tauto DB::wrapInvocable<std::__1::function<void ()> >(bool, std::__1::function<void ()>&&)::‘lambda’()::operator()() [tiflash+28305072]\n \tdbms/src/Common/wrapInvocable.h:36\n 0x1afe828\tstd::__1::packaged_task<void ()>::operator()() [tiflash+28305448]\n \t/usr/local/bin/…/include/c++/v1/future:2089\n 0x1af0ca8\tDB::DynamicThreadPool::executeTask(std::__1::unique_ptr<DB::IExecutableTask, std::__1::default_deleteDB::IExecutableTask >&) [tiflash+28249256]\n \tdbms/src/Common/DynamicThreadPool.cpp:101\n 0x1af0684\tDB::DynamicThreadPool::fixedWork(unsigned long) [tiflash+28247684]\n \tdbms/src/Common/DynamicThreadPool.cpp:115\n 0x1af1804\tauto std::__1::thread DB::ThreadFactory::newThread<void (DB::DynamicThreadPool::)(unsigned long), DB::DynamicThreadPool, unsigned long&>(bool, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, void (DB::DynamicThreadPool::&&)(unsigned long), DB::DynamicThreadPool&&, unsigned long&)::‘lambda’(auto&&…)::operator()<DB::DynamicThreadPool*, unsigned long>(auto&&…) const [tiflash+28252164]\n \tdbms/src/Common/ThreadFactory.h:47\n 0x1af1628\tvoid* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_deletestd::__1::__thread_struct >, std::__1::thread DB::ThreadFactory::newThread<void (DB::DynamicThreadPool::)(unsigned long), DB::DynamicThreadPool, unsigned long&>(bool, std::__1::basic_string<char, std::__1::char_traits, std::__1::allocator >, void (DB::DynamicThreadPool::&&)(unsigned long), DB::DynamicThreadPool&&, unsigned long&)::‘lambda’(auto&&…), DB::DynamicThreadPool*, unsigned long> >(void*) [tiflash+28251688]\n \t/usr/local/bin/…/include/c++/v1/thread:291\n 0xfffc939a88cc\t [libpthread.so.0+35020]”] [thread_id=3266]

Resolution

升级到 v6.1.7 或以上版本

Workaround

关闭 TiFlash async grpc server
对于 TiUP 部署的集群,可以用
tiup cluster edit-config cluster_name
命令来修改集群配置,在 server_configs 的 tiflash 下面加入
profiles.default.enable_async_server: false
之后用
tiup cluster reload cluster_name -R tiflash
来 reload 配置并重启 TiFlash 节点即可
对于非 TiUP 部署的集群,可以直接编辑 tiflash.toml 文件,在
[profiles]
[profiles.default]
下面增加
enable_async_server = false
之后重启对应 TiFlash server

以前遇到这个问题了 :rofl:
当时重建的tiflash集群
TiDB 7.1.0 2台 Tiflash oom之后无法启动.