Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД / 25 сообщений из 91, страница 1 из 4
10.11.2019, 22:02
    #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
10.11.2019, 22:04
    #39887237
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
GrigoriyFominне в инете дело

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

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

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

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

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

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

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

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

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

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

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

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

Если верить последнему тикету в трекере, там после последнего сегмента какие-то странные
тормоза происходят.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
10.11.2019, 22:57
    #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
10.11.2019, 23:09
    #39887249
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
Симонов Денис
В случае блобов на каждый блоб приходится два дополнительных раудтрипа 1. открыть, 2 прочитать сегмент.
3. закрыть
И ещё 1а прочитать инф-цию (необязательный, зависит от того, как написан код).
Т.е. 3-4 раундтрипа. На каждый блоб. В каждой записи.
...
Рейтинг: 0 / 0
10.11.2019, 23:09
    #39887250
hvlad
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
GrigoriyFomin,

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

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

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

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

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

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

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

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

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

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

Насчет размера сегмента - имел ввиду размер страницы БД, который указываю при восстановлении ее из бэкапа. Устанавливаю 16кБ (макс.возможный)
...
Рейтинг: 0 / 0
11.11.2019, 10:54
    #39887350
kdv
kdv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
GrigoriyFominкоторый указываю при восстановлении ее из бэкапа.
размер страницы задается 1 раз при создании БД, и может быть изменен при восстановлении из бэкапа.
Постоянно указывать при restore один и тот же размер страницы нет смысла.
...
Рейтинг: 0 / 0
11.11.2019, 11:04
    #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
11.11.2019, 17:45
    #39887637
vvvait
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
медленная скорость передачи блобов из базы в базу по сети с высокими пингами это мелочи.
Я периодически получаю битые блобы. Сначала пересылал из базы в базу большие xml и они оказывались не валидными.
Потом стал сжимать их gzip. И они не распаковывались на получателе.
...
Рейтинг: 0 / 0
11.11.2019, 17:47
    #39887639
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обнаружил баг или это неизвестная мне фича - блоб поле на удаленной БД
11.11.2019 17:45, vvvait пишет:
> Потом стал сжимать их gzip. И они не распаковывались на получателе.

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

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

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

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

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

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

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


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


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