一周写了 186 GB:WSLg 的 RdClientAutoTrace 撑满了 C 盘
C 盘在一周里快速减少,排查时 952 GB 的磁盘只剩约 69.5 GB。最后找到的主因不是 Docker 镜像,也不是 110 GB 的分页文件,而是 WSLg 远程桌面组件留下的 12,729 个 ETL 文件。
这批日志占了 186.36 GB,而且仍以每天 17~41 GB 的速度增长。

先建立空间基线
面对“C 盘突然满了”,第一反应往往是找最大文件。但最大文件不一定是最近的增长源。我先做只读检查:
Get-PSDrive -Name C |
Select-Object Name,
@{N='UsedGB'; E={[math]::Round($_.Used / 1GB, 2)}},
@{N='FreeGB'; E={[math]::Round($_.Free / 1GB, 2)}}
Get-ChildItem C:\ -Force -File |
Sort-Object Length -Descending |
Select-Object -First 15 FullName,
@{N='SizeGB'; E={[math]::Round($_.Length / 1GB, 2)}},
LastWriteTime
根目录最显眼的两个文件是:
C:\pagefile.sys 110.47 GB
C:\hiberfil.sys 25.49 GB
它们很大,但都属于系统管理对象。尤其是 pagefile.sys,不能因为体积醒目就手工删除。
通过 WMI 查看分页文件后,能看到它采用系统管理大小,而且本次启动的峰值使用量很高。WSL 与终端进程也占据了较多内存提交量。这能解释分页文件为何扩张,却还不能解释一周内持续丢失的几百 GB 空间。
用目录聚合缩小范围
对整个 C 盘直接递归 Get-ChildItem,既慢又会打印海量结果。我用 robocopy /L 做只读枚举,只关心汇总数据:
robocopy "$env:LOCALAPPDATA" C:\Windows\Temp `
/L /E /XJ /BYTES /NFL /NDL /NJH /R:0 /W:0
几个关键参数:
/L只列出,不复制;/XJ排除目录联接,避免递归环和重复统计;/BYTES让结果按字节显示;/R:0 /W:0遇到不可访问项时不重试。
目录逐层拆分后,异常很快集中到 %LOCALAPPDATA%\Temp:
Temp 209.2 GB
Docker 107.5 GB
Programs 16.5 GB
Microsoft 15.6 GB
uv 6.2 GB
继续按 Temp 的第一层目录聚合:
$root = "$env:LOCALAPPDATA\Temp"
$sizes = @{}
Get-ChildItem $root -Force -File -Recurse -ErrorAction SilentlyContinue |
ForEach-Object {
$relative = $_.FullName.Substring($root.Length).TrimStart('\')
$top = ($relative -split '\\', 2)[0]
if (-not $sizes.ContainsKey($top)) {
$sizes[$top] = [double]0
}
$sizes[$top] += $_.Length
}
$sizes.GetEnumerator() |
Sort-Object Value -Descending |
Select-Object -First 25 `
@{N='Entry'; E={$_.Key}},
@{N='SizeGB'; E={[math]::Round($_.Value / 1GB, 2)}}
结果不再含糊:
DiagOutputDir 186.33 GB
<WSL 实例 GUID>\swap.vhdx 7.88 GB
Visual Studio 安装临时目录 5.40 GB
DiagOutputDir 里几乎全部是下面这个目录的 .etl 文件:
%LOCALAPPDATA%\Temp\DiagOutputDir\RdClientAutoTrace
按日期统计后,七天共生成 12,729 个文件:
| 日期 | 文件数 | 当日体积 |
|---|---|---|
| 7 月 12 日 | 679 | 8.87 GB |
| 7 月 13 日 | 1,418 | 16.97 GB |
| 7 月 14 日 | 1,513 | 21.27 GB |
| 7 月 15 日 | 2,530 | 37.30 GB |
| 7 月 16 日 | 2,430 | 34.84 GB |
| 7 月 17 日 | 2,482 | 41.07 GB |
| 7 月 18 日排查时 | 1,542 | 24.30 GB |
到这里,问题不再是“什么占空间”,而是“谁在持续写这些文件”。
从 ETL 文件追到活动会话
.etl 是 Event Trace Log,属于 Windows ETW 事件跟踪输出。只删文件不停止会话,目录很快就会回来。
先看当前运行的跟踪会话:
logman query -ets |
Select-String -Pattern 'RdClient|Remote|AutoTrace|Wpp'
现场结果里有:
RdClientAutoTrace Trace Running
再查询详情:
logman query RdClientAutoTrace -ets
其中几个字段很关键:
Root Path: %LOCALAPPDATA%\Temp\DiagOutputDir\RdClientAutoTrace
Segment Max Size: 100 MB
Circular: On
Buffer Flush Timer: 30 seconds
Provider: TS Client ActiveX Control Trace
Provider: TS Client Trace
它看起来配置了循环记录,但现场不断创建新分段,旧文件没有得到有效限制或回收。
确认写入者是 WSLg
接下来查看远程桌面相关进程的路径和命令行:
Get-CimInstance Win32_Process |
Where-Object {$_.Name -match 'msrdc|rdclient|mstsc'} |
Select-Object Name, ProcessId, ExecutablePath, CommandLine
现场进程来自:
C:\Program Files\WSL\msrdc.exe
命令行带有 /wslg、WSLDVC_PACKAGE 和 wslg.rdp 等参数。这说明它不是用户手动打开的普通远程桌面会话,而是 WSLg 图形转发链路的一部分。
WSLg 会让 Linux GUI 窗口自然出现在 Windows 桌面。Linux 一侧运行 Weston 等组件,Windows 一侧借助远程桌面技术完成画面、输入和音频集成。官方仓库里也有同类报告:WSL Issue #10216。
先止血,再精确删除
第一步是停止写入会话:
logman stop RdClientAutoTrace -ets
然后再次查询,确认会话已经消失:
logman query -ets |
Select-String -Pattern '^RdClientAutoTrace\s'
递归删除前,我没有直接对 %TEMP% 下手,而是解析绝对路径并限制允许范围:
$target = "$env:LOCALAPPDATA\Temp\DiagOutputDir\RdClientAutoTrace"
$allowed = "$env:LOCALAPPDATA\Temp\DiagOutputDir"
$resolved = (Resolve-Path -LiteralPath $target -ErrorAction Stop).Path
$allowedResolved = (Resolve-Path -LiteralPath $allowed -ErrorAction Stop).Path
if (-not $resolved.StartsWith(
$allowedResolved + '\',
[System.StringComparison]::OrdinalIgnoreCase)) {
throw "Safety check failed: $resolved"
}
再统计一次待删除对象:
$before = Get-ChildItem -LiteralPath $resolved -Force -File -Recurse |
Measure-Object Length -Sum
[pscustomobject]@{
Files = $before.Count
SizeGB = [math]::Round($before.Sum / 1GB, 2)
}
确认数量为 12,729、体积为 186.36 GB,且这些日志不再需要提交给技术支持后,才删除这个单一目录:
Remove-Item -LiteralPath $resolved -Recurse -Force
清理后,C 盘可用空间立刻从约 69.5 GB 增加到 255.8 GB。
只删日志为什么不够
第一次清理后,目录很快被重新创建,RdClientAutoTrace 又变成 Running。这证明它不是历史遗留文件,而是活动组件持续生成的输出。
定时删目录只能缓解容量问题,无法停止持续写盘,也会增加 SSD 的无效写入。修复必须改变创建会话的那条路径。
这类问题常见的处理方向有三种:
禁用 WSLg
在 .wslconfig 里设置:
[wsl2]
guiApplications=false
它最直接,但会失去 Linux GUI 应用,不适合仍要开发和调试 WSLg 程序的环境。
用同名文件阻止目录创建
社区里有人删除目录后,创建一个同名普通文件,让记录器无法再创建同名目录。这能止住文件增长,却可能带来新的跟踪启动失败事件,也没有解决底层路径。
切换 WSLg 的远程桌面路径
本次采用的是社区验证过的兼容方案,在 %USERPROFILE%\.wslgconfig 中加入:
[system-distro-env]
WSLG_USE_MSTSC=true
这个变量不是 Microsoft Learn 正式承诺的稳定配置接口,因此应该明确把它当成针对已知问题的临时兼容方案。WSL 更新后要重新验证;官方问题关闭并给出正式修复后,也应考虑移除它。
让配置真正生效
Docker Desktop 使用 WSL 2 后端,可能阻止系统虚拟机完全退出。我先正常停止 Docker Desktop,再关闭 WSL:
docker desktop stop
wsl --terminate Ubuntu
wsl --shutdown
随后重启 Docker Desktop 和 Ubuntu。这里不要为了“关干净”直接删除 Docker 的 VHDX,里面可能有镜像、容器层、卷和持久化数据。
验证不能只看目录暂时为空
修复后至少要确认五件事:
- Ubuntu 能正常启动;
- Docker Desktop 后端能运行;
RdClientAutoTrace会话不存在;- 日志目录没有重新创建;
- C 盘可用空间不再持续下降。
我用 5 秒间隔连续采样:
$tracePath = "$env:LOCALAPPDATA\Temp\DiagOutputDir\RdClientAutoTrace"
1..6 | ForEach-Object {
Start-Sleep -Seconds 5
[pscustomobject]@{
Seconds = $_ * 5
DockerBackend = [bool](
Get-Process 'com.docker.backend' -ErrorAction SilentlyContinue
)
TraceRunning = [bool](
logman query -ets 2>$null |
Select-String -Pattern '^RdClientAutoTrace\s'
)
TraceFolder = Test-Path -LiteralPath $tracePath
FreeGB = [math]::Round((Get-PSDrive C).Free / 1GB, 2)
}
}
连续 30 秒里,Docker 后端保持运行,跟踪会话和日志目录都没有回来,可用空间稳定。
为什么最后又多释放了约 100 GB
日志清理后,可用空间从 69.5 GB 增到 255.8 GB;停止并重启 Docker Desktop 后,又增加到约 356.6 GB。
检查 Docker 数据盘:
Get-Item "$env:LOCALAPPDATA\Docker\wsl\disk\docker_data.vhdx" |
Select-Object FullName,
@{N='LogicalSizeGB'; E={[math]::Round($_.Length / 1GB, 2)}},
LastWriteTime
现场看到它从约 107.4 GB 缩小到 14.4 GB。Docker Desktop 在正常停止和恢复期间回收或整理了稀疏 VHDX,额外释放约 93 GB。
这不意味着每次重启 Docker 都会得到相同结果,更不意味着可以直接删除 docker_data.vhdx。清理 Docker 资源应该先看:
docker system df
docker system prune
docker system prune 会删除未使用资源,执行前必须检查业务影响;涉及卷时尤其要谨慎。
最终结果如下:
| 指标 | 处理前 | 处理后 |
|---|---|---|
| C 盘可用空间 | 约 69.5 GB | 约 356.6 GB |
RdClientAutoTrace | 12,729 个文件,186.36 GB | 会话停止,目录不存在 |
| Docker VHDX | 约 107.4 GB | 约 14.4 GB |
| WSL 2 / Ubuntu | 运行中 | 运行中 |
| Docker Desktop | 运行中 | 恢复正常 |
| WSLg 图形功能 | 可用 | 保留 |
pagefile.sys | 110.5 GB | 未修改 |
留一个只读监控脚本
为了尽早发现复发,可以定期运行:
$tracePath = "$env:LOCALAPPDATA\Temp\DiagOutputDir\RdClientAutoTrace"
$traceBytes = if (Test-Path $tracePath) {
(Get-ChildItem $tracePath -File -Recurse -ErrorAction SilentlyContinue |
Measure-Object Length -Sum).Sum
} else {
0
}
[pscustomobject]@{
Time = Get-Date
CFreeGB = [math]::Round((Get-PSDrive C).Free / 1GB, 2)
TraceRunning = [bool](
logman query -ets 2>$null |
Select-String -Pattern '^RdClientAutoTrace\s'
)
TraceSizeGB = [math]::Round($traceBytes / 1GB, 2)
}
如果日志重现,再检查 .wslgconfig、WSL 和 msrdc.exe 的版本变化,以及 Issue #10216 是否已有正式修复。
结语
这次最危险的误判,是看到 pagefile.sys 和 Docker VHDX 很大,就准备先处理它们。真正的增长源藏在用户临时目录里,而且背后还有一个正在运行的 ETW 会话。
有效的处理顺序是:建立空间基线,逐层聚合目录,确认文件增长速度,追踪活动写入源,停止会话,校验路径后精确删除,最后重启相关组件并连续观察。
清理文件只能止血。让写入源停止,并证明它不会马上回来,才算修复。
微信公众号
欢迎关注「字与码」
如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。
X / Twitter
关注 @ax2_zicode
更即时的技术观察、新文章提醒和一些短想法会发在 X 上。