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 的服务器需要停机操作。这种差距在凌晨告警时体现得最为明显。

相关推荐
sduwcgg1 天前
IQ-Learn 在 RTX 3090 服务器上的环境配置与踩坑记录
运维·服务器
呱呱巨基1 天前
Linux 基础IO
linux·c++·笔记·学习
QFIUNE1 天前
CD-HIT 详解:序列去冗余、安装使用与聚类结果解析
linux·服务器·机器学习·数据挖掘·conda·聚类
vortex51 天前
XFCE 桌面环境组件详解:从面板到剪贴板管理
linux·xfce·桌面环境
marsh02061 天前
43 openclaw熔断与降级:保障系统在异常情况下的可用性
java·运维·网络·ai·编程·技术
摇滚侠1 天前
Docker 如何查询挂载的目录
运维·docker·容器
勇闯逆流河1 天前
【Linux】linux进程控制(进程池的详解与实现)
linux·运维·服务器
zhangfeng11331 天前
部署到服务器上 宝塔系统 使用宝塔在线编辑器 FTP 批量上传 Git 部署 打包上传 codebudyy 编程程序开发
服务器·git·编辑器
WJ.Polar1 天前
Scapy基本应用
linux·运维·网络·python
lljss20201 天前
1. NameServer 域名服务器---NS
linux·服务器·前端