系统学习 故障排查学习路径:从方法论到系统、网络、数据库与 K8s

macos-disk-full

macOS 启动盘空间耗尽、可清除空间异常时的定位与清理

现象

系统提示启动磁盘几乎已满,应用无法保存文件、更新失败,终端报 No space left on device;df -h / 的 Capacity 接近 100%,Finder 或“系统设置 > 通用 > 存储空间”却仍显示几十 GB 可用。也有人看到“系统数据”占用异常大,删掉大文件后空间没有立即回来。

APFS 把容器空间共享给多个卷,df 看到的是当前卷的可用空间,不一定等于容器真实余量;本地 Time Machine 快照、缓存和被进程占用的已删除文件还会形成“可清除空间”。因此要先分清:是真没有空间、被快照或缓存占用,还是被已删除但仍打开的文件占着。

快速定位

先看卷、容器和快照三个层面:

df -h /
df -i /
diskutil info /
diskutil apfs list
diskutil apfs listSnapshots /
tmutil listlocalsnapshots /
tmutil listlocalsnapshotdates /

diskutil info / 里的 Container Free Space 比单个卷的 df 更能反映容器余量;diskutil apfs list 会列出每个卷的 Capacity Consumed 和快照;listSnapshots 中的 Purgeable: Yes 表示该快照可在空间紧张时回收。Time Machine 本地快照通常以 com.apple.TimeMachine. 开头,系统更新快照则以 com.apple.os.update- 开头,后者不要手动删除。

再按目录找大头,注意 APFS 的系统和数据卷分开挂载:

sudo du -xhd1 /System/Volumes/Data 2>/dev/null | sort -h
du -xhd1 ~ 2>/dev/null | sort -h
sudo find /System/Volumes/Data -xdev -type f -size +1G -print 2>/dev/null
sudo lsof -nP +L1

du -x 不跨文件系统,适合逐层下钻;先看一级目录,再进入异常大的目录继续。lsof +L1 列出链接数为零但仍被进程打开的文件,这类文件删除后空间不会释放,直到占用它的进程退出或重新打开日志。最后看日志和系统记录:

/usr/bin/log show --last 1h --style compact \
  --predicate 'eventMessage CONTAINS[c] "no space left"'
ls -lhS /Library/Logs ~/Library/Logs 2>/dev/null | head -30

在 zsh 中 log 可能被同名内建命令占用,写 /usr/bin/log 可以避免参数错误。

常见根因

  1. Time Machine 本地快照长期堆积:系统通常会在快照过期或空间紧张时回收,但备份盘长时间未连接、频繁改动大文件时仍可能积累。
  2. 用户缓存、浏览器缓存、开发工具缓存和容器镜像:~/Library/Caches、~/Library/Developer、~/Library/Containers、Docker 的磁盘镜像等。
  3. iOS 设备备份、照片图库、邮件下载、下载目录和废纸篓中的大文件。
  4. 已被删除但仍被进程打开的文件,例如被守护进程持有的旧日志,du 看不到,空间却未释放。
  5. APFS 容器内的其他卷或快照占用空间,单个卷的 df 看起来还有余量,容器实际已经接近上限。
  6. 系统日志、诊断报告和崩溃报告持续增长:/private/var/log、/Library/Logs/DiagnosticReports、~/Library/Logs/DiagnosticReports。
  7. 虚拟机磁盘、休眠镜像和交换文件:/private/var/vm 由系统管理,不应手动删除。
  8. 第三方清理工具误删缓存或系统文件,导致应用异常并反复重建缓存,反而占更多空间。
  9. iCloud Drive“优化 Mac 存储空间”产生的可清除文件,空间显示为可用但实际需要下载才能访问。
  10. 磁盘本身出现 APFS 或文件系统错误,空间统计异常,需要先做磁盘检查。

修复

先处理最安全、收益最大的部分:清空废纸篓,删除下载目录和项目目录中确认不再需要的大文件,把照片、视频和归档移到外置盘。删除前用 ls -lh 和 du -sh 确认目标,避免误删正在使用的数据。

处理 Time Machine 本地快照。优先让系统按需回收,确实需要立即释放时,用 thinlocalsnapshots 指定回收量而不是一次删光:

sudo tmutil thinlocalsnapshots / 20000000000 4

20000000000 约等于 20 GB,最后一个参数是回收紧迫程度。也可以先看日期,再按日期删除指定快照:

tmutil listlocalsnapshotdates /
sudo tmutil deletelocalsnapshots <快照日期>

删除快照会让对应时间点的本地恢复能力消失,但不会影响已完成的 Time Machine 备份。不要删除 com.apple.os.update- 开头的系统更新快照,也不要用 rm 直接删除快照。

清理缓存要按应用进行:退出应用后删除 ~/Library/Caches/<应用标识>,不要整目录粗暴清空;Docker 用 docker system prune,装了 Xcode 时可用 xcrun simctl delete unavailable 清理不可用模拟器,并在确认后删除 ~/Library/Developer/Xcode/DerivedData。iOS 备份在 Finder 的“管理备份”中删除,照片图库用“照片”应用提供的优化或导出功能处理。

如果怀疑是已删除但仍打开的文件,按 lsof +L1 的 PID 找到进程,优先用 launchctl kickstart -k 或正常重启服务让它释放文件;不要直接 kill -9 正在写数据的进程。重启系统也能释放大部分临时文件和可清除空间,但重启前应保存工作。

日志和诊断报告只删除明确可再生的旧文件,保留最近的崩溃记录用于排障。统一日志不要用 rm 删除,必要时用 /usr/bin/log show 导出后再由系统轮转;/private/var/vm 和 /System/Volumes/Update 属于系统管理区域,不要手动清理。

如果 df 与 Finder 长期矛盾,或 diskutil apfs list 显示容器被其他卷占用,先用“磁盘工具”的“急救”检查文件系统,再决定是否删除不再需要的 APFS 卷。任何删除卷、抹掉磁盘的操作都必须先备份。清理后再次用 df -h /、diskutil apfs list 和 tmutil listlocalsnapshots / 复验,并保留至少 15% 到 20% 的余量,避免更新和快照再次把磁盘填满。

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. Finder 显示还有可用空间,df 却接近满,这两个结果矛盾吗?
  2. 如何安全回收 Time Machine 本地快照?哪些快照不能删?
  3. 删除了大文件但空间没有回来,应该怎么查?
答案
  1. 不矛盾。Finder 的可用空间包含可清除空间,例如本地 Time Machine 快照、缓存和可回收文件;df 反映当前卷的可用块。用 diskutil info / 看容器余量,用 tmutil listlocalsnapshots / 和 lsof +L1 判断空间被什么占着。
  2. 优先让系统自动回收,需要立即释放时用 sudo tmutil thinlocalsnapshots / <字节数> 4,或按 tmutil listlocalsnapshotdates / 的结果删除指定日期的 Time Machine 本地快照。com.apple.os.update- 开头的系统更新快照不能删。
  3. 用 sudo lsof -nP +L1 找已删除但仍被进程打开的文件,重启对应服务或系统释放;再用 diskutil apfs list 检查是否是其他 APFS 卷或快照占用,并确认 du 统计的是数据卷而不是系统卷。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令