首页 > 代码库 > 一个mysql /tmp目录爆满问题的处理

一个mysql /tmp目录爆满问题的处理

突然收到zabbix告警,说mysql服务器的/目录磁盘空间不足。

登录到服务器,看了下发现100GB的根目录,居然使用了差不多90GB。这台服务器上只跑了一个MySQL,应该不是日志未清理等其它原因造成的。


(说明:下面的几张截图是后期截的,当时已经有部分SQL跑完,释放掉部分磁盘空间了)

lsof |grep deleted 发现如下:

技术分享可以看到这个临时文件差不多有40GB。



show processlist; 如下:

技术分享

上图看的话,没有涉及到写binlog的操作,但是由于单纯的select并不会造成/tmp目录爆满的情况,所以猜测他这个同一个事务里面之前还有涉及到写binlog的操作(update、delete等)。



官方的说明:

https://dev.mysql.com/doc/refman/5.6/en/binary-log.html

技术分享

当事务开始时,它将缓冲区语句分配一个binlog_cache_size大小的缓冲区(我这里设置的是16777216bytes,即16MB)。 如果一个语句大于此,线程将打开一个临时文件来存储事务(默认是存放在/tmp/目录下)。 当线程结束时,临时文件会自动被删除。


上面就是因为事务里面的临时文件超过16MB了,被放到/tmp目录下了,但是这个临时文件实在太大了,导致磁盘空间不足告警了。


解决方法:

等上面的查询结束后,我们先关闭mysqld。(条件能允许的话,当然是让查询自己结束。如果直接kill掉的话,估计回滚也要话挺长时间的)


然后调整mysql的tmpdir到其他更大的磁盘去。

mkdir /bdata/mysql_tmp

chown mysql.mysql /bdata/mysql_tmp -R

chown 1777 -R /bdata/mysql_tmp -R

vim /etc/my.cnf 

[mysqld]

tmpdir = /bdata/mysql_tmp


然后启动mysql即可

再次执行lsof|grep deleted 可以看到临时文件的路径已经改到了/bdata/mysql_tmp目录下了。

技术分享


一个mysql /tmp目录爆满问题的处理