问题原因

今天发现MySQL数据库中没有写入新数据,于是看了下Rails后端的日志,发现报了一个Error: Mysql2::Error: Got error 28 from storage engine: SHOW FULL FIELDS FROM plays错误。网上搜了一通说是空间不足造成的。

使用 df -h 命令,结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
root@windstill:/# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/windstill-root
                       28G   28G    0G   0% /
none                   16G  220K   16G   1% /dev
none                   16G     0   16G   0% /dev/shm
none                   16G   52K   16G   1% /var/run
none                   16G     0   16G   0% /var/lock
/dev/mapper/windstill-data_backup
                       28G   16G   11G  59% /data_backup
/dev/mapper/windstill-mysql
                       65G   15G   47G  24% /mysql
/dev/mapper/windstill-opt
                       28G   15G   12G  55% /opt
/dev/mapper/windstill-redis
                       28G   17G  9.8G  63% /redis
/dev/mapper/windstill-prod
                       28G   13G   14G  50% /prod
/dev/mapper/windstill-mongodb
                       65G   50G   12G  82% /mongodb
                       

可以看出 /mysql 空间还是很足的,还有47G空间可用,那是什么原因呢。随着深入了解,原来MySQL查询的时候会生成一些临时的表,在默认的配置里,这些表会被创建在 / 挂载点(目录)中。再结合上述结果中,我的 / 已经没有可用空间了,那这就是问题所在了。

解决方法

既然知道问题的原因是 / 空间不足,那么解决方法就是清理 / 无用的文件。 使用 ls -alh 命令,结果如下:

1
2
-rw-r--r--  1 nobody   root     15G 2014-07-02 11:04 nginx.access.log
-rw-r--r--  1 nobody   root      2G 2014-07-02 11:04 nginx_assets.error.log

发现nginx的log文件都太大,于是使用 rm 命令把他们一一删除了。但是另外的一个小问题出现了,我再次使用 df -h 命令发现 / 可用空间仍然是0。

后来了解到,在Linux或者Unix系统中,通过rm或者文件管理器删除文件将会从文件系统的目录结构上解除链接(unlink)。然而如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用。而我删除的是Nginx的log文件,删除的时候文件应该正在被使用。

通过 lsof |grep deleted 命令可以获得一个已经被删除但是仍然被应用程序占用的文件列表,如下所示:

1
2
3
root@windstill:/# lsof |grep deleted
nginx      6316   nobody    3w      REG              251,4 15966896128    1471723 /tmp/nginx.access.log (deleted)
nginx      6316   nobody    4w      REG              251,4  2815307776    1471730 /tmp/nginx.error.log (deleted)

从输出结果可以看到log文件还在被使用,未被释放空间。一种方法是kill掉Nginx进程,让os自动回收磁盘空间。但这种方法显然不好,会影响线上应用。索性Nginx有个重新打开日志文件的方法:

1
nginx -s reopen

至此,所有问题都解决了。

参考文章

SSL证书申请与在Nginx下的配置

http协议默认情况下是不加密的,各种信息都是明文传送。SSL是Secure Socket Layer的简称,具体的作用就是在部署了SSL证书的网站跟用户浏览器之间建立一个安全的会话。以防止信息在互联网任何中间节点上被盗用。####购买SSL如果购买就不赘述了,我是从 [ …… 阅读全文

评论