Linux Day32——实操五类资源告急排查


type: note

title: Linux:五类资源告急排查(磁盘 / inode / CPU / 内存 / 僵尸)

date: 2026-11-05

description: 从一条现象走到「是哪一类资源 + 第一步看哪条命令」:df -h 与 df -i 分辨空间满和 inode 满;ps --sort=-pcpu 找吃满一个核的进程;journalctl -k 找 OOM killer 的尸检记录;ps 状态列 Z 认僵尸进程

tags: Linux, 排查, 磁盘, inode, 进程, 试点


Linux:五类资源告急排查

> 📌 GitHub:https://github.com/AR-firefly

笔记区

核心观点

**1. 五类资源告急的总判据表**

| 类型 | 现象 | 第一条命令 | 判据 |

| ---------- | ------------------------- | ---------------------------------- | ----------------------------------- |

| 磁盘空间满 | `No space left on device` | `df -h` | `Use%` 到 100% |

| inode 满 | **同一句报错** | `df -i` | `IUse%` 到 100%,而 `Use%` 只有 1% |

| CPU 打满 | 机器卡 | `ps -eo pid,pcpu,cmd --sort=-pcpu` | 单进程 `%CPU` ≈ 100 |

| 内存吃光 | 进程一声不吭消失 | `journalctl -k` | 有 `oom-kill:` / `Killed process` |

| 僵尸进程 | 进程表里多一行不干活的 | `ps -ef` | `STAT` 是 `Z`,`CMD` 带 `<defunct>` |

**2. 磁盘满和 inode 满是两个独立的池子**

两个盘报同一句 `No space left on device`,但坏的地方不一样:

| | 磁盘空间满 | inode 满 |

| --------------- | ---------------- | ----------------- |

| `df -h`(空间) | `64M 64M 0 100%` | `28M 152K 26M 1%` |

| `df -i`(号码) | 只有 1% | `32 32 0 100%` |

  • 空间 = 存文件**内容**的地方(数据块)

  • inode = 每个文件的**身份记录**(权限、大小、内容放在哪几个块)

  • **空文件不占数据块,但一定占一个 inode**:所以建一堆空文件就能把号码耗光,空间一点没动

所以看到 `No space left on device`,**两条命令都要跑**:`df -h` 看是不是空间、`df -i` 看是不是号码。

**3. `df` 的两个参数作用不一样**

| 参数 | 改什么 | 结果 |

| ---- | ----------------------------------- | ----------------------------------- |

| `-h` | 只改**显示单位**(字节换成 K/M/G) | 还是空间那张表 |

| `-i` | **换一份数据**(空间表 → inode 表) | 表头变成 `Inodes IUsed IFree IUse%` |

两个一起写成 `df -hi`,出来的是**inode 那张表**------`-h` 只负责把数字变得好读,它没有权力决定看哪份数据。

**4. `dd` 的工作模型:搬运工**

从 `if=` 读一块 → 往 `of=` 写一块 → 重复。

| 部分 | 意思 |

| -------------- | ------------------------------------------------------------------------- |

| `if=/dev/zero` | 输入源。`/dev/zero` 是**设备文件**,读多少给多少值为 0 的字节,永远读不完 |

| `of=文件路径` | 输出目标,文件不存在就创建 |

| `bs=1M` | 一次搬多少(block size),默认 512 字节 |

| `count=N` | 搬几车就停;**不写就一直搬** |

停下的条件只有两个:**输入读完**、或者**写失败**。`/dev/zero` 永远读得完,所以只能等磁盘写满被拦下。

**写进去的是"很多个 0",不是"什么都没写"**------文件大小看写了多少字节,内容是什么无所谓。这就是用它造测试文件的原因。

**5. 查 CPU 要看单进程,不是整机**

20 核的机器,一个进程吃满一个核 = 整机只用了 1/20 ≈ **5%**。

看整机的 `%Cpu(s)` 会觉得"没事",实际上有一个核已经被榨干。所以第一步是**按进程排**:

  • `%CPU` = 单个进程吃一个核的百分比,**100 = 吃满一个核**

  • 20 核全满才叫 2000

