#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;
Если у вас уже есть такое ограничение таблицы, то это может быть случай повреждения.