Проблема совместимости PG13 🔥

О чём это?

Эта миграция добавляет NULL NOT DISTINCT к индексу таблицы problem_check_trackers. 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 лайков

@drenmi Похоже, нам придется откатить миграцию и рассмотреть другое решение. Вероятно, это вызывает ошибки при установке на собственных серверах.

8 лайков

Я подготовил PR здесь, который должен работать и для PG13. :pray:

Мы всё ещё оцениваем, насколько реалистичен этот случай в реальных условиях, и насколько целесообразно инвестировать в обход этого ограничения. :pray:

1 лайк

Ну, я не могу говорить за других и не знаю, действительно ли я представляю большинство (скорее всего, нет), но я столкнулся с этим дважды в течение 3 дней после внесения этого изменения…

Так что обходное решение (и откат!) было бы очень кстати.

1 лайк

Теперь, когда у нас есть обходной путь, который должен работать и в PG15, мы сможем убрать NULLS NOT DISTINCT.

Из любопытства, что вы делали, что потребовалось восстановить резервную копию PG15 на PG13? :slightly_smiling_face: (На задачу выше это не повлияет, просто пытаюсь понять, что происходит «в реальной жизни» насколько это возможно.)

1 лайк

У нас был один клиент, который пытался восстановить резервную копию (кажется, у них был свой хостинг, и они пытались делать вещи, выходящие за рамки их компетенции :upside_down_face:), а у нас был другой клиент, который попросил нас настроить тестовый сайт для разработки кастомных плагинов, и мы взяли резервную копию с хостинга CDCK.

В целом встроенный механизм версионирования в метаданных резервных копий работает отлично, позволяя заранее определить, произойдёт ли сбой или нет, но такие ситуации* — это как мины :slight_smile:

(* На самом деле, единственное другое, что я могу вспомнить, что не охвачено версионированием миграций, — это когда миграция с более старой датой внедряется в основную ветку, но я отвлекаюсь)

3 лайка

Спасибо за информацию @RGJ! :pray:

PR по удалению NULLS NOT DISTINCT OPTION уже создан:

3 лайка

Я вижу, что проблема уже решена, но для полноты картины добавлю свой опыт: у меня возникла эта проблема при попытке восстановить резервную копию, созданную на хостинге Discourse, в локальный dev-контейнер, настроенный через Docker в рамках подготовки среды разработки. Похоже, что на хостинге Discourse используется PostgreSQL 15, а в среде разработки — 13?

2 лайка

Да, это корень проблемы. Нам нужно обновить наш контейнер с открытым исходным кодом до версии 15. Мы займемся этим в течение следующих нескольких месяцев.

4 лайка

Эта тема была автоматически закрыта через 9 дней. Новые ответы больше не принимаются.