tidb 节点内存飙升

【 TiDB 使用环境】生产环境
【 TiDB 版本】
【复现路径】

【遇到的问题:问题现象及影响】
tidb 节点内存飙升,瞬间占了服务器内存90%几,导致查询数据非常慢

默认tidb 不是只使用内存的80%,怎么会跑到那么高去。

我重启了tidb 节点,5分钟后内存又飙到90%几。

请问是不是我那个参数配置的不正确,或者需要修改那个参数。

【资源配置】
【附件:截图/日志/监控】

是否有使用大内存的SQL
select id,time,info,mem from INFORMATION_SCHEMA.processlist a where a.info is not null

查一下慢sql,以及tidb日志中是否有expecesive sql

里面就一条sql 占用3gb内存。

还想咨询一个问题,比如我服务器内存是32g,tidb 节点使用内存没有设置,使用默认值,但是我单条sql使用内存设置为20g (tidb_mem_quota_query 这个参数设置20g),这样设置是否有问题。单条sql 使用内存 是指查询语句吗?我delete 和update 是否受到影响?
比如一个事务中我是先执行delete 操作,然后执行inster into … select 这些插入语句,这样内存是怎么统计的。

单条SQL假设执行需要20G,你并发执行2个,就得40g内存,就超了。
你这里面实际上是占用3g内存,那就是并发10条就30g了。
tidb-server运行还要占用内存呢。

比如我单条设置执行那个参数我设置20g,实际我查询sql 需要的最大内存是2g,那我应该也是用2g哈,不是20g哈。还用上面那个问题,在同一个事务中执行delect ,update, insert into …select 这个是怎么分配内存的,是只有insert into …select 中的select 会统计内存么?

这个是对的,参数设置的是上限。超过20g就报错。

内存只要分配就得用,update 也得获取一批数据,需要从tikv拿出来,这一批上来也得占用内存。这个内存不只是说所有sql用的。还有go的各个变量,结构占用。

你可以直接设置你的tidbserver的server-memory-quota参数为当前节点的80%,例如你tidbserver节点是32G内存,你这个参数设置为26G,这样可以限制整个tidb server的内存占用量,但是如果有大sql使用达量内存,还是有可能oom导致sql查不出来。

默认不是使用总内存的80%预警吗,这个机器上只有数据库,没得其他程序。

SHOW config WHERE TYPE=‘tidb’ AND NAME LIKE ‘%memory%quota%’ ;你看下是多少,
默认值为 0 表示无内存限制。

全是0

[WARN] [pd.go:152] [“get timestamp too slow”] [“cost time”=35.644834ms]

日志里面有好多这样的日志,这个怎么解决一下呢。

这个大概率就是tidb-server的goroutine太多了,压力太大了。访问pd的时候,goroutine调度不过来,拿时间戳慢了。
如果想解决呢,限制下链接数,让tidb-server健康的工作。

是现在最大连接数吗?就是外部程序连接tidb 那个连接数哈。max-server-connections 这个参数?

用这个是绝对能降低tidb压力的。就是拒绝服务了。你看tidb的cpu利用率,是不是很高了?如果不够高,有点慢就慢吧。如果很高了,可以通过拒绝一部分链接达到限流的目的。

sql 应该优化了,控制SQL内存使用
1、可以考虑加内存资源
2、优化SQL
我这有个临时解决的办法,sql 内存过大kill 掉的脚本

for list in /yourpath/server/mysql5.7/bin/mysql -hxx.xx.xx.xx -p'yourpassword' -vvv -e " select id from INFORMATION_SCHEMA.processlist a where a.info is not null and (mem >=11474836480 or time >600);" |grep -Ev 'id|ID|iD|Id' |awk -F "|" '{print $2}'
do
echo $list
/yourpath/server/mysql5.7/bin/mysql -hxx.xx.xx.xx -p’yourpassword’ -vvv -e " select id,time,info,mem from INFORMATION_SCHEMA.processlist a where id=$list and a.info is not null;" >/yourpath/sh/killsqllog/date +%s.log
/yourpath/server/mysql5.7/bin/mysql -hxx.xx.xx.xx -p’yourpassword’ -vvv -e " kill tidb $list ;"
done;

你这个是不是还要安装mysql 才得行?

只是用到mysql 这个命令了

线上又飙升到90%了。

好多错误日志。

能分享下集群的配置么?
从错误来看是 PD 的处理能力或者网络太拉跨了…