我遇到了以下问题。我已经运营 Discourse 论坛超过 10 年,但由于一段时间以来无法安装更新,我打算设置一台新服务器:
旧服务器运行版本:3.4.0.beta4-dev
新服务器:最新版本
备份文件(不包括上传内容)的 .gz 文件大小已达 673.2 MB。
不幸的是,恢复操作不断中断。日志文件中包含以下错误:
[2026-06-16 07:54:52] ERROR: could not create unique index “index_incoming_referers_on_path_and_incoming_domain_id”
[2026-06-16 07:54:52] DETAIL: Key (path, incoming_domain_id)=(//, 5) is duplicated.
[2026-06-16 07:54:52] EXCEPTION: psql failed: DETAIL: Key (path, incoming_domain_id)=(//, 5) is duplicated.
[2026-06-16 07:54:52] /var/www/discourse/lib/backup_restore/database_restorer.rb:93:in 'BackupRestore::DatabaseRestorer#restore_dump'
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in ‘BackupRestore::DatabaseRestorer#restore’
/var/www/discourse/lib/backup_restore/restorer.rb:61:in 'BackupRestore::Restorer#run'
/var/www/discourse/script/spawn_backup_restore.rb:20:in ‘Object#restore’
/var/www/discourse/script/spawn_backup_restore.rb:33:in ‘block in ’
/var/www/discourse/script/spawn_backup_restore.rb:4:in 'Kernel#fork'
/var/www/discourse/script/spawn_backup_restore.rb:4:in ‘’
[2026-06-16 07:54:52] Trying to rollback...
我该如何解决这个问题,同时不丢失过去 10 年的数据?
提前感谢任何帮助!
你好,哇,欢迎回来,时隔九年!
能看到这样一个运行了这么久的论坛,真的很酷。
我认为这和你在这里讨论的索引问题是同一个:Can't restore due to corrupt indexes (with some clues on how to deal with corrupt indexes)
情况大致如下:
incoming_referers 表用于跟踪将访客引导至你论坛的 URL 路径。它有一个唯一索引,这意味着不能有两行具有相同的路径 + 域名组合。
你的数据库中有两行的 path='//' 且 incoming_domain_id=5。当它在恢复期间尝试重建这个唯一索引时,发现了重复项并中止了整个恢复事务。
因此,你需要找到并清理那个重复的 incoming_referers 条目,然后制作一个新的备份以在新服务器上恢复。
我找到了这个包含说明的主题 ,可能会对你有帮助。
glynhudson:
进入容器
./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
不好意思打扰了,但我好像哪里做错了——执行命令“discourse=# select * from incoming_referers where path LIKE ‘%/search/’ ORDER BY incoming_domain_id;”后,出现了一个语法错误。
你输入的是 “discourse=#” 吗?如果是,请去掉这部分重新输入。
然后我收到了错误消息“bash: syntax error near unexpected token `from’”
作为参考,我当前的位置是:root@community-app:/var/www/discourse#
啊,你还没有进入数据库。
先运行 psql -U discourse discourse(我想应该是这样)
然后提示符应该会变成 discourse=#
好的,我现在也安装了“apt install postgresql-client-common”。不过,我仍然收到错误提示:“错误:您必须至少安装一个 postgresql-client- 包。”
chapoi
2026 年6 月 16 日 11:05
10
好的,这个我不清楚。
也许可以尝试直接通过 Rails 控制台执行:rails c
然后运行
ActiveRecord::Base.connection.execute(<<~SQL)
SELECT id, path, incoming_domain_id
FROM incoming_referers
WHERE path = '//'
AND incoming_domain_id = 5
SQL
这样或许能在不经过数据库的情况下得到相同的结果。
这样可行吗?
我真的非常抱歉当时表现得那么愚蠢。
我现在已经安装了 Rails,看起来安装成功了。我也用“rails c”运行了它。那部分似乎也没问题,但当我输入命令时,显示如下:
“root@community:/var/discourse# ActiveRecord::Base.connection.execute(<<~SQL)
-bash: syntax error near unexpected token `<<’
root@community:/var/discourse# SELECT id, path, incoming_domain_id
SELECT: command not found
root@community:/var/discourse# FROM incoming_referers
FROM: command not found
root@community:/var/discourse# WHERE path = ‘//’
WHERE: command not found
root@community:/var/discourse# AND incoming_domain_id = 5
AND: command not found
root@community:/var/discourse# SQL”
chapoi
2026 年6 月 16 日 11:26
12
别担心,也许是我的说明不够清楚
你说刚安装了 Rails 却连不上数据库,这让我有点困惑。也许是因为版本较旧,情况有所不同,但说实话,我现在也有点摸不着头脑了。
总之,进入 Rails 后,提示符应该会发生变化。从你的输出来看,你似乎还没有进入 Rails 控制台。
我甚至觉得你还没进入实际的容器。你执行过 ./launcher enter app 吗?