Ошибка при добавлении CHECK в таблицу

classic Classic list List threaded Threaded
33 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Ошибка при добавлении CHECK в таблицу

Andrei K.
Единственное подключение к БД. единственная транзакция. На выполнении
операции:

 ALTER TABLE gd_ref_constraints ADD
  CONSTRAINT gd_chk1_ref_contraint CHECK (ref_state IN ('ORIGINAL',
'TRIGGER'))

Получаю ошибку:

This operation is not defined for system tables.
unsuccessful metadata update.
DEFINE TRIGGER failed.
action cancelled by trigger (1) to preserve data integrity.
Cannot update trigger used by a CHECK Constraint.

Почему?

FB 2.5 RC3

Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Anton Zibrov
Andrei пишет:

> Единственное подключение к БД. единственная транзакция. На выполнении
> операции:
>
>  ALTER TABLE gd_ref_constraints ADD
>   CONSTRAINT gd_chk1_ref_contraint CHECK (ref_state IN ('ORIGINAL',
> 'TRIGGER'))
>
> Получаю ошибку:
>
> This operation is not defined for system tables.
> unsuccessful metadata update.
> DEFINE TRIGGER failed.
> action cancelled by trigger (1) to preserve data integrity.
> Cannot update trigger used by a CHECK Constraint.
>
> Почему?

IMHO, 'TRIGGER' зарезервированное слово

Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Dmitry Yemanov
In reply to this post by Andrei K.
20.07.2010 16:42, Andrei пишет:

> Единственное подключение к БД. единственная транзакция. На выполнении
> операции:
>
>   ALTER TABLE gd_ref_constraints ADD
>    CONSTRAINT gd_chk1_ref_contraint CHECK (ref_state IN ('ORIGINAL',
> 'TRIGGER'))
>
> Получаю ошибку:
>
> This operation is not defined for system tables.
> unsuccessful metadata update.
> DEFINE TRIGGER failed.
> action cancelled by trigger (1) to preserve data integrity.
> Cannot update trigger used by a CHECK Constraint.
>
> Почему?

А другой CHECK на этой таблице есть? IMHO, что-то не то записано в
метаданных. После бекап-рестора проблема остается?


Дмитрий

Reply | Threaded
Open this post in threaded view
|

Re: ïÛÉÂËÁ ÐÒÉ ÄÏÂÁ×ÌÅÎÉÉ CHECK × ÔÁÂÌÉÃÕ

Alex Cherednichenko
In reply to this post by Anton Zibrov
Hello, Anton!
You wrote  on Tue, 20 Jul 2010 17:35:49 +0300:

 AZ> IMHO, 'TRIGGER' зарезервированное слово

Да, да.
Прям так в кавычках и зарезервировали.

--
With best regards, Alex Cherednichenko.


Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
In reply to this post by Dmitry Yemanov
1) после бэкап-рестора тоже самое
2) gfix не проходит (см. отд ветку в этой группе)
3) табличка создается предварительно так:

