powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
25 сообщений из 91, страница 1 из 4
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887236
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В ходе переноса данных из удаленной базы данных на локальную обнаружил презабавный глюк, который вылавливал несколько часов.
Приведу запросы полностью, чтоб что-то случайно не затереть, хотя все дело было в 2-х блоб-полях: CARDCOMMENTS и CARDPROPS, значение которых во всех записях - пустая строка (не нулл).

Зная, что на форуме есть представители команды разработчиков ФБ, думаю, обратят на этот нюанс внимание.

Итак - обычное извлечение 100 первых записей занимает у меня 24 секунды. Это очень много, так как записей 20 тыс.
Код: sql
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.
execute block
as
declare variable CARDID type of column CARDS.CARDID;
declare variable CARDNAME type of column CARDS.CARDNAME;
declare variable CARDOWNER type of column CARDS.CARDOWNER;
declare variable TELNO type of column CARDS.TELNO;
declare variable CARDTYPE type of column CARDS.CARDTYPE;
declare variable CARDDATE type of column CARDS.CARDDATE;
declare variable CARDDISCNT type of column CARDS.CARDDISCNT;
declare variable CARDBLOCKED type of column CARDS.CARDBLOCKED;
declare variable CARDTOTAL type of column CARDS.CARDTOTAL;
declare variable OWNERDOC type of column CARDS.OWNERDOC;
declare variable DATEBIRTH type of column CARDS.DATEBIRTH;
declare variable CARDCOMMENTS type of column CARDS.CARDCOMMENTS;
declare variable LASTDATE type of column CARDS.LASTDATE;
declare variable DBDATE type of column CARDS.DBDATE;
declare variable CARDAMOUNT type of column CARDS.CARDAMOUNT;
declare variable CARDPROPS type of column CARDS.CARDPROPS;
declare variable CARDSTATUS type of column CARDS.CARDSTATUS;

begin
  for execute statement 'select first 100 CARDID, CARDNAME, CARDOWNER, TELNO, CARDTYPE, CARDDATE, CARDDISCNT, CARDBLOCKED,
                                 CARDTOTAL, OWNERDOC, DATEBIRTH, CARDCOMMENTS , LASTDATE, DBDATE, CARDAMOUNT, CARDPROPS,
                                 CARDSTATUS from cards'
          on external data source '192.168.97.1:d:\basa\dbserver.fdb'
          as user 'SYSDBA' password 'masterkey'
          into :CARDID, :CARDNAME, :CARDOWNER, :TELNO, :CARDTYPE, :CARDDATE, :CARDDISCNT, :CARDBLOCKED, :CARDTOTAL,
          :OWNERDOC, :DATEBIRTH, :CARDCOMMENTS, :LASTDATE, :DBDATE, :CARDAMOUNT, :CARDPROPS, :CARDSTATUS
  do
  begin
    update or insert into CARDS (CARDID, CARDNAME, CARDOWNER, TELNO, CARDTYPE, CARDDATE, CARDDISCNT, CARDBLOCKED,
                                 CARDTOTAL, OWNERDOC, DATEBIRTH, CARDCOMMENTS, LASTDATE, DBDATE, CARDAMOUNT, CARDPROPS,
                                 CARDSTATUS)
    values (:CARDID, :CARDNAME, :CARDOWNER, :TELNO, :CARDTYPE, :CARDDATE, :CARDDISCNT, :CARDBLOCKED, :CARDTOTAL,
            :OWNERDOC, :DATEBIRTH, :CARDCOMMENTS, :LASTDATE, :DBDATE, :CARDAMOUNT, :CARDPROPS, :CARDSTATUS);
  end
end



Как удалось повысить скорость на несколько порядков!!!!! - в селекте на удаленной БД приводим блоб-поле к типу varchar. И скорость выполнения запроса падает до 0,3 с!!!!!! Причем, объявление локальных переменных простого строкового типа ускорения не дало, только приведение типа в самом запросе.


