mds_stores、mdworker_shared、corespotlightd 谁在吃 CPU?Mac Spotlight 进程只读速查
Frank Zhang
- 11 分钟阅读 - 5244 字TL;DR
这几个名字都属于 Spotlight 这套索引,但不是同一个进程。先只读确认是谁、索引开着没有,不要先删索引目录。
mds、mds_stores、mdworker / mdworker_shared、corespotlightd 都会在活动监视器里和 Spotlight 一起出现,但它们不是同一个进程。短时间或连续很多小时 CPU 高,都不要先删索引目录。Apple 写明:索引发生在第一次设置设备、安装软件更新或升级之后,以及设备上的数据变化时;数据多的话,可以持续数小时甚至数天。About Spotlight indexing and search results 没有给过 CPU 百分比。先用只读命令看是哪一个进程、各宗卷的索引开着没有,再决定把目录放进隐私列表,还是重建。
我之前排查 corespotlightd 时,那台 Mac 上记下的是 corespotlightd 和 mds,不是 mds_stores,也不是 mdworker。那次没有 macOS 版本,也没有删完之后量到的 CPU。经过在corespotlightd CPU 高占用、Mac 发烫:先只读排查,别急着删库,动手之前的顺序在Mac 上 corespotlightd CPU 高占用:先只读排查,再决定要不要删。下面不把那次 180%–200% 的读数挪过来当基准。要部署项目,而不是看 Spotlight,走自部署阅读路线。
四个名字,手册里能对上的只有两个
下表的“做什么”只写能在手册或 Apple 文档里对上的句子。“忙的时候”不写正常百分比:手册和那篇支持文档都没有给。写这篇时,mds(8)、mdworker(8) 能打开;mds_stores、mdworker_shared、corespotlightd 在同一套手册页面里没有专页。
| 进程 | 做什么 | 忙的时候先想到什么 | 不能直接当成 | 只读命令 |
|---|---|---|---|---|
mds | mds(8):metadata server。它为元数据 API 的客户端提供服务,其中包括 Spotlight。手册写明不要手动运行 mds。 | 服务在跑。索引进行时它在,和“服务还开着”一致,不是一份 CPU 标准。 | 索引损坏,或该删某个目录。 | ps、top |
mds_stores | 没有专页。mdutil(1) 的标题是管理 Spotlight 使用的 metadata stores。进程名里有 stores,只能说明要单独看它。 | 把它和 mds、mdworker 分开记一笔:谁的 CPU、谁的内存。 | “索引正在被写坏”,或因此去删 /.Spotlight-V100。 | ps、top、log show |
mdworker,以及名字带 mdworker_shared 的进程 | mdworker(8):metadata server 的 worker。mds 用它在宗卷挂载或文件变化时扫描并索引文件。手册没有写 _shared 这个后缀,也写明不要手动运行 mdworker。 | 刚挂上宗卷,或刚改了大量文件。这和手册写的时机一致。要持续多久,手册没写。 | 开了几个 worker 才算正常,或者该把进程杀掉。ps 里实际印出的名字,才是后面 fs_usage 该过滤的名字。 | ps;fs_usage;mdimport -L 只列 importer |
corespotlightd | Core Spotlight 讲的是 App 把自己的内容放进本机索引,索引留在设备上、不与 Apple 或其他设备同步。这里引用的页面没有定义 corespotlightd 这个守护进程。 | 本站那次是它和 mds 一起忙。如果这次 ps 里主要是它,先读上面两篇,不要套 worker 的判断。 | 该去删 CoreDuet。删库之后充电节奏被打乱,写在删掉 CoreDuet 后,Mac 为什么突然不会省电了?。 | ps、top;细节见那两篇 |
Importer 是另一层。Apple 的 Spotlight importer 排错页 写:/usr/bin/mdimport -L 列出当前认到的 importer 和路径。Core Spotlight 的文档另外写明:Spotlight File Import 扩展在 macOS 上不提供这项功能;要让自定义文件能被 Spotlight 找到,走的是 importer 插件。mdimport -L 只回答“机器上登记了哪些插件”,不回答“现在哪一个插件占着 CPU”。
只读命令
这些命令不关索引,不擦存储,也不重建。写这篇时没有在一台 Mac 上重跑;旗标含义来自手册。你机器上的 man 如果和下面不一致,以你的手册为准。手册页面来自 keith.github.io/xcode-man-pages 转载的文本,不是 developer.apple.com 上的一页。
1. 两轮 CPU,读第二轮
top(1) 写明:-l 的第一轮里,每个进程的 %CPU 无效,因为 CPU 要用两轮之间的差来算。所以要两轮都打完。
top -l 2 -n 20 -o cpu -stats pid,command,cpu,mem
-o cpu 按 CPU 从高到低排(cpu 本来也是默认排序键)。-stats 只留这几列;mem 在手册里是进程的物理内存占用。-n 20 每轮最多 20 个进程,两轮都能在退出前打完。
常见的另一种写法是:
top -l 2 -o cpu -stats pid,command,cpu,mem | head -30
head -30 只留前 30 行,第二轮可能被裁掉,裁掉的那一轮才是 %CPU 有效的一轮。所以上面那条加了 -n 20、没有接 head。top 不改索引。
2. 进程还在不在,已经跑了多久
ps(1):-a 会跳过没有控制终端的进程,除非同时有 -x。系统守护进程通常没有控制终端,所以两条一起用。pcpu 是 CPU 百分比,rss 是驻留内存、单位是 1024 字节,etime 是已经跑了多久,comm 是命令名,不是带参数的整行。
ps -axo pid,pcpu,rss,etime,comm | grep -Ei 'mds|mdworker|corespotlight'
这是子串匹配。命中的每一行都看 comm,不要看见 mds 三个字母就当成同一种进程。命令行里带了这段正则,grep 自己也会出现一行。不想看它,用方括号,和之前那篇一样:
ps -axo pid,pcpu,rss,etime,comm | grep -Ei '[m]ds|[m]dworker|[c]orespotlight'
rss 和 top 的 mem 不是同一列,不要加在一起。etime 很长,只说明进程还在;Apple 说索引可以到数天,所以“跑了很久”本身不是损坏。
3. 各宗卷的索引开着没有
mdutil(1) 的名字就是管理 Spotlight 使用的 metadata stores。-s 显示所列宗卷的索引状态,-a 作用到所有宗卷上的所有 store。下面这条只有 -s 和 -a,没有 -E,也没有 -i。
mdutil -sa
它只查询。我之前那篇里,mdutil -s / 连续几个小时都是 Indexing enabled。那几个词只说明这个宗卷的索引开着,没说扫描走到哪,也没说已经走完。-sa 会多打出几行。每一行是一个状态,不要把两行当成同一个开关。状态原文以你终端里的为准,这里不补一份“所有可能输出”的清单。
4. 看 worker 正在碰哪些路径
fs_usage(1) 实时显示和文件系统活动有关的系统调用。它要 root,因为用了内核跟踪。-w 强制更宽的输出,-f filesys 只留文件系统相关事件。最后的名字会限制为“所有叫这个名字的进程”。手册的例子是 fs_usage -w -f filesys Mail。
先用第 2 步里看到的名字。看到的是 mdworker_shared,就过滤这个名字;看到的是 mdworker,就换掉:
sudo fs_usage -w -f filesys mdworker_shared | head -50
这是持续输出,直到管道断开或你按 Ctrl-C。head -50 是为了只留 50 行;如果它还停不下来,按 Ctrl-C。手册另外有 -t 秒数,可以让它自己在指定秒数内结束。路径列会被截短:手册对 pathname 一列的说明是访问到的路径、最多到最后 28 个字节,默认从左边裁。一段短路径不是“该删的目录”。之前写 corespotlightd 时也说过,fs_usage 输出很密,命令自己也占 CPU,而且那篇没有重测。机器已经发烫时,不要开几个小时。
5. 读已经落盘的日志
log(1) 的 show 显示系统日志库里已有的内容,不改 Spotlight。--last 10m 是相对日志结尾的 10 分钟,--style compact 是紧凑格式。process == "..." 这种谓词出现在手册的例子里。
log show --last 10m --predicate 'process == "mds_stores"' --style compact | tail -50
默认只含 default 级别。没加 --info 或 --debug 时,空输出不等于这个进程刚才没事。tail 只截短你看见的行,查询窗口仍是 10 分钟。如果它说读不了,再考虑 sudo;这里的 sudo 只是读日志的权限,和之前那篇一样,不是在修索引。进程名换成 ps 里看到的那一个。
6. 可选:机器上登记了哪些 importer
只要列表,保留 -L:
mdimport -L
mdimport(1) 写明:不给开关时,隐含的是 -i,会让 Spotlight 按正常途径导入,并把属性写进索引。所以不要把 -L 拿掉,再对一个目录跑 mdimport。那一步会写索引,不是只读。这次读到的转载页在 -d 之后没有后文,大纲里只看得到字母 L。-L 会列出 importer 和路径,依据是上面那页 Apple 的 importer 文档。
先等,还是该看目录
按这个顺序,不要跳到删除:
- 刚第一次设置这台 Mac,刚装了软件更新或升级,或者数据在变(新装了允许被索引的 App、新来的邮件或信息)。这是 Apple 写的索引时机。另外,mdworker(8) 写的是宗卷挂载或文件变化。先接上电源,不用的时候让机器闲着。Apple 还写了:如果邮件或其他数据要先下载才能进索引,连着 Wi-Fi 或以太网会更快完成。按 Command–空格,Spotlight 或 Siri 窗口顶部可能有索引进度。看见了,就是支持文档说的“正在索引”。没看见,不能反证索引已经停。
- 忙了很久,进度也没有,再用
fs_usage看同一段路径是不是反复出现。反复出现的目录是候选,不是已经证明该删。检查时可以先看那些会一直变的地方:依赖目录(例如node_modules)、构建产物、虚拟机镜像、同步盘、外接盘。这是一份检查清单,不是本站某次测量。 ps里主要是corespotlightd,就回到那两篇。那次日志里还有 CoreDuet 的刷屏;为了压 CPU 去删 CoreDuet,不是这篇的下一步。- 不要用
pkill按一个很短的名字结束进程。终端里误杀进程、桌面一起乱掉的记录在误输 pkill 后 Mac 桌面全乱了?真正被你误杀的是 loginwindow。
要改状态的话,从风险低的开始
下面每一步都会改 Spotlight 的行为或索引。只读看完、并且你接受这一步的后果,再做。
1. 把不需要搜索的目录留在隐私列表里
这是不擦整卷索引、又能少索引一块地方的做法。Apple 的 Mac 用户指南 当前页写的是:打开系统设置,点边栏里的 Spotlight(可能要往下滚),点右下角的 Search Privacy,用添加按钮选一个文件夹或磁盘,也可以直接拖进去。
写这篇时打开的那一页,版本菜单里有 macOS Sonoma 14、Sequoia 15、Tahoe 26 和 macOS 27。没有逐个版本点开。同一主题的支持文档 还写了另一种标签:边栏可能是 Spotlight 或 Siri & Spotlight,按钮可能是 Search Privacy 或 Spotlight Privacy。更早的“系统偏好设置”点击路径,没有在这次对照的现行页面里找到。标签对不上,就在系统设置的搜索框里搜 Spotlight。
指南里的两条限制要一起看。排除 Time Machine 备份盘之后,你仍会收到 Spotlight 正在索引它的提示。这份索引是 Time Machine 正常工作所需要的,关不掉。搜索时,Spotlight 会排除备份盘上不属于 Time Machine 备份的项目。排除某些文件和文件夹后,有些 App 有更新时可能不再通知你;把整个内置磁盘排除掉,就收不到任何更新通知。
把一项留在列表里,是排除,这些位置不再被搜索。从列表里拿掉,用户指南写的是这些文件会重新被搜索。这和重建不是同一句话。支持文档 里的重建是:把磁盘或文件夹加进这个列表,等几秒,再拿掉。拿掉之后,Spotlight 会重新索引那一块。那是在修搜索结果,索引会再跑,不是把 CPU 马上压下去的办法。
2. 外接宗卷:只关掉这一卷的索引
确认卷名之后:
sudo mdutil -i off "/Volumes/卷名"
-i off 把所给宗卷的索引状态设为关。同一段还写:索引可能因为磁盘空间不足或其他情况而推迟。这句话说的是索引这件事可能推迟,不是测过的“-i off 会过一会儿才生效”。名字以 mdutil -sa 打出来的为准,有空格就加引号。Apple 文档里的例子盘名是 Macintosh HD,不是你的盘一定叫这个。
这会改索引状态,不是诊断。手册没有写必须加 sudo;这里用 sudo,是因为它在改系统状态。被拒绝就停,那是权限,不是索引结论。对应的打开是 -i on。不要顺手改成 -d:-d 在同一本手册里是关闭该宗卷上的 Spotlight 搜索,和“只关索引”不是同一个旗标。
3. 最后才擦掉这一卷的本地存储并重建
接受搜索会缺一截、而且重建期间机器可能更忙之后,才是:
sudo mdutil -E /
手册的句子是:这个旗标会把所列宗卷的每个本地 store 擦掉;如果合适,这些 store 会被重建。它作用在你写上的那个宗卷。先看过 mdutil -sa 再决定写 / 还是别的路径。
我之前那次在看状态之前就跑过 sudo mdutil -E /。那篇记下的后果是:用户文件还在,重建完成前搜索会缺结果,重建期间 CPU 可能更高而不是马上降下来;没有命令把旧索引导回来,再跑一次 -E 只是再擦一次。那篇没有记下重建花了多久,也没有记下结束时的 CPU。这篇同样不补一个时长。
不要删 /.Spotlight-V100
不要跑 sudo rm -rf /.Spotlight-V100,也不要按猜的路径手工删一个 Spotlight 目录。
我之前那篇没有用过这条命令,也没有核实那台 Mac 上活的索引是不是 /.Spotlight-V100。rm -rf 不走 mdutil。路径写错,尤其是从 / 往下删,删掉的是别的东西。重建这一步,手册已经给了 mdutil -E:擦掉本地 store,并在合适时重建。不需要先用 rm 达到同一个目的,而且 rm 没有“把旧的请回来”的步骤。
同样不要为了 mds_stores 或 mdworker_shared 去删 CoreDuet,也不要先禁用 mds。那两件事改的是另一层状态,写在 corespotlightd 那两篇里。
这篇不承诺的
- 不给“降到多少百分比”或“等多少分钟”。Apple 给的尺度是数小时到数天,随数据量变;那之后的增量更新更快。这是支持文档里的话,这篇没有另做计时。
- 这篇没有测过
mds_stores或mdworker_shared。本站的第一手记录只有 corespotlightd 那次,而且那次写明没有记下这两个进程。 Indexing enabled不是进度条。空的log show不是“它没在干活”。top第一轮的 %CPU 不作数。fs_usage的路径可能是截短的。mds_stores、mdworker_shared、corespotlightd没有在这套手册里找到专页。名字相近不是职责证明。
对照过的页面
你的 Mac 上 man mds、man mdworker、man mdutil、man mdimport、man fs_usage、man top、man log、man ps 优先于转载页。
- mds(8)、mdworker(8)、mdutil(1)、mdimport(1)
- fs_usage(1)、top(1)、log(1)、ps(1)
- About Spotlight indexing and search results on Apple devices(页面上的发布日期是 2026-08-25)
- Prevent Spotlight searches in specific folders or disks on Mac
- Core Spotlight
- Troubleshooting Spotlight Importers
这篇如果有用,欢迎自愿赞助,用来继续更新博客和自部署笔记。这不是慈善捐赠。