Linux第11篇:存储管理——磁盘分区、LVM 与文件系统

本文导读:本文是系列第 11 篇。Java SaaS 应用的数据库文件、日志文件、AI 模型文件都需要可靠的存储管理支撑。本文讲解磁盘分区、ext4/xfs文件系统选型、LVM逻辑卷管理与动态扩容,以及挂载配置,并提供为AI模型文件配置独立大容量存储的实战方案。

关键词:Linux磁盘管理、LVM教程、Linux挂载磁盘、ext4 xfs文件系统对比、Linux磁盘扩容、fstab配置


一、为什么 Java SaaS 运维必须懂存储管理

数据库服务器磁盘空间耗尽,是生产事故中出现频率极高的一类场景------MySQL的binlog不断增长、应用日志没有清理策略、AI模型文件越积越多,任何一项失控都可能导致磁盘写满,进而引发数据库无法写入、应用崩溃的连锁故障。

更麻烦的是,很多团队在服务器初始化时只用了一块磁盘、一个分区,所有东西都堆在根分区下,一旦某个目录(比如日志目录)异常增长,会直接影响整个系统的可用空间,甚至导致系统本身(如 /var、/tmp)无法正常工作。理解磁盘分区、LVM动态扩容,能让你在数据持续增长的业务场景下,从容应对存储规划和紧急扩容需求。

复制代码
不规范的存储布局(风险)          规范的存储布局(推荐)
┌─────────────────┐              ┌─────────────────┐
│   单一根分区 /    │              │  / (系统盘,小)   │
│  系统+数据+日志    │              │  /data (数据盘)   │
│  混在一起          │              │  /var/log (日志)  │
│  一处增长全盘受影响 │              │  各自独立,互不影响 │
└─────────────────┘              └─────────────────┘

二、磁盘与分区基础

2.1 查看磁盘设备

复制代码
# 查看系统识别到的所有磁盘块设备
lsblk
# 输出示例:
# NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
# sda      8:0    0   50G  0 disk
# ├─sda1   8:1    0    1G  0 part /boot
# └─sda2   8:2    0   49G  0 part /
# sdb      8:16   0  100G  0 disk          ← 这是一块还未分区使用的新磁盘

# 查看磁盘的详细分区信息
sudo fdisk -l

# 查看磁盘空间使用情况(已挂载的分区)
df -h

lsblk 的输出是排查存储问题的起点------NAME 列体现了磁盘和分区的父子关系(sda 是整块磁盘,sda1/sda2 是它的分区),TYPE 列区分 disk(整盘)和 part(分区),MOUNTPOINT 显示这个分区当前挂载在哪个目录下,如果这一列是空的,说明这块磁盘或分区还没有被挂载使用,是新增存储设备时需要重点关注的状态。

2.2 磁盘分区操作

复制代码
# 对新磁盘 /dev/sdb 进行分区(以 fdisk 为例,适合MBR分区表,2TB以下磁盘)
sudo fdisk /dev/sdb

# fdisk 交互式操作流程:
# 输入 n  → 创建新分区
# 输入 p  → 选择主分区类型
# 输入分区号(默认即可,直接回车)
# 输入起始扇区(默认即可,直接回车)
# 输入结束扇区或分区大小(如 +50G 表示创建50GB大小的分区)
# 输入 w  → 写入分区表并退出(这一步才是真正生效,之前都可以用q退出放弃修改)

# 对于2TB以上的大磁盘,必须用支持GPT分区表的parted工具(fdisk的MBR分区表无法支持超过2TB)
sudo parted /dev/sdb
# (parted) mklabel gpt
# (parted) mkpart primary ext4 0% 100%
# (parted) quit

