很抱歉再次打扰,我遇到了一个非常奇怪的问题:
discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR: could not create unique index "index_tags_on_name_ccnew"
DETAIL: Key (name)=(chronicillness) is duplicated.
我推测可以通过 @riking 上面建议的解决方案来修复,但我无法弄清楚如何修改语法以适应我的情况。![]()
很抱歉再次打扰,我遇到了一个非常奇怪的问题:
discourse=# REINDEX SCHEMA CONCURRENTLY public;
ERROR: could not create unique index "index_tags_on_name_ccnew"
DETAIL: Key (name)=(chronicillness) is duplicated.
我推测可以通过 @riking 上面建议的解决方案来修复,但我无法弄清楚如何修改语法以适应我的情况。![]()
请参见:
https://twitter.com/petervgeoghegan/status/1264325695997538304?s=20
https://twitter.com/petervgeoghegan/status/1264404749899534338?s=20
因此,如果您遇到此错误,可以采取以下两种措施:
您可以绕过该问题……在这种情况下,tags 表中存在一行重复数据,其名称为 chronicillness。
执行数据探索器查询以搜索相关行:select * from tags where name = 'chronicillness'
删除重复项:
./launcher enter app
rails c
Tag.find_by(id: ID_YOU_FOUND_IN_DATA_EXPLORER).destroy
如果您有数据库的备份以及希望与 Peter 分享的详细信息……请通过私信或 PG 邮件列表与 Peter 分享。
我有一份由 Discourse 生成的 PostgreSQL 10 备份,这会有帮助吗?我能否直接从归档中提取 PostgreSQL 部分并发送?
我不确定……Peter 可能需要的只是你停止数据库,然后复制包含数据库的文件夹的全部内容。
最好的办法是给他发电子邮件确认一下。
好的,我会给他发封邮件来弄清楚这件事 ![]()
注意:我在数据探索器中运行 SQL 时得到了以下结果
| id | name | topic_count | created_at | updated_at | pm_topic_count | target_tag |
|---|---|---|---|---|---|---|
| 1710 | chronicillness | 2 | 2019-12-03T17:49:17.395Z | 2019-12-03T17:49:17.395Z | 0 | NULL |
执行
Tag.find_by(id: 1710).destroy
能解决问题吗?
哦……索引是基于 LOWER(name) 的。
请这样运行查询:
select * from tags where name ilike 'chronicillness'
您应该会得到 2 行结果。
select * from tags where name ilike 'chronicillness'
| id | name | topic_count | created_at | updated_at | pm_topic_count | target_tag |
|---|---|---|---|---|---|---|
| 329 | chronicillness | 12 | 2017-08-22T00:17:38.824Z | 2017-08-22T00:17:38.824Z | 0 | NULL |
| 1710 | chronicillness | 2 | 2019-12-03T17:49:17.395Z | 2019-12-03T17:49:17.395Z | 0 | NULL |
标签名称之间会不会是 -?
我在这看到了两个标签:chronicillness 和 chronic-illness。
那么问题就出在这里……我想你会删除 1710。之后会有两个主题缺少该标签。
#<Tag:0x00005607bb92cf48
id: 1710,
name: "chronicillness",
topic_count: 0,
created_at: 2019-12-03 17:49:17 UTC +00:00,
updated_at: 2019-12-03 17:49:17 UTC +00:00,
pm_topic_count: 0,
target_tag_id: nil
>
为什么我觉得这像是个没有任何关联的小矮人?
删除标签后出现了更多问题!
discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING: 无法并发重新索引无效的索引 "public.tags_pkey_ccnew",已跳过
WARNING: 无法并发重新索引无效的索引 "public.index_tags_on_name_ccnew",已跳过
WARNING: 无法并发重新索引无效的索引 "public.index_tags_on_lower_name_ccnew",已跳过
WARNING: 无法并发重新索引无效的索引 "pg_toast.pg_toast_309322_index_ccnew",已跳过
ERROR: 无法创建唯一索引 "index_tags_on_name_ccnew1"
DETAIL: 键 (name)=(time-management) 重复。
我就是这么做的。不过那些警告没问题吧?我不需要担心那些对吧?
是的,所有警告都是正确的。你的索引已损坏,需要先修复。
所以所有的复制索引现在都已清除,我在重新索引时只剩下这些警告:
discourse=# REINDEX SCHEMA CONCURRENTLY public;
WARNING: cannot reindex invalid index "public.tags_pkey_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "public.index_tags_on_name_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "public.index_tags_on_lower_name_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "public.tags_pkey_ccnew1" concurrently, skipping
WARNING: cannot reindex invalid index "public.index_tags_on_name_ccnew1" concurrently, skipping
WARNING: cannot reindex invalid index "public.index_tags_on_lower_name_ccnew1" concurrently, skipping
WARNING: cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew" concurrently, skipping
WARNING: cannot reindex invalid index "pg_toast.pg_toast_309322_index_ccnew1" concurrently, skipping
REINDEX
是否需要采取某些措施来消除这些警告,还是我们只能接受这些警告的存在?
这让我感到困惑……我们的索引名称中没有以 ccnew 结尾的……这些是你手动创建的吗?
我认为这些是在从 PostgreSQL 10 迁移到 12 时使用的,因为我看到几乎所有遇到索引问题的用户都提到了这些。例如:
https://meta.discourse.org/t/postgresql-12-update/151236/208?u=itsbhanusharma
https://meta.discourse.org/t/postgresql-12-update/151236/237?u=itsbhanusharma
编辑:来源是 PostgreSQL 官方文档
在这种情况下,推荐的恢复方法是删除无效索引,然后再次尝试执行
REINDEX CONCURRENTLY。在处理过程中创建的并发索引,其名称以ccnew结尾;如果是未能删除的旧索引定义,则以ccold结尾。可以使用DROP INDEX删除无效索引,包括无效的 TOAST 索引。
哎呀……正确的索引是否也已经存在于表中?
我想你可以使用数据资源管理器列出表上的索引。
如果正确的索引已经存在,那么你可以直接删除这些有问题的索引。
让我检查一下。我会向您汇报。
因此,索引似乎确实存在
问题索引的重复索引也存在,并添加了 ccnew 或 ccnew1
我不知道如何检查这些索引是否有效,但如果删除它们是一个可行的选项,我很乐意删除并重新建立索引。
编辑:按此处建议的方式使用 DROP INDEX 会有效吗?
是的,全部删掉……不知道它们怎么跑到那儿的……你应该使用 DROP INDEX。
./launcher enter app
rails c
DB.exec('drop index tags_pkey_ccnew1')