服务器磁盘占用过高?这6个运维技巧帮你高效清理,释放存储空间

快小二编导 运维技巧

作为一名资深运维工程师,我曾无数次接到过这样的紧急工单:“服务器磁盘满了!业务系统无法正常运行!” 磁盘占用过高是服务器运维中最常见的问题之一,轻则导致系统响应变慢,重则引发服务崩溃、数据丢失。尤其是在云服务器或物理服务器资源有限的场景下,学会高效清理磁盘空间,是每个运维人员的必备技能。今天,我就结合实际工作经验,分享一套从“定位问题”到“彻底清理”的全流程运维技巧,帮你快速解决磁盘占用危机。

一、先定位:找到磁盘占用的“罪魁祸首”

清理磁盘的第一步,不是盲目删除文件,而是精准定位占用空间的“源头”。如果连问题出在哪都不知道,贸然删除可能会误删系统关键文件,导致更严重的故障。以下是我常用的定位工具和方法:

1. 用df命令看整体磁盘使用情况

首先,通过df -h命令查看服务器所有磁盘分区的使用情况(-h参数以人类可读的单位显示,比如GB、MB):

df -h

输出示例:

Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   38G  1.2G  97% /
tmpfs           1.9G     0  1.9G   0% /dev/shm
/dev/vdb1       100G   50G   45G  53% /data

从结果中可以看到,/dev/vda1分区(根目录/)的使用率已经达到97%,这就是我们需要重点处理的对象。

2. 用du命令逐层排查大文件/目录

知道了哪个分区满了,接下来用du命令(Disk Usage)逐层向下排查,找到占用空间最大的目录或文件。

  • 查看根目录下各子目录的大小:

    du -h --max-depth=1 / | sort -hr

    解释:--max-depth=1表示只看一级子目录,sort -hr按大小倒序排列(h表示人类可读,r表示反向)。
    输出示例:

    30G    /var
    5G     /usr
    2G     /home
    ...

    可以看到/var目录占用了30G,是根目录下的“空间大户”。

  • 继续深入/var目录排查:

    du -h --max-depth=1 /var | sort -hr

    假设输出显示/var/log占用了25G,那问题就锁定在日志文件上了。

  • 找到具体的大文件:
    如果想直接找出某个目录下单个超过1G的文件,可以用:

    find /var/log -type f -size +1G -exec ls -lh {} \;

    这样就能快速定位到占用空间的具体文件,比如/var/log/nginx/access.log可能已经达到10G。

3. 注意“隐藏”的空间占用:已删除但未释放的文件

有时候,你会发现df显示磁盘已满,但du却查不到对应的大文件——这很可能是文件被删除但进程仍在占用(比如日志文件被删除后,nginx还在写入)。此时需要用lsof命令查看“已删除但未释放”的文件:

lsof | grep deleted

输出示例:

nginx    1234  root    5w   REG    8,1 10737418240  123456 /var/log/nginx/access.log (deleted)

解决方法是重启对应的进程(比如systemctl restart nginx),让进程释放对该文件的占用,磁盘空间就会自动释放。

二、再清理:针对性删除“无用数据”

定位到问题后,就可以开始清理了。但清理时一定要区分“可删”和“不可删”,避免误操作。以下是我总结的几类常见清理对象:

1. 日志文件:最常见的“空间杀手”

日志文件(如/var/log下的系统日志、应用日志)是磁盘占用的“重灾区”,尤其是Web服务器(Nginx、Apache)、数据库(MySQL)的日志,很容易积累到几十G。