⚠️ 踩坑记录 :fdisk 的交互式操作中,在执行 w(写入)命令之前,所有的修改都只存在于内存里,可以随时用 q 退出而不产生任何实际影响,这是一个重要的安全机制------意味着你可以放心地多次尝试、查看预览效果,真正有风险的是确认无误后执行 w 的那一刻 。另外,分区操作前务必反复确认操作的是正确的设备 (如/dev/sdb而不是已经在用的/dev/sda),对生产服务器上正在使用的磁盘误操作分区命令,极可能导致数据完全丢失且难以恢复,这是存储管理中最高风险等级的操作之一,没有十足把握之前,宁可多确认几遍设备名称。

2.3 文件系统创建与选型

分区创建好之后,还只是一块"裸"空间,需要格式化成具体的文件系统才能正常存储文件。

复制代码
# 格式化为 ext4 文件系统(最经典、最稳定的Linux文件系统,兼容性最好)
sudo mkfs.ext4 /dev/sdb1

# 格式化为 xfs 文件系统(大文件、高并发写入场景性能更优,很多发行版的默认选择)
sudo mkfs.xfs /dev/sdb1

ext4 和 xfs 是目前生产环境最主流的两种文件系统选择,理解它们的差异有助于针对不同场景做出合理选型:

维度 ext4 xfs
成熟度 极高,历史悠久,社区资源最丰富 成熟稳定,RHEL/CentOS默认选择
单文件最大容量 16TB 8EB(远超实际需求)
大文件写入性能 一般 更优(适合数据库、大模型文件)
缩小分区(shrink) 支持 不支持(这是关键差异,需要慎重规划)
适用场景 通用场景、系统盘 数据库、大文件存储、AI模型存储

⚠️ 踩坑记录 :xfs文件系统创建后无法直接缩小(shrink)容量 ,这是它和ext4最大的实践差异。如果你给 /data 分区规划用xfs且分配了100GB,后续发现规划过大想缩减到50GB,xfs无法直接做到,只能整个重新格式化(意味着数据需要先完整迁移备份)。而ext4在一定条件下支持缩小操作。在分区规划阶段就要想清楚未来的容量需求趋势,存储数据库或大文件、且确定后续只会扩容不会缩容的场景用xfs没有问题;如果不确定容量规划是否合理、可能需要灵活调整的场景,ext4的灵活性更高。


三、LVM:逻辑卷管理,让磁盘扩容不再是噩梦

3.1 为什么需要 LVM

如果直接对磁盘分区使用(前面讲的传统方式),分区大小在创建时就基本固定了,后续想要扩容会非常麻烦(往往需要停机、备份数据、重新分区)。LVM(Logical Volume Manager,逻辑卷管理)通过在磁盘和文件系统之间增加一个抽象层,让存储空间的扩容(甚至跨多块物理磁盘合并空间)变得简单灵活,这是生产环境强烈推荐使用LVM而不是直接对裸分区操作文件系统的核心原因。

复制代码
LVM 三层抽象结构:

  PV (Physical Volume)        物理卷:对应实际的磁盘或分区
  /dev/sdb1  /dev/sdc1
        │         │
        └────┬────┘
             ▼
  VG (Volume Group)           卷组:把多个PV合并成一个统一的存储池
        myapp-vg
             │
             ▼
  LV (Logical Volume)         逻辑卷:从VG中划分出来实际使用的"虚拟分区"
   myapp-vg/data-lv
             │
             ▼
        文件系统(ext4/xfs)    最终挂载使用的文件系统建立在LV之上

这个三层结构的核心价值在于:当VG(卷组)的空间不够用时,只需要往里面添加新的物理磁盘(扩展PV),VG的总容量就会增大,然后就可以从这个更大的"池子"里继续给LV扩容,整个过程通常不需要停机,这是LVM相比传统分区方式最大的优势。

3.2 LVM 完整配置实战

复制代码
# 第一步:创建物理卷(PV),把裸磁盘/分区纳入LVM管理体系
sudo pvcreate /dev/sdb

# 查看已创建的物理卷
sudo pvs
sudo pvdisplay