**6. OOM killer:内存不够时内核开枪**

  • OOM = **O**ut **O**f **M**emory

  • 内存不够时,内核挑一个进程杀掉腾地方------牺牲一个,保整台机器

  • 挑谁:按"坏分数"(badness)排,0 = 永不杀,1000 = 优先杀;每个进程的分数在 `/proc/<PID>/oom_score`

  • 痕迹:`journalctl -k` 里 `oom-kill:` + `Killed process <PID> (<名字>)`

日志一行怎么读:

| 片段 | 意思 |

| -------------------------------------- | ----------------------------------- |

| `oom-kill:constraint=CONSTRAINT_MEMCG` | 触发了杀进程,原因是内存组超限 |

| `Memory cgroup out of memory` | 这个内存组没内存了 |

| `Killed process 9521 (python3)` | 被杀的是 PID 9521 的 python3 |

| `anon-rss:257440kB` | 实际占了约 251M,顶到了 256M 的上限 |

**7. 磁盘满 vs 内存满:两种死法**

| | 磁盘满 | 内存满 |

| ------------------ | ------------------------------------ | ------------------ |

| 谁报错 | **程序自己**拿到报错 | **内核直接开枪** |

| 程序有没有机会说话 | 有,会打印 `No space left on device` | 没有,一声不吭消失 |

| 去哪查 | 程序日志 / 终端 | `journalctl -k` |

所以「进程突然没了、日志里干干净净」要先怀疑 OOM。

**8. 僵尸进程:死了没人收尸**

  • 子进程已经退出,**父进程没去回收**,内核只好保留它的登记信息

  • 进程表里:`STAT` 是 `Z`,`CMD` 是 `名字 <defunct>`

  • 它不占 CPU、不占内存,`TIME` 是 0,**只占着 PID 号**

  • ` ` 方括号的含义:进程参数拿不到时,ps 用方括号把可执行文件名括起来

  • 父进程退出后,init 会把它收走

**9. OOM 和僵尸:两种结局**

| | OOM 被杀 | 僵尸 |

| -------------- | ---------------- | ------------ |

| 进程表里还有吗 | **没有了** | **还有一行** |

| 占资源吗 | 不占(已经死了) | 只占 PID |

关键方法/流程

**磁盘空间满排查**

| 步 | 命令 | 判据 |

| --- | ----------------- | ----------------------------- |

| 1 | `df -h` | 找出哪个挂载点 `Use%` 到 100% |

| 2 | `du -sh <目录>/*` | 找出是哪个文件/目录占的 |

| 3 | 处理 | 删/挪/扩容 |

**inode 满排查**

| 步 | 命令 | 判据 |

| --- | ------------ | -------------------------- |

| 1 | `df -i` | 哪个挂载点 `IUse%` 到 100% |

| 2 | `df -h` 对照 | `Use%` 很低 → 不是空间问题 |

| 3 | 处理 | 删小文件多的目录 |

**CPU 打满排查**

| 步 | 命令 | 判据 |

| --- | ---------------------------------- | ---------------------------- |

| 1 | `ps -eo pid,pcpu,cmd --sort=-pcpu` | 第一行就是元凶,`%CPU` ≈ 100 |

| 2 | 处理 | `kill <PID>` |

**内存吃光排查**

| 步 | 命令 | 判据 |

| --- | -------------------- | -------------------------------- |

| 1 | 进程突然消失、无报错 | 先怀疑 OOM |

| 2 | `journalctl -k` | 找 `oom-kill` / `Killed process` |

| 3 | 处理 | 找出是哪个进程耗内存、限制它 |

**僵尸进程排查**

| 步 | 命令 | 判据 |

| --- | --------- | ---------------------------------------- |

| 1 | `ps -ef` | `CMD` 列找 `<defunct>`,`STAT` 是 `Z` |

| 2 | 看 `PPID` | 找它的父进程 |

| 3 | 处理 | 父进程不管,只能等父进程退出或杀掉父进程 |

实战记录

**记录 1:灌满 64M 小盘**

