在Ubuntu Server管理员的日常工作中,磁盘空间管理是一项看似简单却至关重要的任务。服务器磁盘空间的突然耗尽不仅会导致应用程序异常、服务中断,还可能引发数据丢失和安全问题。与桌面环境不同,服务器通常在没有人工干预的情况下长时间运行,因此磁盘空间的消耗往往是在不知不觉中发生的,直到出现问题才被发现。
传统的df -h
命令虽然可以提供磁盘使用情况的概览,但在复杂的生产环境中,这远远不够。真正的磁盘空间排查需要系统化的方法、专业的工具和深入的知识。本文将从基础命令开始,逐步深入到高级技巧,为您提供一个全面的Ubuntu Server磁盘空间排查指南。
本文将涵盖以下内容:
无论您是初级的系统管理员还是经验丰富的运维工程师,本文都将为您提供有价值的知识和技巧。
df命令详解
df
(disk free)命令是查看文件系统磁盘空间使用情况的最基本工具。虽然df -h
是最常用的形式,但df命令还有许多有用的选项:
# 查看所有文件系统的磁盘使用情况(以人类可读格式)
df -h
# 包含文件系统类型信息
df -hT
# 只显示特定类型的文件系统(如ext4)
df -hT -t ext4
# 显示inode使用情况而不是块使用情况
df -i
# 排除特定类型的文件系统(如tmpfs)
df -h -x tmpfs
# 以JSON格式输出,便于脚本处理
df --output=source,fstype,size,used,avail,pcent,target -h
理解df输出中的"Used"和"Available"列对于准确评估磁盘空间状况至关重要。需要注意的是,大多数文件系统会保留约5%的空间供root用户使用,这是为了防止普通用户填满整个磁盘导致系统问题。
du命令深入使用
du
(disk usage)命令用于估算文件和目录的磁盘使用空间。相比df,du能提供更细粒度的信息:
# 查看当前目录的磁盘使用情况
du -sh
# 查看目录及其子目录的磁盘使用情况(前10个)
du -h /var | sort -rh | head -10
# 排除某些类型的文件(如.log文件)
du -h --exclude="*.log" /var
# 显示所有文件和目录的详细信息
du -ah /path/to/directory
# 设置计算深度(只显示2级目录)
du -h --max-depth=2 /var
# 使用null分隔符处理包含空格的文件名
find /var -type f -exec du -h {} + | sort -rh | head -10
find命令高级用法
find命令是查找大文件的最强大工具之一:
# 查找大于100MB的文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
# 查找最近7天内修改过的大于50MB的文件
find / -type f -size +50M -mtime -7 -exec ls -lh {} \; 2>/dev/null
# 查找并排序最大的10个文件
find / -type f -exec du -h {} + 2>/dev/null | sort -rh | head -10
# 使用%P打印相对路径,避免长路径名问题
find /var -type f -size +50M -printf "%s %P\n" | sort -nr | head -10
# 结合xargs处理大量文件
find / -type f -size +100M -print0 | xargs -0 ls -lh
ncdu - 交互式磁盘使用分析器
ncdu(NCurses Disk Usage)是一个基于ncurses库的交互式磁盘使用分析工具,比传统的du命令更加用户友好:
# 安装ncdu
sudo apt install ncdu
# 扫描整个系统(需要root权限)
sudo ncdu /
# 扫描特定目录
ncdu /var
# 排除某些目录(如node_modules)
ncdu --exclude node_modules /path/to/directory
# 导出扫描结果
ncdu -o scan.txt /var
ncdu的优势在于其交互式界面,允许用户快速导航文件系统树、排序结果和删除文件,而无需记住复杂的命令选项。
稀疏文件处理
稀疏文件是一种特殊类型的文件,它允许高效地存储大部分为空的数据。虽然稀疏文件在磁盘上占用的空间小于其名义大小,但它们可能在某些情况下导致误解:
# 创建稀疏文件
dd if=/dev/zero of=sparse_file bs=1 count=0 seek=1G
# 检查文件是否为稀疏文件
filefrag -v sparse_file
# 查看文件的实际磁盘使用情况
du -h sparse_file
ls -lh sparse_file # 显示的大小可能误导
磁盘空间与已删除文件
当进程打开文件后,即使文件被删除,磁盘空间也不会立即释放,直到所有指向该文件的文件描述符都被关闭:
# 查找已删除但仍被进程占用的文件
lsof +L1 # 显示链接数小于1的文件
lsof | grep deleted
# 检查特定进程打开的文件
ls -l /proc/<PID>/fd/* | grep deleted
磁盘配额检查
在多用户系统中,磁盘配额可能限制用户或组的磁盘使用:
# 检查配额是否启用
quota -v
# 显示所有用户的配额使用情况
repquota -a
# 检查特定用户的配额
quota -u username
inode使用情况分析
inode是Unix-like文件系统中用于存储文件元数据的数据结构。inode耗尽会导致"No space left on device"错误,即使磁盘还有剩余空间:
# 查看inode使用情况
df -i
# 查找inode使用最多的目录
find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n
# 另一种方法:统计每个目录的文件数
sudo find /path -xdev -type f | cut -d "/" -f 2,3 | sort | uniq -c | sort -n
# 查找包含大量小文件的目录
sudo find / -type d -print0 | while IFS= read -r -d '' dir; do
files=$(find "$dir" -maxdepth 1 -type f | wc -l)
echo "$files $dir"
done | sort -rn | head -20
块分配与碎片化分析
文件碎片化虽然在现代文件系统中较少见,但在某些情况下仍可能成为问题:
# 检查文件碎片化情况
filefrag -v large_file
# 检查文件系统碎片化(需要调试工具)
debugfs -R "stat /" /dev/sda1
系统日志轮转机制
Ubuntu使用logrotate管理日志轮转,理解其配置对于管理日志空间至关重要:
# 查看logrotate配置
cat /etc/logrotate.conf
ls /etc/logrotate.d/
# 手动运行logrotate
logrotate -vf /etc/logrotate.conf
# 查看logrotate状态
cat /var/lib/logrotate/status
日志文件分析技巧
# 查找最大的日志文件
find /var/log -type f -name "*.log" -exec du -h {} + | sort -rh | head -10
# 清空日志文件(而不是删除)
: > /var/log/large.log
# 使用journalctl管理systemd日志
journalctl --disk-usage
journalctl --vacuum-size=100M # 保留最近100M的日志
使用btrfs或zfs的高级功能
如果使用btrfs或zfs文件系统,可以利用其高级功能进行空间管理:
# btrfs文件系统空间使用详情
btrfs filesystem usage /
btrfs filesystem df /
# btrfs子卷管理
btrfs subvolume list /
btrfs subvolume du /path
# zfs空间使用详情
zfs list -o space
内核事件跟踪
有时,磁盘空间的异常消耗可能与内核或应用程序的行为有关:
# 使用auditd跟踪文件创建
sudo auditctl -w /path/to/monitor -p w -k disk_monitor
# 使用inotify监控目录变化
inotifywait -m -r -e create --format '%w%f' /path/to/monitor | while read FILE; do
echo "File created: $FILE"
# 记录或处理事件
done
Docker磁盘空间管理
Docker容器和镜像可能消耗大量磁盘空间:
# 查看Docker磁盘使用情况
docker system df
docker system df -v
# 清理无用的Docker资源
docker system prune # 清理所有无用资源
docker image prune # 清理无用镜像
docker volume prune # 清理无用卷
# 查找最大的Docker镜像和容器
docker images --format "{{.Size}}\t{{.Repository}}:{{.Tag}}" | sort -h
docker ps -s --format "{{.Size}}\t{{.Names}}" | sort -h
# 检查Doverlay2驱动器的使用情况
du -h /var/lib/docker/overlay2 | sort -rh | head -20
容器日志管理
容器日志可能快速增长并消耗大量空间:
# 查看容器日志大小
docker ps -q | xargs docker inspect --format='{{.LogPath}} {{.Name}}' | xargs ls -hl
# 限制容器日志大小
# 在docker run时添加参数:--log-opt max-size=10m --log-opt max-file=3
# 清理容器日志(谨慎操作)
truncate -s 0 /var/lib/docker/containers/*/*-json.log
数据库文件管理
数据库可能占用大量磁盘空间,需要特殊的管理策略:
# PostgreSQL空间管理
sudo -u postgres psql -c "SELECT datname, pg_size_pretty(pg_database_size(datname)) as size FROM pg_database;"
# MySQL/MariaDB空间管理
SELECT table_schema "Database",
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) "Size (MB)"
FROM information_schema.TABLES
GROUP BY table_schema;
# 查找最大的数据库表
SELECT table_name,
ROUND((data_length + index_length) / 1024 / 1024, 2) as size_mb
FROM information_schema.TABLES
ORDER BY size_mb DESC
LIMIT 10;
数据库维护操作
定期维护可以回收空间并优化性能:
# PostgreSQL vacuum操作
VACUUM FULL ANALYZE;
# MySQL表优化
OPTIMIZE TABLE table_name;
# SQLite空间回收
sqlite3 database.db "VACUUM;"
备份文件空间管理
备份文件是必要的,但可能占用大量空间:
# 查找备份文件
find / -name "*backup*" -o -name "*.bak" -o -name "*.tgz" -o -name "*.tar.gz"
# 使用rdiff-backup管理增量备份
rdiff-backup --remove-older-than 2M /path/to/backup
# 使用borgbackup空间管理
borg compact /path/to/repo
快照管理
如果使用LVM或btrfs/zfs,快照可能占用大量空间:
# LVM快照管理
lvs -o +snapshot_size # 查看快照大小
lvremove /dev/vg0/snapshot # 删除快照
# btrfs快照管理
btrfs subvolume delete /path/to/snapshot
磁盘空间监控脚本
创建自动化脚本定期监控磁盘空间:
#!/bin/bash
# disk_monitor.sh
THRESHOLD=90
CURRENT=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')
if [ "$CURRENT" -gt "$THRESHOLD" ] ; then
mail -s "磁盘空间警报: 使用率 ${CURRENT}%" admin@example.com <<EOF
警告: 根分区磁盘使用率已超过 ${THRESHOLD}%
当前使用率: ${CURRENT}%
请立即处理。
EOF
# 附加自动化清理操作
find /tmp -type f -mtime +7 -delete
journalctl --vacuum-size=200M
fi
使用监控系统
集成到现有监控系统中:
# Prometheus node_exporter指标
# 默认提供node_filesystem_avail_bytes等指标
# Zabbix监控项
vfs.fs.size[/,pfree]
# Nagios检查命令
check_disk -w 20% -c 10% -p /
日志管理策略
配置合理的日志轮转策略:
# /etc/logrotate.d/custom
/var/log/app/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 root root
size 100M # 基于大小而非时间的轮转
}
配额和限制
实施磁盘配额和用户限制:
# 启用配额
apt install quota
sed -i 's/errors=remount-ro/errors=remount-ro,usrquota,grpquota/' /etc/fstab
mount -o remount /
quotacheck -avugm
quotaon -avug
# 设置用户配额
setquota -u username 500M 1G 0 0 /
趋势分析和预测
使用工具分析磁盘使用趋势:
# 收集历史数据
#!/bin/bash
date +"%Y-%m-%d %H:%M:%S" >> /var/log/disk_usage.log
df -h / >> /var/log/disk_usage.log
echo "---" >> /var/log/disk_usage.log
# 使用Python进行趋势预测
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
import numpy as np
# 分析磁盘使用趋势并预测填满时间
问题描述
生产数据库服务器突然磁盘空间告急,根分区使用率在几小时内从30%上升到95%。
排查过程
df -h
确认磁盘使用情况du -sh /* | sort -rh
发现/var目录异常增大ncdu /var
定位到/var/lib/mysql目录ls -lh /var/lib/mysql
发现大量mysql-bin.*文件解决方案
# 临时清理
PURGE BINARY LOGS BEFORE NOW();
# 永久配置
echo "expire_logs_days = 7" >> /etc/mysql/mysql.conf.d/mysqld.cnf
systemctl restart mysql
问题描述
应用服务器磁盘空间不足,但常规排查未找到明显的大文件。
排查过程
df -h
确认磁盘使用率达98%du -sh /* | sort -rh
显示/var/lib/docker占用最多空间docker system df
确认容器和镜像不是主要问题du -sh /var/lib/docker/containers/* | sort -rh
发现特定容器日志巨大lsof | grep deleted
发现已删除但仍被进程占用的日志文件解决方案
# 清理特定容器日志
truncate -s 0 /var/lib/docker/containers/<container_id>/*-json.log
# 配置全局日志限制
echo '{"log-driver":"json-file","log-opts":{"max-size":"10m","max-file":"3"}}' > /etc/docker/daemon.json
systemctl restart docker
问题描述
服务器频繁出现磁盘空间不足,但每次清理后很快又再次出现。
排查过程
find / -type f -mmin -60 -size +10M
查找最近修改的大文件dmesg | grep -i crash
确认应用程序频繁崩溃解决方案
# 清理现有崩溃文件
apport-cli --purge
# 限制核心转储大小
echo "ulimit -c 1000000" >> /etc/default/apport # 限制为1GB
# 修复应用程序内存泄漏问题
Ubuntu Server磁盘空间管理是一项需要系统性方法和深入知识的任务。从基础的df/du命令到高级的文件系统分析,从 reactive的问题排查到proactive的预防策略,成功的磁盘空间管理需要多方面的技能和工具。
本文涵盖了从基础到高级的各种技术和策略,包括:
最重要的是,磁盘空间管理不应该只是在出现问题时的应急反应,而应该是系统管理日常工作的一部分。通过实施合理的监控、警报和预防措施,可以避免大多数磁盘空间相关的问题,确保系统的稳定性和可靠性。
命令 | 描述 | 示例 |
---|---|---|
| 显示磁盘使用情况 |
|
| 查看目录总大小 |
|
| 交互式磁盘分析 |
|
| 查找已删除但未释放的文件 |
|
| 查找大于100M的文件 |
|
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。