Остановка после 1,000,000,000 транзакций

Билл Карвин, InterBase Software Corp.

Номер транзакции в IB хранится как 32-разрядное целое число, поэтому количество транзакций легко может достигнуть 2 миллиардов. Это справедливо для InterBase на всех платформах.

Однако существует ограничение, когда IB не может стартовать новую транзакцию если разница между новым номером транзакции и старейшей заинтересованной транзакцией (OIT. Подробнее на эту тему см. документ) составляет 2 миллиарда (знаковое целое, MaxInt). "Заинтересованной" является транзакция "подтвержденная", "отменная", "активная", или "отложенная".

Утилита GSTAT покажет вам значения OIT и следующей транзакции. Эти номера не должны сильно отличаться. Если разница между ними выросла в 50,000 и более, то это является предупреждающим сигналом о том, что в БД находится транзакция, мешающая OIT повысить свой номер.

Примите во внимание, что информация о транзакциях (TIP) копируется в память, распределяемую IB для каждого клиента. Если там много транзакций (900,000 и выше), то это уже значительный объем памяти. Кстати, именно благодаря копии TIP для клиента IB обрабатывает транзакции Repeatable Read: каждый клиент получает состояние всех транзакций на момент старта собственной транзакции. Состояния транзакций в клиентской копии TIP указывают, может клиент видеть конкретную версию записи или нет: если версия создана с идентификатором транзакции, которая в TIP указана как committed (подтвержденная), то версия видна.

Вы можете несколькими способами предотвратить "застой" номера OIT:

  • backup и последующее restore очистит TIP полностью, поэтому номера OIT и следующей транзакции будут около 3 (после восстановления БД выполняются несколько транзакций для загрузки данных и построения индексов).
  • gfix -sweep вычистит из БД ненужные версии записей и упростит цепочки версий. По умолчанию интервал sweep равен 20,000. Но пока клиенты работают, sweep не может выполниться в монопольном режиме и изменить состояние TIP.
  • Если вы не произвели в транзакции никаких действий кроме чтения, то завершайте ее подтверждением (commit). Дело в том, что отмененная транзакция (rollback) создает "заинтересованную" транзакцию. Если в такой транзакции не было изменений, то она только засорит TIP.

  • Кузьменко Дмитрий, iBase

    В исходном варианте вышеприведенного документа было ошибочно указано предельное значение разницы между OIT и OAT в 1 миллион транзакций. На самом деле эта разница может быть не более 1 миллиарда. Точнее, не больше 1073741824. То, что разница между OIT и OAT или вообще количество транзакций может быть больше миллиона (1,000,000), подтверждается простым тестом:

    1. Создайте базу данных
    2. Откройте эту базу данных в WISQL или Database Explorer, чтобы создать "заинтересованную" транзакцию.
    3. Создайте приложение с использованием FreeIBComponents, используя компоненты FIBDatabase, FIBTransation, пару TButton и TLabel:

    const 
     stop: boolean = False; 
     cnt: integer = 0; 
    procedure TForm1.Button1Click(Sender: TObject); 
    begin 
      FIBDatabase1.Connected:=True; 
      while not stop do 
         begin 
            Inc(cnt); 
            FIBTransaction1.StartTransaction; 
            FIBTransaction1.Commit; 
            Label1.Caption:=IntToStr(cnt); 
            Application.ProcessMessages; 
         end; 
    end; 
    procedure TForm1.Button2Click(Sender: TObject); 
    begin 
      Stop:=True; 
    end; 

    4. Запустите приложение и ждите.

    Лично у меня терпения хватило дождаться 2,084,586-ой транзакции (работа приложения в течение 4-х часов), при этом статистика по базе данных выглядела следующим образом:

    Database "c:\t.gdb" 
    Database header page information: 
    Flags                      0 
    Checksum               12345 
    Generation           2084607 
    Page size               1024 
    ODS version              9.1 
    Oldest transaction   1044689 
    Oldest active        1044690 
    Oldest snapshot      1044690 
    Next transaction     2084600 
    Bumped transaction         1 
    Sequence number            0 
    Next attachment ID         0 
    Implementation ID         16 
    Shadow count               0 
    Page buffers               0 
    Next header page           0 
    Creation date       Aug 25, 1999 12:17:52 
    Variable header data: 
    Sweep interval:              0 
    *END*