安全清理日志的方法:

  • 方法1:按时间删除旧日志
    很多日志会按日期分割(比如access.log.20240501),可以删除7天前的旧日志:

    find /var/log -name "*.log.*" -mtime +7 -exec rm -f {} \;

    解释:-mtime +7表示修改时间超过7天的文件。

  • 方法2:“截断”正在写入的日志(不重启进程)
    如果日志文件还在被进程写入(比如access.log),直接删除会导致进程无法继续写入(需要重启)。此时可以用truncate命令“清空”文件,保留文件本身:

    随机图片

    truncate -s 0 /var/log/nginx/access.log

    这样既释放了空间,又不影响进程继续写入。

  • 方法3:配置日志轮转(从根源解决)
    清理日志只是“治标”,配置日志轮转(logrotate)才是“治本”。比如为Nginx配置日志轮转:
    编辑/etc/logrotate.d/nginx文件:

    /var/log/nginx/*.log {
      daily       # 每天轮转一次
      rotate 7    # 保留7天的日志
      compress    # 压缩旧日志
      delaycompress # 延迟压缩(避免影响当前日志)
      missingok   # 日志不存在也不报错
      notifempty  # 空日志不轮转
      create 0640 nginx nginx # 新建日志的权限和属主
      sharedscripts
      postrotate
          if [ -f /var/run/nginx.pid ]; then
              kill -USR1 `cat /var/run/nginx.pid` # 通知Nginx重新打开日志文件
          fi
      endscript
    }

    配置后,系统会自动按天轮转日志,无需手动清理。

2. 临时文件:用完即删的“垃圾”

系统和应用会产生大量临时文件,比如/tmp/var/tmp目录下的文件,这些文件通常是临时存储的,重启后会自动删除,但如果长期不清理,也会占用大量空间。

清理临时文件:

  • 删除/tmp下超过7天未修改的文件:
    find /tmp -type f -mtime +7 -exec rm -f {} \;
  • 注意:/tmp目录下可能有正在使用的临时文件,不要直接rm -rf /tmp/*,否则可能导致应用崩溃。

3. 软件包缓存:更新后留下的“遗迹”

Linux系统(如CentOS、Ubuntu)在安装或更新软件时,会缓存安装包(比如RPM、DEB包),这些缓存文件在安装完成后就没用了。

清理软件包缓存:

  • CentOS/RHEL系统(用yum):
    yum clean all # 清理所有缓存
  • Ubuntu/Debian系统(用apt):
    apt-get clean # 清理已下载的安装包
    apt-get autoclean # 清理旧版本的安装包
  • Docker镜像/容器缓存(如果服务器运行Docker):
    Docker的镜像、容器和卷也会占用大量空间,可通过以下命令清理:
    docker system prune -a # 清理未使用的镜像、容器、网络和卷(注意:会删除所有未运行的容器和未使用的镜像)
    docker volume prune # 清理未使用的卷

4. 备份文件:过期的“冗余数据”

很多运维人员会定期备份数据,但备份文件如果长期不清理,会逐渐占满磁盘。比如数据库备份(*.sql)、网站文件备份(*.tar.gz)等。

清理备份文件:

  • 制定备份策略:比如保留最近3份全量备份,删除更早的备份。
  • 示例:删除/data/backup下超过30天的备份文件:
    find /data/backup -name "*.tar.gz" -mtime +30 -exec rm -f {} \;

5. 大文件:意外生成的“巨无霸”

有时候,应用会意外生成大文件,比如程序调试时的输出日志、错误的临时文件等。比如我曾遇到过一个Java应用因bug生成了一个10G的error.log,导致磁盘满了。

处理大文件:

  • find命令找出大文件:
    find / -type f -size +5G -exec ls -lh {} \; # 找出所有超过5G的文件
  • 确认文件用途:如果是无用文件(比如调试日志),直接删除;如果是有用文件(比如数据库文件),考虑迁移到更大的磁盘分区。

6. 系统日志:内核和系统服务的“痕迹”

除了应用日志,系统日志(如/var/log/kern.log/var/log/messages)也可能占用空间。可以用logrotate统一管理,或者手动清理旧日志。

三、后预防:避免磁盘再次“爆满”

清理完磁盘后,还要做好预防措施,避免问题再次发生。以下是几个实用建议:

1. 监控磁盘使用率

通过监控工具(如Zabbix、Prometheus+Grafana)设置磁盘使用率告警,当使用率超过80%时及时通知运维人员,防患于未然。

示例Zabbix告警规则:

  • 触发器:{Template OS Linux:vfs.fs.size[/,pused].last()} > 80
  • 告警级别:警告(使用率80%)、严重(使用率90%)、灾难(使用率95%)

2. 定期自动清理

将清理命令写入定时任务(crontab),实现自动化清理。比如:

  • 每天凌晨2点清理7天前的日志:
    crontab -e # 编辑定时任务
    # 添加以下内容
    0 2 * * * find /var/log -name "*.log.*" -mtime +7 -exec rm -f {} \;
    0 2 * * * find /tmp -type f -mtime +7 -exec rm -f {} \;

3. 合理规划磁盘分区

新服务器部署时,建议将不同目录分在不同分区,比如:

  • /(根目录):分配40-60G
  • /var(日志、临时文件):分配50-100G(如果日志多,可更大)
  • /data(数据、备份):分配剩余大部分空间
    这样即使某个分区满了,也不会影响其他分区的正常运行。

4. 限制日志文件大小

对于重要的应用日志,可以在应用配置中限制单个日志文件的大小,比如Nginx的nginx.conf中设置:

http {
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /var/log/nginx/access.log main;
    error_log /var/log/nginx/error.log warn;

    # 限制单个日志文件大小为1G,超过则自动分割
    open_log_file_cache max=1000 inactive=20s valid=1m;
    log_rotate 10; # 保留10个分割文件
}

四、注意事项:这些“雷区”不要踩

清理磁盘时,有几个“雷区”一定要避开,否则可能导致系统崩溃:

  1. 不要直接删除/var/lib/mysql下的文件:这是MySQL的数据库文件,删除会导致数据丢失。
  2. 不要删除/usr/bin/usr/lib下的系统文件:这些是系统运行的关键文件,删除会导致命令无法执行。
  3. 不要随意rm -rf /:这是“自杀式”操作,会删除根目录下所有文件,导致系统彻底崩溃。
  4. 清理前备份重要文件:比如数据库备份、配置文件等,避免误删后无法恢复。

总结

服务器磁盘占用过高并不可怕,关键是先定位、再清理、后预防。通过dfdu找到问题源头,针对性清理日志、临时文件、缓存等无用数据,再通过监控和定时任务预防问题复发,就能确保服务器稳定运行。记住:清理磁盘的核心是“只删无用数据”,永远不要碰系统关键文件——毕竟,数据安全比释放空间更重要。

希望这些技巧能帮你解决磁盘占用的问题,如果你有其他运维经验,欢迎在评论区分享!

0 16275

留言0

评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
验证码