CREATE TABLE gd_ref_constraints (
  id               dintkey,
  constraint_name  d_fk_metaname UNIQUE,
  const_name_uq    d_fk_metaname,
  match_option     char(7)  character set none,
  update_rule      char(11) character set none,
  delete_rule      char(11) character set none,

  constraint_rel   d_fk_metaname,
  constraint_field d_fk_metaname,
  ref_rel          d_fk_metaname,
  ref_field        d_fk_metaname,

  ref_state        char(8) character set none,
  ref_next_state   char(8) character set none,

  constraint_rec_count COMPUTED BY (
    (SELECT iif(i.rdb$statistics = 0, 0, Trunc(1/i.rdb$statistics +
0.5)) FROM rdb$indices i
      JOIN rdb$relation_constraints rc ON rc.rdb$index_name = i.rdb
$index_name
      WHERE rc.rdb$relation_name = constraint_rel AND rc.rdb
$constraint_type = 'PRIMARY KEY')),

  constraint_uq_count COMPUTED BY (
    (SELECT iif(i.rdb$statistics = 0, 0, Trunc(1/i.rdb$statistics +
0.5)) FROM rdb$indices i
      JOIN rdb$index_segments iseg ON iseg.rdb$index_name = i.rdb
$index_name
        AND iseg.rdb$field_name = constraint_field
      JOIN rdb$relation_constraints rc ON rc.rdb$index_name = i.rdb
$index_name
      WHERE i.rdb$relation_name = constraint_rel AND i.rdb
$segment_count = 1 AND rc.rdb$constraint_type = 'FOREIGN KEY')),

  ref_rec_count COMPUTED BY (
    (SELECT iif(i.rdb$statistics = 0, 0, Trunc(1/i.rdb$statistics +
0.5)) FROM rdb$indices i
      JOIN rdb$relation_constraints rc ON rc.rdb$index_name = i.rdb
$index_name
      WHERE rc.rdb$relation_name = ref_rel AND rc.rdb$constraint_type
= 'PRIMARY KEY')),

  CONSTRAINT gd_pk_ref_constraint PRIMARY KEY (id)
)

4) проблема в том, что проявляется это на конкретной базе, которая тем
не менее проходит бэкап-рестор.
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
In reply to this post by Dmitry Yemanov
я переслал на dimitr[at]users.sourceforge.net архив (13 Мб). Там бэкап
базы и скрипт, который кидает ошибку. На других базах, этот же скрипт
отрабатывает нормально.
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
Похоже, что email изменился. Подскажите, куда слать?
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
In reply to this post by Dmitry Yemanov
базу переслал.

теперь столкнулся с проблемой уже на другой базе. безобидный оператор

alter domain dboolean set default 0

кидает ошибку

"action cancelled by trigger (1) to preserve data integrity
Cannot update trigger used by a CHECK Constraint"

домен определен как:

create domain dboolean
as smallint
check((value is null) or (value in ('0', '1')))

Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
In reply to this post by Dmitry Yemanov
пожалуйста, сообщите удалось ли повторить ошибку. Надо ли делать
запись в треккер или достаточно email-а?
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Dmitry Yemanov
22.07.2010 16:37, Andrei пишет:
> пожалуйста, сообщите удалось ли повторить ошибку. Надо ли делать
> запись в треккер или достаточно email-а?

Удалось. Регистрировать пока не надо, скажу если что.


Дмитрий

Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Dmitry Yemanov
У тебя в системных таблицах какой-то ужас. Два разных чека на разных
таблицах ссылаются на один и тот же системный триггер. Т.е. половина
чеков вообще работать не может в этой базе. А при создании новых лезут
ошибки из-за этого, т.к. внутренняя валидация не проходит.

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


Дмитрий

Reply | Threaded
Open this post in threaded view
|

Re[2]: Ошибка при добавлении CHECK в таблицу

Sergey Mereutsa
Привет!

> У тебя в системных таблицах какой-то ужас. Два разных чека на разных

А подобные ужастики валидация всегда находит или-таки бывают случаи,
когда пока не наступишь - не обнаружится?


--
Best regards,
 Sergey                            mailto:[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Dmitry Yemanov
23.07.2010 18:28, Sergey Mereutsa пишет:

> А подобные ужастики валидация всегда находит или-таки бывают случаи,
> когда пока не наступишь - не обнаружится?

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


Дмитрий

Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
In reply to this post by Dmitry Yemanov

и у меня уже не одна такая база :(

очень надеюсь, что среди баз размером 25-40 Гб таких
битых не окажется. Так как пересоздание их через скрипт
мягко говоря не реально.

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

в процессе апгрейда gbak-ом с Yaffil на 2.5 такой поломки не
может произойти?
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Yurij
On Jul 24, 2:02 am, Andrei <[hidden email]> wrote:
> и у меня уже не одна такая база :(
> очень надеюсь, что среди баз размером 25-40 Гб таких
> битых не окажется. Так как пересоздание их через скрипт
> мягко говоря не реально.

А вот, кстати, откуда такая религия, что пересоздать эти базы через
скрипт нереально?

Ну трудозатратно, конечно, размер большой, логика в БД, а уж если там
такие проблемы
с системными таблицами, запросто может оказаться, что процесс
пересоздания и заливки
данных с первого раза не отработает. Но тем не менее, это в некотором
роде решение
всех проблем раз и навсегда, главное чтобы оно успело за разумное
время отработать.
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Dmitry Yemanov
In reply to this post by Andrei K.
24.07.2010 3:02, Andrei пишет:
>
> перегонка через скрипт -- это единственный вариант? может
> удалить проблемные записи из системных таблиц и пересоздать
> соответствующие чеки?

Тогда уж удалить все чеки и пересоздать их. После удаления проверить,
чтобы rdb$check_constraints была пустой.

> в процессе апгрейда gbak-ом с Yaffil на 2.5 такой поломки не
> может произойти?

Вроде не должно. Но зуб не дам. Я бы с удовольствием поглядел, как такое
на практике получается, но пока никаких мыслей нет...

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


Дмитрий

Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
In reply to this post by Yurij
>
> А вот, кстати, откуда такая религия, что пересоздать эти базы через
> скрипт нереально?
>

в общем случае -- реально. Но, есть частные случаи: предприятия с
круглосуточным циклом производства и базами более 30 Гб. Для db
maintenance реально доступно время с 8:00 воскресенья до 18:00
воскресенья. Такая база врядли перельется за 10 час.

Кстати, чем переливать? IBExpert?
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Yurij


On Jul 24, 11:38 am, Andrei <[hidden email]> wrote:
> > А вот, кстати, откуда такая религия, что пересоздать эти базы через
> > скрипт нереально?
>
> в общем случае -- реально. Но, есть частные случаи: предприятия с
> круглосуточным циклом производства и базами более 30 Гб. Для db
> maintenance реально доступно время с 8:00 воскресенья до 18:00
> воскресенья. Такая база врядли перельется за 10 час.
> Кстати, чем переливать? IBExpert?

Я бы сделал специально под это дело заточенный набор утилит - сначала,
не останавливая базу, проверить, что констрейнты действительно
выполнены, затем создать новую, перелить статические справочники,
затем остановить рабочую, перелить рабочие таблицы и затем создать
индексы. Само собой, держать на разных физических дисках оригинал и
новую базу.
А для оценки времени переливания - возьми сумму времен backup+restore
на этом же сервере.
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Dmitri Kuzmenko
Hello, Yurij!

Yurij wrote:

> Я бы сделал специально под это дело заточенный набор утилит - сначала,
> не останавливая базу, проверить, что констрейнты действительно

сначала надо ПРОВЕРИТЬ всю процедуру на копии базы на отдельной тачке :-)

> выполнены, затем создать новую, перелить статические справочники,
> затем остановить рабочую, перелить рабочие таблицы и затем создать
> индексы. Само собой, держать на разных физических дисках оригинал и
> новую базу.
> А для оценки времени переливания - возьми сумму времен backup+restore
> на этом же сервере.

этого мало. А так по процедуре вроде все ок.

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

--
Dmitri Kouzmenko, www.ibase.ru, (495) 953-13-34


Reply | Threaded
Open this post in threaded view
|

Re: Ошибка при добавлении CHECK в таблицу

Andrei K.
In reply to this post by Dmitry Yemanov
я так понимаю проверить базу на битость можно таким запросом:

select
  c.rdb$constraint_name,
  t.*
from
  rdb$check_constraints c join rdb$triggers t
    on c.rdb$trigger_name = t.rdb$trigger_name
where
  exists (
    select *
    from rdb$check_constraints c2 join rdb$triggers t2
      on c2.rdb$trigger_name = t2.rdb$trigger_name
    where
      c2.rdb$constraint_name <> c.rdb$constraint_name
      and c2.rdb$trigger_name = c.rdb$trigger_name)

?
12