【 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
----------------------------------------------------------±------------
【附件:截图/日志/监控】
kang
2
针对TiDB v8.1.0版本中一个tidb-server节点内存不断增涨的问题的分析和可能的解决方案:
-
内存使用监控与报警:
- 您可以通过配置系统变量
tidb_memory_usage_alarm_ratio
来设置内存使用报警的比例。例如,设置为0.85
表示当内存使用超过总内存的85%时触发报警。
- 当内存使用量超过阈值时,TiDB会记录相关状态文件,并打印包含
tidb-server has the risk of OOM
的报警日志。
-
内存控制策略:
- TiDB支持对读数据算子的动态内存控制功能,可以通过
tidb_mem_quota_query
来控制单条SQL语句的内存使用阈值。
- 对于写入事务,TiDB采用的事务模型要求所有待提交的事务写入操作需先在内存中进行缓存。在写入大的事务时,内存使用可能会增加并成为瓶颈。可以通过调整
tidb_mem_quota_query
为"bulk"
或使用非事务DML语句的方式来减少或避免大事务使用大量内存。
-
数据落盘:
- TiDB支持对执行算子的数据落盘功能,当SQL的内存使用超过Memory Quota时,可以通过落盘执行算子的中间数据,缓解内存压力。支持落盘的算子有:Sort、MergeJoin、HashJoin、HashAgg。
- 落盘行为由参数
tidb_mem_quota_query
、tidb_enable_tmp_storage_on_oom
、tmp-storage-path
、tmp-storage-quota
共同控制。
-
优化建议:
- 检查是否有特定的SQL查询或事务导致了异常的内存使用。通过
pprof
工具分析内存使用情况,您已经发现strings.(*Builder).WriteString
占用了大部分内存,这可能表明有大量的字符串操作或者日志记录导致了内存的增加。
- 优化SQL查询,减少大事务的大小,或者调整事务的提交频率,以减少单个事务对内存的需求。
- 考虑增加物理内存或优化配置,以提供更多的内存资源给TiDB使用。
-
系统表查询:
- 您可以通过查询系统表
INFORMATION_SCHEMA.MEMORY_USAGE
或者CLUSTER_MEMORY_USAGE
来查看具体的内存使用情况。
为什么只有一个tidb-server节点内存增涨,而其它两个节点没有呢?正常来说三个节点负载应该相近吧?
有猫万事足
4
Kongdom
(Kongdom)
7
是不是这个节点上有大查询?一个查询只会在一个tidb server节点上执行。
应用主要都是通过这个tidb server连接的吗?
1.tidb是做了负载均衡的
2.内存高的tidb-server节点heap ppro如下:
strings.(*Builder).WriteString
这个函数是做什么的?
(pprof) top20
Showing nodes accounting for 5824.49MB, 88.60% of 6574.05MB total
Dropped 977 nodes (cum <= 32.87MB)
Showing top 20 nodes out of 175
flat flat% sum% cum cum%
3754.01MB 57.10% 57.10% 3754.01MB 57.10% strings.(*Builder).WriteString
599.73MB 9.12% 66.23% 599.73MB 9.12% github.com/pingcap/tidb/pkg/store/copr.(*copIteratorWorker).handleCopCache
511.53MB 7.78% 74.01% 595.56MB 9.06% github.com/pingcap/tidb/pkg/sessionctx/variable.NewSessionVars
252.93MB 3.85% 77.85% 252.93MB 3.85% github.com/pingcap/tidb/pkg/session.(*txnManager).recordEvent
192.79MB 2.93% 80.79% 192.79MB 2.93% github.com/pingcap/tidb/pkg/util/sqlescape.EscapeSQL
81.04MB 1.23% 82.02% 81.04MB 1.23% github.com/pingcap/tidb/pkg/util/memory.(*Tracker).AttachTo
70.67MB 1.07% 83.09% 70.67MB 1.07% github.com/pingcap/tidb/pkg/table/tables.adjustRowValuesBuf (inline)
70.21MB 1.07% 84.16% 70.21MB 1.07% github.com/pingcap/tidb/pkg/util/chunk.(*Column).AppendBytes
68.01MB 1.03% 85.20% 68.01MB 1.03% github.com/pingcap/tidb/pkg/util/memory.NewTracker
58.52MB 0.89% 86.09% 786.25MB 11.96% github.com/pingcap/tidb/pkg/session.createSessionWithOpt
45.02MB 0.68% 86.77% 45.02MB 0.68% github.com/pingcap/tidb/pkg/sessionctx/variable.NewPlanCacheParamList (inline)
41.02MB 0.62% 87.40% 42.52MB 0.65% github.com/pingcap/tidb/pkg/session.(*session).SetProcessInfo
22MB 0.33% 87.73% 99.04MB 1.51% github.com/pingcap/tidb/pkg/executor.ResetContextOfStmt
15.50MB 0.24% 87.97% 70.52MB 1.07% github.com/pingcap/tidb/pkg/planner/core.(*expressionRewriter).Leave
14MB 0.21% 88.18% 33MB 0.5% github.com/pingcap/tidb/pkg/planner/core.FlattenPhysicalPlan
12.50MB 0.19% 88.37% 44MB 0.67% github.com/pingcap/tidb/pkg/bindinfo.newFuzzyBindingCache (inline)
12MB 0.18% 88.55% 38.50MB 0.59% github.com/pingcap/tidb/pkg/planner/core.(*PlanBuilder).buildSet
1MB 0.015% 88.57% 45MB 0.68% github.com/pingcap/tidb/pkg/bindinfo.NewSessionBindingHandle
1MB 0.015% 88.58% 67.02MB 1.02% github.com/pingcap/tidb/pkg/planner/core.(*PlanBuilder).buildProjection
1MB 0.015% 88.60% 534.18MB 8.13% github.com/pingcap/tidb/pkg/session.runStmt
(pprof) peek WriteString
Showing nodes accounting for 6574.05MB, 100% of 6574.05MB total
----------------------------------------------------------±------------
flat flat% sum% cum cum% calls calls% + context
----------------------------------------------------------±------------
2198.17MB 58.56% | github.com/pingcap/tidb/pkg/statistics/handle/storage.saveBucketsToStorage (inline)
1544.84MB 41.15% | github.com/pingcap/tidb/pkg/statistics/handle/storage.saveTopNToStorage (inline)
11MB 0.29% | github.com/pingcap/tidb/pkg/parser/format.(*RestoreCtx).WriteKeyWord
3754.01MB 57.10% 57.10% 3754.01MB 57.10% | strings.(*Builder).WriteString
----------------------------------------------------------±------------
0.64MB 100% | encoding/json.structEncoder.encode
0 0% 57.10% 0.64MB 0.0097% | bytes.(*Buffer).WriteString
0.64MB 100% | bytes.(*Buffer).grow
----------------------------------------------------------±------------
3.慢查询都发生在内存高的tidb节点并且都是Analyze操作,这类操作会固定在一个tidb节点上?会导致内存不断增涨吗?
有猫万事足
10
https://docs.pingcap.com/zh/tidb/stable/top-sql
这几个tikv进topsql页面对比一下。看看负载有何不同。
负载均衡还是不能排除嫌疑,看看连接数是否有差异。
即使连接没差异,如果是多个系统使用同一个haproxy的情况下,也有可能导致按连接分配后,负载重的连接都在同一个tidb上。
这个时候建议负载重的系统单独使用一个haproxy,不要和其他负载轻的系统混合使用haproxy。
这个占比高,说明内存占用大部分是在执行字符串拼接。说不好是不是analyze导致的。看看top sql页面再说。
https://www.zhihu.com/question/607049431/answer/3102858534