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
chmod 777 -R /bdata/mysql_tmp -R
vim /etc/my.cnf
[mysqld]
tmpdir = /bdata/mysql_tmp
然后启动mysql即可
再次执行lsof|grep deleted 可以看到临时文件的路径已经改到了/bdata/mysql_tmp目录下了。