Доброго времени суток господа!
Есть действующая рабочая база данных Firebird (DB.FDB). Её backup проходит успешно, а вот при estore
базы данных DB.gbk возникает ошибка:
gbak: activating and creating deferred index PK_AI_RAIDERS
gbak:cannot commit index PK_AI_RAIDERS
gbak: ERROR:attempt to store duplicate value (visible to active transactions) in unique index "PK_AI_RAIDERS"
gbak: ERROR:action cancelled by trigger (3) to preserve data integrity
gbak: ERROR: Cannot deactivate index used by a PRIMARY/UNIQUE constraint
gbak:Exiting before completion due to errors
Как видно БД не восстанавливается. Подскажите пожалуйсто, в чём дело и как можно исправить эту ошибку?
P.S. А иначе мне конец...
Невосстанавливаемый backup
В "действующей" исправить индекс (удалить pk, исправить дубликаты, создать pk) и сделать backup.
Данные действительно оказались задвоены! Каким чудом не понятно.
Вот выдержка из DDL таблицы:
ALTER TABLE AI_RAIDERS ADD CONSTRAINT PK_AI_RAIDERS PRIMARY KEY (POLNUM, CBRIDNUM);
Сделал запрос:
select
POLNUM, CBRIDNUM, count(*)
from AI_RAIDERS
group by POLNUM, CBRIDNUM
having count(*)>1
- его результат оказался не пустым, а везде значение count(*)=2!!! То есть, в более чем 200000 записей, оказалось 146 дубликатов.
Теперь надо устранять дубликаты! - На сколько это может быть опасная процедура и как правильно её делать??
Вот выдержка из DDL таблицы:
ALTER TABLE AI_RAIDERS ADD CONSTRAINT PK_AI_RAIDERS PRIMARY KEY (POLNUM, CBRIDNUM);
Сделал запрос:
select
POLNUM, CBRIDNUM, count(*)
from AI_RAIDERS
group by POLNUM, CBRIDNUM
having count(*)>1
- его результат оказался не пустым, а везде значение count(*)=2!!! То есть, в более чем 200000 записей, оказалось 146 дубликатов.
Теперь надо устранять дубликаты! - На сколько это может быть опасная процедура и как правильно её делать??
Попробуй самый тупой способ (может повезёт):
1. create table x as select distinct все_колонки from AI_RAIDERS;
2.
select
POLNUM, CBRIDNUM, count(*)
from x
group by POLNUM, CBRIDNUM
having count(*)>1
Eсли будет пустой, значит повезло. Делай _обязательно_ backup. Дело за малым:
delete from AI_RAIDERS;
commit;
insert into AI_RAIDERS select * from x;
commit;
Далее восстанавливай pk.
Кстати, после удаления pk backup хорошо восстановиться.
1. create table x as select distinct все_колонки from AI_RAIDERS;
2.
select
POLNUM, CBRIDNUM, count(*)
from x
group by POLNUM, CBRIDNUM
having count(*)>1
Eсли будет пустой, значит повезло. Делай _обязательно_ backup. Дело за малым:
delete from AI_RAIDERS;
commit;
insert into AI_RAIDERS select * from x;
commit;
Далее восстанавливай pk.
Кстати, после удаления pk backup хорошо восстановиться.
- Игорь Акопян
- Сообщения: 1419
- Зарегистрирован: 13 окт 2004, 17:11
- Откуда: СПБ
- Контактная информация:
Laba, я правильно понимаю, что ваш способ предлагает без разбору просто убить одну из дубль-записей?
Нееее... не одну, а все без разбору.
И не сразу убить, а предварительно скопировать в другую таблицу и перед окончательным удалением сделать восстанавливаемый buсkup.
Часто из-за глюков появляются записи-дубликаты. У них значения во всех колонках совпадают со значениями в оригинале. В п.1. стоит DISTINCT без ограничений в WHERE, т.е. дубликаты "объединяться" с оригиналами.
И не сразу убить, а предварительно скопировать в другую таблицу и перед окончательным удалением сделать восстанавливаемый buсkup.
Часто из-за глюков появляются записи-дубликаты. У них значения во всех колонках совпадают со значениями в оригинале. В п.1. стоит DISTINCT без ограничений в WHERE, т.е. дубликаты "объединяться" с оригиналами.
- Игорь Акопян
- Сообщения: 1419
- Зарегистрирован: 13 окт 2004, 17:11
- Откуда: СПБ
- Контактная информация:
а если там дубли только по ключу?
Тогда запрос в п.2 будет не пустой - не повезло. В этом случае нужно думать.
При дубликатах только по ключу - возникает много вопросов. На них трудно ответить без описания конкретной ситуации.
При дубликатах только по ключу - возникает много вопросов. На них трудно ответить без описания конкретной ситуации.