corespotlightd CPU 高占用、Mac 发烫:先只读排查,别急着删库
Frank Zhang
- 6 分钟阅读 - 2965 字TL;DR
如果你的 Mac 因为 corespotlightd 长时间占 CPU 而发烫,先按只读顺序看进程、索引开关和已有日志。重建索引、停 Spotlight、删除 CoreDuet 都会改状态;删库我没有重测成通用修法。
Mac 上 corespotlightd 一直占着 CPU、机身发烫时,先看它在干什么,再决定要不要动 Spotlight 或 CoreDuet。下面把只读诊断,和我 2025-07-30 那次实际做过的、会改系统状态的操作分开。删系统数据库我没有重测,所以这里不把它写成通用修法。
当时的 macOS 版本和机型没有记下来。搜索量、排名难度我也没有另做外部数据,这里不写。
当时看见的,和当时的推测
这些是那次留下的观察:
corespotlightd占用高,MacBook 发热。- 我先执行了
sudo mdutil -E /。这条会删掉索引并触发重建,不是诊断。影响写在后面。 - 接着用
mdutil -s /看了几个小时,状态一直停在Indexing enabled(索引已启用)。 sudo asitop里,性能核心长时间停在 100%。top -o cpu跟了多小时,corespotlightd一直异常。corespotlightd和mds持续数小时,CPU 大约在 180%–200%。这是那次top里的读数,不是拿去套所有 Mac 的基准。- 按当时一个 AI 给的命令跑了
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 是 macOS 用来记使用习惯的子系统,好让系统推测你接下来会做什么、什么时候适合索引、电源和后台任务怎么排。比如它会根据你打开了哪个应用,让 Spotlight 先处理相关内容。这些是那次对日志的解释,不是我把数据库文件拆开验证过的结论。
Indexing enabled 的字面意思只是“这个宗卷的索引开着”。它没有说明扫描走到哪,也没有说明已经扫完。我当时把它理解成重建还没结束,这个理解没有用另一条命令复核,所以仍是推测。
日志刷屏也不等于我已经证明数据库文件损坏。更像是 mds 在反复向 CoreDuet 要上下文,请求没有正常结束,于是马上再要一次。这是对照那次刷屏做的推测。正常学习“应该断断续续、几乎不占 CPU”,同样只是拿来对照那次 180%–200% 的判断。我没有测过一台正常索引的 Mac 会占多少 CPU。
只读诊断按这个顺序做
下面这些命令不关闭 Spotlight,不删除数据库,也不重建索引。先跑完,再决定后面要不要进入会改状态的部分。除了我当时已经用过的 mdutil -s /、交互式 top -o cpu 和 log stream,其余命令没有在这次改写里重跑。
1. ps:进程还在不在
ps -axo pid,pcpu,etime,command | grep -E '[c]orespotlightd|[m]ds '
看 corespotlightd 和 mds 在不在、%cpu 大概多少、已经跑了多久。方括号只是为了不让 grep 把自己匹配进去。这条只读进程表。
2. top -l:采样两次就退出
我当时用的是 top -o cpu,窗口开着跟踪了多小时。要少加一点观察本身的负担,用会自己结束的采样:
top -l 2 -n 15 -o cpu
-l 2 表示取两轮然后退出。两轮里 corespotlightd 都靠前,才更像持续占用,而不是刚看一眼时的瞬时值。它不改索引。
3. mdutil -s:只问索引开没开
mdutil -s /
只查询。不要加 -E,也不要加 -i off。-E 会抹掉索引,-i off 会关掉索引,那都是后面“会改状态”的事。
我当时看到的就是 Indexing enabled。只根据这一句,不能判断扫描是否还在进行。
4. log show:回看已经写下来的日志
当时刷屏的是 log stream,它跟着新日志往外吐,终端会被 CoreDuet 的那句 ClientContext objectForContextualKeyPath: 淹没。它不改数据库,但不适合当第一步。
要回看已经落盘的记录,把时间窗口收短:
log show --last 10m --predicate 'subsystem == "com.apple.Spotlight" OR process == "corespotlightd" OR process == "mds"' --style compact
如果提示没有权限,再考虑加 sudo。这里的 sudo 只表示读日志的权限,不表示这条命令会修 Spotlight。我没有在这次改写里重跑 log show,所以不能保证它现在还会打出和当时 log stream 一样的刷屏。
5. fs_usage:可选,而且自己也吃资源
这条不在当时的记录里,我也没有为这篇重测。它只盯着进程的文件调用,不改索引、不删库:
sudo fs_usage -w -f filesys corespotlightd
看几秒就按 Ctrl-C 停掉。输出会非常密,它自己也占 CPU。机器已经发烫时,不要把它开上几个小时。它能告诉你这个进程在碰哪些路径,不能告诉你该删哪个目录。
只读看完,能下的结论就到这里
ps 和 top -l 里如果 corespotlightd 或 mds 持续靠前,同时 mdutil -s / 只说索引开着,你知道的是:索引开关是开的,这两个进程当时很忙。忙的原因可能是正常重建,也可能是日志里那种反复要上下文。只读命令分不出这两种,更不能证明 /private/var/db/CoreDuet/ 里的文件已经损坏。
到这一步就停,也是一种结果。后面的命令都不是“再确认一下”。
我后来做了什么:这些都会改状态
下面是那次已经发生过的操作,按当时的顺序记。不是现在建议你照做的修复。每一条只写它动了什么,以及还能不能撤回来。
重建 Spotlight 索引:sudo mdutil -E /
我在看 mdutil -s 之前就先跑过一次。后来重置 CoreDuet 时又跑了一次。
影响:抹掉这个宗卷现有的 Spotlight 索引,并让系统重建。文稿、照片这些用户文件还在,但重建完成之前,搜索会缺结果。重建期间 CPU 可能更高,而不是马上降下来。原文没有记下重建花了多久,也没有记下结束后的占用。
撤销:没有把旧索引导回来的命令。再执行一次 -E 只是再删一次、再重建一次,不是还原。
停掉并禁用 mds
sudo launchctl disable system/com.apple.metadata.mds
sudo launchctl stop com.apple.metadata.mds
影响:metadata server 停掉。Spotlight 的索引和搜索会一起停,直到重新打开。当时写这两条,是为了后面删文件时它别同时写,不是为了诊断。
撤销:当时记下的对应命令是
sudo launchctl enable system/com.apple.metadata.mds
sudo launchctl start com.apple.metadata.mds
我没有在这次改写里验证这两条在当前系统上是否仍然成对。如果执行之后搜索仍不可用,不要再叠别的禁用项,先用 mdutil -s / 看开关现在是开还是关。
删除 CoreDuet 数据库
正常系统里当时写的是:
sudo rm -rf /private/var/db/CoreDuet/
这条被系统完整性保护(SIP)拦住了,文件没有删成。我没有为了删它去关闭 SIP。关闭 SIP 会放宽整机保护,当时就没有走那条路,这里也不补操作步骤。
后来是关机进入恢复模式,在恢复模式的终端里先 ls /Volumes/,找到主系统宗卷,再删那个目录。当时以宗卷名 Macintosh HD 为例:
rm -rf "/Volumes/Macintosh HD/private/var/db/CoreDuet/"
名字里有空格就要加引号。宗卷名以 ls /Volumes/ 看到的为准。路径写错,删的就是别的盘。
进入恢复模式的路径,原文是照着写的,不是两套机器都试过:
- Apple 芯片:关机,按住电源键直到出现启动选项,点「选项」再继续。
- Intel:开机后立刻按住 Command (⌘) + R,看到 Apple 标志或旋转的地球再松开。
进了恢复模式后,从菜单栏的「实用工具」打开终端。删完关闭终端,用苹果菜单重新启动。
影响:删掉的是 CoreDuet 用来记使用习惯、充电节奏和上下文的库。当时的理解是,文件、照片、邮件、应用这些不在这个目录里;系统里已经由 Apple 训练好的模型,也不在这次删除的范围内。个性化会先空一截:已经形成的「优化电池充电」节奏会丢掉,系统要重新学;Siri 在锁屏或搜索里的建议会暂时不准;程序坞里按时间或地点建议的应用会失效。原文写的重新学习时间是几天到一两周,那是当时得到的说法,不是我这次量出来的。
撤销:当时没有先把 /private/var/db/CoreDuet/ 复制出来。没有原件,就没有还原。系统会新建一个库,再重新学。再删一次不是撤销。
删完之后我自己遇到的后续,不是 CPU 数字,而是省电习惯被清掉。充电器插了一夜,电量仍从 100% 掉到 89%,电池图标写着「电池用量极小,充电已暂停」。那次观察和后来怎么等它自己学回来,写在删掉 CoreDuet 后,Mac 为什么突然不会省电了?。那篇里也写了:别反复删,新库需要时间,我的机器是第二天下午充电逻辑才回来。
观察归观察,修复归修复
日志刷屏是我看见的。数据库损坏、死循环,是解释。180%–200% 是那一次的读数。mdutil -E、停 mds、删除 CoreDuet,每一步都改了系统状态,而且删库没有备份、也没有在别的机器上重测。
所以现在如果再遇到 corespotlightd 占着 CPU、Mac 发烫,我只会先做上面的只读顺序。只读看完仍然说不清,就先停在那里,而不是把删系统数据库当成下一步。