RGJ
(Richard - Communiteq)
2024 年10 月 15 日 22:28
1
这是关于什么的?
此迁移在 problem_check_trackers 表上的索引上引入了 NULL NOT DISTINCT。DEV: Fix problem check tracker unique index not respecting NULLs by Drenmi · Pull Request #29169 · discourse/discourse · GitHub
问题是什么?
默认情况下,在为强制执行唯一索引的目的检查元组的唯一性时,PostgreSQL 会将 NULL 视为不同的值。因此,由于竞争条件,我们可能会错误地创建多个具有 { identifier: \"rails_env\", target: nil } 的条目。这随后会在运行时导致错误。
如何解决?
删除现有索引,并使用 NULLS NOT DISTINCT 选项重新创建它。
问题
但是,NULLS NOT DISTINCT 是在 Postgres 15 beta2 中引入 的。标准安装上的当前 Postgres 版本是 Postgres 13,它不支持此功能。
后果
此更改对 PG13 没有影响,因为 NULLS NOT DISTINCT 将被忽略(来源 )
尝试将 PG15 服务器的备份恢复到 PG13 服务器将失败并出现以下错误
ERROR: syntax error at or near "NULLS"
LINE 1: ...m_check_trackers USING btree (identifier, target) NULLS NOT ...
^
EXCEPTION: psql failed: ^
/var/www/discourse/lib/backup_restore/database_restorer.rb:92:in `restore_dump'
(完整行:CREATE UNIQUE INDEX index_problem_check_trackers_on_identifier_and_target ON public.problem_check_trackers USING btree (identifier, target) NULLS NOT DISTINCT;)
@tgxworld @drenmi
9 个赞
tgxworld
(Alan Tan)
2024 年10 月 15 日 23:20
2
@drenmi 看起来我们必须撤销迁移并重新考虑其他解决方案。这可能会导致自托管安装出错。
8 个赞
ted
(Ted Johansson)
2024 年10 月 18 日 04:35
11
我在这里有一个 PR,应该也能用于 PG13。
main ← fix/problem-check-target-pg13
opened 03:40AM - 18 Oct 24 UTC
### What is this change?
In #29169 we added a `NULLS NOT DISTINCT` option to … the unique index on `problem_check_trackers`. This is to enforce uniqueness even when the `target` is `NULL`. (Postgres considers all `NULL`s to be distinct by default.)
However, this only works in PG15. In PG13 it does nothing.
This commit adds a default dummy string value `__NULL__` to `target`. Since it's a string, PG13 will be able to correctly identify duplicate records.
### Is it safe to run this?
Adding a default value will lock the table and can cause issues on large tables, but the `problem_check_trackers` table is constrained by the number of problem check classes, and is in the ballpark of 10-100 rows.
我们仍在考虑这种情况在实际中有多大可能性,以及我们应该在多大程度上投入精力来规避它。
1 个赞
RGJ
(Richard - Communiteq)
2024 年10 月 18 日 07:33
12
我不能代表其他人发言,也不知道我是否具有代表性(可能不是),但在该更改做出后的 3 天内,我遇到了两次……
因此,非常感谢能提供一个解决方法(并撤销更改!)。
1 个赞
ted
(Ted Johansson)
2024 年10 月 21 日 03:38
13
既然我们有了解决方法,它也应该能在 PG15 上运行,我们应该可以移除 NULLS NOT DISTINCT。
出于好奇,您在做什么需要恢复 PG15 备份到 PG13? (这不会影响上面的任务,只是想尽可能多地了解“实际情况”。)
1 个赞
RGJ
(Richard - Communiteq)
2024 年10 月 21 日 05:35
14
我们有一位客户试图恢复备份(我想他们是自托管的,并且尝试了超出他们知识范围的事情 ),还有另一位客户要求我们设置一个暂存站点用于自定义插件开发,我们从 CDCK 托管中进行了备份。
总的来说,备份元数据中内置的版本控制机制在主动确定何时会出问题方面效果很好,但这种情况*就像地雷
(*实际上,我能想到的唯一另一个不受迁移版本控制覆盖的情况是,当一个具有较早日期戳的迁移 被注入到主版本中时,但我离题了)
3 个赞
ted
(Ted Johansson)
2024 年10 月 22 日 02:29
16
感谢 @RGJ 的信息!
移除 NULLS NOT DISTINCT OPTION 的 PR 已上线:
main ← dev/remove-nulls-not-distinct-from-problem-check-trackers
opened 02:28AM - 22 Oct 24 UTC
### What is this change?
We added `NULLS NOT DISTINCT` to a unique index on `… problem_check_trackers`.
This option is only available in PG15+. It does not in itself break PG13, but restoring a PG15+ backup to PG13 currently errors out. It seems this is an operation that's more common than we first thought.
This commit fixes that by removing the `NULLS NOT DISTINCT`.
### Don't we need it, since we added it?
We already have another, backwards-compatible approach to do the same thing in place, so this shouldn't change existing behaviour.
3 个赞
gpoole
(Greg Poole)
2024 年10 月 23 日 01:16
17
我可以看到问题已经解决,但为了分享一个实际遇到的经验:我在尝试将 Discourse 托管实例创建的备份恢复到我使用 Docker 在本地设置的开发容器时遇到了这个问题,这是设置开发环境的一部分。看起来 Discourse 托管运行的是 PG 15,而开发环境是 13?
2 个赞
sam
(Sam Saffron)
2024 年10 月 23 日 01:27
18
是的,这是问题的根源,我们需要在未来几个月内将我们的开源容器更新到 15。
4 个赞