Swap卡I/O导致D状态幽灵化处理思路

最近在处理一台 NVMe 服务器时,遇到一个 swap 文件问题。整个过程既是操作上的挑战,也是理解 Linux 内核 swap 机制的绝佳案例。


1️⃣ 问题初现:swap 权限不对,关闭失败

我发现 swap 文件 /media/share/swap/swapfile 权限不对(0644),Linux 内核要求 swap 文件权限必须 0600,否则 swapon/swapoff 会报警:

bash 复制代码
swapon /media/share/swap/swapfile
# 输出:
# swapon: /media/share/swap/swapfile:不安全的权限 0644,建议使用 0600

于是尝试关闭 swap 以修改权限:

bash 复制代码
swapoff /media/share/swap/swapfile
chmod 600 /media/share/swap/swapfile

现象 :关闭过程异常缓慢,swapoff 进程陷入 D 状态(不可中断 I/O 等待) ,几乎一动不动。

分析

  • swapoff 的本质是把 swap 中的页面迁回内存。
  • 如果 swap 文件占用的页很大(比如这里 640G),内核需要不断读取 swap 到内存。
  • 一旦 I/O 被阻塞,进程进入 D 状态,这种状态不能用 kill 直接结束。

我等待了两小时,依然无响应。


2️⃣ 查看占用:smem 帮我定位死进程

我用 smem 观察 swap 使用情况:

复制代码
smem -u -r -k

输出示例:

sql 复制代码
User     Count     Swap      USS      PSS      RSS
test003      9    41.6M    35.9G    56.3G   137.5G
...

发现有一些长时间运行的进程占用大量 swap,部分进程僵死。于是杀掉它们后:

bash 复制代码
kill -9 <pid>

等待半小时,swapoff 仍旧一动不动。

分析

  • 即便占用进程被清理,swap 中的数据仍可能被内核锁定。
  • swap 文件对应的 inode 已经被内核记录,路径只是用户空间的引用。

3️⃣ 卸载硬盘:swap 幽灵化

NVMe 硬盘挂载在 /media/share,swap 文件就在上面。我尝试卸载硬盘:

bash 复制代码
umount /media/share

现象

  • swapon --show 仍显示 swap 存在
  • swap 文件路径完全不对应实际硬盘
  • swapoff 和 chmod 都无法操作,报"设备或资源忙"
ini 复制代码
swapon --show
# NAME           TYPE SIZE USED PRIO
# /swap/swapfile file 640G 3.9G   -2

分析

  • 内核 swap 绑定的是 inode,而非路径
  • 卸载硬盘后,inode 对应的块设备暂时不可访问,但内核仍持有 swap inode
  • 用户空间看到的路径与内核认的路径不一致,导致操作失败

4️⃣ 尝试释放缓存与新建 swap

我尝试过:

bash 复制代码
sync; echo 3 > /proc/sys/vm/drop_caches

以及新建其他 swap 文件:

bash 复制代码
fallocate -l 2G /swap/new_swapfile
chmod 600 /swap/new_swapfile
mkswap /swap/new_swapfile
swapon /swap/new_swapfile

现象:原 swap 状态依然卡住,路径错乱无法释放。

分析

  • drop_caches 清理 page cache,但不能释放 swap 文件本身的占用
  • 新建 swap 文件与原 swap inode 无关,不会影响幽灵 swap

5️⃣ 灵光一现:软链接救场

意识到 swap 文件实际存在,但是swapon --show 显示又没问题。尝试创建软链接:(一开始问GPT说是不建议这么操作 没效果)

bash 复制代码
mkdir -p /swap
ln -s /media/share/swap/swapfile /swap/swapfile
ls -l /swap/swapfile
# /swap/swapfile -> /media/share/swap/swapfile

分析

  • 内核操作 swap 时查看的是 inode
  • 软链接让用户空间路径 /swap/swapfile 对应原 swap inode
  • swapoff 可以重新访问文件块,从而开始释放 swap

6️⃣ 执行 swapoff:I/O 重新启动

执行:

css 复制代码
swapoff -a -v

使用 iotop 观察:

复制代码
iotop -oP -u root

现象:swap 开始被读取,内存逐步释放,swap 用量下降。

分析

  • 内核开始将 swap 页迁回物理内存
  • 软链接修正了路径,避免"设备或资源忙"错误
  • 释放完成后,swap 文件可以重新挂载,路径与权限都正确

7️⃣ 关键技术总结

  1. inode 与路径

    • swap 文件挂载后,内核记录 inode,路径只是用户空间引用
    • 卸载硬盘或路径错误时,swap 并未真正消失
  2. D 状态不可杀

    • swapoff 或 I/O 阻塞进程会进入不可中断状态
    • 只能等待 I/O 完成或使用软链接修正路径
  3. 软链接原理

    • 修正用户空间路径,使 swapoff 可以访问内核 inode
    • 无需重启,适用于高可用场景
  4. 权限要求

    • swap 文件必须 0600,否则 swapon 会拒绝

8️⃣ 结论

  • 遇到 swap 卡住,先确认文件权限、inode、占用进程
  • 使用软链接可以热修复 swap 路径异常
  • 熟悉 swap 与 inode 的绑定机制,是解决类似问题的关键

相关推荐
油丶酸萝卜别吃11 分钟前
nginx配置代理服务器
运维·网络·nginx
maomao17131413 分钟前
Jenkins 环境部署
运维·jenkins
dessler1 小时前
Hadoop HDFS-部署和基本操作
linux·运维·hdfs
运维行者_2 小时前
使用Applications Manager进行 Apache Solr 监控
运维·网络·数据库·网络安全·云计算·apache·solr
一心0923 小时前
tomcat 定时重启
运维·tomcat·定时任务
₯㎕星空&繁华3 小时前
Linux-地址空间
linux·运维·服务器·经验分享·笔记
会说法语的猪4 小时前
使用nginx反向代理kkfile
运维·nginx
Mr_Xuhhh5 小时前
传输层协议TCP(3)
运维·服务器·网络·网络协议·tcp/ip·http·https
夜影风5 小时前
Nginx反向代理与缓存实现
运维·nginx·缓存