服務器磁盘寫满,通常不是一瞬間發生的。它更像一個缓慢积累的過程:訪問日誌一天天追加,临时文件没有清理,舊备份留在本地,資料库日誌悄悄膨胀。等到某天凌晨,磁盘使用率到 100%,轻則上传失敗、缓存寫不進去,重則資料库進入只讀、站点直接打不開。
磁盘吃紧时,站点會有哪些表現
- 頁面打開變慢或直接返回 500,但重啟服務後短暂恢复。
- 後台上传图片、發布文章失敗,提示“寫入失敗”或“空間不足”。
- 資料库無法寫入,评论、表單提交、訂單全部卡住。
- 日誌文件不再更新,排查問题时看不到最新记錄。
- SSH 登入後命令补全變慢,甚至無法建立临时文件。
如果你遇到其中两三條,先別急着重啟服務,登入服務器看一眼磁盘使用情况往往更直接。
先定位:哪些目錄在占空間
用 df -h 查看各分区使用率,再用 du -sh 逐层排查大目錄。常见“重灾区”包括:
- 訪問日誌與错誤日誌:Nginx、Apache、PHP、Node.js 等服務的日誌目錄。
- 資料库日誌:binlog、慢查询日誌、错誤日誌,尤其是未設定過期時間的 binlog。
- 應用临时文件:上传临时目錄、缓存目錄、會话文件、队列失敗重试文件。
- 本地备份:自動备份脚本把压缩包留在同一块盘上,越积越多。
- 容器日誌:Docker 預設 json-file 日誌如果不限制大小,可能長到几個 GB。
定位时不要只看總大小,也要看文件數量和最近修改時間。一個几十 GB 的舊备份和一個正在快速增長的日誌文件,處理方式並不一样。
日誌轮轉:別让單個文件無限追加
大多數 Linux 發行版自带 logrotate,但預設配置未必覆盖你的應用日誌。自查时重点看几項:
- 是否按天或按大小切割?只按天切割,遇到突發流量仍可能一天寫满。
- 保留多少份?保留 30 份還是 7 份,直接决定長期占用。
- 是否压缩舊日誌?compress 和 delaycompress 能明顯减少占用。
- 切割後是否通知服務重新打開日誌文件?否則進程可能繼續寫已经改名的文件。
修改配置後,建议先用 logrotate -d 做一次調试執行,確認切割、压缩、刪除顺序符合预期,再交给定时任務。
不要直接刪除正在寫入的日誌文件。進程仍持有文件句柄,磁盘空間不會立即释放。更稳妥的做法是用 logrotate 切割,或者用 truncate 清空。
清理之外,還要留出缓冲
清理只能解决当下問题,运营上還需要一些缓冲策略:
- 系統盘和資料盘尽量分開,避免日誌把系統盘寫满導致服務異常。
- 给磁盘使用率設定监控告警,比如 80% 提醒、90% 告警,別等到 100% 才處理。
- 备份文件定期归档到對象存储,本地只保留最近几份,並設定生命周期規則。
- 容器日誌配置大小上限和保留數量,避免單個容器日誌失控。
- 定期检查自動任務产生的临时文件,尤其是導出、轉碼、爬虫抓取類任務。
磁盘空間自查不需要每天做,但應该纳入每周或每月的运维清單。花几分钟看一眼趋势,比半夜被报警叫醒要從容得多。