Windows Sysinternals 文件工具学习笔记(12.11):综合实战------从磁盘告警到文件替换的一条龙排障
- [Windows Sysinternals 文件工具学习笔记(12.11):综合实战------从磁盘告警到文件替换的一条龙排障](#Windows Sysinternals 文件工具学习笔记(12.11):综合实战——从磁盘告警到文件替换的一条龙排障)
-
- 一、场景设定:一台关键业务服务器的"磁盘告警"
- [二、Step 1:用 DU 快速锁定"罪魁祸首目录"](#二、Step 1:用 DU 快速锁定“罪魁祸首目录”)
- [三、Step 2:Strings + Streams 快速判断"这些东西是不是正常日志?"](#三、Step 2:Strings + Streams 快速判断“这些东西是不是正常日志?”)
- [四、Step 3:Junction + FindLinks 判定"是不是别的地方挂过来了"](#四、Step 3:Junction + FindLinks 判定“是不是别的地方挂过来了”)
-
- [3.1 用 Junction 看目录是否是挂载点](#3.1 用 Junction 看目录是否是挂载点)
- [3.2 用 FindLinks 查文件是不是被多处硬链接引用](#3.2 用 FindLinks 查文件是不是被多处硬链接引用)
- [五、Step 4:确定"能删什么、要保留什么",做一个干净的清理计划](#五、Step 4:确定“能删什么、要保留什么”,做一个干净的清理计划)
- [六、Step 5:MoveFile + PendMoves 处理"正在使用的文件"](#六、Step 5:MoveFile + PendMoves 处理“正在使用的文件”)
-
- [6.1 安排重启后删除大文件](#6.1 安排重启后删除大文件)
- [6.2 用 PendMoves 核对](#6.2 用 PendMoves 核对)
- [6.3 在维护窗口内重启](#6.3 在维护窗口内重启)
- [七、Step 6:把整个过程写成可以反复使用的"排障脚本"](#七、Step 6:把整个过程写成可以反复使用的“排障脚本”)
- 八、运维/安全视角的"加分项"
- [九、总结:12 章文件工具怎么变成"自己的工具箱"](#九、总结:12 章文件工具怎么变成“自己的工具箱”)
Windows Sysinternals 文件工具学习笔记(12.11):综合实战------从磁盘告警到文件替换的一条龙排障
前面 10 篇已经把 Strings / Streams / Junction / FindLinks / DU / PendMoves / MoveFile 各拆开讲了一遍。
本篇不再按"功能手册"写,而是用一个完整故障案例,把这些工具串成一条真正能上生产的"排障流水线"。
一、场景设定:一台关键业务服务器的"磁盘告警"
某天凌晨,监控系统发来告警:
- C 盘空间 < 5%
- 业务日志写入开始报错:
No space left on device - 应用组反馈:近期没有主动上大版本、没有明显大文件操作
典型现实场景:
"谁把盘写满了?"
"是不是日志没滚?"
"能不能先删点什么把业务救回来?"
我们用 Sysinternals 文件工具家族一步步把问题拆开。
二、Step 1:用 DU 快速锁定"罪魁祸首目录"
第一反应:先找"大户",不要上去就人工瞎翻。
cmd
du.exe C:\ -q -l 1
-q静默模式,只输出汇总-l 1只看第一层目录
示例输出(示意):
txt
Size Directory
--------------------------------
15.2 GB C:\Windows
68.7 GB C:\App
2.3 GB C:\Program Files
1.1 GB C:\Users
--------------------------------
Total files: xxxx
明显是 C:\App 爆了。
继续向下钻:
cmd
du.exe C:\App -q -l 1
得到类似结果:
txt
55.3 GB C:\App\logs
10.1 GB C:\App\data
3.3 GB C:\App\temp
👉 初步结论:logs 目录异常膨胀,优先关注。
这一层只解决"去哪儿看"的问题,避免你在文件夹里人肉翻半小时。
三、Step 2:Strings + Streams 快速判断"这些东西是不是正常日志?"
进入 C:\App\logs ,我们发现单个日志文件很大,比如:
C:\App\logs\service.log→ 15 GBC:\App\logs\trace.log→ 20 GB
先用 Strings 看看内容是不是正常文本/日志:
cmd
strings.exe C:\App\logs\service.log | more
- 如果看到的都是可读的英文/中文日志行,说明只是"写太多没滚"
- 如果几乎没有可读文本、全是二进制碎片 → 可能是:
- 程序写错了地方,把数据文件写进 log
- 或文件被其他逻辑占用了
再用 Streams 看有没有莫名其妙的 ADS(替你排除"日志文件上挂暗藏内容"的可能):
cmd
streams.exe -s C:\App\logs
关注输出里是否有类似:
txt
C:\App\logs\service.log:
:Zone.Identifier:$DATA
:hidden_payload:$DATA <-- 这类就非常值得继续查
在绝大多数正常应用里,日志文件不会长 ADS。
如果出现很多奇怪的 ADS 名字,要考虑是不是安全问题或某些工具的"奇葩设计"。
四、Step 3:Junction + FindLinks 判定"是不是别的地方挂过来了"
有时你会看到这样的情况:
C:\App\logs目录很大- 但里面可见文件加起来只有几十 MB...
这时优先想到两种"隐身方式":
- 目录是一个 NTFS Junction / 挂载点
- 文件有很多硬链接,占用空间被算在多处
3.1 用 Junction 看目录是否是挂载点
cmd
junction.exe C:\App\logs
若输出类似:
txt
Junction v1.07
C:\App\logs: JUNCTION
Substitute Name: \??\D:\RealLogs
Print Name: D:\RealLogs
那就说明:
C:\App\logs实际上只是一个"入口"- 真正的占用是在
D:\RealLogs
此时应该改用:
cmd
du.exe D:\RealLogs -q -l 1
去分析真实目录。
3.2 用 FindLinks 查文件是不是被多处硬链接引用
对于异常大的某个文件,比如:
cmd
findlinks.exe C:\App\logs\service.log
如果输出里显示:
txt
Index: 12345
Links: 3
说明这个物理数据被 3 个路径引用,比如:
txt
C:\App\logs\service.log
C:\ShadowCopy\service.log
D:\Backup\merged\service.log
仅删除其中一个路径不会立刻释放全部磁盘空间。这就解释了:
"我明明删了 10GB 日志,怎么盘还是满的?"
五、Step 4:确定"能删什么、要保留什么",做一个干净的清理计划
到这一步,你已经知道:
- 哪个目录是"重灾区"
- 哪些是正常文本日志、哪些是二进制数据
- 目录是否是 Junction
- 文件是否被多处硬链接引用
接下来要输出一个**"可审计的清理计划"**,避免随手一删把业务搞挂。
建议在笔记里写出类似结构:
txt
[清理计划 v1.0]
1. 立即可删(低风险)
- C:\App\logs\*.log 中早于 30 天的日志(已备份)
- C:\App\temp\*.tmp 中早于 7 天的临时文件
2. 需要保留但可压缩/归档
- C:\App\data\archive\*.bak
- D:\RealLogs\*.log (转移到大盘/对象存储)
3. 暂缓处理(需业务确认)
- C:\ShadowCopy\service.log (FindLinks 显示硬链接,压缩后保留)
真正的"高分排障",不是你手速快,而是:
任何删除行为都有记录、能说清为什么删、出了问题能回滚。
六、Step 5:MoveFile + PendMoves 处理"正在使用的文件"
某些日志/数据文件被应用或服务锁着,不能直接删除:
- 直接删除 → "文件正在被另一个程序使用"
- 强制杀服务 → 业务中断风险
如果这些文件可以在下次维护重启时清理,就用:
6.1 安排重启后删除大文件
cmd
MoveFile C:\App\logs\trace.log ""
MoveFile C:\App\logs\service.log.2024-xx-xx ""
意思是:
- 下次启动时自动删除这些文件
6.2 用 PendMoves 核对
cmd
PendMoves
输出中能看到刚才排队的删除操作,建议重定向存档:
cmd
PendMoves > C:\Logs\cleanup_pendmoves_2024-xx-xx.log
6.3 在维护窗口内重启
cmd
shutdown /r /t 120 /c "日志清理:重启时将删除部分大文件(详见 cleanup_pendmoves_*.log)"
这样做的好处:
- 不和正在运行的服务硬刚
- 所有变更可在日志里对上号
- 恢复时可以根据日志精准知道清理了哪些东西
七、Step 6:把整个过程写成可以反复使用的"排障脚本"
一个典型的"半自动排障脚本"可以长这样(示例):
bat
@echo off
setlocal
set TARGET=C:\App\logs
set BACKUP=C:\Backup\logs_%date:~0,10%
echo [1] 磁盘体检
du.exe C:\ -q -l 1
echo [2] 目标目录占用情况
du.exe "%TARGET%" -q -l 1
echo [3] 检查是否为 Junction
junction.exe "%TARGET%"
echo [4] 列出 ADS(可能的隐藏数据流)
streams.exe -s "%TARGET%" > "%BACKUP%_streams.txt"
echo [5] 备份并计划删除 30 天前日志
mkdir "%BACKUP%"
forfiles /p "%TARGET%" /m *.log /d -30 /c "cmd /c copy @file \"%BACKUP%\" & MoveFile @file \"\""
echo [6] 查看 Pending 删除计划
PendMoves > "%BACKUP%_pendmoves.txt"
echo [INFO] 请在维护窗口内重启服务器,清理才会生效。
endlocal
你可以再配合:
- PsExec → 在多台服务器上远程执行这段脚本
- ProcMon → 如果清理后还有莫名其妙写入,抓是谁继续写爆磁盘
这就是一整套可复用的"磁盘空间故障剧本"。
八、运维/安全视角的"加分项"
在写到自己的 CSDN 高分博客时,可以加一些更"工程化"的视角:
- 合规与审计
- 所有删除/替换操作都通过:
- 变更单编号 → 记录在脚本日志中
PendMoves输出文件 → 归档到集中日志系统
- 方便安全/审计团队复盘
- 所有删除/替换操作都通过:
- 回滚策略
- 删除前全部先备份到带日期的目录
- 命名规则统一:
logs_YYYY-MM-DD_HHMM - 若有误删,可以短期内从备份恢复
- 自动健康巡检
- 定时任务 + DU
- 超过阈值时自动生成报告,而不是等磁盘打满再处理
- 知识沉淀
- 把本篇这样的"从告警 → 分析 → 定位 → 处理 → 验证 → 防再发"的流程
写进团队自己的故障手册或Runbook
- 把本篇这样的"从告警 → 分析 → 定位 → 处理 → 验证 → 防再发"的流程
九、总结:12 章文件工具怎么变成"自己的工具箱"
回顾下我们在本篇串起来的工具:
- DU:发现谁占空间
- Strings:判断文件是否是日志/文本
- Streams:排查隐藏数据流 ADS
- Junction:查目录是否为 NTFS 挂载点
- FindLinks:调查硬链接,解释"删不干净"
- MoveFile:写入"重启后操作计划"
- PendMoves:查看系统的文件操作队列
一句总结:
前 10 篇是"认识工具",这一篇是"写剧本"。
你真正需要的是:遇到类似故障时,脑子里能立刻自动弹出这条流水线,而不是在服务器上随机点点看运气。
后面如果你愿意,我们可以再写一篇"模板化 Runbook":
比如《磁盘告警排障手册 v1.0》------直接按章节列 CLI 命令、截图位置、回滚策略,让你团队里任何一个人拿着都能落地执行,这种东西在面试和晋升汇报里都非常好用。