最近在整理 WordPress 博客时,我又注意到了一个以前就比较在意的问题:文章 ID 增长得似乎有点快。
这次刚好有一篇新文章可以作为样本。
中文文章的 ID 是:
27442对应英文翻译文章的 ID 是:
27455两者之间相差了 13。
这篇文章新增加的标签其实只有 1 个,即使把英文对应标签也算进去,也只有 2 个。所以我一开始就在想,这些 ID 到底都被什么内容占用了。
顺着这个问题查下去,最后不仅把 WordPress 的 Revision 完全关闭,还清理掉了:
7085 条 revision
2495 条 wp_sync_storage同时确认没有留下孤儿 postmeta。
这篇文章记录一下完整过程。
一、先确认 27442 到 27455 之间到底是什么
首先查询 wp_posts 中这段 ID:
wp eval --allow-root '
global $wpdb;
$rows = $wpdb->get_results("
SELECT
ID,
post_parent,
post_type,
post_status,
post_title,
post_date
FROM {$wpdb->posts}
WHERE ID BETWEEN 27442 AND 27455
ORDER BY ID
");
foreach ($rows as $row) {
printf(
"%s\t%s\t%s\t%s\t%s\t%s\n",
$row->ID,
$row->post_parent,
$row->post_type,
$row->post_status,
$row->post_title,
$row->post_date
);
}
'清理之前查询到的主要记录是:
27442 中文文章
27443 attachment
27444 attachment
27445 attachment
27446 attachment
27447 attachment
27448 attachment
27449 attachment
27450 attachment
27451 revision
27452 revision
27454 revision
27455 英文文章也就是说,这 13 个 ID 的增长主要来自:
| 类型 | 数量 |
|---|---|
| 图片附件 | 8 |
| Revision | 3 |
| 已不存在的 ID 27453 | 1 |
| 英文文章 | 1 |
这里也顺便确认了一件事:
标签并不会消耗 wp_posts.ID。
真正让 wp_posts.ID 增长的,是文章、附件、Revision,以及其他使用 wp_posts 表存储的数据。
清理 Revision 后再次查询同一区间,可以看到原来的 27451、27452、27454 已经不存在了。

需要注意的是,删除记录以后,已经使用过的 ID 不会重新利用。
所以即使 27451 已经删除,以后的新文章也不会重新从这个 ID 开始。
二、历史 Revision 已经累计到 7085 条
既然这篇新文章一次就留下了 3 条 Revision,我继续统计整个网站:
wp eval --allow-root '
global $wpdb;
$count = (int) $wpdb->get_var(
"SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = '\''revision'\''"
);
echo "revision_count={$count}\n";
'结果:
revision_count=70857085 条。
我的博客已经运行很多年,而且现在又是中英文双语,所以有一定数量的 Revision 很正常。
但是问题在于:我实际上几乎从来没有使用过 WordPress 的“恢复到以前版本”功能。
既然这个功能长期不用,继续保留几千条甚至以后更多的历史版本,对我来说意义并不大。
三、绝大多数 Revision 都来自博客文章
为了避免直接把所有 Revision 都当成文章历史版本,我又按父内容类型统计了一次:
wp eval --allow-root '
global $wpdb;
$rows = $wpdb->get_results("
SELECT
p.post_type AS parent_type,
COUNT(*) AS revision_count
FROM {$wpdb->posts} r
LEFT JOIN {$wpdb->posts} p
ON p.ID = r.post_parent
WHERE r.post_type = '\''revision'\''
GROUP BY p.post_type
ORDER BY revision_count DESC
");
foreach ($rows as $row) {
printf(
"%-25s %d\n",
$row->parent_type ?: "(missing parent)",
$row->revision_count
);
}
'结果:
post 7024
wp_template 19
page 13
wp_navigation 9
nimble_post_type 6
wp_template_part 6
wp_global_styles 3
custom_css 3
contx_post_type 27085 条 Revision 中:
7024 条来自 post占绝大多数。
这里的 post 同时包含中文文章和英文文章。Polylang 下的中英文文章,本质上仍然是两篇独立的 WordPress post。
剩下的则来自:
- 页面
- 模板
- 导航
- 模板部件
- 全局样式
- Custom CSS
- 部分插件自定义内容类型
这些数量都很少。
因为我本身就不打算继续使用 Revision 回滚功能,所以最后决定:全部删除,而不是只删除博客文章的 Revision。
四、彻底关闭 WordPress Revision
原来的配置是:
define( 'WP_POST_REVISIONS', 3 );也就是每篇内容最多保留 3 个 Revision。
我直接修改为:
define( 'WP_POST_REVISIONS', false );
修改完成后,通过 WP-CLI 验证:
wp eval --allow-root '
echo "WP_POST_REVISIONS=";
var_export(WP_POST_REVISIONS);
echo PHP_EOL;
echo "AUTOSAVE_INTERVAL=" . AUTOSAVE_INTERVAL . PHP_EOL;
'结果:
WP_POST_REVISIONS=false
AUTOSAVE_INTERVAL=60这里有一个很重要的区别:
关闭 Revision,并不等于关闭自动保存。
我没有在 wp-config.php 中单独配置 AUTOSAVE_INTERVAL,所以 WordPress 仍然使用默认的:
60 秒也就是说,我现在的策略是:
不长期保存历史 Revision,但保留编辑过程中的自动保存。
这对我来说更加合适。
五、删除前先备份数据库
因为这一次要删除的是几千条数据库记录,所以正式操作前,我先使用 UpdraftPlus 做了一次数据库备份。
这次只涉及数据库,因此只勾选:
在备份中包括数据库
没有必要重新备份全部上传文件。

虽然删除的是 Revision,但既然数据库已经积累了这么多年,我还是更愿意先留一个完整的恢复点。
六、分批清理 7085 条 Revision
没有直接执行类似:
DELETE FROM wp_posts WHERE post_type = 'revision';而是继续通过 WordPress 自己的删除接口处理。
每批删除 500 条:
while true; do
IDS=$(wp eval --allow-root '
global $wpdb;
$ids = $wpdb->get_col("
SELECT ID
FROM {$wpdb->posts}
WHERE post_type = '\''revision'\''
ORDER BY ID
LIMIT 500
");
echo implode(" ", $ids);
')
if [ -z "$IDS" ]; then
echo "全部 revisions 已清理完成"
break
fi
COUNT=$(echo "$IDS" | wc -w)
echo "本批删除 ${COUNT} 条 revision"
wp --allow-root post delete $IDS --force
done这样处理的一个好处是,不只是单纯把 wp_posts 中的行直接删除,而是走 WordPress 的删除流程。
最终再次统计:
revision_count=0原来的:
7085已经全部清理。
七、清理完 Revision,又发现 2495 条 wp_sync_storage
Revision 清掉以后,我重新统计了 wp_posts 中各种 post_type:
attachment 9678
post 2999
wp_sync_storage 2495
series_grouping 48
nav_menu_item 34
wpcode 31
...这时候一个很显眼的内容类型出现了:
wp_sync_storage 2495数量竟然接近 2500 条。
继续检查这些记录:
wp eval --allow-root '
global $wpdb;
$rows = $wpdb->get_results("
SELECT
post_status,
COUNT(*) AS count,
MIN(ID) AS min_id,
MAX(ID) AS max_id,
MIN(post_date) AS first_date,
MAX(post_date) AS last_date
FROM {$wpdb->posts}
WHERE post_type = '\''wp_sync_storage'\''
GROUP BY post_status
ORDER BY count DESC
");
foreach ($rows as $row) {
printf(
"status=%-15s count=%-6d ID=%d-%d date=%s -> %s\n",
$row->post_status,
$row->count,
$row->min_id,
$row->max_id,
$row->first_date,
$row->last_date
);
}
'结果:
status=publish
count=2495
ID=9453-23604
date=2026-04-09 11:16:45 -> 2026-08-07 19:15:33最后一条记录停留在:
2026-08-07 19:15:33而现在已经是 9 月 6 日。
我隐约记得之前已经把 WordPress 的协作编辑相关功能关闭了,所以继续验证当前状态。
八、确认协作功能确实已经关闭
执行:
wp eval --allow-root '
echo "wp_is_collaboration_enabled=";
var_export(
function_exists("wp_is_collaboration_enabled")
? wp_is_collaboration_enabled()
: "function_missing"
);
echo PHP_EOL;
echo "WP_ALLOW_COLLABORATION=";
if (defined("WP_ALLOW_COLLABORATION")) {
var_export(WP_ALLOW_COLLABORATION);
} else {
echo "(not defined)";
}
echo PHP_EOL;
echo "wp_collaboration_enabled option=";
var_export(get_option("wp_collaboration_enabled", "(not set)"));
echo PHP_EOL;
'结果:
wp_is_collaboration_enabled=false
WP_ALLOW_COLLABORATION=(not defined)
wp_collaboration_enabled option='(not set)'也就是说当前实际状态确实是:
wp_is_collaboration_enabled=false再结合:
wp_sync_storage 最后一条记录停留在 2026-08-07基本可以确认,这 2495 条是之前使用相关功能时留下来的历史数据。
九、2495 条 wp_sync_storage 还关联了 2682 条 postmeta
在真正删除之前,我又查了一下这些记录对应的 postmeta:
wp eval --allow-root '
global $wpdb;
$count = (int) $wpdb->get_var("
SELECT COUNT(*)
FROM {$wpdb->postmeta} pm
INNER JOIN {$wpdb->posts} p
ON p.ID = pm.post_id
WHERE p.post_type = '\''wp_sync_storage'\''
");
echo "sync_storage_postmeta_count={$count}\n";
'结果:
sync_storage_postmeta_count=2682也就是说:
2495 条 wp_sync_storage
2682 条关联 postmeta所以这里同样没有直接使用 SQL 硬删。
继续使用:
wp post delete --force分批清理。
十、最终清理结果
全部完成以后,我把几个关键状态放在一起进行了最终验证。

结果:
=== WordPress cleanup verification ===
WP_POST_REVISIONS=false
AUTOSAVE_INTERVAL=60
collaboration_enabled=false
revision_count=0
wp_sync_storage_count=0
orphan_postmeta_count=0现在最终状态是:
| 项目 | 结果 |
|---|---|
| WordPress Revision | 已关闭 |
| 自动保存 | 60 秒,继续保留 |
| 历史 Revision | 7085 → 0 |
| 协作编辑 | 已关闭 |
wp_sync_storage | 2495 → 0 |
wp_sync_storage 关联 postmeta | 已随记录清理 |
孤儿 postmeta | 0 |
这一次仅 wp_posts 就删除了:
7085 + 2495 = 9580也就是 9580 条历史或内部记录。
十一、为什么我最终选择完全关闭 Revision
一开始我其实考虑过:
define( 'WP_POST_REVISIONS', 1 );也就是至少保留上一个历史版本。
但是再想了一下,我用了 WordPress 这么多年,几乎从来没有真正使用过 Revision 恢复功能。
对我来说:
- 编辑过程中意外退出,可以依靠 Autosave;
- 正式文章发布以后,很少需要恢复到几个小时甚至几天前的版本;
- 数据库本身也有定期备份;
- 网站文章数量已经比较多;
- 现在还是中英文双语,文章数量还会继续增长。
所以最终选择:
define( 'WP_POST_REVISIONS', false );反而更符合我的实际使用方式。
当然,这个选择并不一定适合所有网站。
如果是多人编辑、新闻编辑部、团队协作网站,Revision 的价值会明显更高。
但是对于我这种主要由自己维护、而且几乎从不回滚文章历史版本的个人技术博客来说,关闭它是可以接受的。
十二、不要为了“追回 ID”重置 AUTO_INCREMENT
还有一个容易产生误解的地方。
这次删除了 9580 条 wp_posts 记录,但并不意味着以前占用过的 ID 会重新使用。
例如:
27451
27452
27454原来的 Revision 已经删除,但这些 ID 仍然会永久空缺。
这是正常现象。
因此我没有去做:
重置 AUTO_INCREMENT也没有尝试重新排列文章 ID。
WordPress 内部大量关系都依赖 ID,单纯为了让数字“连续漂亮”去动它,没有实际意义,反而可能增加风险。
十三、这次排查最大的收获
最开始,我只是因为:
中文文章 ID:27442
英文文章 ID:27455觉得两个 ID 相差得有点多。
最后一路查下来,却发现了两个长期积累的数据来源:
7085 条 revision
2495 条 wp_sync_storage而且还确认了另外几个容易混淆的问题:
- 标签不会消耗
wp_posts.ID - 图片附件会消耗 ID
- Revision 会消耗 ID
- 删除 Revision 不会把 ID 重新利用
- 关闭 Revision 不等于关闭 Autosave
- 中英文 Polylang 文章本身仍然是独立的
post - 已关闭的协作功能还可能留下历史
wp_sync_storage - 删除关联数据后还应该检查孤儿
postmeta
现在:
revision_count=0
wp_sync_storage_count=0
orphan_postmeta_count=0数据库状态已经干净很多。
接下来再发布新的中英文文章时,也可以继续观察中文文章和英文文章之间的 ID 变化。
到时候剩下的 ID 消耗,应该就更容易判断究竟来自图片附件、自动保存,还是其他 WordPress 内部记录了。
需要长期技术维护或远程问题排查?
我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。
如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:
- ✅ PHP / Laravel / Yii2 老项目无人维护
- ✅ Go / Gin 后端接口需要排查或优化
- ✅ WordPress 网站访问慢、报错或插件冲突
- ✅ Nginx / MySQL / Redis / Linux 服务器异常
- ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
- ✅ 需要长期远程技术支持或兼职维护
更多介绍请查看:关于我 & 合作
微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan
