дубликат ключа в индексе PostgreSQL

#postgresql #indexing #unique

#postgresql #индексирование #уникальный

Вопрос:

Я хочу переместить свою базу данных ownCloud на новый сервер, но во время восстановления операция завершается с ошибкой.

 pg_restore: [archive program (db)] COPY failed for table "oc_storages": ERROR: value of a duplicate key breaks unique constraint "storages_id_index"
DETAIL: The key "(id) = (local :: / var / www / owncloud_data /)" already exists.
  

Действительно, простой запрос к базе данных oc_sorages показывает, что дубликат существует.

 ocl=# select  * from oc_storages where id ~* 'owncloud_data';
               id               | numeric_id | available | last_checked 
-------------------------------- ------------ ----------- --------------
 local::/var/www/owncloud_data/ |        491 |         1 |             
 local::/var/www/owncloud_data/ |        838 |         1 |             
(2 rows)
  

но в то же время postgresql удалось создать индекс для этой таблицы на основе идентификатора (storages_id_index). Как возможно, что PostgreSQL принимает этот дубликат в этой таблице?

 ocl=# SELECT indexname, indexdef FROM pg_indexes WHERE tablename = 'oc_storages';
     indexname     |                                      indexdef                                       
------------------- -------------------------------------------------------------------------------------
 oc_storages_pkey  | CREATE UNIQUE INDEX oc_storages_pkey ON public.oc_storages USING btree (numeric_id)
 storages_id_index | CREATE UNIQUE INDEX storages_id_index ON public.oc_storages USING btree (id)
(2 rows)
  

Что делать, чтобы выйти из этого тупика: удалить одно из двух значений? какой?

Заранее спасибо.

Эрнест.

Комментарии:

1. Что вы делали? восстановление в недавно выделенную базу данных? -> Проверьте кодировку / сопоставление.

2. Вы пробовали переиндексировать таблицу / индексы?

Ответ №1:

Обычно этому есть два объяснения:

  • Аппаратные проблемы, приводящие к повреждению данных. Затем удалите конфликтующие строки вручную, экспортируйте базу данных и импортируйте ее во вновь созданный кластер, чтобы избавиться от потенциального скрытого повреждения данных.

  • Вы обновили библиотеку C в операционной системе, и параметры сортировки изменились, повредив индекс. Затем удалите конфликтующие строки вручную и REINDEX индексы со строковыми столбцами.

Комментарии:

1. проблема возникла в моем экземпляре Owncloud 10.0.3 и posgresql 9.4. Я произвольно удалил один из дубликатов, и все работает нормально. Спасибо!

2. PostgreSQL 9.4, вероятно, в старой системе… Я не удивлен.

Ответ №2:

Это одна из тех семантических проблем, с которыми я сталкиваюсь в Postgres, но создание УНИКАЛЬНОГО ИНДЕКСА в таблице фактически не добавляет принудительного ограничения таблицы.

Вам необходимо явно добавить каждое ограничение, ИСПОЛЬЗУЯ созданный индекс, например:

 CREATE UNIQUE INDEX oc_storages_pkey ON public.oc_storages USING btree (numeric_id);
ALTER TABLE public.oc_storages ADD CONSTRAINT oc_storages_pkey UNIQUE USING INDEX oc_storages_pkey;
  

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