"ОШИБКА: psql не удался: ДЕТАЛИ: Ключ (post_id)=(36946) дублируется."

Я пытаюсь перенести свой сервер на новый хост, поэтому загрузил файл резервной копии и загрузил его на новый хост. Установил свежую копию Discourse и следовал инструкциям по восстановлению из командной строки:

К сожалению, команда discourse restore databasename завершается ошибкой:

ALTER TABLE
ALTER TABLE
ALTER TABLE
ERROR:  could not create unique index "posts_search_pkey"
DETAIL:  Key (post_id)=(36946) is duplicated.
EXCEPTION: psql failed: DETAIL:  Key (post_id)=(36946) is duplicated.
/var/www/discourse/lib/backup_restore/database_restorer.rb:92:in `restore_dump'
/var/www/discourse/lib/backup_restore/database_restorer.rb:26:in `restore'
/var/www/discourse/lib/backup_restore/restorer.rb:51:in `run'
script/discourse:149:in `restore'

Похоже, что-то не так с файлом базы данных? Не могли бы вы подсказать, как исправить эту ошибку? У меня всё ещё есть доступ к исходному серверу, который, кажется, работает нормально.

Есть ли какая-то SQL-команда или что-то ещё, что я мог бы запустить для анализа (и исправления?) базы данных перед загрузкой резервной копии?

Похоже, у вас поврежден индекс. Какая версия PostgreSQL используется?

По этой теме есть несколько обсуждений. Вы можете попробовать переиндексировать эту таблицу на работающем экземпляре, а затем удалить или исправить дублирующиеся ID.

Да, я думаю, что данные повреждены. Буду очень признателен, если кто-нибудь подскажет, как это исправить :slight_smile:

Версия Postgres — 13.6. Я пытаюсь перенести его на новый инстанс на другом сервере.

Я запустил rake search:reindex внутри контейнера Docker, но получил ошибку:

........rake aborted!
PG::UniqueViolation: ERROR:  duplicate key value violates unique constraint "posts_search_pkey"
DETAIL:  Key (post_id)=(86919) already exists.

Можно ли просто удалить проблемную запись и снова выполнить индексацию или что-то подобное?

Любая помощь будет очень кстати!

Да, я рекомендую просто удалить строку — это самый простой способ.

Может, кто-нибудь подскажет команды psql, которые помогут найти и удалить проблемные строки?

Спасибо, очень ценю вашу помощь!

Кажется, это что-то вроде

./launcher enter app
su - postgres
psql discourse
select id from post_search_data where post_id>86918 and post_id<86921;
--- когда вы получите id ----
delete from post_search_data where id=ID_FROM_LAST_QUERY

Возможно, есть и другие варианты.

Возможно, кто-то другой сможет помочь больше, но без доступа к вашему серверу я могу предложить только это. Если вам нужна более существенная помощь, вы можете написать в Marketplace или связаться со мной напрямую.

Или, возможно, будет безопасно просто удалить эти данные и позволить системе сгенерировать их заново, но я не до конца уверен в этом.

Спасибо за помощь, ребята.

Мне удалось сделать следующее:

discourse=# reindex index concurrently "posts_search_pkey";
ERROR:  could not create unique index "posts_search_pkey_ccnew2"
DETAIL:  Key (post_id)=(116038) is duplicated.
discourse=# delete from post_search_data
where post_id = 116038;
DELETE 2
discourse=# delete from post_search_data
where post_id = 116038;
DELETE 0
discourse=# reindex index concurrently "posts_search_pkey";
ERROR:  could not create unique index "posts_search_pkey_ccnew3"
DETAIL:  Key (post_id)=(9336) is duplicated.
discourse=# delete from post_search_data
where post_id = 9336;
DELETE 1
.
.
.
.
discourse=# reindex index concurrently "posts_search_pkey";
REINDEX

Когда всё казалось в порядке, я сделал полную резервную копию и восстановил её на новом сервере без проблем.

Я ценю время всех. Я люблю Discourse!

Урок усвоен: время от времени проверяйте резервные копии, чтобы убедиться, что они в порядке :slight_smile: Я делаю ежедневные резервные копии, а также храню ежемесячные «снимки». Самая ранняя резервная копия, в которой не было повреждённой базы данных, была четырёхмесячной давности :frowning:

Отлично! Очень рад, что у вас получилось!

@sam, тревожит то, что я думал, будто объяснение заключалось в проблеме с PG<13, но у вас запущен PG13.