Настройки серверов ФБ что на локальной, что на удаленной машинах одинаковые, дефолтные, суперсервер, v3.0.4, соединение по ВПН по инету со скоростью 10мбит (не в инете дело)
Вот слегка модифицированный предыдущий запрос, который решил проблему тормозов.
Код: sql
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.
execute block
as
declare variable CARDID type of column CARDS.CARDID;
declare variable CARDNAME type of column CARDS.CARDNAME;
declare variable CARDOWNER type of column CARDS.CARDOWNER;
declare variable TELNO type of column CARDS.TELNO;
declare variable CARDTYPE type of column CARDS.CARDTYPE;
declare variable CARDDATE type of column CARDS.CARDDATE;
declare variable CARDDISCNT type of column CARDS.CARDDISCNT;
declare variable CARDBLOCKED type of column CARDS.CARDBLOCKED;
declare variable CARDTOTAL type of column CARDS.CARDTOTAL;
declare variable OWNERDOC type of column CARDS.OWNERDOC;
declare variable DATEBIRTH type of column CARDS.DATEBIRTH;
declare variable CARDCOMMENTS type of column CARDS.CARDCOMMENTS;
declare variable LASTDATE type of column CARDS.LASTDATE;
declare variable DBDATE type of column CARDS.DBDATE;
declare variable CARDAMOUNT type of column CARDS.CARDAMOUNT;
declare variable CARDPROPS type of column CARDS.CARDPROPS;
declare variable CARDSTATUS type of column CARDS.CARDSTATUS;

begin
  for execute statement 'select first 100 CARDID, CARDNAME, CARDOWNER, TELNO, CARDTYPE, CARDDATE, CARDDISCNT, CARDBLOCKED,
                                 CARDTOTAL, OWNERDOC, DATEBIRTH, cast(CARDCOMMENTS as varchar(2000)), LASTDATE, DBDATE, CARDAMOUNT, cast(CARDPROPS as varchar(2000)),
                                 CARDSTATUS from cards'
          on external data source '192.168.97.1:d:\basa\dbserver.fdb'
          as user 'SYSDBA' password 'masterkey'
          into :CARDID, :CARDNAME, :CARDOWNER, :TELNO, :CARDTYPE, :CARDDATE, :CARDDISCNT, :CARDBLOCKED, :CARDTOTAL,
          :OWNERDOC, :DATEBIRTH, :CARDCOMMENTS, :LASTDATE, :DBDATE, :CARDAMOUNT, :CARDPROPS, :CARDSTATUS
  do
  begin
    update or insert into CARDS (CARDID, CARDNAME, CARDOWNER, TELNO, CARDTYPE, CARDDATE, CARDDISCNT, CARDBLOCKED,
                                 CARDTOTAL, OWNERDOC, DATEBIRTH, CARDCOMMENTS, LASTDATE, DBDATE, CARDAMOUNT, CARDPROPS,
                                 CARDSTATUS)
    values (:CARDID, :CARDNAME, :CARDOWNER, :TELNO, :CARDTYPE, :CARDDATE, :CARDDISCNT, :CARDBLOCKED, :CARDTOTAL,
            :OWNERDOC, :DATEBIRTH, :CARDCOMMENTS, :LASTDATE, :DBDATE, :CARDAMOUNT, :CARDPROPS, :CARDSTATUS);
  end
end
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887237
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFominне в инете дело

Да нет, именно в нём. Ключевое слово "латентность".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887238
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin,

это не баг, а особенность передачи BLOB по сети
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887240
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

GrigoriyFominне в инете дело

Да нет, именно в нём. Ключевое слово "латентность".

Если можно - поподробнее - как инет влияет на передачу пустой строки как блоба, и как varchar? Неужели 2 х 16кБайт блока данных с блобом вызывают ТАКИЕ тормоза?
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887241
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис
GrigoriyFomin,

это не баг, а особенность передачи BLOB по сети

Ну мож тогда этот аспект где-то осветить? ЗА 10 лет работы с ФБ в документации такого не встречал, хотя мож не заметил. Хорошо, а обычная работа с базой по сети тоже будет проявлять эту особенность блобов? Для пустой строки все равно будет гнаться 16кБ кусок данных?
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887244
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin,

для этого достаточно посмотреть Firebird API, а именно как осуществляется работа с БЛОБ и тогда всё станет ясно.

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

В случае простых типов в firebird есть оптимизация сетевого протокола, например префетч записей курсора.
В случае блобов на каждый блоб приходится два дополнительных раудтрипа 1. открыть, 2 прочитать сегмент. Причём если блоб большой, то 2 ещё и может быть повторён много раз.

GrigoriyFominзначение которых во всех записях - пустая строка (не нулл).

