资讯动态

磁盘空间告警排查实战:从Codex缓存到WinSxS组件存储的根因定位

发布时间:2026/10/4 8:42:57 来源:尧图企业网站定制
周二下午三点十七分告警群里又一次弹出那条熟悉的消息C盘剩余空间不足10%当前剩余8.2GB。上一次我清理完临时文件两天后又满了上一周我迁走了开发环境缓存撑了四天。这次我没有急着动手而是把问题挂上了“Bug悬案侦破大会”的案卷。这是我最近在团队里发起的一项技术活动把平时零散的排障经历整理成有卷宗、有角色、有五幕流程的集体演练用一场“破案”的方式把那些反复出现的怪Bug彻底拆开来看。这次大会选了两起主案正好对应最近大家讨论最多的两类问题一个是与AI编程助手Codex相关的磁盘异常占用一个是被无数人提起却很少被真正讲透的Windows WinSxS组件存储膨胀。这篇复盘就是这两场侦破的完整记录也把我们从“会修Bug”到“会破Bug”的整个协作机制一起讲清楚。如果你平时要做开发、运维、测试或者只是经常被C盘空间不足折磨这份内容应该能给你一点不一样的角度。1. 悬案大会的由来为什么我把排障办成了一场比赛1.1 “修完了就忘了”是团队最大的浪费先说动机。我们团队以前处理Bug的方式很传统谁线上报障谁接手排查排查出原因改了代码验证通过然后写一条“已修复”的评论这事就算翻篇了。但时间一长我发现一个问题很多Bug被修完之后中间的排查过程完全不记得了。尤其是“环境类”“空间类”“偶现类”这些老大难问题经常是几个人轮流处理一整天最后某个人无意中动了某个参数问题消失了但到底为什么消失、有没有可能在别的机器上再犯没有人能说清楚。这种“修完即忘”的模式对单个需求来说问题不大但对整个团队来说是一种持续的浪费。同一类坑可能这个月踩一次、下个月再踩一次换个人又踩一次。我觉得与其等Bug反复来敲门不如专门腾出时间把那些“看起来已经解决、但心里没底”的案子翻出来用一套标准的流程重新侦破一遍并且把侦破过程固化成团队都能复用的经验。于是就有了“Bug悬案侦破大会”。1.2 五幕结构报案、勘查、取证、审讯、结案大会的玩法并不复杂。我设计了一个五幕流程每一幕都对应排障过程中一个真实环节报案提交案卷写清楚现象、影响范围、首次出现时间、复现步骤。写不出来的部分就是我们需要查的部分。勘查到现场采集线索包括磁盘快照、日志时间线、进程状态、配置变更记录以及“一切和正常情况有差异”的东西。取证针对勘查阶段发现的疑点做定向实验用日志、代码遍历、工具输出作为证据呈现而不是凭感觉“拍脑袋”。审讯把可疑的组件一个接一个拉进“审讯室”用控制变量法逐一排除直到剩下的那一个如何都洗不清嫌疑。结案基于证据宣读“判定书”说明根因、触发链路、修复方案和加固措施最后由至少两名工程师签字确认。文章里我会不停提到的两起主案就是在这个框架里完成的。但先别急着看过程我想先聊一个问题为什么快要被说烂的磁盘空间问题反而最适合拿来当“悬案”破因为磁盘类Bug有个特点现象极其明确但原因极其隐蔽。文件占空间这件事只要不去逐层翻永远不知道背后是哪一环在偷偷生长。而只要找到了那一环修复的路径通常非常简单。所以这类问题非常适合作为“大会”的演练对象——它考验的完全是排查思路。2. 第一桩悬案Codex 磁盘 Bug——本地快照的渐进式吞噬2.1 现场连续三周充满又清理C盘到底在被谁吃第一桩案子的主角是那台挂在我工位旁边的Windows开发机。我们团队当时正在把AI编程助手Codex引入日常开发流程用它辅助写单元测试、解释老代码、生成提交信息。需求量不低任务频率也不低。大概三周之后就有同事开始喊C盘满了。我一开始以为是Windows更新缓存或者是npm、pip的缓存膨胀抱着常规心态做了一遍清理清临时文件、清npm缓存、跑磁盘清理工具。做完之后空间确实回来了一部分结果两天之后再一次跌破10%。按常规手段无效我开始怀疑问题没那么简单。第一件事我用了一款文件夹空间扫描工具把C盘从顶层往下按占用大小排序。扫完之后最大的嫌疑浮出水面用户目录下的AppData\Local里有一个和Codex相关的数据目录体积已经超过42GB。这里要插一句很多人在看到某个目录“体积巨大”之后会立刻想删。先别急着删。体积大是现象不是证据。我们必须搞清楚这里面的内容是什么、为什么会产生、删了之后会不会影响工具正常使用。于是我把这一层线索放进了“勘查记录”继续往里挖。2.2 勘查与取证用两个时间点的快照对比逼近真凶进入勘查阶段后我做了三件比较关键的事。第一件统计目录里的文件构成。打开这个Codex数据目录发现下面有大量以会话ID命名的子目录每个会话目录里还有.log文件、状态快照、对话上下文备份、临时脚本文件等。我用PowerShell跑了一个统计脚本按文件扩展名汇总数量结果触目惊心光.log文件就有几十万个快照文件也有十几万个。第二件做时间差对比。我不删任何东西先记录当前这个目录的总大小和文件数然后正常使用Codex完成两个开发任务再次记录同一目录的变化。结果显示两个任务结束后这个目录新增了大约500MB文件。也就是说磁盘占用和任务量存在严格的线性关系这已经排除了“后台自动更新导致的偶发生长”这类可能。第三件验证异常触发条件。我有意构造了一次“任务失败重试”的场景让Codex执行一个会报错的复杂重构指令等待失败后重试两次。结果非常明显——失败任务的单次数据增量远高于成功任务每次失败会落下一个包含完整上下文的大快照用于后续续接对话但这些快照在任务重试成功后并没有被及时删除。到这里这个案子的嫌疑范围已经缩得非常小了不是Windows更新不是常规开发缓存而是Codex自身在本地落盘的数据没有按生命周期回收。2.3 根因判定像反复复制粘贴却只删掉目录条目通过对证据链的串联我们最终把根因归结为一个非常一致的行为模式正常情况下每个会话任务会生成一次快照并在任务结束后保留一份近期会话的可恢复上下文。但是在“并发任务”或者“失败重试”这两种场景下每触发一次都会额外生成多份快照。整个清理机制按“最活跃会话”的索引去做引用判断却遗漏了磁盘上已经不再被引用的历史快照文件。于是逻辑层的引用被释放了物理文件却一直躺在硬盘里。这个行为模式很像你在一个文档里反复复制粘贴大段内容最后只删除目录里那一行条目文件本体却全部留在原地。每一次失败重试都会复制一份新的“全体内容”。这也是很多“新工具类”磁盘Bug的通病产品团队往往只关注了核心链路的功能正确性对本地缓存、会话快照这类附带产物的生命周期管理考虑得不够周全。我们遇到的情况不一定所有机器都会触发但只要你用得多、跑过失败任务目录就会悄悄长大。2.4 修复与加固先定“哪些文件可删”再谈清理脚本修复环节我的原则是先证明“哪些文件可以安全删”再动手删。绝不能因为看到一个42GB的目录就一把梭。我先翻了这个目录下近30天的文件生成时间分布然后把“成功完成且已超过N天没有被任何会话索引引用的快照”定义为可清理对象。在这个定义基础上写了一个清理策略脚本核心逻辑是保留最近7天内产生且关联到活跃会话的快照保留所有失败日志中标记为“近期调查中”的内容最多30天超过上述条件且未被当前索引引用的快照进入删除名单删除前后各跑一次统计对比释放空间和文件数并把对比结果写入清理日志。脚本写好后我在一台备用机器上先验证两件事清理后Codex的已保存对话是否还能正常恢复、后续任务是否受影响。确认安全后才动那台C盘告警的机器。一次性清理出的空间约有31GB。之后连续观测两周磁盘占用一直稳定在一个合理区间。沿着这个案子我们还调整了团队的使用规范给Codex的本地数据目录设置了计划任务每周自动执行一次按策略清理在文档里明确提示同事遇到失败任务连续重试后记得手动跑一次清理检查后续把类似“AI工具本地缓存目录”纳入了常规磁盘巡检名单。关于这个案子我想提醒同行一点很多“AI编程助手导致磁盘占用”的排查帖会直接建议卸载或关闭历史保留功能这当然有效但比较粗暴。更稳妥的做法是先通过时间差对比确认触发条件再按策略保留“近期可恢复上下文”其余的全部归档清理。既保证工具能力又控制磁盘成本。3. 第二桩悬案WinSxS 组件存储的大膨胀——为什么越清理越满3.1 现象删了所有能删的临时文件C盘依然亮红灯第二起案子来自另一台长期使用的Windows工作站。同事反映C盘空间持续告警他已经用磁盘清理工具清理过Windows更新缓存、删除过下载目录、甚至把休眠文件都关了空间依旧紧张。我登上去一查C盘总容量500GB其中Windows目录占了将近200GB而C:\Windows\WinSxS单独一个文件夹属性里显示的“大小”就有98GB。我先没急着处理WinSxS而是采用了和上一案一样的思路——先看它为什么会这么大。用DISM跑了一次组件存储分析命令是dism /online /cleanup-image /analyzecomponentstore输出显示组件存储的“实际物理大小”远低于“虚拟大小”可清理的组件数量并不多。这说明一个很关键的事实WinSxS目录里很大比例的内容并不是“重复占用两份空间”而是以硬链接形式存在的同一份物理数据的多个逻辑入口。如果你直接按文件夹体积去衡量很容易被吓到也很容易误判为“有一堆垃圾可以删”。3.2 原理前置硬链接、组件存储、挂起操作哪个都不能乱动在讲接下来的排查之前我有必要把这个目录的基本机制说清楚因为太多人在这里栽过跟头。WinSxS全称是“Windows Side-by-Side组件存储”用来保存系统运行所需的组件、驱动、更新包以及它们的多版本副本。它设计的初衷是保证系统组件可以安全更新和回滚你装了补丁之后旧版本组件不会立刻被删除而是留在WinSxS里以防新版本出问题时能回退。这里有两个关键点第一WinSxS里的很多文件通过硬链接与系统其他目录共享同一块物理磁盘空间。比如你看到WinSxS里有1000个文件其中700个实际上和System32里某些文件指向同一个数据块。删除WinSxS里的文件很可能连带破坏正在被系统使用的另一个入口。第二组件存储有自己严格的引用计数机制。真正可以安全清理的是那些“已被新版本取代、且不再被当前系统引用”的旧组件。在Windows 10及更高版本上这些可清理组件通常已经可以通过更新清理流程回收。如果只是普通的补丁迭代系统隔段时间会自动或半自动地清理。但有一种特殊情况会让组件存储“只进不出”更新包反复安装失败导致大量待处理的操作被写入挂起队列即通常说的Pending.xml每次失败都会尝试重新暂存、解压、写入组件清单而每一次重试都会在WinSxS里留下零散的残留数据。这个案子的根因恰恰就在这里。3.3 排查链路从更新日志里的同一串错误码开始我当时的排查顺序是这样的第一步先确认组件存储有没有异常挂起。我查了C:\Windows\Logs\CBS\CBS.log和系统事件查看器里的Setup日志发现最近一个月的累积更新补丁反复尝试安装、反复失败错误码每次都一样。这说明不是网络问题也不是空间暂时不足导致的偶发失败而是某个环境状态卡住了安装过程。第二步检查挂起的部署操作。在管理员命令行里用命令查询当前组件的处理状态能看到有多个处于“待处理”状态的部署操作时间跨度拉得很长。这些操作迟迟没有完成就成了WinSxS里不断积攒临时文件的核心推手。第三步尝试正常完成或清理挂起操作。这里我要特别说明直接改注册表删除Pending.xml是很多网帖里的“终极大法”但我非常不建议在没有充分备份和专业知识的情况下使用因为挂起操作里往往包含着还没有完成的驱动或系统文件替换计划强行删除可能导致系统损坏甚至无法启动。正确的顺序是先尝试让系统自己把这些挂起的操作执行完。我的做法是停止Windows Update服务同时停止Cryptographic Services和Background Intelligent Transfer Service清理SoftwareDistribution目录下的Download缓存排除“下载中途损坏”的可能重新启动相关服务然后手动触发一次更新检查让安装流程重走一遍一步步观察更新是否从“反复失败”变成“正常完成”。等挂起的更新流程走完之后再回到WinSxS本身。3.4 收网用DISM完成组件清理并把重置基线作为备选更新流程恢复正常后我重新执行了一次组件存储分析。这次的结果比之前乐观不少可清理组件数量明显增多说明之前被挂起操作占用的部分已经释放。接下来才进入真正安全清理的步骤dism /online /cleanup-image /startcomponentcleanup这个命令会扫描WinSxS移除被取代且不再引用的组件版本。执行耗时比较长过程中最好不要动电脑也别强制关机。第一次跑完之后我又跑了一次分析组件存储的物理占用明显下降。但对于这台机器来说如果还想把空间压得更狠还有一个备选参数/ResetBase它会将所有已安装更新对应的基线组件永久重置旧版本不再保留回滚能力。这个参数能压出更多空间但代价是“不能通过删除这次清理之前的最新更新来回滚系统”。我在实际操作中对这台机器的判断是更新已经恢复正常且系统已经顺利运行数周回滚旧补丁的需求很低于是执行了带/ResetBase的清理。前后对比下来WinSxS从98GB压到了约52GBC盘总可用空间从8GB回升到接近70GB。针对这个案子我想特别强调几条避坑经验不要试图直接删除WinSxS文件夹甚至不要手动删除其中任一子目录。系统对这个目录的管理是自动化的人工干预只会破坏组件引用。不要一上来就用/ResetBase。先修更新、先清理常规组件如果空间压力没那么极端完全可以先不加这个参数。如果机器上存在大量“重复安装失败的更新”不要只顾着清空间一定要先解决更新失败的环境根因否则清理没多久又会涨回去。4. 两起悬案背后的通用破案方法论复现、证据闭环、根因验证两起案子走完之后我把它们的共性抽成了一套团队内部通用的破案流程。这里不聊这些方法本身对不对只说说我们在实际执行中踩过哪些坑、坚持了哪些原则。4.1 铁律一复现不出来就不要开口分析这个原则在Codex案子上尤其吃得开。我们最开始收到C盘告警时很多人的第一反应是“最近是不是装了太多开发工具”。如果顺着这个怀疑去卸载软件可能半天过去空间还是没有回来。正确的做法是先构造一次操作观察磁盘占用的对应变化不跑任务空间不涨跑任务空间涨连跑失败任务空间猛涨。这就是把模糊的“磁盘老是被吃”变成了可复现的“某个动作会触发增长”。复现的作用不只是帮你确认问题它更是在帮你建立“因果证据”。没有复现条件的分析本质上都是猜。4.2 铁律二一切删除和修改之前先做证据闭环磁盘类Bug的修复动作往往不可逆尤其是WinSxS这种系统目录。无论是对Codex缓存做清理还是对组件存储执行/ResetBase我都会在动手前留下三样东西当前的完整状态快照包括目录大小、文件数、可用空间预期会发生变化的目标范围哪些目录、哪些规则会被影响可回滚或可备份的路径如果是系统级操作至少做一次系统还原点或快照备份。整个过程中所有执行命令的输出都会保存下来。后面写复盘卷宗的时候这些输出就是证明“修复有效”的直接证据而不是一句“看起来好了”。4.3 控制变量与二分逼近尽快把嫌疑人名单缩到一个人现场勘查阶段最忌讳的是“觉得哪里可疑就动哪里”。我们在两起案子里都用了一致手法列嫌疑人名单、逐个验证、只改一个变量。比如WinSxS那个案子最开始的嫌疑人列表有四个常规Windows更新缓存、软件安装残留、WinSxS组件膨胀、用户自身文件。我先用DISM分析和磁盘扫描排除了前两个再用更新日志找到了“反复失败”的更新包最后用组件存储分析确认可清理空间。整个过程没有哪一步是同时动两处地方的。4.4 根因验证不是“看着好了”就完事修复完当天磁盘空间确实回来了但不等于案子结束。真正的根因验证要看修复后的几天内问题有没有继续按原来的节奏增长。Codex案子修完后的两周我们每天记录一次缓存目录体积和C盘可用空间确认数值基本平稳WinSxS案子修完后的一个月我们也复查了两次更新日志和组件存储分析确认没有再次出现挂起操作。只有这些长期观测做完我们才在结案栏里写“根因已闭环”。5. 协作机制复盘把“会”开成“实验室”让Bug变成团队的共同经验两起案件单独拿出来每起都能写成一篇讲技术原理的文章。但“Bug悬案侦破大会”区别于普通文章的地方在于它把整个排查过程放进了协作框架里。同样的案子如果只是我一个人修完团队其他人最多看一篇复盘文档感受不深。但当他们亲自扮演“审讯员”“见证人”每个人的技术判断力都会被拉起来。我们给每次大会设计了角色剧本侦察员负责最枯燥的现场线索采集比如统计文件增量、翻日志、跑扫描工具。这个角色适合新人因为能快速熟悉环境。技术专家由对相关领域最有经验的人担任负责根据线索形成根因假设比如分析WinSxS的组件原理或者梳理Codex的会话快照逻辑。记录员全程守着时间线和证据链专门指出“你这里还缺一个证据”。见证人负责质疑不停反问“你凭什么认为嫌疑已经被排除”。见证人是防止我们过早下结论的关键角色。我们复盘文档也刻意分成了两种写法一种是事故报告面向那些需要快速知晓结果的同事写得简短、直接另一种是知识沉淀把排查思路、禁忌动作、可复用命令整理进团队WIKI。很多人不太在意第二类文档但我的体会是这一类文档才是Bug大会真正的产出物。因为事故会过去但排查经验会留下来。还有一个不能忽略的规则“不追责只追踪”。大会全程不允许出现“这是谁的锅”这类讨论。Bug不是某个人的道德污点它是系统设计、流程机制和环境状态共同作用下的信号。谁在错误的方向上多花了一个小时不是大会上要追责的事情大家只关心这条路径为什么走不通下次怎么少走弯路。6. 如果你想办一场类似的“Bug 大会”落地建议与避坑指南每次我把这个活动讲给同行听都有不少人问我也想在团队里搞但怕开成批斗会也怕大家不愿意来。这里我给你几个经过实践检验的落地建议。第一选题要选“中等难度”的Bug不要一上来就拿线上重大事故练手。理想案卷是那种“很多人遇到过、但没深挖过”的磁盘空间问题、日志泄露问题、构建偶现失败。难度太低没有讨论价值难度太高大家连勘查阶段都撑不过去会打击积极性。第二频率控制在一个月一次到两次每次控制在一到两小时。我和团队采用的是“两场主案一场快闪”的排期快闪案件只花二十分钟讲现象和根因主案才做完整的五幕流程。这样既保证深度又不占用太多开发时间。第三不要把大会的结果和绩效挂钩。我们内部从一开始就明确这是一场技术练习不是为了找谁的问题。谁在大会上提出一个关键质疑、一个新颖的排查方法会得到公开的感谢和掌声而不是因为修了一个Bug被奖励。这种非功利的环境反而让很多平时话不多的同事开始主动分享自己的排障经历。第四一定要有人在会上做“决策记录”。我们每次大会结束后记录员会整理出三样东西这次的案子是否结案、是否存在未完全排除的疑点、下次大会需要跟进的事项。如果不做这个动作再精彩的讨论也容易在一周后被人遗忘。最后说一个我自己很深的体会。这个大会办了两期之后团队里“凭感觉修Bug”的声音少了很多。大家在群里讨论问题开始习惯性地说“我先复现一下再判断是不是缓存问题。”这个转变比修好任何一个具体Bug都实用。磁盘类Bug的排查所有人都在和时间赛跑但你跑得快的前提不是手速而是先停下来把证据链补齐。你越急着删那个大文件夹越容易删错你越愿意花十分钟看一眼增量规律越能一次解决问题。这套方法不止用于C盘告警系统更新异常、日志无限增长、缓存持续膨胀底层逻辑都是如此先找触发点再锁根因最后才动刀。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