生产环境Tidb问题,无业务流量情况下,Tidb server持续性CPU,内存耗尽,网络长期处于100MB/s的带宽占用

【 TiDB 使用环境】
生产环境
【概述】:
Tidb在没有业务流量情况下出现Tidb server持续高CPU和高内存使用的情况,经过排查原因基本确定是Tidb集群周期性触发analyze table failed 导致。analyze failed 的原因是“GC life time is shorter than transaction duration”。
断定上述排查结果的是因为当我们经过对这个测试的表(3亿左右的数据量)删除后,集群资源耗尽的问题确实得到了解决。

【背景】:
1.生产环境搭建完成后投入使用前进行过大批量造数据的情况,但造完数据即集群空置并无业务使用。
2.造完数据以后,集群处于空置状态,集群并无业务流量进入。
3.等到业务接入前,监控配置好才发现集群处于不正常的状态。

【现象】:
在没有业务流量的情况下,Tidb集群自行出现了高CPU和高内存的情况。

【问题】:
需要咨询的问题是:

  1. 不确定这个是否为Tidb的设计缺陷导致,如果life_time过短不满足safe_point,analyze failed这个判断完全可以前置判断,为什么会产生大量的资源占用?
  2. 根据FAQ,调大tidb_gc_life_time 可以解决问题。但是有一点不明白的是,在新版本的说明里面:“如果一个事务的运行时长超过了 tidb_gc_life_time 配置的值,在 GC 时,为了使这个事务可以继续正常运行,系统会保留从这个事务开始时间 start_ts 以来的数据。例如,如果 tidb_gc_life_time 的值配置为 10 分钟,且在一次 GC 时,集群正在运行的事务中最早开始的那个事务已经运行了 15 分钟,那么本次 GC 将保留最近 15 分钟的数”。既然Tidb会为最长的事务保留数据,但为什么还会报这个错误?

对于Tidb server的源码进行浏览也确定了Tidb server的safe point的计算会是以当前集群中执行事务的最小的start_ts为准作为safe point的基准值,那为什么又会产生上面的报错???

【业务影响】:
【TiDB 版本】:5.2.1
【附件】:

1 个赞

补充一下说明我的疑问吧:
主要的疑问还是集中在,我理解的Tidb的gc策略是对所有小于safe_point时间戳的数据可以做数据清理,而safe_point的计算方式是min(当前执行中事务的最小start_ts, now - tidb_gc_life_time)得到的一个最小值。那么基于这个策略,理论上就不会出现事务执行过程中发现safe_point跑到了事务start_ts后面的情况。
对应的我也翻过tidb server的源码了,确实是这样的策略,希望Tidb对应的开发大神能抽空指导下是不是我哪里理解的不够正确。


1 个赞

请用户取下火焰图

现场已经没有了

请问问题解决了吗?

这个问题我们是通过drop 测试的表解决了。但是具体原因还得希望各位大佬能够回答下?
“主要的疑问还是集中在,我理解的Tidb的gc策略是对所有小于safe_point时间戳的数据可以做数据清理,而safe_point的计算方式是min(当前执行中事务的最小start_ts, now - tidb_gc_life_time)得到的一个最小值。那么基于这个策略,理论上就不会出现事务执行过程中发现safe_point跑到了事务start_ts后面的情况。
对应的我也翻过tidb server的源码了,确实是这样的策略,希望Tidb对应的开发大神能抽空指导下是不是我哪里理解的不够正确。”

@Lucien-卢西恩 @spc_monkey @yilong 各位大佬有空能帮助答疑解惑一下吗?

好的,我们确认一下

1 个赞

刚刚在研究过程中有了点新的思路,需要辛苦你这边帮忙确认下是不是理解正确。
1.tidb后台自动触发的analyze任务并不会出现在show processlist表之中,如下图中的auto开头的任务在processlist表中找不到对应的项


2.tidbserver代码中计算txn最小start_time的操作数据来源使用的是show processlist命令。
%E5%9B%BE%E7%89%87
3.也就是说自动触发的分析任务analyze table 事务,它的start_time并不会纳入safe_point的计算之中。这也就导致了safe point会超过analyze table的事务的start_time,从而导致anlyze table失败。

不知道我这边的推理是否正确,辛苦tidb的大佬帮我确认,谢谢!
@spc_monkey

4 个赞

:+1::+1::+1:是你说的那个逻辑导致的,我们会复现,进行改善一下

这里的showprocesslist 和mysql 客户端执行的show processlist是否相同? 活跃事务在tidb server内部是怎么组织的,是否有类似于innodb的read view这种结构? 另外看到有一个meta结构,每个未提交的事务信息是否在这里? 谢谢!
// Meta is for handling meta information in a transaction.
type Meta struct {
txn *structure.TxStructure
StartTS uint64 // StartTS is the txn’s start TS.
}

1 个赞

:joy:我也不清楚

1 个赞

此话题已在最后回复的 1 分钟后被自动关闭。不再允许新回复。