# 第二步:创建卷组(VG),把物理卷组织成一个存储池
sudo vgcreate myapp-vg /dev/sdb

# 查看卷组信息
sudo vgs
sudo vgdisplay myapp-vg

# 第三步:从卷组中创建逻辑卷(LV),指定要使用多大空间
sudo lvcreate -L 50G -n data-lv myapp-vg
# -L: 指定大小  -n: 逻辑卷名称  myapp-vg: 从哪个卷组划分空间

# 也可以用百分比指定占用卷组的比例,而不是固定大小
sudo lvcreate -l 100%FREE -n data-lv myapp-vg
# -l 100%FREE 表示用掉卷组里所有剩余空间

# 查看逻辑卷信息
sudo lvs
sudo lvdisplay /dev/myapp-vg/data-lv

# 第四步:对逻辑卷格式化文件系统(这一步和普通分区格式化操作完全相同)
sudo mkfs.xfs /dev/myapp-vg/data-lv

# 第五步:创建挂载点并挂载
sudo mkdir -p /data
sudo mount /dev/myapp-vg/data-lv /data

# 验证挂载结果
df -h /data

3.3 LVM 动态扩容实战:业务增长时的无缝扩容

这是LVM最核心的实战价值。假设业务数据增长,原本规划的50GB空间不够用了,需要扩容到80GB:

复制代码
# 场景:往服务器新增了一块磁盘 /dev/sdc,准备把它的空间并入已有的卷组用于扩容

# 第一步:把新磁盘纳入PV管理
sudo pvcreate /dev/sdc

# 第二步:把新的PV加入已有卷组,卷组总容量随之增大
sudo vgextend myapp-vg /dev/sdc

# 验证卷组容量已经增加
sudo vgs myapp-vg

# 第三步:扩展逻辑卷大小(这里扩展到80G,也可以用 +30G 表示在原基础上增加30G)
sudo lvextend -L 80G /dev/myapp-vg/data-lv

# 第四步:扩展文件系统大小,使其填满刚扩大的逻辑卷空间
# 注意:这一步的命令因文件系统类型而异!

# 如果是 xfs 文件系统:
sudo xfs_growfs /data

# 如果是 ext4 文件系统:
sudo resize2fs /dev/myapp-vg/data-lv

# 验证扩容结果
df -h /data

💡 生产提示 :这套LVM扩容流程的最大优势是全程不需要停机、不需要卸载文件系统、业务可以持续运行------这对生产数据库服务器尤其重要,传统的"备份数据、重新分区、恢复数据"流程往往需要数小时甚至更长的停机时间,而LVM扩容通常几分钟内就能完成,对业务几乎无感知。这是为什么生产环境的数据盘、日志盘强烈建议从一开始就用LVM管理,而不是直接对裸分区操作,即使最初规划的容量看起来"应该够用很久",业务增长的速度往往超出预期,提前用LVM做好弹性扩容的准备是更稳妥的做法。
⚠️ 踩坑记录 :lvextend 扩展逻辑卷大小后,必须紧接着执行对应文件系统的扩容命令 (xfs用xfs_growfs,ext4用resize2fs),这一步经常被遗漏。如果只扩展了LV但忘记扩展文件系统,lvs命令看到的逻辑卷容量已经变大了,但df -h看到的实际可用空间却还是原来的大小------这种"LV扩容了但文件系统没跟上"的状态会让人困惑,误以为扩容操作失败了,其实只是漏了最后一步。另外要特别注意:xfs_growfs的参数是挂载点路径(如/data),而resize2fs的参数是设备路径(如/dev/myapp-vg/data-lv),两者用法不同,混用会报错。


四、挂载管理:mount 与 /etc/fstab 自动挂载

4.1 手动挂载与卸载

复制代码
# 手动挂载(重启后失效,仅本次会话有效,适合临时测试)
sudo mount /dev/myapp-vg/data-lv /data

# 查看当前所有挂载点
mount | grep myapp-vg
df -hT    # -T 额外显示文件系统类型

