tidb-server内存问题请教

【 TiDB 版本】
v8.1.0
【遇到的问题:问题现象及影响】
TiDB集群3个tidb-server,其中一个tidb-server节点内存不断增涨,触发了go_memstats_heap_inuse_bytes{job=“tidb”} > 1e+10告警,其他两个tidb-server节点正常。
Goroutine Count无异常。

go tool pprof heap.profile

File: tidb-server
Build ID: 121ec23f62e64cf12ab251610a96d00bde5f33fa
Type: inuse_space
Time: Nov 22, 2024 at 6:29pm (CST)
Entering interactive mode (type “help” for commands, “o” for options)
(pprof) top
Showing nodes accounting for 5.35GB, 86.04% of 6.22GB total
Dropped 1026 nodes (cum <= 0.03GB)
Showing top 10 nodes out of 174
flat flat% sum% cum cum%
3.57GB 57.33% 57.33% 3.57GB 57.33% strings.(*Builder).WriteString
0.56GB 8.94% 66.27% 0.56GB 8.94% github.com/pingcap/tidb/pkg/store/copr.(*copIteratorWorker).handleCopCache
0.48GB 7.68% 73.95% 0.56GB 8.95% github.com/pingcap/tidb/pkg/sessionctx/variable.NewSessionVars
0.24GB 3.82% 77.77% 0.24GB 3.82% github.com/pingcap/tidb/pkg/session.(*txnManager).recordEvent
0.19GB 3.01% 80.79% 0.19GB 3.01% github.com/pingcap/tidb/pkg/util/sqlescape.EscapeSQL
0.08GB 1.23% 82.02% 0.08GB 1.23% github.com/pingcap/tidb/pkg/util/memory.(*Tracker).AttachTo
0.07GB 1.09% 83.11% 0.07GB 1.09% github.com/pingcap/tidb/pkg/table/tables.adjustRowValuesBuf
0.07GB 1.05% 84.16% 0.07GB 1.05% github.com/pingcap/tidb/pkg/util/chunk.(*Column).AppendBytes
0.06GB 1.01% 85.17% 0.06GB 1.01% github.com/pingcap/tidb/pkg/util/memory.NewTracker
0.05GB 0.86% 86.04% 0.74GB 11.82% github.com/pingcap/tidb/pkg/session.createSessionWithOpt
(pprof) peek WriteString
Showing nodes accounting for 6369.94MB, 100% of 6369.94MB total
----------------------------------------------------------±------------
flat flat% sum% cum cum% calls calls% + context
----------------------------------------------------------±------------
2144.48MB 58.72% | github.com/pingcap/tidb/pkg/statistics/handle/storage.saveBucketsToStorage (inline)
1496.50MB 40.98% | github.com/pingcap/tidb/pkg/statistics/handle/storage.saveTopNToStorage (inline)
11MB 0.3% | github.com/pingcap/tidb/pkg/parser/format.(*RestoreCtx).WriteKeyWord
3651.98MB 57.33% 57.33% 3651.98MB 57.33% | strings.(*Builder).WriteString
----------------------------------------------------------±------------

【附件:截图/日志/监控】
tidb-server内存


Goroutine Count

heap.profile (4.4 MB)

针对TiDB v8.1.0版本中一个tidb-server节点内存不断增涨的问题的分析和可能的解决方案:

  1. 内存使用监控与报警

    • 您可以通过配置系统变量tidb_memory_usage_alarm_ratio来设置内存使用报警的比例。例如,设置为0.85表示当内存使用超过总内存的85%时触发报警。
    • 当内存使用量超过阈值时,TiDB会记录相关状态文件,并打印包含tidb-server has the risk of OOM的报警日志。
  2. 内存控制策略

    • TiDB支持对读数据算子的动态内存控制功能,可以通过tidb_mem_quota_query来控制单条SQL语句的内存使用阈值。
    • 对于写入事务,TiDB采用的事务模型要求所有待提交的事务写入操作需先在内存中进行缓存。在写入大的事务时,内存使用可能会增加并成为瓶颈。可以通过调整tidb_mem_quota_query"bulk"或使用非事务DML语句的方式来减少或避免大事务使用大量内存。
  3. 数据落盘

    • TiDB支持对执行算子的数据落盘功能,当SQL的内存使用超过Memory Quota时,可以通过落盘执行算子的中间数据,缓解内存压力。支持落盘的算子有:Sort、MergeJoin、HashJoin、HashAgg。
    • 落盘行为由参数tidb_mem_quota_querytidb_enable_tmp_storage_on_oomtmp-storage-pathtmp-storage-quota共同控制。
  4. 优化建议

    • 检查是否有特定的SQL查询或事务导致了异常的内存使用。通过pprof工具分析内存使用情况,您已经发现strings.(*Builder).WriteString占用了大部分内存,这可能表明有大量的字符串操作或者日志记录导致了内存的增加。
    • 优化SQL查询,减少大事务的大小,或者调整事务的提交频率,以减少单个事务对内存的需求。
    • 考虑增加物理内存或优化配置,以提供更多的内存资源给TiDB使用。
  5. 系统表查询

    • 您可以通过查询系统表INFORMATION_SCHEMA.MEMORY_USAGE或者CLUSTER_MEMORY_USAGE来查看具体的内存使用情况。

为什么只有一个tidb-server节点内存增涨,而其它两个节点没有呢?正常来说三个节点负载应该相近吧?