一、当服务器磁盘爆满时会发生什么

想象一下你的服务器是个仓库,突然有一天管理员跑来告诉你:"货架全满了,新到的快递都没地方放了!"这时候系统会开始报错:数据库写入失败、应用程序崩溃、日志无法记录...甚至可能触发连锁反应导致整个业务停摆。

典型症状包括:

  • No space left on device 错误霸占终端
  • 数据库服务默默罢工(比如MySQL会直接拒绝写入)
  • 监控系统疯狂报警,手机被短信轰炸

真实案例:某电商大促期间,日志服务未设置轮转策略,一夜之间200GB磁盘被塞满,支付系统无法生成订单,直接损失300万订单量——这就是血的教训啊!

二、紧急止血的五大招式

招式1:快速定位磁盘大胃王

用Linux的duncdu组合拳,比侦探破案还刺激:

# 查看各目录占用空间(人类可读格式)
du -h --max-depth=1 / | sort -hr  
# 输出示例:
# 56G    /var
# 12G    /home
# 800M   /etc

# 安装ncdu进行交互式分析(按大小降序排列)
apt install ncdu -y && ncdu /var  
# 操作提示:
# → 方向键导航 | d 删除文件 | n 按文件名排序

避坑指南

  • 别在根目录直接运行rm -rf,手滑会删库跑路!
  • /var/log//tmp/是经典重灾区,重点检查

招式2:日志文件的断舍离

面对堆积如山的日志文件,像整理衣柜一样分类处理:

# 示例:清理7天前的Tomcat日志(保留最新)
find /opt/tomcat/logs/ -name "catalina.*.log" -mtime +7 -exec rm {} \;

# 更优雅的方式:使用logrotate配置自动化轮转
cat <<EOF > /etc/logrotate.d/tomcat
/opt/tomcat/logs/catalina.out {
    daily
    rotate 30
    missingok
    compress
    delaycompress
    notifempty
    copytruncate
}
EOF

高级技巧

  • 对于Kubernetes集群,记得清理/var/log/pods/下的僵尸日志
  • 使用zstd替代gzip压缩,节省40%空间

招式3:数据库瘦身手术

以MySQL为例,教你怎么给数据库抽脂:

-- 查询哪些表最占空间(单位MB)
SELECT 
  table_schema as '数据库',
  table_name as '表名',
  round(data_length/1024/1024, 2) as '数据大小(MB)',
  round(index_length/1024/1024, 2) as '索引大小(MB)'
FROM information_schema.TABLES
ORDER BY (data_length + index_length) DESC
LIMIT 10;

-- 清理过期数据示例(订单保留1年)
DELETE FROM order_history WHERE create_time < DATE_SUB(NOW(), INTERVAL 1 YEAR);
OPTIMIZE TABLE order_history; -- 注意这会锁表!

血泪经验

  • 生产环境慎用OPTIMIZE TABLE,建议在低峰期操作
  • 考虑使用分区表(Partition)实现自动过期

招式4:容器僵尸清理指南

Docker占用的磁盘空间就像黑洞,试试这套组合拳:

# 显示磁盘占用详情
docker system df

# 核弹级清理(慎用!会删除所有未使用的资源)
docker system prune --all --volumes --force

# 精准打击悬虚镜像
docker images --filter "dangling=true" -q | xargs docker rmi

特别提醒

  • 清理前确保没有重要数据在未使用的volume中
  • 在K8s环境中注意kubectl logs和etcd的存储占用

招式5:应急扩容黑科技

当删除文件后空间仍未释放?可能是进程还在占用:

# 查找被删除但未释放的文件(lsof神器)
lsof -nP | grep deleted  
# 输出示例:
# java    1234  root  456r   REG   253,0  10G  123456 /var/log/app.log (deleted)

# 释放方法:重启相关进程或清空文件描述符
echo "" > /proc/1234/fd/456  

高阶操作

  • 使用fallocate快速创建临时交换文件应急
  • 对于XFS文件系统,可以尝试xfs_fsr碎片整理

三、防患于未然的运维之道

监控预警系统搭建

推荐Prometheus+Alertmanager的黄金组合:

# prometheus.yml 片段示例
alerting:
  alertmanagers:
  - static_configs:
    - targets: ['alertmanager:9093']

rule_files:
  - '/etc/prometheus/rules/*.rules'

# 磁盘预警规则配置
groups:
- name: disk-alert
  rules:
  - alert: DiskSpaceCritical
    expr: 100 - (node_filesystem_avail_bytes{mountpoint="/"} * 100 / node_filesystem_size_bytes{mountpoint="/"}) > 90
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "{{ $labels.instance }} 磁盘即将爆满 (当前使用 {{ $value }}%)"

自动化运维策略

用Ansible实现定期清理的自动化:

# cleanup.yml
- hosts: all
  tasks:
    - name: Clean old logs
      file:
        path: "/var/log/nginx/access.log.$(date -d '7 days ago' +%Y%m%d)"
        state: absent
      
    - name: Rotate MySQL binary logs
      command: "mysql -e 'PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY)'"
      when: "'db-server' in group_names"

四、技术方案深度对比

方案 优点 缺点 适用场景
手动清理 精准控制 耗时易出错 紧急情况
自动化脚本 可重复执行 需要开发成本 周期性维护
存储配额 预防性控制 配置复杂 多用户环境
云存储动态扩展 弹性扩容 成本较高 云环境
日志收集外抛 减轻本地存储压力 依赖外部系统 大规模集群

终极建议

  • 中小规模部署推荐:日志轮转 + 基础监控 + 季度人工审计
  • 大型分布式系统建议:EFK日志中心 + 自动化清理策略 + 动态存储编排

记住,运维的最高境界不是救火,而是让火灾根本不会发生。下次遇到磁盘报警时,希望你能优雅地喝口咖啡,然后淡定地敲出早已准备好的解决方案。