# 卸载(卸载前必须确保没有进程正在使用这个挂载点下的文件,否则会报错"device is busy")
sudo umount /data

# 如果卸载时提示设备忙,可以用 lsof 或 fuser 查找是哪个进程在占用
sudo lsof +D /data
sudo fuser -m /data

4.2 配置开机自动挂载:/etc/fstab

手动挂载在服务器重启后会失效,生产环境必须配置 /etc/fstab 实现开机自动挂载。

复制代码
# 查看分区的UUID(强烈建议用UUID而不是设备名/dev/sdb1来配置fstab)
sudo blkid /dev/myapp-vg/data-lv
# 输出示例:
# /dev/mapper/myapp--vg-data--lv: UUID="1234abcd-5678-..." TYPE="xfs"

# 编辑 fstab 配置文件
sudo vim /etc/fstab

# /etc/fstab 配置示例(追加新的一行)
UUID=1234abcd-5678-... /data xfs defaults 0 2

/etc/fstab 每一行有6个字段,理解它们的含义对正确配置至关重要:

字段 含义 示例
1 设备标识(推荐用UUID) UUID=1234abcd-...
2 挂载点 /data
3 文件系统类型 xfs
4 挂载选项 defaults
5 dump备份标记(通常设0,不使用传统dump备份机制) 0
6 fsck开机检查顺序(根分区是1,其他数据分区是2,0表示不检查) 2
复制代码
# 配置完fstab后,先用这条命令测试配置是否正确,而不要直接重启服务器验证!
sudo mount -a

# 如果mount -a执行没有报错,说明fstab配置语法正确,可以放心重启验证
df -h /data

⚠️ 踩坑记录(极其重要) :/etc/fstab 配置错误是导致服务器"重启后无法正常启动"的高频原因之一------如果文件里某一行的UUID写错、或者指向了一个已经不存在的设备,系统重启时会在尝试挂载这个不存在或错误的设备时卡住,进入紧急救援模式(emergency mode),无法正常登录系统,需要通过云控制台或者物理终端进入救援模式手动修复fstab才能恢复。这就是为什么强烈建议改完fstab后先用mount -a命令验证语法和设备正确性,而不要直接重启服务器去验证 ,mount -a会按照fstab的配置尝试挂载所有未挂载的条目,如果有问题会立刻报错提示,但不会导致系统进入无法启动的危险状态,这是更安全的验证方式。另外,用UUID而不是/dev/sdb1这类设备名是最佳实践,因为设备名在某些情况下(比如增减了磁盘后)可能会发生变化(原来的sdb可能变成sdc),导致fstab指向错误的设备,而UUID是文件系统创建时生成的唯一标识,不会因为设备顺序变化而改变。


五、AI 大模型文件的独立存储配置实战

结合第02篇提到的AI模型文件存储规划,这里给出完整的LVM配置实战,专门为模型文件准备一块独立、可弹性扩容的数据盘:

复制代码
#!/bin/bash
# 文件名:setup-ai-storage.sh
# 用途:为AI大模型文件配置独立的LVM管理存储空间

set -euo pipefail

DISK="/dev/sdb"          # 假设这是新挂载的大容量数据盘
VG_NAME="ai-data-vg"
LV_NAME="models-lv"
MOUNT_POINT="/data/models"

echo "===== 开始配置AI模型存储 ====="

# 1. 创建物理卷
sudo pvcreate "${DISK}"

# 2. 创建卷组
sudo vgcreate "${VG_NAME}" "${DISK}"

# 3. 创建逻辑卷,使用卷组全部可用空间(AI模型文件体积大,建议把整块盘都用上)
sudo lvcreate -l 100%FREE -n "${LV_NAME}" "${VG_NAME}"

# 4. 格式化为xfs(大文件写入性能更优,适合存储几GB到几十GB的模型权重文件)
sudo mkfs.xfs "/dev/${VG_NAME}/${LV_NAME}"

