不明原因导致TiDB preparedStmt相关内存占用无法回收

【 TiDB 使用环境】测试
【 TiDB 版本】6.1.0
【复现路径/问题现象及影响】
大批量执行 prepared statement 插入,使用 batch insert,size = 2000,jdbc param = “useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSize=1000&prepStmtCacheSqlLimit=20480&useConfigs=maxPerformance&rewriteBatchedStatements=true”


插入过程中 TiDB 内存占用不断升高,间断式地暂停和继续插入时,内存占用如下图


image
取消查询断开连接后一段时间,内存回收
image
这种情况无法稳定复现,但出现时单独重启tidb或tikv均无法解决问题(内存会清空但插入后仍会无法回收内存),重启整个集群后问题消失
pprof.tidb-server.alloc_objects.alloc_space.inuse_objects.inuse_space.021.pb.gz (112.6 KB)

useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSize=1000&prepStmtCacheSqlLimit=20480&useConfigs=maxPerformance&rewriteBatchedStatements=true
看这个配置,prepStmtCacheSize和prepStmtCacheSqlLimit 都比官方最佳实践中的最大配置大很多,所以大批量执行 prepared statement 插入可能会占用很多内存,看看是不是根据实际场景调整一下这两个参数试试?我看你说的也是测试环境


https://docs.pingcap.com/zh/tidb/stable/java-app-best-practices

这个测试时使用的是同一个插入语句,感觉应该不是预处理语句长度或者数目的问题?

看下这个帖子,看上去跟这个有点像,你再看看?

2 个赞

确实是这个问题,我将执行计划缓存关闭后,内存不再激增。之前理解上有一些问题,混淆了语法树的解析和物理执行计划的生成这两个不同的阶段。但除此之外还有一些疑问,一个是当使用rewriteBatchedStatements时,重写后的sql长度是否受到prepStmtCacheSqlLimit的限制,在我关闭tidb_enable_prepared_plan_cache后,发现原来解析阶段耗时为0的insert sql每次执行都需要重新解析ast;第二个是如果按照 执行计划缓存 | PingCAP 文档中心这里面描述的,一般的insert语句重复执行时应该不会触发cache miss,但实际上在执行时tidb解析出了大量执行计划并放入缓存导致oom;第三个就是为什么这不是一个能够稳定复现的问题,重启集群为什么会对它造成影响

感谢指路,我再去找那个版主请教下

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