您好,
我正在尝试将一个论坛迁移到新服务器。两个服务器都运行最新版本的 Discourse Docker。通过命令行导入备份时,出现以下错误:
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id"
DETAIL: Key (path, incoming_domain_id)=(/search/, 418) is duplicated.
EXCEPTION: psql failed: DETAIL: Key (path, incoming_domain_id)=(/search/, 418) is duplicated.
这似乎与以下链接中的错误相同或相似:
I have a duplicate key issue also, is there a documented fix?
discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR: could not create unique index "index_incoming_referers_on_path_and_incoming_domain_id_ccnew"
DETAIL: Key (path, incoming_domain_id)=(/search/, 1905) is duplicated.
[1] pry(main)> IncomingReferer.where(path: "/m/search")
=> [#<IncomingReferer:0x0000557176d3f210 id: 44231, path: "/m/search", incoming_domain_id: 4>,
#<IncomingReferer:0x0000557176d925c8 id: 42228, path: "/m/…
但是,在我的案例中,重复的记录是 /search/ 路径,而不是上面链接线程中提到的 /m/search。
我已经连接到旧服务器上的容器(./launcher enter app),并在 Rails 控制台(rails c)中尝试使用以下命令搜索重复的记录:
IncomingReferer.where(path: "/search")
和
IncomingReferer.where("path LIKE '%/search%'")
然而,这会显示数百条记录。我该如何找出哪些记录是重复的,以及如何安全地删除它们并重建?论坛在旧服务器上目前运行正常,我们只是需要迁移到新硬件。
不,我以为通过 GUI 导入会调用相同的导入流程?我现在就试试。
pfaffman
(Jay Pfaffman)
2021 年10 月 31 日 23:24
4
我怀疑这意味着您的索引已损坏。您正在运行哪个版本的 Postgres?
类似如下命令:
cd /var/discourse
cat shared/standalone/postgres_data/PG*
(我有点记不清 Postgres 的具体文件名了。)
您可以在这里搜索“postgres corrupt index”,找到我曾撰写的一个主题,其中介绍了如何追踪并删除那些损坏的记录。
您基本上可以尝试重建该索引,删除它报错的记录,然后再次尝试重建索引,直到成功重建为止。
刚刚尝试通过 GUI 导入,结果完全一样:
pfaffman:
您正在运行哪个版本的 Postgres?
旧服务器上没有名为 PG_VERSION 的文件,如何确定其运行的版本?我今天已将 docket 安装更新到最新版本。
新服务器(刚完成引导)运行的是 Postgres V13
cat shared/standalone/postgres_data/PG_VERSION
13
是否有推荐的执行此操作的具体步骤?
pfaffman
(Jay Pfaffman)
2021 年11 月 1 日 00:33
6
我曾有一个包含一些提示的主题,但现在看不到了。自 PostgreSQL 12 升级以来已接近一年。
reindex index index_incoming_referers_on_path_and_incoming_domain_id;
以及
ActiveRecord::Base.connection.execute('reindex index index_incoming_referers_on_path_and_incoming_domain_id;')
是尝试重建索引的方法。这会报错,然后您可以删除出错的记录。您需要同时包含路径和 ID。
好的,我已经修复了。我执行了以下操作:
进入容器
./launcher enter app
连接到数据库
su postgres -c 'psql discourse'
尝试查找重复项
discourse=# select * from incoming_referers where path LIKE '%/search/' ORDER BY incoming_domain_id;
id | path | incoming_domain_id
------+------------+--------------------
3339 | /search/ | 33
6257 | /search/ | 91
1567 | /search/ | 298
1777 | /search/ | 341
3010 | /search/ | 418
6247 | /search/ | 418
4293 | /search/ | 644
2899 | /search/ | 653
3447 | /search/ | 793
3696 | /search/ | 852
4395 | /a/search/ | 1050
6968 | /search/ | 1305
5634 | /search/ | 1387
5834 | /search/ | 1437
6519 | /search/ | 1637
7127 | /search/ | 1787
7280 | /search/ | 1827
(17 rows)
删除重复项
DELETE FROM incoming_referers WHERE path LIKE '%/search/' AND id IN (6247);
然后重建
discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING: cannot reindex invalid index "public.incoming_referers_pkey_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "public.index_incoming_referers_on_path_and_incoming_domain_id_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "pg_toast.pg_toast_20732_index_ccnew" concurrently, skipping
REINDEX
之后我再次进行了备份,将其复制到新服务器,并成功导入
如果备份过程能够检测重复项以避免任何问题就好了。我很幸运还能访问仍在运行的原始服务器。如果我在恢复冷备份,这可能会成为一个更大的问题。
非常感谢您的帮助。