重建无效的索引

我刚将一个拥有 180 万条帖子的站点升级到了 2.7.0.beta2,并同时将 PostgreSQL 从 10 升级到 13。我看到 beta3 刚刚发布,其中包含“改进的数据库迁移性能”,于是我立即再次进行了升级。

当我尝试执行 reindex concurrently 时,收到了以下提示:

WARNING:  cannot reindex invalid index "public.allowed_pm_users_pkey_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_allowed_pm_users_on_user_id_and_allowed_pm_user_id_ccnew" concurrently, skipping
WARNING:  cannot reindex invalid index "public.index_allowed_pm_users_on_allowed_pm_user_id_and_user_id_ccnew" concurrently, skipping

我本想删除这些索引并重新创建,但在当前源码中并未找到任何 ccnew 相关内容,因此不确定该如何处理。

看起来_ccnew 索引是并发重建索引机制的一部分:

  • 在系统目录中创建一个新索引,它是被重建索引的副本(存在一些例外情况,例如分区索引的继承依赖关系不是在创建时注册,而是在交换时注册)。这个新的临时索引以“_ccnew”作为后缀。简而言之。

能否在不使用 concurrently 关键字的情况下重建这些索引?

或者,引用该文章后文的内容:

随后,REINDEX TABLE CONCURRENTLY跳过无效索引,因为如果连续多次失败,索引数量会不断累积,每次运行翻倍,导致后续重建索引操作产生大量膨胀:

不过,仅使用 REINDEX INDEX CONCURRENTLY 是可以重建无效索引的:

_ccnew 是之前尝试通过 reindex concurrently 创建但未能成功的索引,通常是因为违反了唯一性约束。这些失败的 reindex concurrently 尝试会残留其中,需要手动删除。

第二次运行 reindex concurrently 时,PostgreSQL 将跳过这些失败产物。

谢谢 Rafael!问题解决了。我 drop 掉了这些索引,并再次进行了并发重建索引,一切顺利。