```

$ df -h ~/lab/d2/mnt_full

Filesystem Size Used Avail Use% Mounted on

tmpfs 64M 0 64M 0% /home/ar-26710/lab/d2/mnt_full

$ dd if=/dev/zero of=~/lab/d2/mnt_full/big bs=1M

dd: IO error: No space left on device

$ df -h ~/lab/d2/mnt_full

Filesystem Size Used Avail Use% Mounted on

tmpfs 64M 64M 0 100% /home/ar-26710/lab/d2/mnt_full

$ du -sh ~/lab/d2/mnt_full/*

64M /home/ar-26710/lab/d2/mnt_full/big

```

**记录 2:耗光 inode**

```

$ touch ~/lab/d2/mnt_inode/{1..30}

touch: cannot touch '/home/ar-26710/lab/d2/mnt_inode/21': No space left on device

...(21 到 30 全部失败)

$ df -i ~/lab/d2/mnt_inode

Filesystem Inodes IUsed IFree IUse% Mounted on

/dev/loop0 32 32 0 100% /home/ar-26710/lab/d2/mnt_inode

$ df -h ~/lab/d2/mnt_inode

Filesystem Size Used Avail Use% Mounted on

/dev/loop0 28M 152K 26M 1% /home/ar-26710/lab/d2/mnt_inode

```

空间还剩 26M,文件却建不出来------号码用完了。

**记录 3:CPU 满**

```

$ yes > /dev/null &

1 8050

$ ps -eo pid,pcpu,cmd --sort=-pcpu

PID %CPU CMD

8050 99.9 yes

85 0.0 /usr/lib/systemd/systemd-udevd

...

```

**记录 4:OOM 现场**

查到的内核日志:

```

kernel: oom-kill:constraint=CONSTRAINT_MEMCG,...

kernel: Memory cgroup out of memory: Killed process 9521 (python3) total-vm:2370148kB, anon-rss:257440kB ...

```

**记录 5:僵尸进程**

```

$ ps -ef

ar-26710 8198 8196 0 23:06 ? 00:00:00 python3 <defunct>

```


线索区(学完后合上材料,自问自答)

**Q: 五类资源告急,各自第一条命令是什么?**

A: 磁盘 `df -h`;inode `df -i`;CPU `ps -eo pid,pcpu,cmd --sort=-pcpu`;内存 `journalctl -k`;僵尸 `ps -ef` 看 `STAT`。

**Q: 同样一句 `No space left on device`,怎么分清是空间满还是 inode 满?**

A: 两条都跑。`df -h` 到 100% = 空间满;`df -h` 很低但 `df -i` 到 100% = inode 满。

**Q: 为什么不写 count 的 dd 会一直跑?**

A: 它停的条件是输入读完或写失败。`/dev/zero` 永远读不完,所以只能等磁盘写满。

**Q: 写进文件的都是 0,为什么还占空间?**

A: 文件大小看写了多少**字节**,不看内容是什么。64M 个 0 照样占 64M。

**Q: 20 核机器上一个进程 100%,整机显示多少?**

A: 约 5%。所以看整机看不出来,必须按进程排。

**Q: 进程突然消失、日志里没报错,先怀疑什么?**

A: OOM killer。去 `journalctl -k` 找 `oom-kill` / `Killed process`。

**Q: `df -hi` 出来的是哪张表?**

A: inode 那张。`-i` 决定看哪份数据,`-h` 只决定数字好不好读。

**Q: 僵尸进程占什么资源?**

A: 只占 PID 号,不占 CPU 也不占内存,`TIME` 是 0。

**Q: `(sd-pam)` 和 `python3 <defunct>` 有什么区别?**

A: 圆括号是正常进程(参数拿不到时的显示方式),方括号加 `<defunct>` 才是僵尸。


总结(50字以内,用自己的话概括今天学到了什么)

磁盘满看 df -h,号码满看 df -i;CPU 看单进程;内存被 OOM 杀查 journalctl -k;僵尸看 Z。


复习卡片

| 概念 | 必学/了解 | 一句话 | 场景 |

| ----------------- | --------- | ---------------------------------------- | -------------------- |

