powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / RC, select id from T order by id DESC rows 1: не понимаю рез-т при интенс. вставках в <T>
2 сообщений из 2, страница 1 из 1
RC, select id from T order by id DESC rows 1: не понимаю рез-т при интенс. вставках в <T>
    #38703280
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hi all

Есть вот такой скриптик:
file = `inf.sql`
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
set term ^;
execute block as
begin
  begin execute statement 'drop sequence g'; when any do begin end end
end
^
set term ;^
commit;

create sequence g;
commit;

recreate table t(id int);
commit;
create descending index t_id_desc on t(id);
commit;
set term ^;
execute block as
declare n int = 500000;
declare i int;
begin
    while (1=1) do
    begin
       in autonomous transaction do
       begin
          i=0;
          while (i<n) do
          begin
              insert into t(id) values( gen_id(g,1) );
              i = i + 1;
          end
          rdb$set_context('USER_SESSION','INFIN_LOOP_CURR_GEN', gen_id(g,0));
       end
   end
end
^
set term ;^
commit;
Он в бесконечном цикле стартует автономную трн, в которой делает 500 тыс вставок в таблицу T. Вставки идут в поле ID, с использованием gen_id(g, +1 ), но по этому полю есть убывающий индекс.
Это значит, что при навигации по этому индексу мы будем видеть примерно вот это:
момент времениключи индекса T_ID_DESC при навигации по немуt11t22; 1t33; 2; 1t4 4; 3; 2; 1t55; 4; 3; 2; 1. . .. . .Когда автономка добавит свою порцию строк (в тексте скрипта их 500 тыс), то перед самым своим коммитом она задаст значение контекстной переменной 'INFIN_LOOP_CURR_GEN', равное текущему значению генератора. Очевидно, оно будет расти с шагом, равным числу добавленных строк.

Теперь делаю так:

Код: plaintext
1.
2.
 session #1 
SQL> in inf.sql; -- понеслось в бескон. цикле...

Код: plaintext
 session #2.  
Периодически запускаю:
Код: plaintext
SQL> commit; set transaction read committed; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

Вижу в окне сессии-2:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
SQL> commit; set transaction read committed; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
      207133                500000

SQL> commit; set transaction read committed; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
      710285               1000000

SQL> commit; set transaction read committed; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
     1236675               1500000

SQL> commit; set transaction read committed; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
     1625762               2000000

SQL> commit; set transaction read committed; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
     2120415               2500000

Как видим, значения в столбе "CURR_G" идут с шагом = 500 тыс - т.е. это значит, что select-стейтмент в сессии-2 может возвращать данные из таблицы только тогда, когда в окне-1 будет выполнен commit автономки.
Это подтверждается и трейсом.
Вот что он показывает для сессии-1:
установка context-переменной + commit произошли в 18:30:32.7770
Код: plaintext
1.
2.
3.
4.
2014-07-22T 18:30:32.7770  (1010:0x7fa91b4c5670) SET_CONTEXT
	/var/db/fb30/tmp30.fdb (ATT_11, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
	/opt/fb30trnk/bin/isql:4876
		(TRA_84, CONCURRENCY | WAIT | READ_WRITE)
[USER_SESSION] INFIN_LOOP_CURR_GEN = "500000"
И вот что для сессии-2:
стейтмент завершился в 18:30:32.8560
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
2014-07-22T 18:30:32.8560  (1010:0x7fa91b4c2288) EXECUTE_STATEMENT_FINISH
	/var/db/fb30/tmp30.fdb (ATT_12, SYSDBA:NONE, NONE, TCPv4:127.0.0.1)
	/opt/fb30trnk/bin/isql:4895
		(TRA_85, READ_COMMITTED | NO_REC_VERSION | WAIT | READ_WRITE)

Statement 180:
-------------------------------------------------------------------------------
select id, gen_id(g,0) curr_g from t order by id desc rows 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PLAN (T ORDER T_ID_DESC)
1 records fetched
   6473 ms, 9 fetch(es)

Table                             Natural     Index    Update    Insert    Delete   Backout     Purge   Expunge
***************************************************************************************************************
T                                                 1    


И это выглядит странно.
Потому что когда в RC-транзакции стартует этот самый select <...> order by id desc rows 1, то он, конечно, может видеть закоммиченные данные после своего старта, но причём тут новые ID'шники, которые поступают в левый хвост листового уровня индекса уже после старта данного селекта ? Допустим, на момент старта селекта в индекса были ключи: 100; 99; 98; ... 10; 9; 8; ... ; 1 - причём, к закоммиченным данным относились только эти: "10; 9; 8; ... ; 1".
Дальше, согласно плану ORDER T_ID_DESC, этот селект должен начать с ключа 100, затем идти вправо и остановиться на ключе 10 - и выдать его.
С какого перепугу он, селект этот, должен видеть новые ключи (101, 102 етц), которые прут в это время от сессии-1 и ложатся левее того ключа, с которого началась навигация ? Выполняется ли "рестарт" этой самой навигации в случае, когда листовой уровень пополняется слева новым ключами ?

И еще. Хотя CURR_G выдаётся строго с шагом = 500 тыс, значение ID'шника от него всё время отстаёт. Дифферент равен примерно половине от шага (чуть меньше). Если селект в сессии-2 смог вернуть данные только тогда, когда сессия-1 закоммитилась (судя по значениям генератора), то что помешало ему увидеть актуальное на тот момент значение ID ?
...
Рейтинг: 0 / 0
RC, select id from T order by id DESC rows 1: не понимаю рез-т при интенс. вставках в <T>
    #38703368
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прояснилось. Спасибо ДЕ за промыв мозга: по дефолту RC работает как no record_version.
Как только добавил кляузу, так сразу и зашелестело:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SQL> commit; set transaction read committed record_version; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
      416813                500000

SQL> commit; set transaction read committed record_version; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
      500000                590624

SQL> commit; set transaction read committed record_version; select id, gen_id(g,0) curr_g from t order by id desc rows 1;

          ID                CURR_G
============ =====================
      500000                676841
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / RC, select id from T order by id DESC rows 1: не понимаю рез-т при интенс. вставках в <T>
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]