视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MySQL内存不释放_MySQL
2020-11-09 19:10:54 责编:小采
文档


前几天业务线发现一例MySQL数据库内存增长异常案例,现象如下:
数据库版本:Percona MySQL 5.0.67
数据量:670M+
内存大小:16G
Innodb Buffer Pool Size:4G
其它回话内存分配并不大,基本在100M以内,并且连接数非常少
服务器负载不高,开启Binlog,数据库和程序都已经进行过迁移,问题仍然存在。通过top命令查看MySQL占用内存一直在增长,且开始使用Swap。

分析排除过程:
1.怀疑到的是InnoDB内存占用,使用show engine innodb status查看,发现Free Buffer占很大部分,因此可以判断分配给Innodb引擎的内存够用
2.查看回话,回话数基本在3~4个,且回话分配的内存大小与现在MySQL占用的回话总和相差很大,因此也不会是回话的问题
3.程序、数据库软件问题。已经迁移过两次,版本与一致,问题依旧,因此也排除了这个问题
4.MySQL重启后内存释放,因此问题还是在MySQL身上,根据网上说的Flush Tables的做法发现无效,所以也不是打开的表数量过大的问题导致。

就在临时维护前1小时,网上查找案例时,有人说内存表配置不当也有可能导致内存异常,但因为天龙没有用到Memory引擎,因此没太在意,但已经山穷水尽,也不知道该做什么,就查了下数据库中Innodb以外的表,主要集中在mysql库及information_schema库:
+——————–+—————————————+——–+
| TABLE_SCHEMA | TABLE_NAME | ENGINE |
+——————–+—————————————+——–+
| information_schema | CHARACTER_SETS | MEMORY |
| information_schema | CLIENT_STATISTICS | MEMORY |
| information_schema | COLLATIONS | MEMORY |
| information_schema | COLLATION_CHARACTER_SET_APPLICABILITY | MEMORY |
| information_schema | COLUMNS | MyISAM |
……
| mysql | help_topic | MyISAM |
| mysql | time_zone | MyISAM |
| mysql | time_zone_leap_second | MyISAM |
| mysql | time_zone_name | MyISAM |
| mysql | time_zone_transition | MyISAM |
| mysql | time_zone_transition_type | MyISAM |
| mysql | user | MyISAM |
+——————–+—————————————+——–+
因为MyISAM表不多,而且表都不大,内存分配也没有问题,所以我大概过了一遍,剩下的就是MEMORY 表了。
单独对这些表进行查看,最终发现CLIENT_STATISTICS表非常异常,原因是作为内存表查询速度非常慢,,并且会报错,在/tmp/下的一个临时文件需要修复,因此到/tmp目录下进行查看,基本就定位到问题了:导出的临时表约为7~8G!
查看表数据基本不可能,因此在维护时,重启了数据库,并且查看了里面的数据,发现数据增长非常快,里面记录的都是客户端的连接记录,比较特别的就是主机名显示不全。因此我们选择将主机名改成IP的形式,用于定位出问题的服务器(当时还在怀疑是程序连接中断导致记录数增长)。但修改完后发现问题消失了,该台服务器与其他服务器区别,问题表的数据量也正常了,因此我们定位问题到了主机名上,我进行了一下实验:

现在有245、246两台机器:
246是客户端、245是服务器端
(root:245:Thu Apr 24 16:37:28 2014)[information_schema]> select count(*) from CLIENT_STATISTICS;
+———-+
| count(*) |
+———-+
| 2 |
+———-+
1 row in set (0.00 sec)
可以看到表里面的数据是2条

[dbatlbb@ ~]$ mysql -h 245 -uwuwl_test -p
mysql: Can’t create/write to file ‘/home/mysql/query.log’ (Errcode: 13)
Error logging to file ‘/home/mysql/query.log’
Logging to file ‘/home/dbatlbb/mysql/query.log’
Enter password:
Welcome to the MySQL monitor. Commands end with ; or /g.
Your MySQL connection id is 556
Server version: 5.0.67-percona-highperf-log Source distribution

Type ‘help;’ or ‘/h’ for help. Type ‘/c’ to clear the buffer.

(wuwl_test:${HOSTNAME}:Thu Apr 24 16:39:19 2014)[(none)]> show processlist;
+—–+———–+———————————+——+———+——+——-+——————+
| Id | User | Host | db | Command | Time | State | Info |
+—–+———–+———————————+——+———+——+——-+——————+
| 556 | wuwl_test | gs_438_friuha_fgesihs_fsd:50768 | NULL | Query | 0 | NULL | show processlist |
+—–+———–+———————————+——+———+——+——-+——————+
1 row in set (0.00 sec)
连接了一下,并进行了一次查询操作
(root:NJ-245:Thu Apr 24 16:38:38 2014)[information_schema]> select count(*) from CLIENT_STATISTICS;
+———-+
| count(*) |
+———-+
| 5 |
+———-+
1 row in set (0.01 sec)
发现数据有增长,再次进行几次查询,发现每次查询都会有增长,这个正常现象么?我修改了下主机名进行了再次查询,发现表数据不再增长。
修改方法:主机名需要小于16字节。
目前在5.5和5.6版本上进行了测试,发现这个表数据为空,因此这个问题可能是在5.0版本上面的一个BUG。

总结:
本次问题现象主要是:内存异常被MySQL占用不释放并持续上涨,更换过程序和数据库服务器仍没有效果,服务器数据量很小,Innodb Buffer空闲很大。
问题原因:由于数据库自身的统计数据表information_schema.CLIENT_STATISTICS 数据量过大导致内存占用,CLIENT_STATISTICS是一张内存表。
问题处理方法:由于CLIENT_STATISTICS表里面的Host列是16个字节的,因此如果主机名过长,会导致客户端每一次的操作都会在表里面新增一条数据,无论操作是否成功。因此只需要修改连接的主机名不要超过16位就不会导致内存占用不释放的问题。
思考:修改了默认的东西,需要在小部分服务器上进行测试,并详细记录修改后的异常,用于对比不同服务器之间的差别。

延伸:
CLIENT_STATISTICS 用于统计客户端连接,目前5.5、5.6以及Maria已经将client字段升级为个字节,且该统计功能默认关闭,所以如果大家有统计需要,一定要记得主机名不能大于个字节!

下载本文
显示全文
专题