Странная поломка базы

fraks
Дата: 25.05.2012 15:39:19
Firebird 2.1.3

В филиале случилась некая поломка базы.
При апдейте определенной конкретной записи в таблице на клиенте вылетает ошибка:

+
---------------------------
S5-localhost:d:\DB\KRAS\KRAS_GAMES.FDB
---------------------------
FrmRevisesEdit.QUpd:

Unsuccessful execution caused by a system error that precludes
successful execution of subsequent statements.

Internal gds software consistency check (cannot find record back version (291), file: vio.cpp line: 5034).

---------------------------
ОК
---------------------------


Вставка новой записи в эту таблицу или такой же апдейт но на другой записи к ошибке не приводит.

В логе сервера найдено такое:

+
SERVER (Server) Fri May 25 14:51:21 2012
Database: D:\FDB\GAMES.FDB
internal gds software consistency check (cannot find record back version (291), file: vio.cpp line: 5034)


База бэкапится и ресторится без каких-либо ошибок, но на отресторенной воспроизводится такая же фигня.

При проверке базы (IBExpert-ом) сразу после рестора ошибок не обнаруживается.

После чего произведя те же действия в базе ошибка опять воспроизводится.

Экспортирование всей базы в скрипт и воссоздание из скрипта ошибку устранило. Однако база "усохла" с 88,7мб до 83,5мб.

Никакие версии записей в бэкап не попадают.
Сравнение скрипта новой и старой базы различий не выявляют.
За счет чего усохла база?
Что это было?

На таблице есть триггер модифицирующий эту же таблицу.

+
CREATE GENERATOR GEN_ACCREV_ID;

CREATE TABLE ACCREV (
    ID        INTEGER NOT NULL,
    IDACCAGR  INTEGER NOT NULL,
    IDPOST    INTEGER NOT NULL,
    DATA      TIMESTAMP NOT NULL,
    SUMM      NUMERIC(18,2),
    COMMENT   VARCHAR(255) DEFAULT '',
    ACTIV     VARCHAR(1)
);

ALTER TABLE ACCREV ADD CONSTRAINT ACCREV_PK PRIMARY KEY (ID);

ALTER TABLE ACCREV ADD CONSTRAINT ACCREV_FK_IDACCAGR FOREIGN KEY (IDACCAGR) REFERENCES ACCAGR (ID);
ALTER TABLE ACCREV ADD CONSTRAINT ACCREV_FK_IDPOST FOREIGN KEY (IDPOST) REFERENCES SPOST (ID);

SET TERM ^ ;

CREATE OR ALTER TRIGGER ACCREV_BI FOR ACCREV
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW.ID IS NULL) THEN
    NEW.ID = GEN_ID(GEN_ACCREV_ID,1);
END
^

CREATE OR ALTER TRIGGER ACCREV_BIU_ACTIV FOR ACCREV
ACTIVE BEFORE INSERT OR UPDATE POSITION 0
as
begin
  -- автоматический сброс активности у сверок при установке новой активной
  if (NEW.activ = 'T') then begin
    update accrev set activ = '' where idaccagr = NEW.idaccagr;
  end --if
end
^

SET TERM ; ^
Гаджимурадов Рустам
Дата: 25.05.2012 15:45:54
Параметры рестора какие были (резервирование места и пр.) ?
fraks
Дата: 25.05.2012 15:49:47
Гаджимурадов Рустам
Параметры рестора какие были (резервирование места и пр.) ?


Ровно те же что и всегда

set gbak= e:\Programs\Firebird-2.1.3\BIN\gbak.exe -user SYSDBA -pass masterkey -v

Title Restore KRAS_GAMES

%gbak% -rep .\FBK\KRAS_GAMES.FBK ..\KRAS_GAMES.FDB

pause


т.е. все по дефолту.
fraks
Дата: 25.05.2012 15:52:20
перебэкап делается так:

set gbak=e:\Programs\Firebird-2.1.3\BIN\gbak.exe -v -user %USER% -pass %password%


%gbak%      -B KRAS_GAMES.FDB KRAS_GAMES.FBK
%gbak%      -c KRAS_GAMES.FBK KRAS_GAMES_N.FDB


Про -rep рассказывать ничего не надо :)
Dimitry Sibiryakov
Дата: 25.05.2012 15:53:02

fraks
CREATE OR ALTER TRIGGER ACCREV_BIU_ACTIVFOR ACCREV
ACTIVE BEFORE INSERT OR UPDATE POSITION0
as
begin
    -- автоматический сброс активности у сверок при установке новой активной
    if (NEW.activ ='T') then begin
      update accrev set activ='' where idaccagr=NEW.idaccagr;
    end  --if
end

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

Posted via ActualForum NNTP Server 1.5

Гаджимурадов Рустам
Дата: 25.05.2012 16:02:27
Dimitry Sibiryakov
fraks
CREATE OR ALTER TRIGGER ACCREV_BIU_ACTIVFOR ACCREV
ACTIVE BEFORE INSERT OR UPDATE POSITION0
as
begin
    -- автоматический сброс активности у сверок при установке новой активной
    if (NEW.activ ='T') then begin
      update accrev set activ='' where idaccagr=NEW.idaccagr;
    end  --if
end
За такой триггер руки разработчику базы надо отпиливать бензопилой. Вынеси идентификатор
активной сверки в другую таблицу. Или как минимум добавь условие, чтобы данная запись
повторно не апдейтилась.
Кстати, да - триггер хоть и без бесконечной рекурсии, но странный
и довольно жестокий (если под условие попадает много записей).
fraks
Дата: 25.05.2012 16:04:54
Dimitry Sibiryakov
fraks
CREATE OR ALTER TRIGGER ACCREV_BIU_ACTIVFOR ACCREV
ACTIVE BEFORE INSERT OR UPDATE POSITION0
as
begin
    -- автоматический сброс активности у сверок при установке новой активной
    if (NEW.activ ='T') then begin
      update accrev set activ='' where idaccagr=NEW.idaccagr;
    end  --if
end

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


Разработчик - я.
Проблем с триггером не было, хоть повторно там апдейтится хоть не повторно.
В таком виде работало несколько лет и в нескольких базах.
В этом триггере не вижу причин что бы вдруг перестало работать именно сегодня и именно на этой записи.
hvlad
Дата: 25.05.2012 16:07:19
fraks
База бэкапится и ресторится без каких-либо ошибок, но на отресторенной воспроизводится такая же фигня.
На 2.1.5\2.5.2 воспроизводится ?
fraks
Дата: 25.05.2012 16:09:04
Гаджимурадов Рустам
Кстати, да - триггер хоть и без бесконечной рекурсии, но странный
и довольно жестокий (если под условие попадает много записей).


Апдейтятся сверки по одному договору.
Обычное максимальное число сверок по одному договору - 5-7шт.
Так что ничего страшного не происходит.

Но согласен, что придраться есть к чему :)
fraks
Дата: 25.05.2012 16:10:11
hvlad
fraks
База бэкапится и ресторится без каких-либо ошибок, но на отресторенной воспроизводится такая же фигня.
На 2.1.5\2.5.2 воспроизводится ?


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