а надо было хранить null, это позволило бы не открывать блоб вовсе экономя сетевые пакеты.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887245
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисВ случае блобов на каждый блоб приходится два дополнительных раудтрипа 1. открыть, 2
прочитать сегмент. Причём если блоб большой, то 2 ещё и может быть повторён много раз.

Если верить последнему тикету в трекере, там после последнего сегмента какие-то странные
тормоза происходят.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887248
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис
GrigoriyFomin,

В отличие от полей других типов Блобы не вытаскиваются сразу в записи при фетче. Вместо блобов вытаскивается только их идентификатор, а затем блоб надо открыть и прочитать все его сегменты.
.....
В случае простых типов в firebird есть оптимизация сетевого протокола, например префетч записей курсора.
В случае блобов на каждый блоб приходится два дополнительных раудтрипа 1. открыть, 2 прочитать сегмент. Причём если блоб большой, то 2 ещё и может быть повторён много раз.

Но ведь физически даже после приведения типа все равно считывается блоб по своему обычному алгоритму - те же шаги проходят. Значит проблема при передаче самого блоба по сети. У меня сегмент БД установлен 16кБ, значит 2 блоб поля вынуждают гнать лишних 32кБ по сети. Но все равно как-то многовато - почти тысячекратная разница в передаче блоба и варчара, учитывая, что другие поля совсем не нулевые и тоже место в трафике занимают. 32кБ * 100 записей - это 3,2 МБ лишнего трафика, и на них тратиться аж 24с!!! Это при том, что вся таблица CARDS (20к записей) занимает в файле БД 8,2 МБ, умещается на 504 страницах и передается по новому SQL-коду за 9с.
Получается сетевые расходы на 100 записей с 2-мя блобами = лишние 200 страниц за 24с, а вся таблица на 504 страницах (без блобов ессно) - за 8 с.
Более чем 6-тикратное превышение времени передачи одного и того же количества страниц. Явно не в сетевом соединении узкое горлышко, и явно не в скорости считывания блоба из БД.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887249
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денис
В случае блобов на каждый блоб приходится два дополнительных раудтрипа 1. открыть, 2 прочитать сегмент.
3. закрыть
И ещё 1а прочитать инф-цию (необязательный, зависит от того, как написан код).
Т.е. 3-4 раундтрипа. На каждый блоб. В каждой записи.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887250
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin,

Что ты прицепился к этим несуществующим 16КБ ? Забудь про них.

Пусть пинг в твоей интернет сети 10 мс (это весьма оптимистично)
2 блоба * 3 раундтрипа * 100 записей * 10 мс = 6 сек

У тебя реально 24 сек ? Значит пинг около 40 мс.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887251
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin,

я тебе по передачу блоба по сети и рассказывал. Ещё раз загляни в API как происходит работа с блобами.

GrigoriyFominНо ведь физически даже после приведения типа все равно считывается блоб по своему обычному алгоритму - те же шаги проходят

нет после того как ты привёл блоб к строке передавать его по сети как блоб уже не надо. По крайней мере в ES это самостоятельно определяется

GrigoriyFominУ меня сегмент БД установлен 16кБ, значит 2 блоб поля вынуждают гнать лишних 32кБ по сети.

ты не прав. Где ты этот размер сегмента устанавливаешь?

Опять же ты считаешь какие-то мегабайты, а проблема не в них, а в количестве сетевых пакетов.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887261
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис,

то есть вы намекаете, что при работе с удаленной базой данных обычные локальные процессы начинают происходить по сети? Я полагал, что запрос отрабатывает удаленный сервер, упаковывая готовые данные для транспортировке по сети. А по вашим описаниям то же многостадийное считывание блоба происходит по сети, генеря при этом кучу вспомогательных сетевых запросов?

Насчет размера сегмента - имел ввиду размер страницы БД, который указываю при восстановлении ее из бэкапа. Устанавливаю 16кБ (макс.возможный)
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887350
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFominкоторый указываю при восстановлении ее из бэкапа.
размер страницы задается 1 раз при создании БД, и может быть изменен при восстановлении из бэкапа.
Постоянно указывать при restore один и тот же размер страницы нет смысла.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887355
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin,

не надо искажать смысл моего ответа. Я не переходил с сетевого уровня на уровень движка.

