Por padrão, ao verificar a exclusividade de uma tupla para fins de imposição de um índice exclusivo, o PostgreSQL considera os NULLs como valores distintos. Por causa disso, poderíamos ter incorretamente várias entradas com { identifier: "rails_env", target: nil } criadas devido a condições de corrida. Isso causaria erros em tempo de execução.
Como isso resolve?
Remover o índice existente e recriá-lo com a opção NULLS NOT DISTINCT.
Problema
No entanto, NULLS NOT DISTINCT foi introduzido no Postgres 15 beta2. A versão atual do Postgres em uma instalação padrão é o Postgres 13 e ele não suporta este recurso.
Consequências
esta alteração não terá efeito no PG13, pois o NULLS NOT DISTINCT será ignorado (fonte)
tentar restaurar um backup de um servidor PG15 para um servidor PG13 falhará com o seguinte erro
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'
(linha completa: CREATE UNIQUE INDEX index_problem_check_trackers_on_identifier_and_target ON public.problem_check_trackers USING btree (identifier, target) NULLS NOT DISTINCT;)
Bem, não posso falar por outros e não sei se sou realmente representativo (provavelmente não), mas me deparei com isso duas vezes em 3 dias após essa alteração ter sido feita…
Portanto, uma solução alternativa (e um revert!) seria muito apreciada.
Agora que temos a solução alternativa, que também deve funcionar no PG15, poderemos remover o NULLS NOT DISTINCT.
Por curiosidade, o que você estava fazendo que necessitou restaurar um backup do PG15 no PG13? (Isso não afetará a tarefa acima, apenas estou tentando entender o que está acontecendo “no mundo real” o máximo possível.)
Tivemos um cliente que estava tentando restaurar um backup (acho que eles eram auto-hospedados e estavam tentando coisas além do seu nível de conhecimento ), e tivemos outro cliente que nos pediu para configurar um site de staging para fins de desenvolvimento de plugins personalizados e nós tiramos um backup da hospedagem CDCK.
Em geral, o mecanismo de versionamento integrado nos metadados de backup funciona muito bem em ser capaz de determinar proativamente quando algo vai explodir ou não, mas esses tipos de situações* são como minas terrestres
(* Na verdade, a única outra coisa que consigo pensar que não é coberta pelo versionamento de migração é quando uma migração com um carimbo de data/hora mais antigo é injetada no main, mas estou divagando)
Consigo ver que o problema já foi resolvido, mas para adicionar uma experiência real: Tive esse problema ao tentar restaurar um backup criado em uma instância hospedada no Discourse para um contêiner de desenvolvimento que configurei localmente usando o Docker como parte da configuração de um ambiente de desenvolvimento. Parece que o hospedagem do Discourse executa o PG 15, mas o ambiente de desenvolvimento é 13?