一、当服务器磁盘爆满时会发生什么
想象一下你的服务器是个仓库,突然有一天管理员跑来告诉你:"货架全满了,新到的快递都没地方放了!"这时候系统会开始报错:数据库写入失败、应用程序崩溃、日志无法记录...甚至可能触发连锁反应导致整个业务停摆。
典型症状包括:
No space left on device错误霸占终端- 数据库服务默默罢工(比如MySQL会直接拒绝写入)
- 监控系统疯狂报警,手机被短信轰炸
真实案例:某电商大促期间,日志服务未设置轮转策略,一夜之间200GB磁盘被塞满,支付系统无法生成订单,直接损失300万订单量——这就是血的教训啊!
二、紧急止血的五大招式
招式1:快速定位磁盘大胃王
用Linux的du和ncdu组合拳,比侦探破案还刺激:
# 查看各目录占用空间(人类可读格式)
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日志中心 + 自动化清理策略 + 动态存储编排
记住,运维的最高境界不是救火,而是让火灾根本不会发生。下次遇到磁盘报警时,希望你能优雅地喝口咖啡,然后淡定地敲出早已准备好的解决方案。
评论