| `df -h` | 必学 | 看文件系统空间用量,`-h` 换成 M/G | 磁盘满第一步 |

| `df -i` | 必学 | 看 inode 用量,`-i` 换一份数据 | 空间没满却建不了文件 |

| inode | 必学 | 文件的户口号,每个文件扣一个,空文件也扣 | 判断号码有没有用完 |

| `du -sh` | 了解 | 只看某个目录/文件占多大;`man 1 du` | 找出是谁占的 |

| `%CPU` | 必学 | 单进程吃一个核的百分比,100 = 满一个核 | 找 CPU 元凶 |

| OOM killer | 必学 | 内存不够时内核按分数挑进程杀 | 进程无声消失 |

| `journalctl -k` | 必学 | 只看内核日志,`-k` = kernel | 查 OOM / 内核事件 |

| `<defunct>` / `Z` | 必学 | 子进程已死、父进程没收尸 | 僵尸进程 |

| `df -hi` | 了解 | 出来的是 inode 表,`-h` 不改看哪份数据 | 参数组合 |

| `load average` | 了解 | 系统负载均值;`man 1 uptime` | 看整体压力 |


流程附加段

旧知识回收

| 概念 | 一句话 | 出处 |

| -------------------------- | -------------------------------------------------------------------------------------- | ---------- |

| 端口开 ≠ 服务能用 | `LISTEN` 只说明内核在等连接;要 `curl` 敲门拿到回应才算能用 | 复习 11-02 |

| `ping` vs `curl` | `ping` 走 ICMP,敲的是**机器**,不认识端口;`curl` 走 TCP/HTTP,敲的是**端口上的服务** | 复习 11-02 |

| 三层判断 | 门开没开(`LISTEN`)→ 人进没进来(三次握手)→ 进来有没有人理(应用层回应) | 复习 11-02 |

| `journald` vs `journalctl` | `d` 结尾是后台服务,`ctl` 结尾是手里的命令 | 点 4 |

| `-u` vs `-k` | `-u` 按服务(unit)筛,`-k` 只看内核 | 点 4 |

| `-bash` 的横杠 | 表示登录 shell,不是报错 | 点 5 |

| `(sd-pam)` 圆括号 | 正常进程参数拿不到时的显示方式,不是僵尸 | 点 5 |

今日产出验收

| 产出条 | 证据 | 结果 |

| ------------------------ | ------------------------------------------------------------------------ | ---- |

| 五类各造一次现象 | 记录 1--5 全部有真实输出 | 过 |

| 五类各用一条命令定位 | 复盘第 1 问答出 `df -h` / `df -i` / `ps --sort` / `journalctl -k` / `ps` | 过 |

| 磁盘满 vs inode 满能分清 | 两个盘对照,`Use%` 与 `IUse%` 一个 100 一个 1 | 过 |

| 进程突然消失知道去哪查 | 复盘第 3 问答出 `journalctl -k` 找 `oom-kill` | 过 |

相关推荐
skywalk816332 分钟前
hive 常驻集群:像 OSPF 一样在线,像 git 一样可信
运维·人工智能·hive
StarsGreen43 分钟前
libva中的图像格式说明
linux
H.莓飛1 小时前
【C++】【STL】vector_OJ题
linux·服务器·开发语言·数据结构·c++·visual studio
Rabitebla1 小时前
【Linux操作系统】进程篇(十一):进程程序替换——从底层原理到 exec 函数族
linux·服务器·c++·笔记·学习·算法
景煜拾年2 小时前
InnoAI SQL 助手
运维·数据库·笔记·sql
无人生还别怕3 小时前
如何搭建docker仓库(轻量级)registry
linux·运维·docker·云原生·容器·registry·openanolisos
无足鸟ICT3 小时前
【RHCA+】agedu命令(查看磁盘使用情况)
linux
StarsGreen3 小时前
Android 启动流程详解
android·linux·单片机·嵌入式硬件
分布式存储与RustFS3 小时前
Hudi 表想摆脱 HDFS 绑定?用 Spark + Hudi 直接写进 RustFS
运维·云原生·开源·对象存储·分布式存储·s3·性能基准