powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
8 сообщений из 33, страница 2 из 2
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500458
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrТы до какого-то бреда уже докопался, ей богу.OK, оставим это :-)
Вернёмся к перечитке страниц с диска.

Вот DDL, тут в новой базе с page_size=4096 создается табличка, одно из полей которой есть varchar(32760). И заполняется оно так, чтобы никакое RLE-сжатие не катило:
Код: sql
1.
2.
3.
4.
SQL> create sequence g; commit;
SQL> recreate table t(id int, s varchar(32760)); commit;
SQL> create index t_id on t(id); commit;
SQL> insert into t3 select gen_id(g,1), rpad('', 32760, uuid_to_char(gen_uuid())) from rdb$types,rdb$types rows 1000; commit;


Далее смотрим в gstat: в базе 196 страниц (якобы; но мы-то все знаем, что в 2.5 показываются только страницы, относящиеся к хвостам-огрызкам длинных записей)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
gstat empty25 -r -t T
Analyzing database pages ...
T (128)
    Primary pointer page: 165, Index root page: 166
    Average record length: 33008.39, total records: 1000
    Average version length: 0.00, total versions: 0, max versions: 0
     Data pages: 196 , data page slots: 196, average fill: 87%
    Fill distribution:
         0 - 19% = 4
        20 - 39% = 2
        40 - 59% = 0
        60 - 79% = 0
        80 - 99% = 190

Теперь делаем следующее.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
 step 1. Коннект-1. 
SQL> out nul;
SQL> set stat off; select * from t where id=1; set stat on;
SQL> select * from t where id=1;
Reads = 0 -- OK, вся длинная запись была в кеше, на диск не лезли

 step 2. Коннект-2. 
-- апдейтим запись, которая находится стопудово не на той же странице, что с id=1:
SQL> update t set s=null where id=999;

 step 3. Коннект-1. 
SQL> select * from t where id=1;
Reads = 1 -- хоп! откудова это ? ведь коннект-2 на 99.(9)% не мог запрашивать эту же страницу!

 step 4. Коннект-2. 
SQL> rollback;

 step 5. Коннект-1. 
SQL> select * from t where id=1;
Reads = 1 -- опять!

PS.
И какие бы записи я не апдейтил в коннекте-2, коннект-1 при перечитке своей записи с id=1 каждый раз лезет на диск:
Код: plaintext
1.
2.
3.
4.
5.
SQL connect-2> update t set s=null where id=555;
   SQL connect-1> select * from t where id=1; -- ==> reads=1
SQL connect-2> update t set s=null where id=888;
   SQL connect-1> select * from t where id=1; -- ==> reads=1
SQL connect-2> update t set s=null where id=444;
   SQL connect-1> select * from t where id=1; -- ==> reads=1
...
Рейтинг: 0 / 0
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500636
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

а с чего ты взял, что перечитывается именно страница данных? Ты смотрел на счетчик page writes на шагах 2 и 4? В первом случае наверняка изменяется pointer page (ибо твой апдейт приводит к выделению новой страницы), которую запросто может захотеть перечитать коннект 1. Во втором случае он наверняка будет перечитывать измененную TIP.
...
Рейтинг: 0 / 0
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500703
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitrТы смотрел на счетчик page writes на шагах 2 и 4?сорри, я там ошибся: делал вставку в таблицу t 3 , которая уже балы в этой базе, да еще и структура у неё та же самая оказалась :(

Сделал всё с самого начала. Странности всё-таки есть. Лезут.
Всех, кому интересно, прошу проверить у себя, на базе с page_size = 4096 , charset = none. ФБ 2.5, в архитектуре SuperClassic .

Вот DDL :
Код: sql
1.
2.
3.
4.
SQL> recreate table t(id int, s varchar(32760)); commit;
SQL> create index t_id on t(id); commit;
SQL> insert into  t  select gen_id(g,1), rpad('', 32760, uuid_to_char(gen_uuid())) from rdb$types,rdb$types rows 1000; commit;
SQL> quit;



Далее:

Код: 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.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
 Коннект-1. 
Database:  192.168.0.201/3252:empty25
-- вычитываем в кеш:
SQL> out nul; select cast(right(s,10) as varchar(10)) rs,current_timestamp dts from t where id=1; out; set stat on;
-- проверяем, что на диск больше лезть не надо:
SQL> select cast(right(s,10) as varchar(10)) rs,current_timestamp dts from t where  id = 1 ;

RS                               DTS
========== =========================
C7402EA022 2013-12-13 23:53:54.5810

Current memory = 1543088
Delta memory = 0
Max memory = 1581632
Elapsed time= 0.02 sec
Buffers = 256
 Reads = 0  -- ОК, так и есть
Writes 0
Fetches = 19

 Коннект-2. 
C:\MIX\firebird\fb25>isql 192.168.0.201/3252:empty25 -n -c 256
Database:  192.168.0.201/3252:empty25
SQL> update t set s=null where id  = 4 ;

 Коннект-1. 
SQL> select cast(right(s,10) as varchar(10)) rs,current_timestamp dts from t where id = 1;

RS                               DTS
========== =========================
C7402EA022 2013-12-13 23:54:10.8780

Current memory = 1543088
Delta memory = 0
Max memory = 1581632
Elapsed time= 0.01 sec
Buffers = 256
 Reads = 1
Writes 0 
Fetches = 19

 Коннект-2. 
SQL> rollback;

 Коннект-1. 
SQL> select cast(right(s,10) as varchar(10)) rs,current_timestamp dts from t where id=1;

RS                               DTS
========== =========================
C7402EA022 2013-12-13 23:54:20.6590

Current memory = 1543088
Delta memory = 0
Max memory = 1581632
Elapsed time= 0.01 sec
Buffers = 256
 Reads = 1
Writes 0 
Fetches = 19

И еще одно наблюдение. Несложный (но муторный) повтор для разных значений ID'шников привёл к следующим результатам:
коннект-1 будет реагировать статистикой с reads=1 ...
1) ... как для update t set s = null, так и для rollback'a в коннекте-2, - но только при условии, что коннект-2 меняет записи с id=2...5;
2) ... только для rollback'a в коннекте-2, если этот коннект-2 меняет записи с id=6...110

