IIS服务器磁盘占满或响应变慢,如何检查日志增长、NTFS错误与I/O延迟
本文介绍IIS服务器磁盘空间不足或响应变慢时的分层排查方法,涵盖日志目录与增长趋势、NTFS和存储事件、磁盘I/O延迟及队列分析,并给出日志归档、文件系统修复和修复后复测要点,适合Windows服务器运维人员参考。

IIS 站点开始间歇性超时、后台操作明显变慢,或者系统盘只剩很少空间时,不要立即重启 IIS,也不要直接清空日志目录。磁盘占满可能只是表象:持续增长的访问日志、失败请求跟踪文件、NTFS 元数据错误,以及存储队列堆积,都可能让 IIS服务器出现写日志失败或响应时间上升。
排查顺序应从低风险检查开始:先确认各卷剩余空间和增长速度,再定位具体目录与日志来源;空间正常但仍然缓慢时,检查 NTFS、磁盘及存储控制器事件;最后采集 I/O 延迟和队列数据,将异常时间与 IIS 请求日志对应起来。这样可以区分“日志增长导致容量不足”“文件系统异常”与“磁盘性能不足”三类问题。
先确认是容量不足还是磁盘响应变慢
建议使用管理员权限打开 PowerShell。首先查看本地磁盘的容量、剩余空间和文件系统类型:
Get-CimInstance Win32_LogicalDisk -Filter "DriveType=3" |
Select-Object DeviceID,
VolumeName,
FileSystem,
@{Name='SizeGB';Expression={[math]::Round($_.Size / 1GB, 2)}},
@{Name='FreeGB';Expression={[math]::Round($_.FreeSpace / 1GB, 2)}},
@{Name='FreePercent';Expression={
if ($_.Size -gt 0) {
[math]::Round($_.FreeSpace * 100 / $_.Size, 2)
}
}}
不要只看系统盘。IIS 日志、网站文件、应用临时目录和分页文件可能位于不同卷,因此需要逐个确认。
接着核对故障时间线:
- 磁盘空间是否在几小时或几天内快速下降。
- IIS 响应变慢是否与日志体积突增发生在同一时段。
- 重启后是否暂时恢复,但空间仍在持续减少。
- 系统事件日志中是否同时出现 NTFS、Disk 或存储控制器错误。
- 只有某个站点缓慢,还是同一磁盘上的多个站点都受到影响。
如果释放少量空间后 IIS 很快恢复,但空间再次下降,重点应转向日志来源和保留策略;如果容量充足而请求仍然缓慢,则不能继续把问题简单归因于“磁盘快满了”。
定位 IIS 日志到底增长在哪里
IIS 访问日志默认位于系统盘,但站点级配置可以覆盖默认目录。排查时至少检查以下位置:
| 日志类型 | 常见默认路径 | 主要用途 |
|---|---|---|
| IIS W3C 访问日志 | C:\inetpub\logs\LogFiles |
记录请求方法、URI、状态码和处理时间 |
| HTTPERR 日志 | C:\Windows\System32\LogFiles\HTTPERR |
记录由 HTTP.sys 拒绝、超时或无法交给 IIS 的请求 |
| 失败请求跟踪日志 | C:\inetpub\logs\FailedReqLogFiles |
保存 Failed Request Tracing 生成的 XML 等文件 |
| 应用自身日志 | 由应用配置决定 | 可能位于站点目录、ProgramData 或其他自定义路径 |
实际路径可能不是 C:。可以在 IIS 管理器中选择对应站点,打开“日志”功能,查看目录、日志格式和滚动周期。失败请求跟踪则需要检查站点的“失败请求跟踪规则”。
安装了 IIS 管理脚本工具后,也可以使用 PowerShell 查看站点及日志配置:
Import-Module WebAdministration
Get-Website |
Select-Object Name, ID, State, PhysicalPath
Get-WebConfiguration -PSPath 'MACHINE/WEBROOT/APPHOST' `
-Filter 'system.applicationHost/sites/site' |
ForEach-Object {
[PSCustomObject]@{
SiteName = $_.Name
SiteID = $_.Id
LogDirectory = $_.logFile.directory
Period = $_.logFile.period
TruncateSize = $_.logFile.truncateSize
}
}
如果站点级 LogDirectory 为空,需要继续检查 siteDefaults 中的继承配置,或者直接以 IIS 管理器显示结果为准。
统计日志体积和文件数量
下面的命令只读取文件信息,不会删除文件,但递归扫描大量小文件本身也会产生 I/O。生产环境应先限定日志目录,并尽量避开业务高峰。
$root = 'C:\inetpub\logs'
$stats = Get-ChildItem -LiteralPath $root -File -Recurse -Force `
-ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum
[PSCustomObject]@{
Path = $root
Files = $stats.Count
SizeGB = [math]::Round($stats.Sum / 1GB, 2)
}
还可以按子目录统计,快速判断是访问日志还是失败请求跟踪文件占用较大:
Get-ChildItem -LiteralPath 'C:\inetpub\logs' -Directory |
ForEach-Object {
$result = Get-ChildItem -LiteralPath $_.FullName -File -Recurse `
-ErrorAction SilentlyContinue |
Measure-Object -Property Length -Sum
[PSCustomObject]@{
Directory = $_.FullName
Files = $result.Count
SizeGB = [math]::Round($result.Sum / 1GB, 2)
}
} |
Sort-Object SizeGB -Descending
如果体积并不夸张,但文件数量非常多,目录枚举、备份和安全软件扫描仍可能明显变慢。
Windows 没有 Linux 式的 inode 耗尽
NTFS 不使用面向管理员的 inode 计数,因此 Windows 上没有与 df -i 完全对应的检查方式。NTFS 使用主文件表 MFT 保存文件和目录记录。大量小型日志、失败请求跟踪 XML 或临时文件会增加 MFT 和目录索引压力,但这不等于 Linux 中“磁盘还有空间、inode 已耗尽”的故障。
可以查看 NTFS 基本信息:
fsutil fsinfo ntfsinfo C:
其中能够看到 MFT 起始位置、有效数据长度等信息。MFT 较大本身不代表损坏,判断重点应放在以下方面:
- 日志目录中的文件数量是否持续高速增长。
- 目录打开、递归扫描和备份是否明显变慢。
- 系统日志是否出现 NTFS 错误。
- 删除旧文件后,可用空间和目录操作是否恢复。
删除大量小文件后,MFT 文件本身不一定立即缩小,因此不能把“MFT 大小没有下降”直接判断为清理无效。
判断日志为什么突然增长
IIS 设置“每天”或“按大小”滚动日志,只会生成新文件,并不会自动删除历史日志。如果没有归档或保留任务,日志最终仍可能占满磁盘。
可以按文件最后修改日期估算近期增长趋势:
$root = 'C:\inetpub\logs\LogFiles'
$start = (Get-Date).AddDays(-7)
Get-ChildItem -LiteralPath $root -File -Recurse `
-ErrorAction SilentlyContinue |
Where-Object { $_.LastWriteTime -ge $start } |
Group-Object { $_.LastWriteTime.ToString('yyyy-MM-dd') } |
ForEach-Object {
$size = $_.Group |
Measure-Object -Property Length -Sum
[PSCustomObject]@{
Date = $_.Name
Files = $_.Count
SizeMB = [math]::Round($size.Sum / 1MB, 2)
}
} |
Sort-Object Date
文件最后修改时间可能受复制、恢复和日志滚动方式影响,因此该结果适合观察趋势,不应当作精确流量统计。预计剩余时间可以用以下方式粗略计算:
预计可用天数 = 当前剩余空间 ÷ 最近每日平均增长量
如果增长速度突然变化,应打开最新日志,先查看 #Fields 字段定义,再检查重复 URI、异常状态码和耗时请求。W3C 日志中的日期时间通常按 UTC 记录,关联系统事件时要注意时区差异。
$latest = Get-ChildItem 'C:\inetpub\logs\LogFiles' -File -Recurse |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1
if ($latest) {
$latest.FullName
Get-Content -LiteralPath $latest.FullName -Tail 50
}
重点关注:
- 同一个 URI 是否被高频重复请求。
404是否大量增加,可能来自错误链接、扫描或静态资源路径异常。500系列错误是否触发客户端或上游重复重试。sc-status、sc-substatus、sc-win32-status是否集中出现相同组合。time-taken是否在磁盘异常时段同步升高。- 是否临时开启了范围过大的失败请求跟踪规则。
time-taken 可以辅助定位,但它不只代表磁盘处理时间。必须与磁盘计数器、请求时间点和本机访问结果结合判断。
检查 NTFS、磁盘和存储控制器错误
容量不足解决后,如果 IIS 仍然间歇性卡顿,应检查 Windows“系统”事件日志。以下命令读取最近七天与 NTFS、磁盘和常见存储控制器相关的事件:
$start = (Get-Date).AddDays(-7)
Get-WinEvent -FilterHashtable @{
LogName = 'System'
StartTime = $start
} -ErrorAction SilentlyContinue |
Where-Object {
$_.ProviderName -match 'Ntfs|Disk|storahci|stornvme|iaStor|volmgr|partmgr'
} |
Select-Object TimeCreated, Id, ProviderName, LevelDisplayName, Message |
Sort-Object TimeCreated -Descending |
Format-List
常见结果应这样理解:
| 事件表现 | 可能含义 | 后续操作 |
|---|---|---|
| NTFS 报告文件系统结构错误 | 卷元数据可能不一致 | 先备份,再执行在线扫描 |
| Disk 报告读写失败或坏块 | 磁盘、虚拟磁盘或底层存储异常 | 检查存储健康状态和备份完整性 |
| 控制器重置、请求重试 | 控制器、驱动、链路或存储超时 | 结合厂商工具和宿主层事件检查 |
| 卷被标记为 dirty | Windows 认为卷需要检查 | 安排维护窗口修复,不要仅重启 IIS |
检查卷是否被标记为需要修复:
fsutil dirty query C:
Windows Server 2012 及后续版本的 NTFS 卷,可以先执行在线扫描:
chkdsk C: /scan
/scan 通常不要求卸载系统卷,但扫描仍会增加磁盘负载,应避开业务高峰。较旧的 Windows Server 版本应先核对 chkdsk /? 支持的参数。
如果扫描确认需要修复,必须先完成数据备份并安排维护窗口。对系统卷执行以下命令通常会提示在下次重启时处理:
chkdsk C: /f
不要把 /r 当作默认选项。它会执行更全面的扇区检查,耗时和 I/O 影响都更大,只应在怀疑介质错误并完成备份后使用。若事件指向控制器重置或底层磁盘故障,chkdsk 只能处理文件系统问题,不能修复硬件或存储链路。
采集磁盘 I/O 延迟并与 IIS 请求对应
容量充足、NTFS 扫描正常,并不代表磁盘性能没有问题。可以运行 perfmon 打开性能监视器,添加 PhysicalDisk 下的以下计数器:
Avg. Disk sec/ReadAvg. Disk sec/WriteAvg. Disk sec/TransferCurrent Disk Queue LengthDisk Reads/secDisk Writes/secSplit IO/sec
英文计数器名称适用于英文系统;中文 Windows 的显示名称可能已本地化。可以在性能监视器图形界面中选择对应项,避免因语言不同导致命令报错。
英文计数器环境下,可以采集约一分钟样本:
$counters = @(
'\PhysicalDisk(*)\Avg. Disk sec/Read',
'\PhysicalDisk(*)\Avg. Disk sec/Write',
'\PhysicalDisk(*)\Avg. Disk sec/Transfer',
'\PhysicalDisk(*)\Current Disk Queue Length',
'\PhysicalDisk(*)\Disk Reads/sec',
'\PhysicalDisk(*)\Disk Writes/sec'
)
Get-Counter -Counter $counters -SampleInterval 2 -MaxSamples 30
Avg. Disk sec/* 的单位是秒,如需换算为毫秒可乘以 1000。不要仅凭一次采样或一个固定阈值下结论,磁盘类型、阵列、虚拟化环境和并发负载都会影响正常范围。更可靠的判断方式是:
- 在故障时段连续采样,而不是只看瞬时峰值。
- 与同一服务器正常时段的基线比较。
- 同时观察延迟、队列和吞吐量,避免只看
% Disk Time。 - 将异常时间与 IIS 日志中的
time-taken、状态码对应。 - 在资源监视器的“磁盘”活动中确认具体进程和文件路径。
如果资源监视器显示 w3wp.exe 持续访问应用文件、缓存或上传目录,问题可能来自应用自身;如果主要是 System、安全软件或备份代理访问 IIS 日志目录,则需要检查扫描、备份和日志滚动任务是否重叠。未经安全评估,不应直接把网站或日志目录加入杀毒排除列表。
若 IIS 请求耗时升高,但磁盘延迟、队列和系统事件均正常,磁盘就不应继续作为主要故障方向,应转向应用、数据库或外部依赖排查。
根据检查结果采取不同处理方式
只有 IIS 历史日志占满磁盘
先备份 IIS 配置。该备份只包含 IIS 配置,不包含网站数据和日志:
$name = "BeforeDiskFix-{0}" -f (Get-Date -Format 'yyyyMMdd-HHmmss')
$appcmd = "$env:windir\System32\inetsrv\appcmd.exe"
& $appcmd add backup $name
随后将已经关闭的历史日志归档到另一个有足够空间的卷。下面的 robocopy 命令带有 /L,只预览超过 30 天的文件,不会移动或删除:
robocopy "C:\inetpub\logs\LogFiles" "D:\IISLogArchive" *.log /S /MINAGE:30 /COPY:DAT /DCOPY:T /R:1 /W:1 /L
确认文件范围、目标卷容量和归档要求后,才可以在维护窗口移除 /L 并加入 /MOV:
robocopy "C:\inetpub\logs\LogFiles" "D:\IISLogArchive" *.log /S /MINAGE:30 /COPY:DAT /DCOPY:T /R:1 /W:1 /MOV /LOG:"D:\IISLogArchive\move.log"
/MOV 会在复制成功后删除源文件,属于有数据影响的操作。执行前必须确认日志保留政策、备份状态和筛选日期,并在执行后核对目标文件数量、大小及 robocopy 返回码。不要移动当前正在写入的日志,也不要直接删除整个 LogFiles 目录。
长期处理应包括:
- 为访问日志和失败请求跟踪设置明确的保留周期。
- 将归档任务设置在业务低峰。
- IIS 日志滚动与历史日志删除分开管理。
- 修改日志目录后,确认新目录权限和新日志写入正常。
- 关闭不再需要的失败请求跟踪规则,而不是长期全量采集。
出现 NTFS 或存储层错误
先确认备份可恢复,再处理文件系统。如果同时出现控制器重置、I/O 重试或磁盘错误,应优先检查底层存储健康状态、驱动和虚拟化宿主层,而不是反复执行 chkdsk。
修复完成后重新读取系统事件,确认没有新的 NTFS 或 Disk 错误。如果错误持续出现,即使 IIS 暂时恢复,也不能视为故障已经解除。
空间正常,但 I/O 延迟持续升高
使用资源监视器确认高 I/O 进程与文件路径,再处理冲突来源:
- 避免备份、日志压缩和安全扫描在同一时间集中运行。
- 检查失败请求跟踪、应用调试日志是否产生大量小文件。
- 在配置和权限允许时,将高频日志与业务数据分散到不同卷。
- 保留相同采样周期和计数器,比较调整前后的变化。
- 如果底层存储持续重试,应在存储层处理,而不是单纯回收应用池。
回收应用池可能暂时减少活动请求,但无法修复磁盘延迟、NTFS 错误或日志保留缺失,不应作为默认修复手段。
修复后如何复测与持续观察
完成清理、文件系统修复或 I/O 调整后,至少进行一次完整日志滚动周期和一个业务高峰时段的观察,并记录测试节点、时间、请求路径、样本数量及服务器负载,避免用单次访问判断性能。
复测时依次确认:
- 各卷剩余空间稳定,按近期增长量计算的预计占满时间符合运维要求。
- IIS 仍在正确目录生成新日志,日志字段和滚动策略没有被误改。
- HTTPERR 与失败请求跟踪目录没有继续异常增长。
- 系统事件日志中没有新增 NTFS、Disk 或存储控制器错误。
- 使用与故障时相同的采样间隔复查磁盘延迟、队列和吞吐量。
- 从服务器本机访问固定健康检查地址,再从实际访问节点复测,分别记录结果。
- 检查站点和应用池状态,确认没有因磁盘占满遗留启动失败、临时文件写入失败或权限问题。
如果空间增长重新出现,应根据新增文件时间反查对应请求和任务;如果空间稳定但 I/O 延迟仍高,则继续从高 I/O 进程、具体文件路径和底层存储事件入手,而不是再次无差别清理日志。