Mac 上 corespotlightd CPU 高占用:先只读排查,再决定要不要删
Frank Zhang
- 5 分钟阅读 - 2314 字TL;DR
corespotlightd 占着 CPU、机器发烫,先看进程和索引开关。这篇不把删 Spotlight 目录或删 CoreDuet 当成第一步。
Mac 上 corespotlightd 占着很多 CPU、机身发烫时,不要一上来就删 Spotlight 的文件。先看一次进程表,做一次会自己退出的 top -l,再跑 mdutil -s /。这三步不关索引,也不擦掉索引。本站记下的那一次,是 corespotlightd 和 mds 忙了好几个小时,mdutil -s 一直显示 Indexing enabled,实时 log stream 被 CoreDuet 的消息刷屏。那篇没有写下 macOS 版本,也没有写下删除之后量到的 CPU。
当天的经过在corespotlightd CPU 高占用、Mac 发烫:先只读排查,别急着删库。这篇只排“动手之前先看什么”。要自己部署项目,走另一条:自部署阅读路线。
那次记录里真正有的东西
2025-07-30,机器发热,corespotlightd 很忙。sudo asitop 里性能核心长时间停在 100%。top -o cpu 开了几个小时,corespotlightd 一直靠前。它和 mds 一起,连续几小时大约 180%–200% CPU。这是那次 top 里的读数,不是所有 Mac 都能拿去对照的基准。
那几个小时里,mdutil -s / 一直是 Indexing enabled(索引已启用)。这句话只说明这个宗卷的索引开着。它没说扫描还在走,也没说已经走完。把它理解成“重建还没结束”,是当时的猜测,没有用第二条命令复核。
当时还跑过一条实时日志:
log stream --predicate 'subsystem == "com.apple.Spotlight" or process == "corespotlightd" or process == "mds"' --style compact
终端被 mds 的 CoreDuet: ClientContext objectForContextualKeyPath: 刷满。这条命令不改数据库,但不该当第一步,因为它停不下来,除非你自己中断。
mds 是 metadata server,Spotlight 用来处理元数据的服务。corespotlightd 是它旁边的辅助进程,也就是那次吃 CPU 的那个。CoreDuet 是记下使用习惯、用来猜测何时索引、怎样安排电源和后台任务的子系统。这是对那次日志的解释,不是把数据库文件打开核对过。
也有人会搜 mds_stores、mdworker 占 CPU。这篇笔记没有写下那两个进程在那台 Mac 上做了什么,只写下了 corespotlightd 和 mds。
只读检查,按这个顺序
这些命令不关闭 Spotlight,不删数据库,也不重建索引。它们能回答的问题问完就可以停。真正跑过的是 mdutil -s、交互式 top -o cpu 和 log stream。另外几条是同一类只读,写这篇时没有重跑。
1. 进程还在不在
ps -axo pid,pcpu,etime,command | grep -E '[c]orespotlightd|[m]ds '
只读进程表:corespotlightd 和 mds 在不在、%cpu 大概多少、已经跑了多久。方括号是为了不让 grep 把自己也匹配进去。
2. 采样两次就退出
当时用的是 top -o cpu,窗口开了几个小时。要少给已经发烫的机器再加负担,用会自己结束的采样:
top -l 2 -n 15 -o cpu
-l 2 取两轮然后停。两轮里 corespotlightd 都靠前,才更像持续占用,而不是看一眼时的尖峰。它不改索引。
3. 只问索引开没开
mdutil -s /
只查询。不要加 -E,也不要加 -i off。-E 会抹掉索引,-i off 会把索引关掉。笔记里的输出是 Indexing enabled。这一句看不出扫描走到哪。
4. 读已经落盘的日志
比起一直跟着吐的实时流,先把时间窗口收短:
log show --last 10m --predicate 'subsystem == "com.apple.Spotlight" OR process == "corespotlightd" OR process == "mds"' --style compact
如果它说读不了日志,这里的 sudo 只是读日志的权限,不是在修 Spotlight。这篇没有重跑 log show,所以不能保证它现在还会打出那天 log stream 里那种 CoreDuet 刷屏。
5. 可选:看几秒文件调用
fs_usage 不在当天的记录里,这里也没有重测。它只看文件调用,不改索引,不删库:
sudo fs_usage -w -f filesys corespotlightd
看几秒就按 Ctrl-C。输出很密,命令自己也占 CPU。机器已经发烫时,不要开几个小时。它能看到进程碰过哪些路径,不能告诉你该删哪个目录。
在建索引,还是在空转
如果 ps 和 top -l 里 corespotlightd 或 mds 一直靠前,而 mdutil -s / 只说索引开着,你知道的是:开关是开的,这两个进程当时很忙。忙,可能是正常重建,也可能是日志里那种情况:mds 反复向 CoreDuet 要上下文,请求没有正常结束。只读命令分不出这两种,也不能证明 /private/var/db/CoreDuet/ 里的文件已经坏了。
查到这里就停,也是一种结果。
不要做的事
不要跑 sudo rm -rf /.Spotlight-V100,也不要手工去删一个你猜的 Spotlight 目录。本站的笔记没有用过这条命令。直接 rm -rf 不走 Spotlight 自己的工具。路径写错,尤其是从 / 往下删,删掉的就是别的东西。笔记也没有核实过那台 Mac 上活的索引是不是 /.Spotlight-V100,所以按猜的路径去删,不是诊断。
也不要把 sudo mdutil -E / 当成第一眼。当天是先跑了它,后看的 mdutil -s。它会抹掉这个宗卷现有的 Spotlight 索引,然后让系统重建。你的文件还在,但重建完成前搜索会缺结果,重建期间 CPU 可能更高,而不是马上降下来。没有命令能把旧索引导回来。再跑一次 -E,只是再擦一次。
不要为了压 CPU 去删 CoreDuet:
sudo rm -rf /private/var/db/CoreDuet/
那天在正常系统里,这条被系统完整性保护拦住了。没有为了删它去关 SIP。后来是进恢复模式,先 ls /Volumes/ 确认宗卷名,再删。事后真正记下的不是一个 CPU 数字:充电器插着过夜,电量从 100% 掉到 89%,菜单写着因为电池用量很小所以暂停充电。那次副作用在删掉 CoreDuet 后,Mac 为什么突然不会省电了?。当时没有先把这个目录复制出来,所以没有东西可还原。再删一次不是撤销。
不要先禁用 mds 来“看一看”:
sudo launchctl disable system/com.apple.metadata.mds
sudo launchctl stop com.apple.metadata.mds
这会停掉 metadata server。索引和搜索会一起停,直到你再打开。笔记里用它,是为了后面删文件时不要和正在写的进程抢。它不是诊断。
如果你还是要重建索引
只读步骤做完,并且你接受一次重建之后,才是:
sudo mdutil -E /
然后等。笔记没有写下重建花了多久,也没有写下结束时的 CPU。它只写下这条命令用了两次:一次在看状态之前,一次在 CoreDuet 目录删掉之后。两次都没有计时,不能当成一份测过的时长。
当时一并写下、这篇没有再验证是否仍然成对的打开命令是:
sudo launchctl enable system/com.apple.metadata.mds
sudo launchctl start com.apple.metadata.mds
如果做完搜索还是不能用,不要再叠一条禁用。先跑 mdutil -s /,看开关现在是开还是关。
该停的时候
只读检查仍然分不清是在建索引,还是 CoreDuet 请求在反复失败,就停。不要再手工删 /.Spotlight-V100,也不要把清掉 CoreDuet 当成下一步。当天 mdutil -E 和删库各自改了什么,写在上面那篇中文经过里。充电被打乱的后续,写在 CoreDuet 那篇里。
这篇如果有用,欢迎自愿赞助,用来继续更新博客和自部署笔记。这不是慈善捐赠。