TiDB 节点内存不回收

【 TiDB 使用环境`】生产
【 TiDB 版本】 5.2.1
【遇到的问题】tidb 集群的tidb节点内存一直增大 直到被oom kill,就是不回收内存,之前都是正常的 ,开发确认没上线新功能,tidb 日志里面expensivequery 最大也就是700M左右的 sql 不是单独一个sql导致的

【复现路径】做过哪些操作出现的问题
【问题现象及影响】

tidb 集群的tidb节点内存一直增大 直到被oom kill,就是不回收内存,之前都是正常的 ,开发确认没上线新功能,tidb 日志里面expensivequery 最大也就是700M左右的 sql 不是单独一个sql导致的 几个小时以后就oom了

gc相关的参数调整,最好再发点tidb的内存监控图看看

1.查一下大SQL是否较多?
2.为TiDB节点增加环境变量 echo "GODEBUG=madvdontneed=1">>/etc/profile,以调整GO 语言内存释放策略。

gc 相关参数 我看了下 基本都是对tikv 节点设置的 都是默认设置没有修改过
zabbix

  1. 是有一些 单次使用700M 或者140M的sql (基本一分钟之内就执行完了) ,之前都没有这种查询完了 还不释放的问题,10月8日上午11点左右 开发那边执行了一个insert 内存使用达到34.7G oom了以后就出现这种一直涨不释放的问题了。

  1. 请问 设置这个环境变量是要重启tidb 节点么?

tidb 官网看下内存控制,可以尝试配置 oom action
这个配置 tidb run 脚本应该是配置了的 ,在比较新版本中:

cat run_tidb.sh 
#!/bin/bash
set -e

# WARNING: This file was auto-generated. Do not edit!
#          All your edit might be overwritten!
DEPLOY_DIR=xxx

cd "${DEPLOY_DIR}" || exit 1
exec env GODEBUG=madvdontneed=1 bin/tidb-server \

麻烦上传一下 runtime 中的 memory usage的图。

这个好像不怎么行

5 个赞

Go 的内存管理可以算是两层的,执行垃圾回收以后,没有用到的内存会归还给 Go 的 runtime,这是一层。然后 Go 的 runtime 什么时候把没有使用到的内存,再归还给操作系统,这是第二层。 你得看看内存不释放问题,发生在第一层还是第二层,即 Go 的 runtime 没有及时地把内存归还给操作系统。

有没有做什么具体的操作复现一下

1 个赞

oom_action 默认就是cancel 默认大小是1G 1G太小就修改到8G了 但是是很久以前修改的了,目前没有看到 有单条sql 超过2G 的 8G的也没有了,内存是一点一点涨上去的
直接涨到32G左右,那个环境变量已经添加重启了 目前看 似乎没有效果

找下对应 SQL 在慢日志中记录,最终是否执行成功,慢日志中有个字段可以代表。
如果没有执行成功,这个内存统计是不完整的,因为只有部分数据上传了。
可以搞个简单的办法,就是看慢日志, oom 那段时间,执行时间较长,但是最终没有执行成功的。一般就是相关 SQL 导致的。
如果不是 SQL 导致的,那就只能是 tidb 内存溢出了。orz

第一个节点的:


第二个节点:

目前是第一个节点是正常的 不会一直增加 不释放,第二个节点 在一直增加不释放
zabbix 监控

你可以对比一下图1,和图2,图2的uesd-by-go一直都在缓慢的增长。所以导致runtime部分,reserved-by-go部分也在持续增长。

到第二个节点上看下tidb日志,查下有没有expensive query。
https://docs.pingcap.com/zh/tidb/v5.4/identify-expensive-queries

如果没有到话,你可能需要做 Heap Profile 来定位一下,内存主要耗费在哪里了。
Heap Profile 使用可以参考下这个帖子

现在是找不到原因 也就没法复现了 就是这个节点涨到oom 挂了 另一个节点涨 到oom

没有expensivequery

好像是整点就oom了,6点,14点,17点,22点

刚才查错日志了 只有一共expensivequery 占用129M