MySQL5.7 访问Information_schema.TABLES 导至内存持续增长
适用范围
mysql 5.7
问题概述
在生产环境5.7.30的数据库中,部署了MYSQL监控,但是发现部署完监控后,mysqld的内存持续增长。后通过监控发现也正是监控用户占用了大量的内存。
问题原因
通过排查确认,这是mysql 5.7的bug ,在采集表信息,当这些连接断开后,有可能导至内存不会自动释放,从而影响内存的持续增加。https://bugs.mysql.com/bug.php?id=86279
为了证实这个bug ,在生产环境下的slave 做了如下测试:
检查当前内存:
[root@s2ahuMaster01 ~]# free -m
total used free shared buff/cache available
Mem: 32011 23159 5799 1593 3052 6865
Swap: 0 0 0
第一次查询 information_schema.TABLES 查询 :
检查当前内存,内存减少了 1001 M:
[root@s2ahuMaster01 ~]# free -m
total used free shared buff/cache available
Mem: 32011 24159 4526 1593 3325 5864
Swap: 0 0 0
第二次查询information_schema.TABLES 查询(未断开连接) :
检查当前内存,内存减少了 5M:
[root@s2ahuMaster01 ~]# free -m
total used free shared buff/cache available
Mem: 32011 24164 4786 1593 3059 5859
Swap: 0 0 0
第三次查询information_schema.TABLES 查询(断开连接,重新连接) :
检查当前内存,内存减少了 810 M:
[root@s2ahuMaster01 ~]# free -m
total used free shared buff/cache available
Mem: 32011 24975 3681 1593 3354 5049
Swap: 0 0 0
通过验证,我们确认该BUG在 5.7.30版本中仍然存在。
解决方案
1.升级mysql 到8.0 , 目前mysql 5.7 将在2023年10月结束支持,且5.7上的该问题没有得到有效的解决。
2.监控时禁止采集information_schema 下的信息 ,但会影响监控信息的采集和使用;
如在监控软件中可以在msyql_exporter 通过 --collect.info_schema.tables=false 禁止采集 tables 的相关信息,同时禁用以下参数。
3.经过测试发现短连接会出来类似问题更为严重,为避免这个问题可以将监控的短连接改成长连接。
4.临时通过gdb手动回收内存
注: 在生产环境中执行gdb有风险,需经过DBA确认后在业务低峰执行。
free -m
gdb --batch --pid `pidof mysqld` --ex 'call malloc_trim(0)'
free -m
补充:
经过验证确认,客户在每天跑批的存储过程的,也有用到 information_schema.cloumns 对象,经过验证,同样存在不释放的问题,这也解释了,为什么每天跑完批后,内存就会增加,不释放的原因。