# 5. 创建挂载点并挂载
sudo mkdir -p "${MOUNT_POINT}"
sudo mount "/dev/${VG_NAME}/${LV_NAME}" "${MOUNT_POINT}"

# 6. 配置开机自动挂载
UUID=$(sudo blkid -s UUID -o value "/dev/${VG_NAME}/${LV_NAME}")
echo "UUID=${UUID} ${MOUNT_POINT} xfs defaults 0 2" | sudo tee -a /etc/fstab

# 7. 验证fstab配置正确性
sudo mount -a

echo "===== 配置完成 ====="
df -h "${MOUNT_POINT}"

echo "提示:将Ollama的模型存储路径指向这个目录:"
echo "export OLLAMA_MODELS=${MOUNT_POINT}/ollama"

这套脚本把本篇所有核心操作串联了起来:创建PV/VG/LV、格式化xfs(因为AI模型文件通常是几GB到几十GB的大文件,xfs的大文件写入性能优势在这个场景下能充分发挥)、配置fstab自动挂载并用mount -a验证。脚本最后特意提示了如何把Ollama的模型存储路径指向这块新配置的独立数据盘,这正是呼应第02篇提到的"AI模型文件绝对不能放在系统盘根分区"的最佳实践,把理论和实操串联了起来。


六、磁盘空间紧急排查与清理

当磁盘空间告急(df -h显示使用率超过90%)时,需要快速定位是什么占用了空间:

复制代码
# 第一步:确认哪个分区空间紧张
df -h

