老鹰506
(Ti D Ber Uhzt Tfx J)
1
【 TiDB 使用环境】生产环境
【 TiDB 版本】7.5.3
【遇到的问题:问题现象及影响】
在迁移MySQL数据到TIDB之后遇到慢查看到存在一些 “解析耗时”或者“生成执行计划耗时” 导致的慢查,
然后查阅官方文档打开tidb_enable_non_prepared_plan_cache参数并调整tidb_session_plan_cache_size到200;同时tidb_plan_cache_max_plan_size从2M增加10M(刚开始没有理解这个参数,调的有点,后来减少到5M,恢复到2M)
发现内存持续上涨
server内存上涨是这里的 session-plan-cache 上涨导致的
然后在 15:29的时候关闭了 tidb_enable_non_prepared_plan_cache参数,且修改的值都改回默认是(包括另外一个没有使用的server节点也都确保修改会默认值了)
XXXX@192.168.1.30:4002 15:19: [shop] >SET tidb_enable_non_prepared_plan_cache = OFF;
Query OK, 0 rows affected (0.00 sec)
XXXX@192.168.1.30:4002 16:01: [shop] >show variables like 'tidb_plan_cache_max_plan_size';
+-------------------------------+---------+
| Variable_name | Value |
+-------------------------------+---------+
| tidb_plan_cache_max_plan_size | 2097152 |
+-------------------------------+---------+
1 row in set (0.00 sec)
XXXX@192.168.1.30:4002 16:02: [shop] >show variables like 'tidb_enable_non_prepared_plan_cache';
+-------------------------------------+-------+
| Variable_name | Value |
+-------------------------------------+-------+
| tidb_enable_non_prepared_plan_cache | OFF |
+-------------------------------------+-------+
1 row in set (0.00 sec)
XXXX@192.168.1.30:4002 16:02: [shop] >show variables like 'tidb_session_plan_cache_size';
+------------------------------+-------+
| Variable_name | Value |
+------------------------------+-------+
| tidb_session_plan_cache_size | 10 |
+------------------------------+-------+
1 row in set (0.00 sec)
XXXX@192.168.1.30:4002 16:02: [shop] >show variables like 'tidb_prepared_plan_cache_size';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| tidb_prepared_plan_cache_size | 10 |
+-------------------------------+-------+
1 row in set (0.00 sec)
后来甚至把 tidb_session_plan_cache_size 从100降到10也是没有解决问题。
但是实际上 session-plan-cache 和 server的内存都还在持续上涨。
请问这个问题如何修复?
这个缓存多久失效呢?
yg_2024
(yangguang)
2
尝试ADMIN FLUSH [SESSION | INSTANCE] PLAN_CACHE,试试呢?
有猫万事足
3
你这30g增长的内存里面只有2g是缓存的问题。
其他的应该都不是。go这种带内存回收机制的,如果你的机器内存很足,有垃圾也不会着急回收的。等着不够用了再去回收。
另外non-prepared缓存对你来说还挺合适的,居然有3-40%的命中率。反而是prepared的命中率非常糟糕,不如直接关了。
老鹰506
(Ti D Ber Uhzt Tfx J)
5
1、30g增长的内存里面只有2g是缓存的问题
这个你是从哪里判断的呀?
倒是这里内存监控显示增长很快,但是通过主机内存监控看到波动确实不大呢
2、3-40%的命中率
大佬这个数据又是怎么得到的呀
从历史监控看 prepared的确实使用的极少,之前也没有怎么关注过这块的问题
3、如果你的机器内存很足,有垃圾也不会着急回收的。等着不够用了再去回收。
这里这个缓存清理只能是等待server节点本身内存超限的时候才会清理么?
老鹰506
(Ti D Ber Uhzt Tfx J)
8
还发现个问题,第一次关闭这个参数之后,查看的时候确实是OFF了,如问题中描述的。但是后来再次查看的时候发现这个参数又是ON了,再次尝试关闭的时候,,监控图上才体现 non-prepared queries 开始下降了
老鹰506
(Ti D Ber Uhzt Tfx J)
9
从server节点日志中只能看到最开始的 开启和 16:15 (SET @@global.tidb_enable_non_prepared_plan_cache = OFF) 的再次关闭记录
tidb-2024-12-11T15-06-51.783.log:[2024/12/11 14:45:07.987 +08:00] [INFO] [set.go:169] ["set global var"] [conn=1774594746] [name=tidb_enable_non_prepared_plan_cache] [val=ON]
tidb-2024-12-11T16-42-22.806.log:[2024/12/11 16:15:14.391 +08:00] [INFO] [set.go:169] ["set global var"] [conn=1775523008] [name=tidb_enable_non_prepared_plan_cache] [val=OFF]
第二次的 set tidb_enable_non_prepared_plan_cache = OFF 没有在日志中找到,
而且最终一次生效的 set tidb_enable_non_prepared_plan_cache = OFF 没有在日志中找到
kfzdba@192.168.1.30:4002 16:34: [(none)] >show variables like 'tidb_enable_non_prepared_plan_cache';
+-------------------------------------+-------+
| Variable_name | Value |
+-------------------------------------+-------+
| tidb_enable_non_prepared_plan_cache | ON |
+-------------------------------------+-------+
1 row in set (0.00 sec)
kfzdba@192.168.1.30:4002 16:34: [(none)] >
kfzdba@192.168.1.30:4002 16:34: [(none)] >set tidb_enable_non_prepared_plan_cache = OFF;
Query OK, 0 rows affected (0.00 sec)
另外第一次开启也是session级别,时间是14:47 ,和日志的14:45也有时差
kfzdba@192.168.1.30:4002 14:47: [(none)] >SET tidb_enable_non_prepared_plan_cache = ON;
Query OK, 0 rows affected (0.00 sec)
有人知道 tidb 默认session级别的变量更新是不记录日志吗?
有猫万事足
10
这里。
这里non-prepared命中400多,未命中600多。
别猜了,从dashboard里面导出一个内存dump看看,什么东西占用高。
https://docs.pingcap.com/zh/tidb/stable/dashboard-profiling#开始性能分析
这个页面选heap。看看存了啥。
就是这部分的dump。
有猫万事足
11
session级设置关闭plancache的意思就是这个session不用。
其他的连接建立的时候从global级读取这个变量还是会使用plancache。
有猫万事足
12
另外这个问题需要开发注意一下的,不用prepared用不上plancache还是小问题。
最大的问题是,不用prepared sql,那只能字符串拼接sql。及其容易出现sql注入。
一个没注意,被sql注入攻击了,那就玩完了。
https://juejin.cn/post/6986531291659255838
2 个赞
老鹰506
(Ti D Ber Uhzt Tfx J)
16
能帮忙分析看看heap文件,是不是因为开启了 non_prepared_plan_cache 之后,导致的统计信息增多导致的嘛
heap_tidb_192.168.1.30_4002_4206134845.proto.zip (10.7 MB)
有猫万事足
18
确实是统计信息相关的占用高。是否plancache相关我说不好,你是从哪里看到这种说法的?我也想看看。
如果这台当时就是在运行analyze的话,我感觉这个是主要原因,可以调整一下统计信息收集的时间。看看是否会好一些。
老鹰506
(Ti D Ber Uhzt Tfx J)
19
因为之前另外一个老集群OOM挂过, 产生的OOM heap文件分析当时内存最大的也是 statistics接口。 那会之前调整过慢查的阈值,分析是因为导致慢查增多,然后关联的统计信息增多导致的oom,再把阈值调大之后就慢慢恢复了。
和这次heap分析有点类似。所以怀疑也是和统计信息收集关系,我先调整了慢查,缓解了不怎么快速涨了。
老鹰506
(Ti D Ber Uhzt Tfx J)
20
”调整一下统计信息收集的时间“ 这个怎么调整呢?
另外发现个问题 tidb_enable_non_prepared_plan_cache 这个参数的修改有问题呢,昨天修改了三次最终才立即生效。
今天13:07 我又关闭了,但是从监控上看没有”完全生效“ 似的