云主机磁盘空间不足如何处理?
- 来源:纵横数据
- 作者:中横科技
- 时间:2026/4/21 11:27:29
- 类别:新闻资讯
上个月某个工作日的上午十点,一家做在线文档协作的客户突然打来电话,语气非常焦急。他们说用户无法保存文档了,每次点击保存按钮都提示操作失败。技术同事检查后发现,应用服务器的磁盘使用率已经达到了百分之百,系统日志里满是“设备上没有剩余空间”的错误。更麻烦的是,由于磁盘满了,远程登录也时断时续,连上去执行一条命令都要卡半天。
我让他们通过云控制台的远程连接功能登录进去,先清理了一批日志文件,把磁盘使用率降到了百分之八十左右,服务才勉强恢复。事后仔细排查发现,问题的根源是应用代码里的一个日志打印逻辑出了问题,某个循环每执行一次就往日志里写一行,运行了两个月,写出来一个几百GB的日志文件。
磁盘空间不足这个问题,说简单也简单,无非就是删文件或者加空间。但说复杂也复杂,因为如果你只做临时清理不去找根本原因,同样的坑你还会掉进去第二次、第三次。本文将从实际运维经验出发,梳理一套从紧急处理到根源治理的完整思路。
先搞清楚磁盘空间去哪儿了,精准定位大文件
当磁盘空间告警的时候,最忌讳的就是拍脑袋乱删文件。有人习惯性地去删日志,有人跑去删临时文件,删了半天发现使用率只降了一点点,反而把有用的数据搞没了。
正确的做法是先用几个命令搞清楚磁盘空间的分布情况。第一个命令是df,它能告诉你每个分区的使用情况。重点关注Use%这一列,如果某个分区的使用率超过了百分之八十五,就需要处理了。第二个命令是du,它能统计目录和文件占用的空间大小。用法是在根目录下执行du -sh *,这会把根目录下每个一级目录的总大小列出来,从大到小排个序,你就能一眼看出哪个目录是空间大户。
我遇到过很多次这样的情况,有人直接用du扫描整个根目录,结果因为文件太多,命令跑了十几分钟还没跑完,服务器负载反而被拉高了。一个更高效的方法是逐层深入,先看一级目录,找到占用最大的那个,再进入这个目录继续往下查,这样很快就能定位到具体的文件。
另外一个容易忽略的细节是隐藏文件。以点开头的文件和目录在普通的ls命令下是不显示的,但它们同样占用磁盘空间。比如用户家目录下的.bash_history、.cache这些隐藏目录,有时候会积累大量数据。检查的时候记得用ls -la来查看所有文件,包括隐藏的。
日志文件是最常见的元凶
根据我处理过的磁盘空间不足案例来看,超过一半的问题都出在日志文件上。日志文件就像厨房里的垃圾桶,如果你不定时倒掉它,总有一天会满出来。
系统日志通常存放在/var/log目录下。这个目录里的文件会被各种系统服务和应用程序写入。其中messages、syslog、kern.log这类系统核心日志,在服务器运行时间长了之后,单个文件可能达到好几个GB。有些应用程序的日志更是夸张,比如Web服务器的访问日志和错误日志,在高并发场景下一天就能写出几十GB。
处理日志文件的思路有两种。一种是临时清理,直接删除那些不再需要的旧日志。可以用find命令配合时间参数,比如找出七天之前修改过的日志文件然后删除。但需要特别注意一点,有些日志文件正在被进程写入,直接删除文件不会立刻释放磁盘空间,需要重启对应的服务或者用清空文件内容的命令来释放空间。
另一种思路是建立日志轮转机制。Linux系统自带的logrotate工具就是专门干这个活的。你可以配置logrotate定期切割日志文件,比如每天切割一次,只保留最近七天的日志,更早的自动删除。切割之后还可以选择是否压缩,压缩后的日志文件通常只有原来的十分之一大小。
有一个真实的案例让我印象深刻。客户的服务器每两个月左右磁盘就会满一次,每次都是手动去删日志。我帮他们配置了logrotate之后,大半年过去了再也没有出现过磁盘满的情况。这个工具配置一次,终身受益,强烈建议每台服务器都配置好。
应用运行产生的临时文件
除了日志,临时文件是另一个磁盘空间的大户。
应用程序在运行过程中会产生各种临时文件。比如Web应用上传文件时,文件会被先存到临时目录,处理完成后再移动到正式目录。如果上传过程中出现了错误,临时文件可能没有被及时清理,一直留在临时目录里占着空间。Linux系统的临时目录通常是/tmp和/var/tmp。这两个目录在系统重启时通常会被清空,但对于长期不重启的服务器来说,里面的垃圾文件可能会越积越多。
另一个典型的临时文件来源是各种软件包管理器。比如用yum安装软件时,下载的rpm包会缓存在/var/cache/yum目录下。用apt-get安装软件时,deb包会缓存在/var/cache/apt/archives目录下。这些缓存文件在软件安装完成后就没有用处了,可以安全地清理掉。yum清理缓存的命令是yum clean all,apt对应的命令是apt-get clean。
还有一类临时文件来自数据处理任务。比如一个数据导入任务在处理一个大型CSV文件时,可能会把它拆分成多个小块存放在临时目录里。如果任务异常中断,这些临时文件可能就永远留在了磁盘上。这类问题的根治方法是在应用程序代码中增加临时文件的清理逻辑,不管任务成功还是失败,最后都要把临时文件删除掉。
数据库和存储系统的特殊处理
如果你的云主机上运行着数据库服务,那磁盘空间不足的问题会更复杂一些。
数据库的数据文件和日志文件通常占用的空间非常大,而且不是你想删就能删的。比如MySQL的ibdata1文件是共享表空间文件,里面存着数据库的各种数据,随意删除会导致整个数据库崩溃。正确的做法是通过数据库自身的维护命令来回收空间。
MySQL的二进制日志是另一个常见的空间杀手。二进制日志记录了所有修改数据库数据的操作,用于主从复制和基于时间点的恢复。如果你的数据库开启了二进制日志,但没有设置自动清理策略,这些日志文件会一直累积,直到占满整个磁盘。解决的方法是在MySQL配置文件中设置expire_logs_days参数,比如设置为7,表示只保留最近七天的二进制日志。
PostgreSQL数据库的WAL日志类似,也需要配置合理的清理策略。对于大多数业务场景来说,保留最近三天的WAL日志已经足够了。如果磁盘空间实在紧张,可以考虑将这个保留时间进一步缩短。
还有一个容易被忽略的问题是数据库的查询临时文件。当数据库执行一个大型的排序操作或者哈希连接时,如果内存不够用,它会将中间结果临时写入磁盘。这些临时文件通常存放在数据库的数据目录下,以temp或者tmp开头。正常情况下查询结束后这些文件会被自动删除,但如果数据库进程异常崩溃,这些临时文件可能就留下了。
Docker和容器运行时占用的空间
如果你在云主机上运行Docker容器,磁盘空间的管理会面临额外的挑战。
Docker默认的存储目录是/var/lib/docker。这个目录里存放着所有的镜像、容器、卷和网络配置。随着时间的推移,这个目录很容易膨胀到几十GB甚至上百GB。
镜像层是主要的空间占用者。每当你执行docker pull拉取一个镜像,或者执行docker build构建一个镜像,都会在本地存储镜像的各个层。那些不再使用的旧镜像和悬空镜像可以通过docker image prune命令一键清理。
另一个空间大户是容器生成的数据。容器在运行过程中写入的所有数据都保存在容器的可写层里,即使容器被删除了,这些数据默认也不会自动清理。如果你用docker ps -a查看,可能会发现有很多已经停止运行但仍然存在的容器,它们占用的磁盘空间一直没有释放。定期执行docker container prune可以清理掉所有停止的容器。
容器的日志文件也值得关注。每个容器的标准输出和标准错误输出都会被Docker记录下来,存放在/var/lib/docker/containers目录下。如果一个容器长时间运行并且不停地打印日志,这个日志文件可能会变得非常大。解决的方法是在启动容器时通过log-opts参数限制日志文件的大小和数量。
清理已删除但未释放的文件
这是一个比较隐蔽的问题,很多人都没有意识到它的存在。
在Linux系统中,当一个文件正在被某个进程使用时,即使你用rm命令删除了这个文件,磁盘空间也不会立即释放。因为进程还持有这个文件的句柄,操作系统会保留文件的内容直到这个进程关闭文件或者结束。
如何发现这类问题呢?可以用lsof命令查看所有被进程打开的文件,其中标记为deleted的那些就是已经被删除但尚未释放空间的文件。如果发现某个文件被删除后仍然被进程打开,并且文件体积很大,就需要重启对应的进程,让系统真正释放磁盘空间。
我遇到过的一个案例是,一台服务器的磁盘使用率显示已经删除了几十GB的文件,但df命令看到的可用空间却没有增加。排查后发现是PHP的error_log文件被删除了,但php-fpm进程还在往这个已经不存在的文件里写错误信息。重启php-fpm之后,磁盘空间立刻释放出来了。
扩容磁盘,当清理解决不了问题的时候
有时候业务增长太快,无论你怎么清理,磁盘空间还是不够用。这时候就需要考虑扩容了。
云服务商的云硬盘支持在线扩容,也就是说你可以在不停止服务器、不丢失数据的情况下,把磁盘容量变大。操作过程分为两步,先在云控制台上调整磁盘容量,然后登录到服务器内部对文件系统进行扩容。
文件系统扩容这一步很多人觉得有风险,其实只要操作正确,风险非常低。关键是要搞清楚你的磁盘分区格式是MBR还是GPT,文件系统是ext4还是xfs,不同组合对应的扩容命令不一样。ext4文件系统用resize2fs,xfs文件系统用xfs_growfs。
扩容之前建议先做一次磁盘快照,万一操作过程中出了意外,可以用快照快速回滚。虽然扩容操作本身是安全的,但提前做个备份总是没有坏处。
一个完整的排查和解决案例
今年夏天,一家做视频处理的客户遇到了磁盘空间问题。他们的转码服务器每天处理大量视频文件,每处理完一个视频就会在本地生成一个临时文件,转码完成后再上传到对象存储。但代码里有一个bug,转码完成后没有及时删除本地的临时文件,几个月下来积累了将近2TB的数据,磁盘彻底写满了。
我接到求助之后,首先通过云控制台的远程连接登录到服务器,用df命令确认了磁盘确实已满。然后用du逐层排查,发现/var/video/temp这个目录占了绝大部分空间。进去一看,里面有数万个临时文件,最早的创建日期是三个月前。
确认这些临时文件都已经不需要之后,用find命令配合delete参数一次性删除了所有三天之前的临时文件,释放了大约1.5TB的空间。然后我帮客户写了一个简单的定时任务,每天凌晨自动清理超过一天的临时文件,避免同样的问题再次发生。
最后,我建议他们将转码过程中的临时文件目录挂载为单独的云硬盘,这样即使临时文件再次失控,也不会影响到系统盘的正常运行。客户采纳了这个建议,之后再也没有出现过磁盘写满导致服务中断的情况。
长效治理,让问题不再重现
临时清理只能解决眼前的问题,真正的长效治理需要从多个维度入手。
建立磁盘使用率的监控告警是最基础的。建议设置两个告警阈值,使用率达到百分之七十时发出警告,提醒你开始关注;达到百分之八十五时发出紧急告警,要求立即处理。这样你就有足够的时间窗口来应对,而不是等到磁盘写满了才被动响应。
对于日志文件,统一的轮转策略是必须的。无论是系统日志、应用日志还是容器日志,都应该配置自动切割和自动清理。日志保留周期可以根据业务需求来定,对于大多数场景,保留三十天已经足够。
定期巡检也是一个好习惯。每个月抽出一个小时,登录到每台服务器上,检查一下各个目录的空间占用情况,看看有没有异常增长的目录。早发现早处理,远比等到磁盘满了再手忙脚乱地处理要轻松得多。
总结
云主机磁盘空间不足的问题,处理起来说难不难,说简单也不简单。关键在于要有系统化的思路,而不是临时抱佛脚。
紧急情况下的处理流程是先用df确认哪个分区满了,再用du定位大文件和大目录,然后根据文件类型采取不同的清理策略。日志文件用logrotate做轮转,临时文件用find命令批量删除,Docker镜像和容器定期执行prune清理。
更重要的是建立长效的预防机制。监控告警让你提前发现问题,日志轮转让日志文件自动瘦身,定期巡检让你对磁盘空间的使用情况心中有数。只有把这几件事都做好了,才能真正摆脱磁盘空间不足的困扰,让服务器健康稳定地运行。




使用微信扫一扫
扫一扫关注官方微信 

