官网说设置oom-action=cacel可kill掉大sql,我配置如下:
mem-quota-query: 1073741824
oom-action: cancel
可是超过1G(1073741824)没有kill掉该sql,我又加上参数 oom-use-tmp-storage: false,还是不可以,我的sql只是多表关联,left join和inner join,没有group by 和order by,没有子查询,是我配置有问题么?a.bmp (2.1 MB) b.bmp (2.1 MB)
配置后需reload,如果确定已经配置了,还是oom,可能不是单条sql内存问题。
已经reload,目前这个tidb server只有这个sql,我是用navicat连的这个server单独执行的,我三个窗口同时执行,tidbserver直接宕机了,一个窗口执行,返回:(但是内存跳到16G左右,如上图)
1105 - Out Of Memory Quota![conn_id=3]
时间: 20.551s
三个窗口同时执行 这一个sql?
执行计划看下
1、可以使用 TiDB Dashboard 慢查询页面,按照内存排序,看看有那些SQL 是使用内存比较大的。
2、另外看看日志是否有expensive query:https://docs.pingcap.com/zh/tidb/stable/identify-expensive-queries/#expensive-query-日志示例
3、另外tidb_distsql_scan_concurrency 参数值设置的多少?
大sql无可避免,我是希望如果有耗tidb内存的大sql,一是tidb server能够不宕机,kill掉该大sql;二是能够记录该sql,我看了官网,第一个可以通过设置oom-action=cacel可kill掉大sql,第二个可以设置oom-use-tmp-storage及其路径存储该sql,我现在第一个清空实验不成功,第二个我正在实验,我是想问第一个为啥没成功,是否设置两个参数即可?
mem-quota-query: 1073741824
oom-action: cancel
1、如果开启了流控参数tidb_enable_rate_limit_action,这个变量控制是否为读数据的算子开启动态内存控制功能。读数据的算子默认启用 tidb_distsql_scan_concurrency 所允许的最大线程数来读取数据。当单条 SQL 语句的内存使用每超过 tidb_mem_quota_query 一次,读数据的算子会停止一个线程。
2、当读数据的算子只剩 1 个线程且当单条 SQL 语句的内存使用继续超过 tidb_mem_quota_query 时,该 SQL 语句会触发其它的内存控制行为,落盘。
3、所以不一定是内存达到了mem-quota-query 就马上被kill掉的。
4、另外需要注意的一点,mem-quota-query 是指query 大小,不是全局占用的内存大小。
[quote=“听风吹雨, post:8, topic:572843”]
单条 SQL 语句的内存使用继续超过 tidb_mem_quota_query 时,该 SQL 语句会触发其它的内存控制行为,落盘
[/quote]
是的,正是因为担心内存不足时tidb会有落盘行为,我把落盘给关了oom-use-tmp-storage: false(我最上面的帖子落盘关不关都试了),另外,我这个是另外启动的一个tidbserver,没有任何人使用,只有我的sql在上面执行,我是通过火炬图上去看的,tidbserver分配内存和实际使用内存都远远超过我配置的1G,是不是还有什么地方导致没有直接kill掉?
内存升高时候 你觉得异常就可以
可以尝试把 tidb_distsql_scan_concurrency
设置为1测试下。
考虑下设置max_execution_time?
测试文章:https://docs.pingcap.com/zh/tidb/v5.3/configure-memory-usage
经过测试(sql语句占用内存足够大)
1、oom-action: log 会一直查tidbserver,直至tidbserver宕机
oom-action: cancel 会返回 > 1105 - Out Of Memory Quota![conn_id=5],占用内存远超mem-quota-query的
设置,过一会会释放内存,但是同时多个 sql查询,tidbserver仍然会宕机,mem-quota-query和oom-use-tmp-storage的设置不会影响oom-action
2、 tidb-server 内存占用过高时的报警
memory-usage-alarm-ratio = 0.8 当内存占用达服务器的80%的时候,tidbserver 可以得到一组文件,其中包括 goroutinue
、 heap
、 running_sql
3 个文件,文件放在show config where name like ‘%tmp-storage-path%’;所在的路径,类似:/tmp/1002_tidb/MC4wLjAuMDo0MDAwLzAuMC4wLjA6MTAwODA=/tmp-storage/record/,可以找到导致大内存的sql
tidb_distsql_scan_concurrency=1没发现有什么不同
如果设置了max_execution_time,我有些语句可能就没执行,其实设置oom-action=cancel,20秒左右返回了 > 1105 - Out Of Memory Quota![conn_id=5],只是内存占用远远超过了我设置的阈值1G,同时查多个还是能把tidbserver查死,我期望的是快速kill超过阈值的sql,保持tidb活着,防止其他sql无法执行
看了下上面也没提供相关日志。
建议你这边,梳理下当前的参数情况,手动选择一台 tidb-server 执行 SQL ,并提供以下信息:
1.当前参数配置
2.SQL 文本以及 SQL 执行情况
3.tidb.log(起始时间:需包含最近的一个 welcome 到手动执行 SQL 的时间)
附件是完整的测试,麻烦看一下,我的内存设置是1G,oom-action=cancel,火焰图最终内存到达12.9G时kill掉了sql,tidbserver内存为32G
配置信息.bmp (2.1 MB) sql.txt (5.8 KB) 执行计划.bmp (2.7 MB) tidb.log (380.2 KB)
日志时间 没有包含最近一次 welcome 的时间,重新拿下日志呢