Linux磁盘与存储管理:分区、LVM 与 IO 性能全栈分析

前置阅读Linux 文件系统入门:目录结构不是随便画的进程管理:Linux 怎么看、怎么管、怎么杀


文章目录

    • 引言:磁盘问题为什么难排查
    • 整体知识框架
    • [一、IO 栈:数据从进程到磁盘的完整路径](#一、IO 栈:数据从进程到磁盘的完整路径)
    • [二、分区方案:MBR/GPT 的本质区别与工具选择](#二、分区方案:MBR/GPT 的本质区别与工具选择)
      • [2.1 MBR vs GPT:不只是大小限制](#2.1 MBR vs GPT:不只是大小限制)
      • [2.2 三种分区工具的使用场景](#2.2 三种分区工具的使用场景)
      • [2.3 分区对齐:一个容易忽略的性能陷阱](#2.3 分区对齐:一个容易忽略的性能陷阱)
    • 三、LVM:弹性存储的核心原理与实操
      • [3.1 三层模型:PV / VG / LV](#3.1 三层模型:PV / VG / LV)
      • [3.2 基础操作:创建、查看、扩容](#3.2 基础操作:创建、查看、扩容)
      • [3.3 LVM 快照:写时复制的数据结构](#3.3 LVM 快照:写时复制的数据结构)
      • [3.4 Thin Provisioning:超额分配的利与弊](#3.4 Thin Provisioning:超额分配的利与弊)
    • [四、IO 性能分析:从数字到根因](#四、IO 性能分析:从数字到根因)
      • [4.1 iostat:指标背后的内核含义](#4.1 iostat:指标背后的内核含义)
      • [4.2 iotop:定位到具体进程](#4.2 iotop:定位到具体进程)
      • [4.3 iowait:被误解最多的指标](#4.3 iowait:被误解最多的指标)
      • [4.4 完整的 IO 排查流程](#4.4 完整的 IO 排查流程)
    • [五、df/du 联合分析:空间用在哪里](#五、df/du 联合分析:空间用在哪里)
      • [5.1 df 与 du 差异的根本原因](#5.1 df 与 du 差异的根本原因)
      • [5.2 du 使用技巧:快速找到大文件目录](#5.2 du 使用技巧:快速找到大文件目录)
    • 六、文件描述符耗尽:一个被忽略的"磁盘"问题
      • [6.1 现象与诊断](#6.1 现象与诊断)
      • [6.2 调整 fd 上限](#6.2 调整 fd 上限)
    • 七、联合分析场景:一次完整的磁盘问题排查
    • 总结

引言:磁盘问题为什么难排查

CPU 高了看 top,内存涨了看 free,但磁盘问题往往更隐蔽------服务响应变慢,但 CPU 和内存都正常;日志写入突然卡顿,iostat 的 %util 看起来也不高;扩容之后空间又莫名其妙不够了。

原因在于磁盘问题涉及三个独立的层次:存储层 (怎么组织物理空间)、文件系统层 (怎么管理文件)、IO 栈层(数据从进程到磁盘经历了什么)。这三层之间的问题互相影响,但诊断工具各自只照亮一个层面,需要联合起来分析。

本文的核心思路是:先理解 IO 栈的结构,再看 LVM 如何在存储层提供弹性,最后建立一套"从现象到根因"的联合分析框架------不是命令清单,是排查思路。


整体知识框架

磁盘与存储管理
IO 栈结构
VFS 虚拟文件系统
Page Cache 缓存层
块设备层
调度器队列
驱动与物理介质
分区方案
MBR vs GPT 对比
fdisk/gdisk/parted 选择
分区对齐原则
文件系统格式化
LVM 体系
PV/VG/LV 三层模型
写时复制快照原理
在线扩容实操
Thin Provisioning
IO 性能分析
iostat 指标解读
iotop 进程级定位
iowait 的真正含义
blktrace 深度追踪
文件描述符
fd 耗尽现象
lsof/ulimit 诊断
内核参数调整


一、IO 栈:数据从进程到磁盘的完整路径

在学任何磁盘工具之前,先理解数据流动的路径------诊断问题时,知道"卡在哪一层"比知道"用什么命令"更重要。
命中
未命中
HDD
SSD/NVMe
用户进程 write 系统调用
VFS 虚拟文件系统层
Page Cache 命中?
直接写入 Page Cache 返回
分配新 Page 写入 Cache
内核后台 pdflush/writeback 异步刷盘
通用块层 Generic Block Layer
IO 调度器 CFQ/deadline/noop/mq-deadline
设备驱动层
存储类型
磁盘寻道 + 旋转等待 + 传输
Flash 控制器 FTL 转换 + 写入

这张图解释了几个常见的"奇怪现象":

为什么 write 返回了但数据还没真正写到磁盘? 因为默认情况下 write 只是写进 Page Cache 就返回了,内核异步刷盘。如果进程写完就退出,而内核还没来得及刷盘,机器掉电数据就丢失了------这是 fsync() 存在的原因。

为什么 %util 不高但服务还是慢? %util 反映设备的使用率,但如果 IO 调度器队列里堆积着大量等待的请求(await 高),单位时间的设备利用率可能并不高,但每个请求的等待时间却很长。

为什么 SSD 比 HDD 快这么多? HDD 每次随机 IO 都需要物理寻道(7200rpm 的磁盘寻道时间约 4-8ms),SSD 通过 FTL 层将逻辑地址映射到 Flash 块,随机 IO 没有寻道代价(约 0.1ms 级别)。这也解释了为什么 HDD 的 IO 延迟对随机读写极其敏感,而 SSD 相对容忍。


二、分区方案:MBR/GPT 的本质区别与工具选择

2.1 MBR vs GPT:不只是大小限制

GPT 分区表
MBR 分区表
局限性催生
MBR 主引导记录 512B
最多 4 个主分区
最大支持 2TB 磁盘
分区信息存在单一位置
EFI 保护 MBR
GPT 头部 + 128 个分区表项
最大支持 18EB 磁盘
分区信息有备份副本
每个分区有 GUID 唯一标识

GPT 相比 MBR 的实质性差异不只是"支持更大的磁盘",关键在于:

  • 分区表冗余:GPT 在磁盘末尾保存了分区表的完整副本,MBR 损坏了数据会难以恢复,GPT 可以从备份恢复分区表
  • 分区数量:MBR 最多 4 个主分区(或 3 主 + 1 扩展),GPT 默认支持 128 个分区,不需要"扩展分区"这个折中方案
  • 唯一标识 :每个 GPT 分区有 UUID,不会因为磁盘添加顺序变化而导致 /dev/sdb1 变成 /dev/sdc1/etc/fstab 用 UUID 挂载更安全

服务器实践原则:2TB 以上的磁盘必须用 GPT;有 UEFI 固件的机器引导盘需要 GPT + EFI 分区;2TB 以下的数据盘两者都可以,但 GPT 更推荐。

2.2 三种分区工具的使用场景

工具 适用场景 特点
fdisk MBR 分区、老设备、脚本化操作 交互式,最广泛可用
gdisk GPT 分区专用 fdisk 的 GPT 版
parted 两者兼容,支持 GB 级参数、脚本调用 非交互友好,LVM 扩容常用

实际操作流程(以 GPT + parted 为例):

bash 复制代码
# 1. 查看磁盘整体情况
lsblk -f                        # 显示磁盘、分区、文件系统、挂载点
fdisk -l /dev/sdb               # 显示分区表详情

# 2. 使用 parted 创建 GPT 分区(适合脚本化)
parted /dev/sdb --script \
    mklabel gpt \
    mkpart primary ext4 1MiB 100% \
    align-check optimal 1       # 验证分区对齐

# 3. 格式化
mkfs.ext4 -L data-disk /dev/sdb1

# 4. 获取 UUID 后写入 fstab(重启后自动挂载)
UUID=$(blkid -s UUID -o value /dev/sdb1)
echo "UUID=$UUID /mnt/data ext4 defaults,noatime 0 2" >> /etc/fstab

# 5. 挂载并验证
mount -a
df -h /mnt/data

2.3 分区对齐:一个容易忽略的性能陷阱

现代磁盘(HDD 和 SSD)的物理扇区是 4096 字节(4K),但对外报告的仍是 512 字节的逻辑扇区。如果分区起始位置不是 4K 的整数倍,每次写入都会跨越两个物理扇区,需要"读-改-写"三步操作,性能会下降 30-50%。

partedalign-check optimal 1 命令会验证分区对齐状态------如果返回 1 aligned,则对齐正常;返回 1 not aligned 则需要调整起始位置。现代版本的 parted 在创建分区时默认会对齐到 MiB 边界(1MiB = 256 个 4K 扇区),这已经满足所有常见磁盘的对齐要求。


三、LVM:弹性存储的核心原理与实操

3.1 三层模型:PV / VG / LV

LV 逻辑卷
VG 卷组
物理层
/dev/sdb1

PV 200GB
/dev/sdc1

PV 300GB
/dev/sdd1

PV 500GB
vg_data

总容量 1000GB

可用 600GB
lv_app

100GB

/app
lv_db

200GB

/var/lib/mysql
lv_log

100GB

/var/log

LVM 把物理磁盘抽象成一个存储池(VG),再从池里划分出逻辑卷(LV)给文件系统使用。这个抽象层带来三个传统分区没有的能力:

  1. 在线扩容:LV 不够用了,从 VG 里划拨更多空间过来,文件系统在线扩展,服务不需要停
  2. 跨磁盘合并:VG 可以横跨多块物理磁盘,LV 的实际数据条带化分布在各 PV 上
  3. 快照:对 LV 做快照,在不停服务的情况下得到一个一致性的数据副本

LVM 的核心单位是 PE(Physical Extent),默认 4MB。所有的空间分配都以 PE 为粒度,就像内存管理里的内存页。

3.2 基础操作:创建、查看、扩容

bash 复制代码
# ─── 初始化物理卷 ────────────────────────────────────────────
pvcreate /dev/sdb1 /dev/sdc1
pvs                     # 查看 PV 信息(简洁)
pvdisplay /dev/sdb1     # 详细信息

# ─── 创建卷组 ────────────────────────────────────────────────
vgcreate vg_data /dev/sdb1 /dev/sdc1
vgs                     # 查看 VG 信息
vgdisplay vg_data

# ─── 创建逻辑卷 ──────────────────────────────────────────────
lvcreate -L 100G -n lv_app vg_data        # 固定大小
lvcreate -l 50%FREE -n lv_db vg_data      # 使用 50% 可用空间
lvs                     # 查看 LV 信息

# ─── 在 LV 上创建文件系统并挂载 ─────────────────────────────
mkfs.xfs /dev/vg_data/lv_app
mount /dev/vg_data/lv_app /app

在线扩容(最常用操作)

bash 复制代码
# 场景:/var/lib/mysql 所在 LV 空间不足,需要扩容 50GB

# 步骤 1:确认 VG 有足够可用空间
vgs vg_data
# VFree 列要 >= 50GB,否则需要先添加新 PV

# 步骤 2:扩展 LV
lvextend -L +50G /dev/vg_data/lv_db

# 步骤 3:扩展文件系统(不同文件系统命令不同)
# ext4:
resize2fs /dev/vg_data/lv_db
# xfs(xfs 只支持扩大,不支持缩小):
xfs_growfs /var/lib/mysql

# 验证
df -h /var/lib/mysql

整个过程 MySQL 不需要停止------LV 扩展是元数据操作,文件系统扩展 resize2fs/xfs_growfs 在挂载状态下操作是安全的。

向 VG 添加新磁盘(扩容前提):

bash 复制代码
# 新增了一块磁盘 /dev/sdd,初始化并加入现有 VG
pvcreate /dev/sdd
vgextend vg_data /dev/sdd
# 此后 VG 可用空间增加,可以继续 lvextend

3.3 LVM 快照:写时复制的数据结构

LVM 快照是一个容易被误解的功能,多数文章只说"用来备份",但不解释它为什么可以在不停服务的情况下得到一致性副本。
快照元数据表 快照 LV (snap_db) 原始 LV (lv_db) 应用进程 快照元数据表 快照 LV (snap_db) 原始 LV (lv_db) 应用进程 快照创建瞬间:元数据表为空,不复制数据 快照保留了创建时刻的完整镜像 原始 LV 继续正常使用 写入数据块 Block 检查 未修改,执行写前复制 将 Block 标记 Block 写入新值到 Block

关键原理 :快照创建时,只记录"快照时刻 LV 的元数据",不复制任何数据。当原始 LV 上的某个数据块第一次被修改时,LVM 先把该块的旧值复制到快照空间,再写入新值。这就是"写时复制"(Copy-on-Write)。

这意味着:

  • 快照创建是瞬间完成的(只是元数据操作)
  • 快照初始占用空间很小,随着原始 LV 上的数据变化而增长
  • 快照大小需要预估原始 LV 在备份期间会发生多少变化,预留足够空间,否则快照满了会自动失效

备份使用流程

bash 复制代码
# 1. 创建快照(5GB 快照空间,用于备份期间的写时复制缓冲)
lvcreate -L 5G -s -n snap_db /dev/vg_data/lv_db

# 2. 挂载快照(只读方式,得到备份时刻的一致性视图)
mkdir /mnt/snap_db
mount -o ro /dev/vg_data/snap_db /mnt/snap_db

# 3. 备份数据(快照提供一致性视图,原始 LV 正常运行)
tar -czf /backup/mysql-$(date +%Y%m%d).tar.gz -C /mnt/snap_db .

# 4. 备份完成,删除快照
umount /mnt/snap_db
lvremove /dev/vg_data/snap_db

3.4 Thin Provisioning:超额分配的利与弊

普通 LVM 创建 LV 时必须明确声明大小,从 VG 中占用实际空间。Thin Provisioning 允许创建"容量超过物理空间"的逻辑卷:先创建一个 Thin Pool,再从中创建 Thin Volume,Thin Volume 声明的大小可以超过 Pool 的实际容量------前提是实际使用量不超过 Pool。

bash 复制代码
# 创建 Thin Pool(100GB 物理空间)
lvcreate -L 100G -T vg_data/thin_pool

# 从 Pool 里创建超额 Thin Volume(声明 50GB,但实际按需分配)
lvcreate -V 50G -T vg_data/thin_pool -n lv_thin_app
lvcreate -V 50G -T vg_data/thin_pool -n lv_thin_db
# 两个 LV 声明合计 100GB,但如果实际用量不超过 100GB,没有问题

# 监控 Pool 使用率(关键!超出会导致所有 Thin LV 变为只读)
lvs -a -o name,lv_attr,lv_size,pool_lv,data_percent

生产使用风险 :Thin Pool 耗尽时,所有依赖这个 Pool 的 Thin Volume 会变成只读,服务直接挂掉。所以使用 Thin Provisioning 时必须设置告警(data_percent > 80% 时报警)并定期扩容 Pool。容器环境(Docker 的 devicemapper 驱动)大量使用 Thin Provisioning,这也是 Docker 磁盘使用超预期的根本原因之一。


四、IO 性能分析:从数字到根因

4.1 iostat:指标背后的内核含义

iostat 是磁盘性能分析的第一站,但它的字段容易被误读。

bash 复制代码
# 每 2 秒刷新一次,显示 x 模式(扩展统计)
iostat -xz 2

典型输出:

复制代码
Device  r/s   w/s  rMB/s  wMB/s  rrqm/s  wrqm/s  r_await  w_await  svctm  %util
sda    10.5  45.2   0.41   1.78    0.20    12.50     4.23    28.50   0.82   22.8
nvme0n1 120.0 380.0  15.0   47.5    0.00     0.00     0.15     0.12   0.08   40.2

关键字段解读

字段 含义 排查关注点
r/s / w/s 每秒完成的读/写请求数(IOPS) 对比磁盘标称 IOPS 上限
rMB/s / wMB/s 读写吞吐量 对比磁盘标称带宽上限
rrqm/s / wrqm/s 每秒合并的读/写请求数 高值说明顺序 IO,调度器在合并请求
r_await / w_await 读/写请求的平均等待时间(ms) 核心指标,HDD 正常 <20ms,SSD <1ms
svctm 平均服务时间(已弃用,不再准确) 忽略此字段
%util 设备使用率 容易误读,见下方说明

%util 为什么会撒谎%util 表示"采样周期内设备处于活跃状态的时间比例",对 HDD 有意义(因为 HDD 同一时刻只能处理一个请求),但对支持队列深度(QD)的 NVMe SSD,%util 100% 并不意味着设备饱和------设备可能在并行处理 32 个请求而总吞吐量还远没到上限。

更可靠的饱和判断方式

bash 复制代码
# 查看 IO 队列长度(通过 /proc/diskstats 计算)
# 或者用 iostat -x 看 aqu-sz(平均队列长度)
iostat -x 2 | grep -E "Device|sda|nvme"
# aqu-sz > 1(HDD)或 > 8(NVMe)时,考虑设备已接近饱和

4.2 iotop:定位到具体进程

iostat 显示磁盘 IO 很高,但不知道是哪个进程导致的,iotop 是下一步工具。

bash 复制代码
# 只显示有实际 IO 的进程(过滤掉 0 IO 的进程)
iotop -o

# 批处理模式(适合脚本或日志)
iotop -o -b -n 5        # 采样 5 次后退出
iotop -o -b -d 2        # 每 2 秒采样

# 如果没有 iotop,用 /proc 手工查
# 找到 IO 最多的进程 PID
for pid in /proc/[0-9]*; do
    awk '/^(read_bytes|write_bytes)/{sum+=$2}END{print sum, FILENAME}' \
        "$pid/io" 2>/dev/null
done | sort -rn | head -10

iotop 输出中的关键列:

  • DISK READ / DISK WRITE:进程当前的磁盘 IO 速率
  • SWAPIN:从交换空间读取的比例(高值说明内存压力)
  • IO>:当前 IO 优先级,0/4 是默认的 best-effort 调度 class

4.3 iowait:被误解最多的指标

iowait 出现在 topvmstat 里,含义是"CPU 在等待 IO 完成时的空闲时间百分比"。
没有可运行进程
有进程在等 IO
意味着
意味着
不一定意味着
CPU 空闲
为什么空闲?
idle 空闲
iowait
iowait 高意味着什么?
至少有一个 CPU 在空闲
有进程正在等待 IO 完成
磁盘真的是瓶颈
例如:进程在等网络 IO

也会计入 iowait
单线程 IO 程序在单核上

iowait 会高,但磁盘不忙

iowait 高不等于磁盘是瓶颈 ,需要结合 iostatawait 和吞吐量一起看:

bash 复制代码
# 联合分析示例
# 终端 1:持续监控 CPU
vmstat 2

# 终端 2:持续监控磁盘
iostat -xz 2

# 如果 iowait 高 + iostat await 高 + 吞吐量接近磁盘上限
# → 磁盘确实是瓶颈

# 如果 iowait 高 + iostat await 正常 + 吞吐量不高
# → 可能是进程在等网络 IO,或者单线程程序的 IO 等待

4.4 完整的 IO 排查流程

HDD await >50ms

SSD await >5ms
await 正常
顺序写入大文件
随机小 IO 高频
读 IO 异常高
服务响应变慢
iostat -xz 2 观察
await 是否异常?
确认磁盘延迟问题
查其他方向:CPU/网络/内存
iotop -o 定位进程
是哪类 IO?
可能是日志/备份占满带宽
数据库/缓存 IO 压力
Page Cache 失效 或 冷启动
检查日志轮转配置

考虑 ionice 降低优先级
检查查询是否走全表扫描

考虑 buffer pool 大小
检查内存是否不足导致 Cache 频繁淘汰


五、df/du 联合分析:空间用在哪里

dfdu 是最常用的空间分析工具,但两者报告的数字有时候差异很大------这是一个生产中真实存在的困惑。

5.1 df 与 du 差异的根本原因

bash 复制代码
# 常见困惑:df 显示 /var 使用了 80GB,du -sh /var 只显示 50GB
df -h /var
# Filesystem  Size  Used  Avail  Use%  Mounted on
# /dev/sda2   100G   80G    20G   80%  /var

du -sh /var
# 50G     /var

# 差异 30GB 去哪了?

原因:已删除但仍被进程打开的文件 。当一个进程打开了一个文件,即使该文件被 rm 删除了(即目录项被删除,inode 引用计数减 1),只要进程还没关闭文件描述符,实际的磁盘空间不会被释放。du 遍历目录树,看不到这些"已删除但仍占用"的文件;df 从文件系统层面统计,能看到这些空间。

定位和清理

bash 复制代码
# 找到持有已删除文件的进程
lsof +L1
# +L1 = link count < 1,即文件已删除但 fd 还开着
# 输出格式:进程名  PID  用户  FD  文件大小  文件名(deleted)

# 常见场景:日志文件被 logrotate 删除,但程序还在写旧文件
# 解决方案 1:重启该进程(让它关闭旧 fd,重新打开新日志文件)
# 解决方案 2:如果不能重启,向进程发 SIGHUP 让它重新打开日志
kill -HUP <PID>

5.2 du 使用技巧:快速找到大文件目录

bash 复制代码
# 按目录大小排序,只显示第一层(不递归)
du -h --max-depth=1 /var | sort -rh | head -20

# 找出大于 1GB 的文件
find /var -type f -size +1G -exec ls -lh {} \;

# 找出最近 24 小时内修改的大文件(排查突然增大的日志)
find /var/log -type f -mtime -1 -size +100M

# 快速统计某个目录的文件数量(inode 占用分析)
find /path -type f | wc -l

六、文件描述符耗尽:一个被忽略的"磁盘"问题

文件描述符(fd)耗尽不是磁盘空间问题,但症状和磁盘问题很像------应用报"too many open files",无法创建新连接,无法写日志,看起来像磁盘坏了。

6.1 现象与诊断

bash 复制代码
# 1. 查看当前系统 fd 总使用量
cat /proc/sys/fs/file-nr
# 输出:已分配数  空闲数  最大限制
# 例:32768  0  1048576(已用 32768,最大 1048576)

# 2. 查看单个进程的 fd 使用情况
ls -la /proc/<PID>/fd | wc -l       # 该进程打开的 fd 数
lsof -p <PID> | wc -l               # 更详细

# 3. 查看进程的 fd 限制
cat /proc/<PID>/limits | grep "open files"

# 4. 找出 fd 使用最多的进程
lsof 2>/dev/null | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

6.2 调整 fd 上限

bash 复制代码
# ─── 临时调整(重启后失效)───────────────────────────────────
ulimit -n 65535      # 当前 shell 及其子进程的软限制

# 对运行中的进程(不需要重启)
prlimit --pid <PID> --nofile=65535:65535

# ─── 持久化调整 ──────────────────────────────────────────────
# /etc/security/limits.conf(PAM 方式,用户级别)
cat >> /etc/security/limits.conf <<EOF
*    soft    nofile    65535
*    hard    nofile    65535
EOF

# /etc/systemd/system/myapp.service(systemd 管理的服务)
[Service]
LimitNOFILE=65535

# ─── 系统级别 fd 上限 ────────────────────────────────────────
# /etc/sysctl.conf(所有进程的系统总上限)
fs.file-max = 1048576
# 生效
sysctl -p

七、联合分析场景:一次完整的磁盘问题排查

场景 :某台服务器上的 MySQL 响应变慢,df 显示 /var/lib/mysql 所在分区使用率 92%,系统 iowait 维持在 35-40%。

bash 复制代码
# 第一步:确认空间实际占用来源
du -h --max-depth=2 /var/lib/mysql | sort -rh | head -20
# 发现 binlog 文件占用了 20GB,正常情况应该只保留 7 天

# 第二步:确认 binlog 占用是否可清理(查 MySQL 是否在使用)
mysql -e "SHOW BINARY LOGS;"
mysql -e "SHOW MASTER STATUS;"
# 确认 binlog 保留策略
mysql -e "SHOW VARIABLES LIKE 'expire_logs_days';"
# 如果 expire_logs_days=0,表示不自动清理

# 第三步:分析磁盘 IO 是否和 binlog 有关
iostat -xz 2 &
iotop -o -b -d 2 -n 5
# 如果 mysqld 的写 IO 很高,而 binlog purge 正在进行,可能是 purge 操作造成的 IO 峰值

# 第四步:清理旧 binlog 并修复自动清理策略
mysql -e "SET GLOBAL expire_logs_days = 7;"
mysql -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);"

# 第五步:确认 LVM 状态,考虑是否扩容
lvs vg_data
vgs vg_data
# 如果 VG 有可用空间,立即扩容 LV 防止满盘
lvextend -L +20G /dev/vg_data/lv_db
xfs_growfs /var/lib/mysql

这个场景串联了本文的多个工具:df/du 定位空间来源、iostat/iotop 分析 IO 行为、LVM 提供在线扩容兜底------三个层次各司其职。


总结

磁盘管理核心
理解 IO 栈
Page Cache 解释 write 语义
await 比 util 更准确
iowait 不等于磁盘瓶颈
存储方案选择
GPT 优于 MBR
分区对齐防性能陷阱
LVM 是生产必备
LVM 三个核心用法
在线扩容无停机
快照写时复制备份
Thin Provisioning 监控为先
联合分析习惯
df+du 找空间差异
iostat+iotop 定位 IO 进程
lsof 找已删除占用文件
fd 管理
limits.conf 持久化
systemd LimitNOFILE
prlimit 不重启调整

磁盘问题的排查本质是"分层"------确认是存储层(空间不足)、文件系统层(inode 耗尽、已删除文件占用)还是 IO 栈层(延迟高、带宽满),再对应层次选择工具。跳过分层直接用单一工具排查,往往会绕很多弯路。

LVM 在生产环境中的价值不是"高级功能",而是兜底能力------在磁盘快满的紧急情况下,有 LVM 的服务器可以在5分钟内完成在线扩容,没有 LVM 的服务器需要停机操作。这种差距在凌晨告警时体现得最为明显。

相关推荐
IMPYLH9 小时前
Linux 的 pinky 命令
linux·运维·服务器·bash
HelloWorld_SDK10 小时前
Docker安装OpenClaw
运维·docker·容器·openclaw
REDcker10 小时前
Linux iptables 与 Netfilter:原理、路径与运维要点
linux·运维·服务器
KKKlucifer12 小时前
零信任融合实践:国内堡垒机如何落地动态权限与实时阻断
运维
嵌入式×边缘AI:打怪升级日志12 小时前
Linux 驱动开发入门:从最简单的 hello 驱动到硬件交互
linux·驱动开发·交互
Bert.Cai13 小时前
Linux useradd命令详解
linux·运维
无忧.芙桃14 小时前
进程控制(上)
linux·运维·服务器
十年编程老舅14 小时前
深入 Linux 中断:原理详解 + 实战落地
linux·网络·linux内核·c/c++·中断
Bert.Cai14 小时前
Linux rm命令详解
linux·运维