Умирают индексы и внешние ключи
Умирают индексы и внешние ключи
InterBase 7.5.0.174
Ситуация по логике: добавляется запись, потом вызывается хранимая процедура, которая по некоторой логике эту запись разбивает на несколько (в исходной записи есть число, после разбития сумма чисел в полученных записях равно исходной). Временами возникают условия, при которой разбить на несколько записей не удается, в этом случае процедура вызывает EXCEPTION EX_NAME;
Теперь проблема: если добавить запись, сделать Commit, а потом вызвать процедуру, то просто получаю Exception.
Если добавить запись и НЕ делая Commit вызвать процедуру, то:
1) "слетают" (corrupt) все внешние ключи в этой таблице
2) слетают все индексы этой таблицы, в которых есть указание одного из полей внешних ключей
3) умирает часть внешних ключей в других таблицах (эти таблицы в процедуре используются только для SELECT)
Попытки использовать в приложении SavePoint никаких результатов не дали.
Временное решение получено: расстановка в процедуре некоторого кол-ва флагов с дополнительными SELECT'ами, но из-за этого увеличилось время выполнения процедуры.
Непонятна причина падения индексов, несмотря на то, что всё, что эта транзакция делает RollBack при получении ошибки.
При этом, обращу еще раз внимание: если сделать Commit записи, а потом начать новую транзакцию -- всё работает без повреждений базы, если транзакцию не коммитить, а пытаться провести действия сразу после добавления, то индексы умирают.
PS: для доступа в приложении используется IBX11
Ситуация по логике: добавляется запись, потом вызывается хранимая процедура, которая по некоторой логике эту запись разбивает на несколько (в исходной записи есть число, после разбития сумма чисел в полученных записях равно исходной). Временами возникают условия, при которой разбить на несколько записей не удается, в этом случае процедура вызывает EXCEPTION EX_NAME;
Теперь проблема: если добавить запись, сделать Commit, а потом вызвать процедуру, то просто получаю Exception.
Если добавить запись и НЕ делая Commit вызвать процедуру, то:
1) "слетают" (corrupt) все внешние ключи в этой таблице
2) слетают все индексы этой таблицы, в которых есть указание одного из полей внешних ключей
3) умирает часть внешних ключей в других таблицах (эти таблицы в процедуре используются только для SELECT)
Попытки использовать в приложении SavePoint никаких результатов не дали.
Временное решение получено: расстановка в процедуре некоторого кол-ва флагов с дополнительными SELECT'ами, но из-за этого увеличилось время выполнения процедуры.
Непонятна причина падения индексов, несмотря на то, что всё, что эта транзакция делает RollBack при получении ошибки.
При этом, обращу еще раз внимание: если сделать Commit записи, а потом начать новую транзакцию -- всё работает без повреждений базы, если транзакцию не коммитить, а пытаться провести действия сразу после добавления, то индексы умирают.
PS: для доступа в приложении используется IBX11
www.ibase.ru/devinfo/allversions.htm
апдейты на офсайте. Надо 7.5.1 SP 1
апдейты на офсайте. Надо 7.5.1 SP 1
что-то страшное... либо какой то неизвестный ранее баг (нам не попадалось), либо стечение обстоятельств, и на машинке есть кривое железо.Если добавить запись и НЕ делая Commit вызвать процедуру, то:
1) "слетают" (corrupt) все внешние ключи в этой таблице
проверки на InterBase 7.5.0.174 и на InterBase 7.5.1.162 дали одинаковые результаты
использование советов из http://ibase.ru/devinfo/ibstp.htm также не дало результатов
может быть ошибка возникает при большом кол-ве вложенности вызовов процедур:
главная процедура -> процедура 2 -> процедура 3 -> процедура 4 -> процедура 5 (в которой появляется Exception)
?
до тех пор пока Exception вызывался в 3-ем уровне, проблем не возникало, но заказчиком были поставлены требования, которые привели к такому вот разрастанию вызовов (в БД вшита вся логика, а в ПО идет просто вызов процедур без каких-либо проверок, по требованию заказчика)
но на какие-либо ограничения по вложенности процедур не удалось найти информации
из попыток локализовать ошибку выяснилось, что именно в таком вызове "процедура 5" индексы становятся corrupt, при вызове "процедура 5" из главной процедуры (там где эти вызовы по логике нужны) появляется Exception, но индексы остаются целыми
PS: к "парку" тестовых машин добавилось 2 ноутбука (тестировалось на InterBase 7.5.1.162) -- результаты точно такие же...
использование советов из http://ibase.ru/devinfo/ibstp.htm также не дало результатов
может быть ошибка возникает при большом кол-ве вложенности вызовов процедур:
главная процедура -> процедура 2 -> процедура 3 -> процедура 4 -> процедура 5 (в которой появляется Exception)
?
до тех пор пока Exception вызывался в 3-ем уровне, проблем не возникало, но заказчиком были поставлены требования, которые привели к такому вот разрастанию вызовов (в БД вшита вся логика, а в ПО идет просто вызов процедур без каких-либо проверок, по требованию заказчика)
но на какие-либо ограничения по вложенности процедур не удалось найти информации
из попыток локализовать ошибку выяснилось, что именно в таком вызове "процедура 5" индексы становятся corrupt, при вызове "процедура 5" из главной процедуры (там где эти вызовы по логике нужны) появляется Exception, но индексы остаются целыми
PS: к "парку" тестовых машин добавилось 2 ноутбука (тестировалось на InterBase 7.5.1.162) -- результаты точно такие же...
Да тоже столкнулись с подобной проблемой, вложенность тут не причем.
Создаем таблицы
CREATE TABLE A (
ID INTEGER NOT NULL,
B_ID INTEGER
);
ALTER TABLE A ADD CONSTRAINT PK_A PRIMARY KEY (ID);
CREATE TABLE B (
ID INTEGER NOT NULL,
NAME VARCHAR(20)
);
INSERT INTO B (ID, NAME) VALUES (1, 'www');
COMMIT WORK;
ALTER TABLE B ADD CONSTRAINT PK_B PRIMARY KEY (ID);
ALTER TABLE A ADD CONSTRAINT FK_A_1 FOREIGN KEY (B_ID) REFERENCES B (ID);
И процедуру:
CREATE PROCEDURE PP (
ID INTEGER)
AS
begin
update a set id=id where id=:id;
update a set b_id=1 where id=:id;
exception EX_PERM;
end
И выполняем в одной транзакции:
INSERT into A (id, b_id) values (1,null);
EXECUTE PROCEDURE pp(1);
делаем commit;
все FK битый,
select * from a where b_id is null ничего не дает, хотя запись есть.
Если сделать commit после вставки все ок.
Если в процедуре убрать первый UPDATE тоже все ок.
Обновлять можно любое поле не id результат тотже!
Создаем таблицы
CREATE TABLE A (
ID INTEGER NOT NULL,
B_ID INTEGER
);
ALTER TABLE A ADD CONSTRAINT PK_A PRIMARY KEY (ID);
CREATE TABLE B (
ID INTEGER NOT NULL,
NAME VARCHAR(20)
);
INSERT INTO B (ID, NAME) VALUES (1, 'www');
COMMIT WORK;
ALTER TABLE B ADD CONSTRAINT PK_B PRIMARY KEY (ID);
ALTER TABLE A ADD CONSTRAINT FK_A_1 FOREIGN KEY (B_ID) REFERENCES B (ID);
И процедуру:
CREATE PROCEDURE PP (
ID INTEGER)
AS
begin
update a set id=id where id=:id;
update a set b_id=1 where id=:id;
exception EX_PERM;
end
И выполняем в одной транзакции:
INSERT into A (id, b_id) values (1,null);
EXECUTE PROCEDURE pp(1);
делаем commit;
все FK битый,
select * from a where b_id is null ничего не дает, хотя запись есть.
Если сделать commit после вставки все ок.
Если в процедуре убрать первый UPDATE тоже все ок.
Обновлять можно любое поле не id результат тотже!
Выпрямляю руки, дёшево
Таблица битая уже в этот момент. Дальнейшие приключения с FK могут быть следствиями, хотя может и сами по себе мальчики (С). Структуры метаданных создаются на коммите, сам Create - только протокол о намерениях То есть, перед Insert должен быть ещё один коммит. Ну и создание констрайнтов тоже следует коммитить перед DML-операциями.Felix1978 писал(а): CREATE TABLE B (
ID INTEGER NOT NULL,
NAME VARCHAR(20)
);
INSERT INTO B (ID, NAME) VALUES (1, 'www');
COMMIT WORK;
Умник, проблема не в этом создай все с коммитами после каждого действия. Можешь потом подключиться снова и выполнить 3 действия результат битый ключ!Таблица битая уже в этот момент. Дальнейшие приключения с FK могут быть следствиями, хотя может и сами по себе мальчики (С). Структуры метаданных создаются на коммите, сам Create - только протокол о намерениях То есть, перед Insert должен быть ещё один коммит. Ну и создание констрайнтов тоже следует коммитить перед DML-операциями.
Проблема в том, что при вызове Insert->процедура на update->потом commit и все ж....
Причем в процедуре должно быть 2 update этой записи. А если сделать commit между insert и процедурой все ок!
Есть мысли у кого-нибудь?
1. По begin..end см. "savepoints", "system savepoints". Проблема явно в них.
2. Хамите, парниша? Можешь не писать - не пиши.
3. Делать можно всё. Ты явно нарвался на какой-то глюк (или "особенность") работы IB. Глюки не документируют, их исправляют. И посоветовали тебе не "совсем не делать", а "так не делать, обойти проблему".
2. Хамите, парниша? Можешь не писать - не пиши.
3. Делать можно всё. Ты явно нарвался на какой-то глюк (или "особенность") работы IB. Глюки не документируют, их исправляют. И посоветовали тебе не "совсем не делать", а "так не делать, обойти проблему".
-
- Сообщения: 1
- Зарегистрирован: 11 апр 2008, 15:54
Человек просил конструктивный совет, а вы выливаете ему какой-то шлак. А его "хамство" это результат на ваше хамство (см пост мерина)... и модератору, если он не слеп на один глаз, следовало бы обратить внимание и выставить предупреждение сначало на этот пост.
А проблема действительно серьезная. У меня подобное происходит тоже на ИБ7.5 и ИБ2007. Интересно есть ли такое в MSSQL?
из примерчика получается что индексы не откатываются при эксепшенах...
Выход - делать коммит после инсерта (если можно)
А проблема действительно серьезная. У меня подобное происходит тоже на ИБ7.5 и ИБ2007. Интересно есть ли такое в MSSQL?
из примерчика получается что индексы не откатываются при эксепшенах...
Выход - делать коммит после инсерта (если можно)
И ему дали конструктивный совет - так не делать, обойти проблему.PostMan007 писал(а):Человек просил конструктивный совет
Кто-то из фанатов MS уже активно использует их новый, версионный, движок?PostMan007 писал(а):Интересно есть ли такое в MSSQL?
В FB, кстати, такой проблемы нет. Я уже намекнул, что похоже на баг в IB.