Остановка после 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;
  1. Запустите приложение и ждите. Лично у меня терпения хватило дождаться 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*

Подпишитесь на новости Firebird в России

Подписаться