WordPress 跨云迁移实战:Rank Math sitemap 404 的真凶,藏在数据库一行空选项里

适用环境:WordPress 7.1.2 + Rank Math 1.0.279 + Nginx + PHP 8.3 + MariaDB 10.11(Rocky Linux 10.2,腾讯云)

背景

前阵子把博客从阿里云迁到腾讯云。没用镜像的方式,而是应用层重建 + 数据搬迁:新机器装好 Nginx / PHP-FPM / MariaDB,然后 mysqldump 导库、tar 打包 wp-content、scp 过去。

迁移本身很顺,坑在后面一个接一个:固定链接 404(缺 try_files)、502(nginx 配的 unix socket 但 php-fpm 监听 TCP 9000)、页面被 CDN 缓存了坏掉时期的 404……这些都比较常规,修完网站就正常了。

真正的硬骨头是 sitemap_index.xml 一直 404。这篇文章记录完整的排查过程——最后发现真凶居然是数据库里一行空选项,而且中间还踩了两个”写对了地方但写错了字段”的坑。

第一轮:把能排除的都排除掉

sitemap 404 常见原因无非:伪静态、rewrite 规则、插件模块没开、CDN 缓存。挨个验:

1. CDN 干扰?直连源站绕过:

curl -sk -o /dev/null -w "%{http_code}\n" \
  --resolve huangdi888.top:443:127.0.0.1 \
  https://huangdi888.top/sitemap_index.xml

源站也 404,CDN 无罪(响应头 eo-cache-status: MISS 也佐证了这点)。

2. rewrite 规则?

php -r "require 'wp-load.php'; foreach (get_option('rewrite_rules') as \$k => \$v)
  if (strpos(\$k,'sitemap')!==false) echo \"\$k => \$v\\n\";"

sitemap_index\.xml$ => index.php?sitemap=1 在,规则没问题。

3. Rank Math 模块?

rank_math_modules 选项里 sitemap 在,模块开着。template_redirect 钩子上的 render_sitemaps 也挂上了。

4. query_vars?

在钩子里打日志,{"sitemap":"1"},解析正确,但 is_404=true。

到这里有点诡异:WordPress 明明把请求识别成了 sitemap,却返回了 404。

第二轮:直接驱动 Generator

既然 Web 链路全通,那就绕过 Web 直接测插件内部:

$g = new RankMath\Sitemap\Generator();
echo strlen($g->get_output('1', 1));    // 索引输出长度
echo strlen($g->get_output('post', 1)); // post-sitemap 长度

结果:两个都是 0。而 wp_count_posts() 显示文章 10 篇、页面 9 页,内容都在。

翻了 Rank Math 源码,class-sitemap-xml.php 里有一段:

if ( empty( $this->sitemap ) ) {
    $wp_query->set_404();      // ← 404 是插件主动设的
    status_header( 404 );
    return;
}

404 不是”找不到”,是插件主动设的——因为 Generator 认为没有任何内容类型需要进 sitemap。

第三轮:数据库里找答案

查 wp_options 表里 Rank Math 的所有选项行:

php -r "require 'wp-load.php'; global \$wpdb;
  print_r(\$wpdb->get_col(\"SELECT option_name FROM {\$wpdb->options}
  WHERE option_name LIKE 'rank_math%'\"));"

发现关键的一行:rank-math-options-sitemap 存在,但值是空的。迁移导库的时候这行的内容丢了。general 和 titles 两个选项都完好,就 sitemap 这行是空的——丢失得毫无规律。

踩坑一:连字符 vs 下划线

第一反应是补选项,但想当然地写成了:

update_option('rank_math_options_sitemap', [...]);  // ❌ 下划线,无效!

写完一测,还是 404。再查表才发现库里同时存在两套命名:

  • rank-math-options-sitemap(连字符,Rank Math 实际用的)
  • rank_math_options_sitemap(下划线,我写的那份,没人读)

看插件源码 includes/helpers/class-options.php 第 84 行确认:

update_option( 'rank-math-options-sitemap', $sitemap );  // 连字符

踩坑二:字段名带 _sitemap 后缀

换成连字符的 key 重新写,内容是:

$opt['pt_post'] = 'on';
$opt['pt_page'] = 'on';

还是 404。Generator 输出还是 0。这时不再猜了,直接 grep 插件源码看判断条件:

grep -n "pt_" includes/modules/sitemap/providers/class-post-type.php

第 78 行:

! Helper::get_settings( 'sitemap.pt_' . $type . '_sitemap' ) ||

真凶找到了:1.0.279 判断的字段是 pt_post_sitemap、pt_page_sitemap,带 _sitemap 后缀。我写的 pt_post 根本不在它的检查范围内——写了等于没写。

修复

$opt = get_option('rank-math-options-sitemap');
$opt['items_per_page']          = 200;
$opt['include_images']          = 'on';
$opt['include_featured_images'] = 'on';
$opt['pt_post_sitemap']        = 'on';   // 带 _sitemap 后缀
$opt['pt_page_sitemap']         = 'on';
$opt['tax_category_sitemap']    = 'on';
update_option('rank-math-options-sitemap', $opt);

验证:

索引输出长度: 569
post-sitemap 长度: 4339
源站 sitemap -> 200

sitemap_index.xml 恢复,索引里 post-sitemap 和 page-sitemap 都回来了。顺带一提,后台 Rank Math → Sitemap Settings 页面之前一直空白,也是同一个原因(选项数组缺字段导致面板渲染失败),选项修好后自动恢复。

最后进后台点一次 Save Changes 让插件补全所有默认字段,去 Google Search Console 重新提交 sitemap,完事。

踩坑总结

这次排查最大的教训:改插件选项之前,先 grep 插件源码确认真实的 key 和字段名,不要凭经验猜命名风格。

三个具体坑:

  1. Rank Math 的 option key 是连字符(rank-math-options-sitemap),和大多数 WordPress 插件的下划线风格不一样
  2. sitemap 模块的字段名带 _sitemap 后缀(pt_post_sitemap),不是直觉上的 pt_post
  3. 插件选项行丢失不报错,只 404——迁移后 SEO 类插件的 sitemap 建议主动验一次,这种失败太隐蔽了

迁移收尾清单(自查)

  • 固定链接正常(nginx try_files $uri $uri/ /index.php?$args)
  • fastcgi_pass 和 php-fpm 监听方式一致(socket vs TCP)
  • 修完源站清一次 CDN 缓存(坏掉期间的 404 可能被缓存住了)
  • sitemap 200 且内容完整
  • 删 readme.html(暴露 WP 版本)
  • 关掉排查用的 WP_DEBUG
  • 删掉所有临时探针文件

排查期间往 mu-plugins 里塞的调试探针记得删干净——挂在 template_redirect 上的探针写错了会全站 500,后台页面也跑不掉,还会制造”设置页空白”这种假象,把排查方向带偏。

https://huangdi888.top/wp-content/uploads/2026/09/wordpress-sitemap-404-diagnosis.zip

这里上面的zip可以导入您的Agent里面,说实话这里有一些复杂,如果您使用可以导入让ai协助路径也可以替换您自己的方便使用,下载zip后也可以直接点击里面的md文件自行查看分析,不过技能版更便于 AI 执行

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注