pwritev() “/var/lib/nginx/proxy/2/05/0000000052” failed (28: No space left on device) while reading upstream, client:

这是一个非常典型的服务器错误,和臭鳜鱼的做法无关。这个错误信息表明您的服务器(运行Nginx)遇到了磁盘空间问题。 下面为您详细解释这个错误、如何排查以及如何解决。

错误信息解读

  • pwritev() failed: pwritev是一个系统调用,用于将数据写入文件。这里失败是因为遇到了下一个错误。
  • /var/lib/nginx/proxy/2/05/0000000052: 这是 Nginx 作为反向代理时,为了缓存上游服务器(Upstream Server)的响应而创建的临时缓存文件路径。
  • (28: No space left on device): 这是最核心的错误原因,即“设备上没有剩余空间”。这通常意味着服务器磁盘的存储空间已满。
  • while reading upstream: 错误发生在 Nginx 从上游服务器(如 PHP-FPM, Tomcat, 或其他后端服务)读取数据的过程中。

简单来说:当用户请求一个资源时,Nginx 需要将后端服务器的响应(可能是一个大文件或页面)先缓存到一个临时文件中,然后再发送给用户。但由于磁盘空间已满,创建或写入这个临时文件失败了,导致整个请求过程失败。


问题排查与解决步骤

请按照以下步骤登录您的服务器(需要 root或具有 sudo权限的用户)进行排查和修复。

第1步:确认磁盘空间使用情况

使用 df -h命令检查所有磁盘分区的使用情况。

df -h

查看结果的重点:

  • Use%: 找到使用率达到或接近 100%的分区。
  • Mounted on: 确认这个已满的分区是哪个挂载点(例如 //var/home)。根据错误信息中的路径(/var/lib/nginx/...),很可能是 //var分区满了。

示例输出:

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   39G     0 100% /
...

这个例子显示根分区 /已经使用了 100%,空间耗尽。

第2步:查找大文件或目录(定位问题根源)

磁盘满通常是由日志文件、缓存文件或上传的文件过大/过多导致的。使用 du命令来查找占用空间最大的目录。

  1. 进入可能已满的分区的根目录(例如,如果是 /分区满了,就进入 /;如果是 /var分区满了,就进入 /var)。 cd /
  2. 使用以下命令找出当前目录下各子目录的大小,并按从大到小排序du -h --max-depth=1 | sort -hr
    • du -h --max-depth=1: 以人类可读的格式显示当前目录下一级子目录的大小。
    • sort -hr: 按人类可读的数字大小进行逆序排序(从大到小)。
  3. 分析结果,找到占用空间异常大的目录(例如,几个GB或几十个GB的目录)。常见的“罪魁祸首”有:
    • /var/log: 日志文件。这是最常见的原因,特别是如果网站访问量大且日志没有自动轮转和清理。
    • /var/lib/nginx: Nginx 的缓存和临时文件目录本身。
    • /tmp: 临时文件目录。
    • /home: 用户上传的文件,如果网站有上传功能。
  4. 进入占用空间大的目录,重复上述 du命令,层层深入,直到找到具体的大文件或目录。

第3步:清理空间(解决问题)

根据找到的原因进行清理。 情况A:日志文件过大(最常见)

  • 检查 Nginx 日志/var/log/nginx/目录下的 access.logerror.log文件可能非常大。
  • 清理方法
    1. 清空当前日志文件(推荐):直接清空文件内容而不是删除文件,避免影响正在写入日志的进程。 cat /dev/null > /var/log/nginx/access.log cat /dev/null > /var/log/nginx/error.log
    2. 使用 logrotate:系统通常自带日志轮转工具 logrotate。检查 /etc/logrotate.d/nginx配置,确保其正常工作。您可以手动强制执行一次日志轮转: logrotate -f /etc/logrotate.d/nginx
    3. 删除过旧的日志文件find /var/log -name "*.log" -mtime +30 -exec rm -f {} \; # 删除30天前的日志文件

情况B:Nginx 缓存文件过大

  • 如果 /var/lib/nginx目录本身过大,可以考虑清理其下的 proxy_cache等缓存目录。但请注意,这可能会暂时影响性能。 rm -rf /var/lib/nginx/cache/*
  • 更好的做法是:在 Nginx 配置中设置合理的缓存大小和过期时间。

情况C:其他垃圾文件

  • 清理系统包管理的缓存(对于 Ubuntu/Debian): apt-get clean
  • 清理系统不再需要的旧内核和软件包(对于 Ubuntu/Debian): apt-get autoremove --purge

第4步:重启Nginx服务

清理出空间后,重启 Nginx 服务以使更改生效,并确保错误不再出现。

systemctl restart nginx

预防措施

  1. 设置日志轮转(Logrotate):确保 Nginx 和其他重要服务的日志轮转配置合理,能自动压缩旧日志并定期删除。
  2. 监控磁盘空间:设置磁盘空间监控告警(例如使用 Prometheus+ Grafana+ Alertmanager,或简单的 cron脚本),在空间使用率达到 80% 或 90% 时发送通知。
  3. 定期清理:将清理缓存和旧文件的任务加入定期计划任务(Cron Job)中。

按照以上步骤,您应该能快速定位并解决这个“No space left on device”错误。

Comments

No comments yet. Why don’t you start the discussion?

发表回复