Вот что происходит схематично при работе с blob (полная семантику вызовов я не повторял)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
st = attachment->prepare(tr, SQL);
rs = st->openCursor();
while(rs->fetch(&buffer)) {
  // обрабатываем обычные типы
  // ....
  if (!blobIdNull) {
    blob = attachment->openBlob(tr, blobId);
    while(blob->get_segment(&blb)) {
      // ...
    }
    blob->close();
  }
  // ...
}
rs->closeCursor();



Итак не каждый вызов rs->fetch() требует нового сетевого пакета, поскольку есть префетч и за один пакет может быть выбрано несколько записей, потом просто до поры до времени сетевой пакет не генерируется.

Но блобы выбираются отдельно от fetch, который даёт только их id. А вот openBlob, get_segment и close требуют каждый раз новый сетевой пакет. Ну возможно есть кое-какая оптимизация в get_segment.

Теперь понял?
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887637
vvvait
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
медленная скорость передачи блобов из базы в базу по сети с высокими пингами это мелочи.
Я периодически получаю битые блобы. Сначала пересылал из базы в базу большие xml и они оказывались не валидными.
Потом стал сжимать их gzip. И они не распаковывались на получателе.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887639
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
11.11.2019 17:45, vvvait пишет:
> Потом стал сжимать их gzip. И они не распаковывались на получателе.

у тебя ошибка в программе.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887722
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvvait,

напиши программу, которая миллион раз передаст сжатый файл, примет и проверит его. О количестве ошибок (с номерами блоков) напиши сюда.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887747
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvvait
медленная скорость передачи блобов из базы в базу по сети с высокими пингами это мелочи.
Я периодически получаю битые блобы. Сначала пересылал из базы в базу большие xml и они оказывались не валидными.
Потом стал сжимать их gzip. И они не распаковывались на получателе.

Тоже такое было.
Расследование всякий раз показывало, что это я нарукожопил.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887748
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ёёёёё,

к слову, риторически. что за проблема - взять два бинария, один исходный, другой из блоба (сохраненный сторонней программой в том числе), и сравнить их - посмотреть, где данные искорёжены.
Если там повреждены начало или конец, так это софт. Если всё перепутано - так значит в блоб залито такое. А вот если где-то посередине - тогда, скорее всего, повреждено при передаче.
ФБ что принял, то и сохранил. Если такой блоб целиком поврежден, я могу разве что списать на дефект памяти на компе, но и то, такие вещи опять же бинарным сравнением видны без монокля.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887749
GrigoriyFomin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов Денис,

дабы окончательно понять - доступ к блобам удаленной БД происходит на удаленной стороне или на локальной? По идее я запрашиваю селект на удаленной БД и по сети должен передаться датасет с полями тех типов, которые в БД, то есть блобы должны по сети дергаться. Тогда это объясняет такую разницу в скорости доступа. Но поять-таки, неплохо это где-то в гайде написать, чтоб предостеречь.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887750
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin
доступ к блобам удаленной БД происходит на удаленной стороне или на локальной?
Симонов Денис
В отличие от полей других типов Блобы не вытаскиваются сразу в записи при фетче. Вместо блобов вытаскивается только их идентификатор, а затем блоб надо открыть и прочитать все его сегменты.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887754
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GrigoriyFomin,

у вас какие-то совершенно дикие представления о том как работает клиент-сервер. Тебе же объяснили что чтение блобов просто отложенное. Естественно на стороне сервера оно читается движком, а затем передаётся по сети. Да по сети они передаются в несколько сетевых пакетов, но зато это позволяет читать очень большие блобы, ибо их не возможно поместить в буфер фиксированной ширины как для остальных типов.
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887757
vvvait
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ошибки в передаче блобов наблюдаются редко, менее 1%, и только на каналах с большой и плавающей задержкой от 70 до 500 мс.
это по вашему ошибка в программе? ну если только её имя fbserver
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887758
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvvaitэто по вашему ошибка в программе? ну если только её имя fbserver

Эх, молодо-зелено...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
    #39887768
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vvvait
ошибки в передаче блобов наблюдаются редко, менее 1%, и только на каналах с большой и плавающей задержкой от 70 до 500 мс.
это по вашему ошибка в программе? ну если только её имя fbserver


Фигассе, "редко", 1%...
...
Рейтинг: 0 / 0
25 сообщений из 91, страница 1 из 4
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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