本文约 3,069 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:整库恢复太重,只想要那几篇文章
场景很常见:
- 编辑误删了 20 篇文章,但站点设置、插件配置、近期评论都要保留;
- 从旧站迁移内容到已经配置好的新站;
- 只想恢复 uploads 里的图片,不动数据库。
整库恢复会把所有东西都回退,代价太大。这时候要做选择性恢复。
原理分析:WordPress 内容存在哪些表
| 表 | 内容 |
|---|---|
wp_posts |
文章、页面、附件、修订版本、菜单项 |
wp_postmeta |
每篇文章的自定义字段、特色图片 ID、SEO 数据 |
wp_term_relationships |
文章与分类/标签的关联 |
wp_term_taxonomy / wp_terms |
分类与标签本身 |
wp_options |
站点设置(恢复时通常要避开) |
wp_comments / wp_commentmeta |
评论 |
所以”只恢复文章”的最小集合是:
wp_posts + wp_postmeta + wp_term_relationships(+ 分类标签表)
而不恢复 wp_options,这是与整库恢复最大的区别。
保姆级实操
方式一:WXR 导出导入(最安全,推荐)
适合”从备份站/旧站把文章搬到当前站”。
# 在备份恢复出来的临时站上导出
wp --path=/tmp/restore-test export --dir=/tmp/exp \
--post_type=post --status=publish --skip_comments
# 在当前站导入
wp plugin install wordpress-importer --activate
wp import /tmp/exp/*.xml --authors=create
优点:不动 wp_options,不覆盖设置;WordPress 会处理 ID 重映射。
缺点:导入会产生新 ID(原 ID 不保留),如果文章间有互相引用需要修正;附件需要能下载。
方式二:SQL 选择性导入(保留 ID)
适合恢复误删的、ID 已经不存在的文章。
# 1. 从备份库导出指定 ID 范围的文章
mysqldump wordpress_backup wp_posts \
--where="ID IN (101,102,103) OR post_type='attachment'" > posts.sql
mysqldump wordpress_backup wp_postmeta \
--where="post_id IN (101,102,103)" > postmeta.sql
# 2. 导入到生产库
mysql wordpress < posts.sql
mysql wordpress < postmeta.sql
注意:mysqldump 默认带 DROP TABLE 和 CREATE TABLE,会覆盖目标表!必须加参数去掉:
mysqldump --no-create-info --skip-add-drop-table \
wordpress_backup wp_posts --where="ID IN (101,102,103)" > posts.sql
--no-create-info 只导出 INSERT 语句,不导出建表语句——这是关键参数。
方式三:只恢复单表到临时表再挑选
更安全:先把备份表导入成临时表,再 INSERT 挑选的记录。
# 导入成备份表
mysql wordpress < restore_posts.sql # 表名改为 wp_posts_backup
-- 挑出当前库已删除、备份里存在的文章
INSERT INTO wp_posts
SELECT * FROM wp_posts_backup b
WHERE b.post_status = 'publish'
AND b.post_type = 'post'
AND NOT EXISTS (SELECT 1 FROM wp_posts p WHERE p.ID = b.ID);
-- 同步 meta
INSERT INTO wp_postmeta (post_id, meta_key, meta_value)
SELECT post_id, meta_key, meta_value FROM wp_postmeta_backup b
WHERE b.post_id IN (SELECT ID FROM wp_posts_backup)
AND NOT EXISTS (
SELECT 1 FROM wp_postmeta m WHERE m.post_id = b.post_id AND m.meta_key = b.meta_key
);
方式四:只恢复上传文件
rsync -avP /backup/files/wp-content/uploads/ /var/www/site/wp-content/uploads/
chown -R www-data:www-data /var/www/site/wp-content/uploads
只恢复文件而数据库记录不恢复的话,媒体库里看不到这些图片(需要”Add From Server”类插件扫描入库)。
方式五:用 WP-CLI 只导入文章内容
# 从备份库导出成 CSV 或 SQL,再用 wp post create 逐条创建
wp post create --post_type=post --post_title='标题' --post_content='内容' --post_status=publish
适合数量少的情况。
常见踩坑与失败案例
- 忘记
--no-create-info——DROP TABLE wp_posts被执行,当前站点所有文章被删。这是最危险的操作,务必先备份当前库。 - 案例:某站恢复文章时只导入了
wp_posts,结果特色图片、SEO 标题、自定义字段全部丢失——因为它们都在wp_postmeta。posts 和 postmeta 必须成对恢复。 - ID 冲突 —— 备份里的 ID 在当前库已被新文章占用,
INSERT会主键冲突。用INSERT IGNORE或让 WordPress 重新分配 ID(WXR 方式)。 - 分类标签没同步 —— 文章导入了但分类显示不出来,因为
wp_term_relationships没导入。 - 附件仍指向旧域名 —— 导入后用
wp search-replace修正 URL。 - 导入后站点 404 —— 忘了
wp rewrite flush。
总结
选择性恢复的两种方式各有适用场景:WXR 导出导入最安全,适合跨站搬运内容(不碰设置、ID 自动重映射);SQL 选择性导入能保留原 ID,适合误删恢复,但必须用 --no-create-info 避免覆盖整表,且要同时恢复 wp_posts 与 wp_postmeta。无论哪种,执行前都要:备份当前库 → 在测试库试一遍 → 确认无误再上生产。另外提醒一句,恢复完成后一定要 wp rewrite flush 并检查前台访问。
