WordPress 运行几年后,wp-content/uploads 很容易积累数万张文件。媒体库里看起来只有一张图片,磁盘上却可能同时存在原图、主题缩略图、WooCommerce 商品图、旧主题留下的尺寸以及图片编辑产生的备份文件。直接进入服务器按文件名删除,短时间内可能腾出空间,却会留下数据库记录、破损图片和无法恢复的页面。
安全的清理顺序是:先确认空间被什么占用,完整备份数据库和上传目录,再区分原图、缩略图、未附加附件与孤立文件,最后分批删除并检查前台。下面的命令适用于可以使用 SSH 和 WP-CLI 的常见 Linux 主机;虚拟主机用户也可以按同样的判断顺序,在主机面板和 WordPress 后台操作。

一张图片为什么会生成很多文件
WordPress 上传图片后,会为附件建立数据库记录,并把原始文件路径、宽高、文件大小和各个子尺寸写入附件元数据。主题和插件还可以注册额外尺寸,因此同一张原图旁边出现多个 文件名-宽x高.jpg 并不一定是重复上传。
先在 WordPress 根目录查看当前注册的图片尺寸:
wp media image-size
输出中的 thumbnail、medium、large 以及主题或插件自定义尺寸,都会影响新上传图片生成多少个文件。站点更换过主题、商城插件或页面构建器后,旧尺寸可能仍留在磁盘中,但不再出现在当前注册列表里。
清理前要把文件分成四类:
- 原始图片:媒体库附件的源文件,删除后通常无法仅靠缩略图恢复完整画质。
- 当前缩略图:仍被主题、响应式图片或插件使用的子尺寸。
- 旧缩略图:以前注册、现在已取消的图片尺寸,需要核实旧页面和外部链接是否仍引用。
- 孤立文件或附件:文件存在但数据库没有记录,或者数据库有附件记录但页面用途不明确。
这四类不能用同一种批量删除规则处理。
清理前同时备份数据库和 uploads
只备份图片目录不够。媒体附件与文章、特色图片、商品相册、自定义字段之间的关系保存在数据库中;只备份数据库也不够,因为真正的图片文件在 wp-content/uploads。
先确认当前目录确实是目标站点:
wp core is-installed
wp option get home
wp option get siteurl
然后导出数据库,并把上传目录压缩到站点公开目录之外:
wp db export ../backup-before-media-cleanup-$(date +%F-%H%M).sql
tar -czf ../uploads-before-media-cleanup-$(date +%F-%H%M).tar.gz wp-content/uploads
备份完成后检查文件是否存在、大小是否合理,并把副本下载到另一台设备或对象存储。使用媒体云存储、图片压缩或 WebP 转换插件的站点,还要核对远端对象、原图保留策略和插件自己的恢复方式。不要假设压缩包生成成功就等于可以恢复。
先做容量和附件清单
记录清理前基线,后面才能判断到底释放了多少空间,也能在误删时定位批次。
du -sh wp-content/uploads
find wp-content/uploads -type f | wc -l
find wp-content/uploads -type f -printf '%s %p\n' | sort -nr | head -30
再导出媒体附件清单:
wp post list \
--post_type=attachment \
--post_status=inherit \
--post_mime_type=image \
--fields=ID,post_date,post_title,post_parent,guid \
--format=csv > ../media-attachments-before-cleanup.csv
这份 CSV 至少保留附件 ID、上传时间、父级文章和 URL。后续发现某篇文章缺图时,可以快速追溯被处理的附件。
“未附加”不等于“未使用”
媒体库的“未附加”通常表示附件没有通过 post_parent 关联到某篇文章。它不能证明图片没有被使用。
以下场景都可能让图片显示为未附加,但前台仍在调用:
- 区块编辑器或经典编辑器直接保存了图片 URL。
- 页面构建器、ACF 或主题设置把附件 ID 存在自定义字段中。
- 图片被用作站点图标、菜单图、分类封面或小工具背景。
- WooCommerce 商品图库、邮件模板或弹窗插件单独保存了关系。
- CSS 文件、外部页面、搜索广告落地页或其他网站直接引用图片地址。
可以先列出未附加图片作为候选,而不是直接删除:
wp post list \
--post_type=attachment \
--post_parent=0 \
--post_mime_type=image \
--fields=ID,post_date,post_title,guid \
--format=table
实际检查时,优先从上传时间早、尺寸大、命名明显属于旧活动的图片开始。打开附件详情,搜索完整 URL、文件名和附件 ID,并检查文章正文、自定义字段、商品图库、主题设置、CSS 与 CDN 日志。确认用途不清楚的图片先保留,或移动到待观察清单,不要为了凑清理数量强行删除。
按风险从低到高清理
第一批适合处理的是后台明确确认的测试图、重复上传图、失败导入图和已经下线的临时活动素材。一次只处理少量附件,删除后立即查看首页、重点栏目、热门文章、商品页和移动端页面。
优先从 WordPress 媒体库或 WordPress API 删除附件。WordPress 永久删除附件时,会同时清理附件记录、相关元数据以及属于该附件的文件。直接使用 rm 删除 uploads 中的图片,只会移除磁盘文件,数据库和页面引用仍然存在。
具备 WP-CLI 环境时,也应先用少量已核实的 ID 测试:
wp post delete 123 456
该命令默认尝试把对象移入回收站。只有在附件用途已经核实、备份可恢复且确实需要永久删除时,才考虑增加 --force。媒体回收站是否启用也会影响实际行为,因此要先用一两个附件验证结果。不要把未经人工核验的全部“未附加”ID直接交给批量删除命令。
第二批再处理旧主题、旧插件留下的缩略图。原图和当前缩略图不要混在这一批中。
清理旧缩略图前先看注册尺寸
wp media regenerate 的主要作用是重新生成缩略图,不是通用的媒体库清理器。不同参数的影响差别很大:
--only-missing只补生成缺失的尺寸,适合修复换主题后缺图的问题。--skip-delete在重新生成时保留原有缩略图,适合仍可能存在外链的站点。--delete-unknown会删除旧的、当前未注册的缩略图,可能释放空间,但必须先在测试环境或少量附件上验证。
先选择几张普通附件做测试:
wp media regenerate 123 456 --delete-unknown
检查这些图片对应的文章、srcset、CDN 缓存和移动端显示均正常后,再考虑扩大范围。没有附件 ID时,命令会针对全部媒体并要求确认;大型站点不要在业务高峰直接全量执行。
如果旧缩略图 URL 被搜索引擎、邮件、论坛或外部网站引用,删除后会产生 404。此类站点可先使用 --skip-delete,或者为确实需要保留的旧尺寸恢复注册规则,再安排逐步迁移。
孤立文件要用数据库清单交叉核对
磁盘上的文件不一定都能在媒体库中找到。历史迁移、手工 FTP 上传、插件卸载失败或数据库恢复不完整,都可能造成 uploads 文件与附件记录不一致。
不要仅凭文件名中的 -300x200 就认定它可以删除。较稳妥的做法是把附件元数据中的原图和子尺寸导出为“已知文件清单”,再与 uploads 实际文件列表比较。差集只作为候选,还要排除以下内容:
- 缓存插件生成的 WebP、AVIF 或临时文件。
- 图片优化插件保留的原图备份。
- 导入器、表单、下载插件和会员插件管理的文件。
- 不通过媒体库上传、但被主题或 CSS 使用的资源。
这类比对最好先在站点副本中完成。直接写 SQL 删除 wp_posts 或 wp_postmeta 记录风险更高,也可能绕过插件的清理钩子,不建议作为日常处理方式。
清理后检查页面、日志和可恢复性
每处理一批附件,至少做以下检查:
- 随机打开旧文章、最新文章、分类页和移动端页面,确认原图与响应式缩略图正常。
- 检查浏览器开发者工具和 Web 服务器日志中是否新增图片 404。
- 清除页面缓存与 CDN 缓存,避免缓存掩盖已经删除的文件。
- 再次记录 uploads 容量和文件数量,与清理前基线比较。
- 从备份中抽取一张原图并尝试恢复,确认备份不是空包或损坏包。
后续可以每季度记录一次媒体库附件数、uploads 容量和注册图片尺寸。更换主题、商城插件或图片优化方案时,先记录新增尺寸,再决定是否为历史图片批量生成。这样可以在文件数量开始异常增长时处理,而不是等磁盘告警后再冒险清空媒体库。
参考资料
- WordPress 官方:Media Library screen
- WordPress 开发者文档:wp_get_attachment_metadata()
- WordPress 开发者文档:wp_delete_attachment()
- WP-CLI:wp post delete
- WP-CLI:wp media image-size
- WP-CLI:wp media regenerate
- WordPress 官方:Backups
资料核验日期:2026 年 9 月 21 日。