# 第二步:定位到具体是哪个目录占用过多空间(从根目录开始逐层排查)
du -sh /* 2>/dev/null | sort -rh | head -10

# 第三步:进入占用最大的目录继续往下排查
du -sh /var/log/* 2>/dev/null | sort -rh | head -10

# 查找体积异常大的单个文件(前面第03篇讲过的find命令实战应用)
find / -type f -size +1G 2>/dev/null -exec ls -lh {} \;

# 一个常见的隐藏陷阱:已删除但仍被进程占用的文件,不会立即释放磁盘空间
# 这种情况 du 看不出问题(因为文件名已经不存在于目录树),但df显示空间确实被占用
sudo lsof | grep deleted
# 找到对应进程后,可以考虑重启该进程来真正释放这部分空间

💡 生产提示 :磁盘空间被"已删除但仍被进程占用的文件"占满,是一个相当隐蔽但并不罕见的场景------典型情形是日志文件被rm删除了,但写日志的进程的文件句柄还没有关闭,磁盘空间实际上还没有真正释放,du命令统计目录大小时看不到这部分占用(因为文件已经从目录结构里消失了),但df看到的实际磁盘使用率却没有下降,这种"数字对不上"的现象会让人困惑。用lsof | grep deleted能找到这类幽灵文件,确认后重启对应进程(让它重新打开一个新的日志文件句柄)就能真正释放被占用的空间,这是排查"明明删了文件磁盘空间却没释放"问题的关键技巧。


七、常见问题解答(FAQ)

❓ Q1:直接对裸分区扩容和用LVM扩容,能不能都靠in-place完成?

裸分区(没有LVM)扩容非常受限,通常需要这块磁盘后面恰好有连续的未分配空间才能用growpart等工具扩展分区,且很多情况下还是建议先备份数据更稳妥;而LVM从设计上就是为弹性扩容而生的,可以跨多块物理磁盘合并空间,扩容操作标准化且风险低得多。如果是新规划的存储,强烈建议直接用LVM而不是裸分区,为未来的扩容需求留出余地。

❓ Q2:xfs不支持缩小,是不是意味着xfs就不该用了?

不是。是否支持缩小只是众多选型因素之一,对于数据库、大模型文件这类"只会越用越多、几乎不会缩容"的场景,xfs的大文件写入性能优势更有实际价值。真正需要权衡的是:如果你的业务场景存在"数据量可能大幅波动、需要灵活缩容"的需求(比较少见),才需要优先考虑ext4;绝大多数生产场景下数据是持续增长的,xfs不支持缩小这一限制在实践中影响有限。

❓ Q3:LVM 会不会影响磁盘性能?

LVM作为一个中间抽象层,理论上会带来极小的性能开销,但在现代硬件和内核优化下,这部分开销在绝大多数应用场景中可以忽略不计,远小于它带来的运维灵活性收益。只有在对IO延迟极端敏感的特殊场景(比如某些高频交易系统)才需要认真评估是否要绕过LVM直接操作裸设备,普通的Java SaaS应用、数据库、AI推理服务完全不需要担心这点性能差异。

❓ Q4:可以对正在使用中(已挂载且有数据写入)的LV做扩容吗?

可以,这正是LVM相比传统分区方式的核心优势之一,本篇演示的扩容流程全程不需要卸载文件系统、不需要停止正在运行的应用,对xfs文件系统而言这是被官方明确支持的在线(online)扩容操作。但需要注意,扩容(增大)是被广泛支持的在线操作,缩容(减小)通常需要先卸载文件系统才能操作,风险也更高,这是两个完全不对等的操作复杂度。

❓ Q5:fstab 配置出错导致系统无法启动,怎么紧急恢复?

如果是云服务器,多数云厂商提供"VNC远程连接"或"救援模式"功能,可以从控制台进入,不依赖SSH网络连接登录系统,进入后编辑/etc/fstab删除或修正有问题的那一行,保存后重启即可恢复。如果是本地物理机或虚拟机,可以用Linux安装盘的"救援模式"(rescue mode)启动,挂载原系统分区后修改fstab文件。这也是为什么本篇反复强调"修改fstab前先用mount -a验证,而不是直接重启"的原因------提前避免比事后补救成本低得多。


本篇小结与系列导航

📌 核心结论 :磁盘存储管理应当遵循"系统盘、数据盘、日志盘分离"的规划原则,避免单一分区故障影响整个系统。LVM通过PV-VG-LV三层抽象,让存储扩容变成无需停机的标准化操作,是生产环境强烈推荐的存储管理方式。文件系统选型上,ext4通用性更强且支持缩容,xfs在大文件写入场景性能更优但不支持缩容,AI模型文件、数据库文件等持续增长场景更适合xfs。配置/etc/fstab实现开机自动挂载时务必用UUID而非设备名,且修改后先用mount -a验证语法正确性,避免直接重启导致系统进入救援模式。


📚 参考资料


如果本文对你有帮助,请点赞 👍 收藏 ⭐ 支持一下!欢迎在评论区留言交流。

系列标签 :Linux LVM 磁盘管理 存储扩容 xfs ext4 AI大模型存储 Java运维

相关推荐
雯宝3 小时前
mnt_init 函数
linux
律宏阔9 小时前
WSL Docker 端口明明空闲,但就是绑不上端口
linux·windows
律宏阔9 小时前
WSL 突然断网,无法 ping 内网或外网
linux·windows
穷人小水滴9 小时前
用容器编译 VirtualBox 虚拟机软件 (ArchLinux, podman)
linux·容器·virtualbox
乱码三千9 小时前
如何优雅地直连无公网 IP 的远程 GPU 服务器
linux·人工智能·程序员
yunwei379 小时前
使用 eBPF 跟踪 Nginx 请求
linux·后端·性能优化
yunwei379 小时前
使用 eBPF 跟踪 MySQL 查询
linux·后端·性能优化
yunwei379 小时前
eBPF 示例教程:使用 XDP 捕获 TCP 信息
linux·后端·性能优化
judezh9 小时前
api 容器一直 unhealthy?我把一个 Agent 运行时的健康检查逐条拆了,查出四个问题
运维·docker
GeW9 小时前
制造业高端化,为什么必须重估Linux和数据库?
linux