我使用 Apache2 在我的 Debian 网络服务器上的 PHP 会话mod_php
似乎随机失败,说没有空间来编写它们:
sudo tail -60 /var/log/apache2/error.log
[Fri Jan 30 15:55:35 2015] [error] [client xxx.xxx.xxx.xxx] PHP Warning: session_start() [<a href='function.session-start'>function.session-start</a>]: open(/tmp/sess_555555555555555555, O_RDWR) failed: No space left on device (28) in /path/to-first-session-use/core/bootstrap.php on line 18
当我尝试:
ls /tmp
它只是永远挂起,所以这很糟糕。
但是当我检查可用空间并检查 inode 使用是否合理时......
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 150G 121G 22G 85% /
tmpfs 2.0G 0 2.0G 0% /lib/init/rw
udev 10M 16K 10M 1% /dev
tmpfs 2.0G 4.0K 2.0G 1% /dev/shm
$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda1 19922944 11143605 8779339 56% /
tmpfs 513524 4 513520 1% /lib/init/rw
udev 513524 135 513389 1% /dev
tmpfs 513524 3 513521 1% /dev/shm
数字看起来不错。当然,85% 比我想要的多,但不是 99% 或任何东西。
我怀疑这是一个问题,因为 5 年没有重新启动机器,并且可能创建了很多小文件,但我得到的 inode 信息有点矛盾。我应该在哪里调查?
编辑:
ls -l /
drwxrwxrwt 4 root root 692M Feb 1 11:09 tmp/
drwxr-xr-x 10 root root 4.0K Jan 1 2013 usr/
drwxr-xr-x 14 root root 4.0K Oct 7 2010 var/
...etc
可能是
/tmp/
目录本身充满了未清理的陈旧 PHP 会话;这意味着问题的根源可能与/tmp/
目录本身隔离。如果是这种情况,我会删除所有/tmp/sess_*
文件。首先,列出所有sess_*
文件,如下所示:或者你可以
wc
这样计数:现在,一旦您确认那里有一些疯狂的文件,请继续运行以下命令来删除
/tmp/sess_*
文件:短暂的会话文件将被吹走。
但是另一种蛮力(但相对安全)的处理方式是清除
/tmp
目录本身,重新创建/tmp
目录并重新启动服务器。由于该
/tmp
目录基本上是缓存材料的编码笔,因此那里没有任何有效的内容。所以我最好的建议是运行以下命令来删除和重新构建/tmp
目录。现在,一个衬里基本上是一个由它连接的 shell 命令列表
&&
,它将首先删除/tmp
、重新创建/tmp
、将所有权更改/tmp
回root:root
,然后为/tmp
目录设置适当的权限。如果您愿意,如果您觉得这样做更安全,您可以一个一个地运行每个命令。完成后,我建议重新启动服务器。事情应该再次平静下来。
有时损坏的文件系统会产生类似的效果 - 例如,当目录 /tmp 损坏时。或者 - 当文件太多时。
对于“快速”修复:
如果有帮助 - 尝试重新启动系统和 fsck 根文件系统。如果没问题 - 只需删除 /tmp.xxx 目录。
另一种可能性是 - 当 /tmp 是“其他”分区或 tmpfs(在 linux 虚拟服务器上看到)时 - 但 df 不显示(因为 df 从 /etc/mtab 文件中获取分区列表有时不正确)。尝试通过命令直接在 tmp 上检查磁盘空间:
通常有助于会话的其他选项 - 它使用其他会话机制。如果您有很多临时会话,它们不需要非常持久 - 我建议您使用 memcache 进行会话存储。配置它很简单——你必须安装 php-memcache、memcached 然后在 php.conf 中配置:
然后 - 会话将存储在 memcache 中,达到定义的大小。超过它 - 最旧的将被自动删除。
对我来说,改变 fs.inotify.max_user_watches 就可以了。
修复 /etc/sysctl.conf 中更改的值