Если же коннект-2 меняет записи с id >= 111, то ни апдейт, ни роллбак НЕ будут отражены в reads коннекта-1 при перечитке записи.
Что касается счетчика writes, то он в коннекте-1 ВСЁ ВРЕМЯ был равен нулю.

Мутная вода.
Длина данных в каждой записи (32760 строка + 4 байта id'шник + 16 байт заголовок записи) в ВОСЕМЬ раз превышает размер страницы базы. Счетчик записей (writes) во всех замерах был равен НУЛЮ ==> никаких новых страниц там не выделялось.
Установка коннектом -2 в записи с ID =5 длинного varchar-поля в NULL никак не может отражаться на страницах, прочитанных коннектом -1 для записи с ID =1 . Они же разделены как минимум 8*3 = 24 штуками других страниц!!
А про "эхо" от роллбака, идущее аж от 110-й страницы, я вообще молчу тихо об лёд...

dimitrВ первом случае наверняка изменяется pointer page (ибо твой апдейт приводит к выделению новой страницы), которую запросто может захотеть перечитать коннект 1.Нету там новой страницы. Я делал после первых трёх апдейтов нуллами вот это:
Код: plaintext
gstat EMPTY25.FDB -r -t T|findstr /i /c:"data pages"
- и получал всё время одно и то же:
Код: plaintext
    Data pages:  192 , data page slots:  192 , average fill: 88%
dimitrВо втором случае он наверняка будет перечитывать измененную TIP.Как это достоверно определить ?
...
Рейтинг: 0 / 0
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500718
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ТаблоидКак это достоверно определить ?
Если под виндой, то можно воспользоваться утилиткой из набора Sysinternals, например Process Monitor.
...
Рейтинг: 0 / 0
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500719
NickDee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NickDeeТаблоидКак это достоверно определить ?
Если под виндой, то можно воспользоваться утилиткой из набора Sysinternals, например Process Monitor.
Кроме этого там видно все действия по загрузке плагинов и ICU. ICU - это отдельная песенка :)
Нужно только в фильтре указать ProcessName = firebird.exe.
И всё тайное станет явным :)
...
Рейтинг: 0 / 0
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500760
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоидсорри, я там ошибся: делал вставку в таблицу t 3 , которая уже балы в этой базе, да еще и структура у неё та же самая оказалась :(
зато я не ошибся и делал все для t

ТаблоидЧто касается счетчика writes, то он в коннекте-1 ВСЁ ВРЕМЯ был равен нулю.
ты как обычно не читаешь, что тебе пишут. Ибо я говорил следить за ним в коннекте-2.

ТаблоидУстановка коннектом -2 в записи с ID =5 длинного varchar-поля в NULL никак не может отражаться на страницах, прочитанных коннектом -1 для записи с ID =1 . Они же разделены как минимум 8*3 = 24 штуками других страниц!!
запросто может, ибо одна pointer page адресует почти тысячу страниц данных. А pointer page имеет полное право изменяться при апдейте.

ТаблоидА про "эхо" от роллбака, идущее аж от 110-й страницы, я вообще молчу тихо об лёд...
роллбек или коммит изменяет TIP, один TIP адресует состояние кучи транзакций, коннект-2 изменил состояние последней транзакции, селект в коннекте-1 хочет узнать состояние некоторой предыдущей транзакции (инсертившей запись) и читает ту же самую страницу TIP. Продолжай молчать тихо об лед.

ТаблоидНету там новой страницы
я выполнял твой тест, апдейт приводил к аллокации новой страницы. Но даже без создания новой страницы pointer page может меняться при изменении страницы данных.
...
Рейтинг: 0 / 0
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500764
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dimitr,
вот это:
аз есьмЕсли же коннект-2 меняет записи с id >= 111 , то ни апдейт, ни роллбак НЕ будут отражены в reads коннекта-1 при перечитке записи.- чем объяснить ?
Если апдейт длинной записи на NULL меняет PP, то он меняет для любого ID'шника или нет ?
...
Рейтинг: 0 / 0
Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
    #38500768
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

во-первых, pointer page меняется не всегда, а только при определенных условиях (зависит от заполнения страницы). Но в твоем случае скорее всего записи с id >= 111 относятся уже к другой pointer page, которая не нужна первому коннекту.
...
Рейтинг: 0 / 0
8 сообщений из 33, страница 2 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Classic & SuperClassic: как коннект узнаёт, что ему надо перечитать страницу в свой кеш ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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