磁盘管理:分区、挂载、扩容与空间清理

磁盘满了是服务器上最常遇到的告警。这篇从「看结构」到「扩容」到「清理」走一遍。

一、先看清楚结构

bash
lsblk                    # 块设备树状图,最直观
lsblk -f                 # 带文件系统和 UUID
df -h                    # 已挂载分区的剩余空间
df -hT                   # 带文件系统类型
fdisk -l                 # 分区表详情

典型输出结构:

bash
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
vda    253:0    0   40G  0 disk
├─vda1 253:1    0   39G  0 part /
└─vda2 253:2    0    1G  0 part [SWAP]
vdb    253:16   0  100G  0 disk /data

二、挂载一块新盘

bash
# 1. 确认设备名
lsblk

# 2. 分区(也可以整盘不分区)
sudo fdisk /dev/vdb        # 交互:n 新建 → 一路回车 → w 写入

# 3. 格式化
sudo mkfs.ext4 /dev/vdb1
# 大容量或需要快照用 xfs
sudo mkfs.xfs /dev/vdb1

# 4. 建挂载点并挂载
sudo mkdir -p /data
sudo mount /dev/vdb1 /data

# 5. 写入 fstab 开机自动挂载
sudo blkid /dev/vdb1       # 拿到 UUID

fstab 一行:

bash
# <设备>  <挂载点>  <类型>  <选项>  <dump>  <fsck>
UUID=xxxx-xxxx  /data  ext4  defaults,noatime  0  2

一定要用 UUID 而不是 /dev/vdb1。设备名在重启后可能变化,UUID 不会。改完 fstab 先验证:sudo mount -a,没报错再重启。

三、云盘扩容

控制台把云盘从 40G 扩到 100G 后,系统里还要两步:

bash
# 1. 让内核重新识别磁盘容量
echo 1 | sudo tee /sys/class/block/vda/device/rescan
# 或者
sudo growpart /dev/vda 1        # 扩展分区 1

# 2. 扩展文件系统
sudo resize2fs /dev/vda1        # ext4
sudo xfs_growfs /               # xfs(注意参数是挂载点)

df -h                            # 确认

如果是 LVM:

bash
sudo pvresize /dev/vdb
sudo lvextend -l +100%FREE /dev/mapper/vg0-lv0
sudo resize2fs /dev/mapper/vg0-lv0

四、磁盘满了,怎么找是谁占的

bash
# 1. 先看整体
df -h

# 2. 看一级目录谁最大
sudo du -sh /* 2>/dev/null | sort -rh | head -10

# 3. 逐层深入
sudo du -sh /var/* 2>/dev/null | sort -rh | head

# 4. 找出 TOP20 大文件
sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null \
  | awk '{print $5, $9}' | sort -rh | head -20

常见「空间杀手」:

目录内容清理方式
/var/log日志journalctl --vacuum-size / logrotate
/var/cache/apt包缓存apt clean
/var/lib/docker容器与镜像docker system prune -a
/tmp临时文件谨慎清理,可能有锁文件
已删除但仍被占用文件句柄见下文
bash
# 交互式查看,比 du 直观得多
ncdu /var

删了文件但空间没释放

文件被某进程打开着,删除只是移除了目录项,磁盘块仍被占用:

bash
sudo lsof | grep deleted
# nginx  1234  www-data  5w  REG  253,1  20G  /var/log/nginx/access.log (deleted)

# 解法:让进程重新打开文件(而不是重启服务)
sudo truncate -s 0 /proc/1234/fd/5     # 清空
# 或者重启该服务
sudo systemctl restart nginx

五、inode 也会满

df -h 显示还有空间,但报 No space left on device —— 可能是 inode 用完了:

bash
df -i
# 找出哪个目录文件数最多
sudo find / -xdev -type d -exec sh -c 'echo $(ls -a "{}" | wc -l) {}' \; 2>/dev/null \
  | sort -rn | head -10

大量小文件(缓存、session、邮件队列)是典型原因。

六、文件系统选择

类型特点适用
ext4稳,最通用默认选择
xfs大文件、高并发好,支持在线扩容大容量数据盘
btrfs快照、校验和需要快照但不想用 LVM
zfs功能最强,吃内存存储服务器

七、swap 相关

bash
swapon --show
sudo swapon /swapfile
sudo swapoff /swapfile
cat /proc/sys/vm/swappiness        # 默认 60,服务器建议 10
sudo sysctl -w vm.swappiness=10
echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf

磁盘操作的铁律:动分区表之前先打快照。