超融合下Windows Server 2016磁盘空间不足引发连环故障排查
1. 故障现象一个超融合 Windows Server 2016 同时闹四件事在半虚拟化或超融合集群里跑 Windows Server 2016最容易遇到的就是一堆症状同时冒出来让人看得头皮发麻虚拟机开机速度从原本几分钟拖到十几分钟SQL 数据库服务一直卡在“正在启动”状态手动去打开某个自动启动的服务又提示“磁盘空间不足”管理员关掉服务器管理器的时候还弹一个莫名其妙的错误——“没有足够的用户权限或可用空间来保存用户关系”。这几个问题放在一起第一反应往往是系统权限被改坏了或者环境里已经有人动过安全策略。但我的判断是先不要急着往权限方向走这类现象十有八九和存储空间有关。先把四组症状拆开看。症状一系统启动缓慢。表现为开机时长时间停留在“正在准备 Windows”或转圈界面进入桌面以后鼠标操作也会卡顿任务栏的服务图标一直处于初始化状态。如果此时按 CtrlShiftEsc 打开任务管理器能看到系统盘 I/O 长时间打满或者某个服务进程反复启动又退出。症状二SQL 数据库服务无法启动。服务列表里 MSSQLSERVER 或默认实例的状态一直在“启动、停止、启动失败”之间跳转手动点启动也会很快报错。打开 SQL Server 错误日志通常能看到类似“Could not allocate new page for database”“System call failed”之类的记录指向问题和存储有关。症状三任意自动启动服务提示磁盘空间不足。不只是 SQL其他随系统启动的服务也报同样的错比如打印服务、远程桌面服务、Windows Update 服务。有的管理员会下意识去检查权限把服务的登录账户改成管理员但问题依旧。实际上此时服务控制管理器可能连最基本的临时文件都写不进去。症状四关闭服务器管理器时报权限/空间错误。报错内容很绕叫“不具备用户权限和可用空间来保存用户关系”。这个提示在系统日志里不一定有明显对应的事件但它是服务器管理器在退出前保存自身状态失败时给出的汇总信息。这四个症状实际上指向同一个根因:系统盘的写入能力被不可用空间或底层存储异常堵死了。只要 Windows 在启动、服务初始化、日志写入等环节中无法完成任何一次落盘操作它就会用权限不足、空间不足、操作超时等不同“颜面”把同一个故障表现出来。先把这个判断建立起来后面所有排查路径才能踩在正确方向上。1.1 四组症状之间的共同逻辑Windows 系统在开机阶段需要做大量写盘操作分页文件初始化、用户配置文件加载、事件日志记录、服务状态写入。系统盘空间不足时这些操作会排队等待、重试、超时于是“启动慢”就成了第一个肉眼可见的症状。接下来 SQL Server 数据库服务启动时需要准备 tempdb、读取并打开数据库文件、写入日志。微软的 SQL 引擎对 I/O 故障非常敏感只要某个路径上无法完成写入整个服务就会直接回滚表现为“服务启动失败”。这不是 SQL 实例或数据库本身损坏而是它连最基本的运行环境都拿不到。至于任意服务都提示磁盘空间不足原因是服务控制管理器在启动服务时也要向系统盘写入事件、状态标记、性能计数器等工作文件。在空间耗尽的情况下服务管理器无法为每个服务建立运行时所需的临时数据干脆统一报“磁盘空间不足”。连服务器管理器关闭时保存“用户关系”也会写配置文件写不进去自然也会提示没有可用空间而且 Windows 经常把写盘失败归类为“权限不足”这就是那句绕口报错的由来。1.2 为什么不建议一开始就怀疑权限或病毒很多运维同学遇到“没有足够的用户权限或可用空间来保存用户关系”这句提示第一反应就是去改组策略、重置 ACL甚至开始杀毒排查。但我这些年处理类似问题的经验是如果同时出现启动慢服务无法启动磁盘空间不足优先级最高的永远是先确认存储层是不是真的有空位。权限问题通常不会造成全盘服务启动失败。一台 Windows Server 如果连多个系统服务都起不来更多是因为系统盘满、虚拟磁盘底层存储满、快照膨胀或存储 IO 故障。在超融合平台里还要多查一层就是虚拟磁盘文件所在存储池的剩余空间因为宿主机的存储余量不足会让虚拟机内部看到“一切正常”但写入却迟迟无法完成。2. 排查链路为什么我的第一步是看空间而不是改权限如果你现在手头也有一台这样的 Windows Server 2016而且正打算去重置权限我建议先按下暂停键按照下面这个顺序排查。整个过程我实际执行过很多遍基本能在一个小时内把根因揪出来。2.1 先翻系统事件日志和服务日志别急着重启登录系统以后先打开事件查看器重点看以下三类位置Windows 日志-系统筛选“错误”级别找服务控制管理器事件 ID 7000、7009、7011以及卷和磁盘相关的“Disk”“Ntfs”源事件。Windows 日志-应用程序找 SQL Server 的近期错误记录如果看到“insufficient disk space”或“I/O request failed”方向就很明确。SQL Server 错误日志默认路径在C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Log\ERRORLOG或者用 SQL Server 配置管理器查看。打开后搜索“space”“allocation”“I/O”相关关键词。用系统日志将根因确定后再决定是否重启。如果从日志中能直接看到“The operating system returned error 112”或“There is not enough space on the disk”这类记录那么重启就是短期缓解真正的问题在磁盘空间而不是服务配置。我遇到过不少人跳过日志直接手工启动服务结果发现 SQL 服务报错信息一直到第 N 次尝试才显示“磁盘空间不足”中间浪费了大量时间。先把日志翻一遍能少走很多弯路。2.2 虚拟机内部与超融合存储池双视角检查空间这是最关键的一步不能只看虚拟机内部的剩余空间还要看超融合平台存储池的剩余空间。虚拟机内部用 PowerShell 执行这条命令能直观看到每个逻辑磁盘的容量和剩余空间Get-CimInstance Win32_LogicalDisk -Filter DriveType3 | Select-Object DeviceID, {nSize(GB);e{[math]::Round($_.Size/1GB,2)}}, {nFree(GB);e{[math]::Round($_.FreeSpace/1GB,2)}}如果看到 C 盘剩余空间已经低于 2GB 或者干脆是 0那故障链路基本就闭环了。但还有一种情况会让很多人栽跟头虚拟机内部 C 盘显示的剩余空间并不多然而超融合平台主机的存储池剩余容量已经告急虚拟磁盘文件无法继续膨胀。这时候虚拟机的写入操作会被底层存储卡住表现为服务启动失败或数据库操作超时但虚拟机内部永远看不到“磁盘满”的明确提示。建议同时登录超融合管理控制台检查虚拟机所在宿主机、存储池、数据盘剩余容量并关注虚拟磁盘文件的大小是否远大于系统盘配置容量。如果是动态磁盘且支持快照还要看快照文件占了多大。典型的超融合瘦分配模型下虚拟磁盘文件是“用多少涨多少”底层存储要是满了guest 内部即使有空间也写不进物理落盘。2.3 通过服务器管理器报错反向验证问题如果系统盘空间不足服务器管理器关闭时报“不具备用户权限和可用空间来保存用户关系”几乎是可以预见的。这个错误背后的机制并不复杂服务器管理器要保存当前的“用户关系”本质上就是把当前用户管理了哪些服务器、哪些服务器组、界面状态等记录写入到用户配置目录下的 ServerManager 配置文件中。写入路径通常在两个位置之一%LOCALAPPDATA%\Microsoft_Corporation\ServerManager.exe_*\%APPDATA%\Microsoft\Windows\ServerManager\当系统盘满或用户配置目录无法写入时Windows 会把这个故障统一描述为“没有足够的用户权限或可用空间”。它把权限和空间混在一句话里就是为了让管理员先自查这两个方向。如果排除了权限问题那剩下的就是空间问题。3. 超融合平台为什么会放大这类故障同样的系统盘空间不足放在普通实体服务器上可能只是弹几个警告但放在超融合虚拟化环境里就很容易演变成多个服务连环失败。这背后有三个特殊环节值得专门展开讲。3.1 瘦分配虚拟磁盘的“空间假象”超融合或虚拟化平台的虚拟磁盘常见两种分配模式厚分配和瘦分配。厚分配会一次性划走物理容量瘦分配则是随着数据写入逐步增长。瘦分配能提高存储利用率但它会制造一种“空间假象”虚拟机内部看到的剩余空间是基于逻辑卷容量算出来的而超融合平台上的存储池剩余空间才是物理真相。举个例子一台 Windows Server 2016 虚拟机系统盘分配了 80GB内部看到 C 盘还剩余 20GB似乎一切正常。但如果超融合存储池只剩余 3TB而整个集群还有十几个虚拟机同时在扩展写入系统盘在每次服务初始化产生的临时写入请求就可能触发底层存储池警戒。某些超融合平台在存储池剩余空间不足时会对写入做限速或直接返回 I/O 错误而不是像普通磁盘那样明确报“磁盘满”。所以在超融合平台上排查“磁盘空间不足”时必须把虚拟机内部可见空间和宿主机底层存储池剩余空间合并起来看。我当时处理这台 Windows Server 2016 时正是先在虚拟机内部看到 C 盘只剩几十 MB然后又在超融合控制台看到存储池剩余容量跌破了 10%两个证据一叠加根因立刻确定。3.2 快照与应用生成的隐形空间消耗超融合环境下另一类常见问题是快照和备份机制带来的空间黑洞。很多运维习惯在打补丁或调整配置前给虚拟机拍快照这本是正常操作但如果快照长期保留、合并失败或备份程序反复创建恢复点虚拟磁盘的差分数据会持续膨胀。虚拟机内部删除一个大文件物理空间并不会立即回收因为快照文件仍然保存着旧状态。回到 SQL Server 场景假设数据库文件所在盘是动态虚拟磁盘并且存在一个遗留快照。SQL Server 在启动和运行过程中会不断写入新的日志页这些写入既会落到当前虚拟磁盘也会被快照机制保留。等到超融合平台底层空间不足时SQL 服务一旦触发大量页分配就会立刻报“无法为新页面分配空间”。这种现象在虚拟化环境中特别容易让人误判为 SQL 数据库损坏。因此我在处理这类故障时通常会先查快照列表把过期的整机快照备份好再删除这一步释放的底层空间往往比在虚拟机内部清理临时文件更立竿见影。3.3 存储 I/O 延迟会让 Windows 服务管理器提前“放弃治疗”超融合平台在存储池高负载或容量接近临界时I/O 延迟会明显升高。Windows 服务控制管理器启动一个服务时默认等待服务进程响应的时间是 30 秒左右。如果底层存储响应慢服务刚启动就在等文件写入30 秒一到服务管理器就判定启动超时随后报“服务启动失败”。SQL Server 对 I/O 延迟的敏感程度比一般服务更高。SQL 在启动时要初始化 tempdb、读取数据库中所有文件的元数据并打开日志句柄任何一个 I/O 操作超过 SQL 自身等待阈值服务进程就会主动退出。这就解释了为什么在同一个环境里有时连普通服务都能被强行拉起来唯独 SQL 怎么都启动不了。它不是在“拒绝启动”而是 I/O 慢到了它难以忍受。把这三层因素叠在一起超融合环境 Windows Server 2016 的“启动慢服务无法启动磁盘空间不足”才会形成一组完整故障链。4. 修复操作记录释放空间、恢复 SQL、修好服务器管理器下面是我的实际修复过程。按照“先应急恢复空间再启动关键服务最后清理残留配置”的顺序来做整体操作非常稳妥适用于系统还能登录、C 盘没有彻底写死的场景。4.1 应急释放系统盘空间的正确顺序系统盘空间严重不足时不要盲目删文件更不要直接去动C:\Windows目录里的系统文件。我建议按下面几个低风险步骤来释放空间。第一步关闭休眠文件。很多 Windows Server 虚拟机开着了休眠功能休眠文件会占据与物理内存等大的系统盘空间。如果物理内存有 32GB休眠文件可能就占了 32GB。用管理员 PowerShell 执行powercfg -h off这条命令会让系统不再创建休眠文件立刻释放大量空间。服务器本来就不需要休眠功能虚拟化平台上更用不到。第二步清理临时目录。清空当前用户临时目录和系统临时目录Remove-Item -Recurse -Force $env:TEMP\* -ErrorAction SilentlyContinue Remove-Item -Recurse -Force C:\Windows\Temp\* -ErrorAction SilentlyContinue第三步清理 Windows Update 缓存。停掉 Windows Update 服务后删除缓存目录再重启服务这样能避免文件被占用Stop-Service wuauserv Remove-Item -Recurse -Force C:\Windows\SoftwareDistribution\Download\* -ErrorAction SilentlyContinue Start-Service wuauserv第四步清理卷影副本。这一步要谨慎建议在执行前确认系统有可用的完整备份。如果确保证备份集存在可以用这条命令查看并删除 System Restore 的旧卷影vssadmin list shadows vssadmin delete shadows /forC: /all /quiet卷影副本在超融合虚拟机上尤其耗空间有时能一口气释放出几十 GB。第五步运行磁盘清理工具或 DISM。在图形界面可以执行cleanmgr并勾选“清理系统文件”也可以直接用 DISM 清理组件存储Dism.exe /online /Cleanup-Image /StartComponentCleanup这一步会压缩和清理 Windows 组件存储但耗时较长建议在维护窗口执行。如果系统盘空间只剩几个 GBDISM 也可以跑只是时间会久一点。完成以上步骤后再用 2.2 中的命令复查 C 盘剩余空间。我当时在这个环节把 C 盘从近乎 0 的空间恢复到了 25GB 左右系统响应立刻变得正常服务也不再连续弹“磁盘空间不足”。4.2 恢复 SQL Server 服务系统盘空间恢复后先不要急着手动开 SQL 服务确保相关路径都正常确认tempdb路径所在盘有足够空间。确认数据库文件和日志文件所在盘可用空间充足。查看 C 盘剩余空间是否大于 5GB避免 SQL 启动瞬间还需要生成临时日志。检查完毕后再执行Get-Service MSSQLSERVER Start-Service MSSQLSERVER如果初始实例名不是默认实例把服务名替换成对应的 SQL 服务名称即可。正常情况下服务会从“停止”变为“启动中”然后稳定在“正在运行”。这里有一个关键点如果之前故障中 SQL 服务已经“卡死”过多次系统里可能存在残留的进程。建议先确认没有sqlservr.exe残留在任务管理器里再尝试启动服务否则会报“该服务已启动”或端口冲突。启动完成以后打开 SQL Server Configuration Manager 或执行以下命令检查当前服务状态Get-Service *SQL* | Sort-Object Status | Format-Table Name, Status, StartType数据库实例启动成功以后再连接 SQL Server Management Studio打开数据库属性确认数据库状态不是“Recovery Pending”或“Suspect”。如果还有旧的事务日志没有正常 checkpointSQL 会自动做恢复这一步不必急于干预。4.3 处理服务器管理器“用户关系保存失败”当磁盘空间恢复后重新打开服务器管理器再关闭一般报错就会消失。如果报错仍然存在那就说明用户配置目录里残留了坏配置或 ACL 出现了异常状态需要手工干预。第一步备份并重设服务器管理器配置目录。打开文件资源管理器定位到以下两个位置之一把包含ServerManager的文件夹整体重命名备份%LOCALAPPDATA%\Microsoft_Corporation\ServerManager*%APPDATA%\Microsoft\Windows\ServerManager如果找不到精确路径可直接在%LOCALAPPDATA%和%APPDATA%里搜索ServerManager*文件夹备份后重命名。这样服务器管理器下次启动时会重新生成一份干净的配置历史里的服务器组列表会丢失但多数场景下影响不大。第二步修正用户配置目录 ACL。如果报错还伴随“权限不够”的表现可以给当前用户配置目录赋予完整控制权icacls $env:LOCALAPPDATA /grant $env:USERNAME:(OI)(CI)F /T icacls $env:APPDATA /grant $env:USERNAME:(OI)(CI)F /T这里注意执行完 ACL 修复后最好注销重新登录一次让用户配置文件重新加载生效。第三步验证。再次打开服务器管理器检查左侧“所有服务器”面板是否正常显示关闭时不再弹“没有足够的用户权限或可用空间”之类的提示。如果问题还在再检查服务器管理器是否以管理员身份运行右键选择“以管理员身份运行”再试一次。4.4 重启虚拟机验证整体恢复情况做完应急释放、服务启动、服务器管理器修复后不要立刻认为事情结束了。我强烈建议安排一次重启用来验证“启动慢”是否真正解决。重启后按以下清单检查从开机到进入登录界面是否恢复正常耗时。Get-Service中所有自动启动服务是否为 Running 状态特别是 SQL Server 服务。事件查看器里有没有新增的错误级别事件。服务器管理器正常打开和关闭不再报错。SQL 数据库能否正常连接应用程序侧抽查几条数据查询是否无异常。只有重启验证通过才能证明故障链路完整消失而不是靠某种“服务被侥幸拉起来”的偶然状态撑到当下。5. 事后复盘超融合环境下的容量管理与维护习惯故障恢复以后需要做的是防止同类问题再次发生。毕竟一台 Windows Server 2016 虚拟机把系统盘写满不是一两天造成的背后通常是容量规划不足和监控不到位。这次复盘总结出几个值得长期执行的原则。5.1 虚拟磁盘容量规划不能再抠门很多超融合环境在创建 Windows Server 虚拟机时习惯给一个“初始够用就行”的磁盘比如 40GB 系统盘。但 Windows Server 2016 完整安装加补丁、组件存储、日志文件很快就会逼近 40GB 甚至超过。再加上超融合平台常见的动态扩展机制系统盘在运行中还会因为快照和备份任务膨胀。个人建议是Windows Server 2016 系统盘至少分配 80GBSQL Server 的数据文件、日志文件和 tempdb 尽量放到独立虚拟磁盘上避免 SQL 日志增长直接把系统盘写满。如果因为历史原因系统盘只有 40-60GB那就要用下面的监控手段卡住剩余空间的底线。5.2 建立系统盘与存储池的双层监控在虚拟化平台里只看虚拟机内部磁盘监控是不够的需要建立两层监控第一层虚拟机内部监控各逻辑盘可用空间特别是系统盘剩余空间低于 20% 或剩余值低于 10GB 时告警。第二层超融合平台监控存储池剩余容量低于 20% 时就要引起重视低于 10% 时立即排查虚拟磁盘膨胀和快照占用。可以用 PowerShell 脚本配合计划任务实现简单的空间告警。例如$disk Get-CimInstance Win32_LogicalDisk -Filter DeviceIDC: $freeGB [math]::Round($disk.FreeSpace / 1GB, 2) if ($freeGB -lt 10) { Write-Host C: drive free space is low: $freeGB GB # 此处接入邮件或消息通知逻辑 }有人觉得 10GB 这个阈值太保守但对于 SQL Server 所在的 Windows Server 2016 虚拟机系统盘空间很可能因为临时日志、补丁缓存、组件存储而突然被大量消耗。留 10GB 以上余量是保底不是铺张浪费。5.3 超融合快照与备份文件的定期收敛超融合环境最容易出现的问题是“虚拟机内部空间明明够底层存储池悄悄被填满”。常见来源包括过期快照、备份恢复点、以及失败的磁盘合并任务。建议形成以下维护节奏快照保留时间不超过 3-5 天超过后必须合并。每个月检查一次虚拟磁盘文件大小和快照文件大小对比配置容量。超融合平台做备份任务时合理设置恢复点数量避免保留过多副本。5.4 服务器管理器的日常使用习惯最后说一个容易被忽视的细节Windows Server 2016 的服务器管理器并不需要登录后自动启动。如果日常主要靠命令行或远程管理工具完全可以把“登录时不启动服务器管理器”选项打开减少服务器管理器频繁读写用户配置的概率。即使不打开也要养成定期清理用户配置目录的习惯特别是在服务器管理员账户被多个同事使用同一个账号登录的情况下用户配置里的状态文件很容易被写坏。经历这次故障后我对超融合环境的运维判断有了一个更清晰的优先级任何“启动慢服务无法启动磁盘空间不足”的故障组合一定先把系统和底层存储空间确认清楚再考虑权限、策略、服务配置。把存储这个最大变量管住Windows Server 2016 集群的稳定性就稳了一大半。