Про списки объектов

Привет всем.

В потрохах Firebird многие вещи организованы в списки. Однонаправленные. Других я там не встречал. Ну организованы, так организованы. Вообщем-то, это их личные проблемы, которые снаружи не парят до определенного момента.

В процессе натягивания существующих тестов, созданных для собственного клиента FB (10-12 протоколы), на клиента для FB3 (13-ый протокол), задрался ждать пока завершится ничем неприметный тест. Полчаса работал. Полез в лог: в цикле три раза подряд создается/подготавливается/освобождается группа из 64999 запросов.

[THR:012440] [18.09.2016 10:44:40] ***********************************************
[THR:012440] [18.09.2016 10:44:40] * START TEST [RemoteFB.WORK.013.StmtAllocate.v2.ptype__lazy_send.011.check_release_of_dropped_stmts]
[THR:012440] [18.09.2016 10:44:40] *
[THR:012440] [18.09.2016 10:44:40] [test] Hello from test!
[THR:012440] [18.09.2016 10:44:40] [test] RemoteFB__Connector::ConnectToDatabase ...OK
[THR:012440] [18.09.2016 10:44:40] [test] RemoteFB__Connector::StartTransaction ...OK
[THR:012440] [18.09.2016 10:44:40] [test] Allocate statements ...
[THR:012440] [18.09.2016 10:46:31] [test] OK. We got the error.
[THR:012440] [18.09.2016 10:46:31] [test] 1. [Firebird] too many open handles to database
[THR:012440] [18.09.2016 10:46:31] [test] 2. [LCPI.IBProvider.3] [Подсистема: remote_fb.p13] Ошибка инициализации дескриптора запроса.
[THR:012440] [18.09.2016 10:46:31] [test] nMaxStatements: 64999
[THR:012440] [18.09.2016 10:46:32] [test] RemoteFB__Connector::ConnectToDatabase ...OK
[THR:012440] [18.09.2016 10:46:32] [test] RemoteFB__Connector::StartTransaction ...OK
[THR:012440] [18.09.2016 10:46:32] [test] -------------------------------- pass: 1
[THR:012440] [18.09.2016 10:46:32] [test] Allocate statements ...
[THR:012440] [18.09.2016 10:46:32] [test] ----
[THR:012440] [18.09.2016 10:48:37] [test] Drop statements ...
[THR:012440] [18.09.2016 10:48:37] [test] -------------------------------- pass: 2
[THR:012440] [18.09.2016 10:48:37] [test] Allocate statements ...
[THR:012440] [18.09.2016 10:56:57] [test] ----
[THR:012440] [18.09.2016 10:58:49] [test] Drop statements ...
[THR:012440] [18.09.2016 10:58:49] [test] -------------------------------- pass: 3
[THR:012440] [18.09.2016 10:58:49] [test] Allocate statements ...
[THR:012440] [18.09.2016 11:10:01] [test] ----
[THR:012440] [18.09.2016 11:11:51] [test] Drop statements ...
[THR:012440] [18.09.2016 11:11:51] [test] RemoteFB__Connector::Commit ...OK
[THR:012440] [18.09.2016 11:14:24] [test] RemoteFB__Connector::DetachDatabase ...OK
[THR:012440] [18.09.2016 11:14:24] *
[THR:012440] [18.09.2016 11:14:24] * REAL   TIME:17845270915   [00:29:44.5270915]
[THR:012440] [18.09.2016 11:14:24] * USER   TIME:155844999     [00:00:15.5844999]
[THR:012440] [18.09.2016 11:14:24] * KERNEL TIME:82524529      [00:00:08.2524529]
[THR:012440] [18.09.2016 11:14:24] * TOTAL  TIME:238369528     [00:00:23.8369528]
[THR:012440] [18.09.2016 11:14:24] *
[THR:012440] [18.09.2016 11:14:24] * STOP TEST [RemoteFB.WORK.013.StmtAllocate.v2.ptype__lazy_send.011.check_release_of_dropped_stmts]

А, ну да… Однонаправленный список объектов запросов.

Где-то год назад меня эта однонаправленность конкретно задолбала и пришлось выписать серверу лекарство — двунаправленный список, который гарантирует фиксированное время удаления элементов.

Наверное надо будет в свою тройку его тоже залить. Потому что FB2.5 (такой же отладочный как и тройка) с этим исправлением работает в два раза быстрее:

[THR:013768] [18.09.2016 11:19:07] ***********************************************
[THR:013768] [18.09.2016 11:19:07] * START TEST [RemoteFB.WORK.013.StmtAllocate.v2.ptype__lazy_send.011.check_release_of_dropped_stmts]
[THR:013768] [18.09.2016 11:19:07] *
[THR:013768] [18.09.2016 11:19:07] [test] Hello from test!
[THR:013768] [18.09.2016 11:19:09] [test] RemoteFB__Connector::ConnectToDatabase ...OK
[THR:013768] [18.09.2016 11:19:09] [test] RemoteFB__Connector::StartTransaction ...OK
[THR:013768] [18.09.2016 11:19:09] [test] Allocate statements ...
[THR:013768] [18.09.2016 11:21:38] [test] OK. We got the error.
[THR:013768] [18.09.2016 11:21:38] [test] 1. [Firebird] too many open handles to database
[THR:013768] [18.09.2016 11:21:38] [test] 2. [LCPI.IBProvider.3] [Подсистема: remote_fb.p12] Ошибка инициализации дескриптора запроса.
[THR:013768] [18.09.2016 11:21:38] [test] nMaxStatements: 64999
[THR:013768] [18.09.2016 11:22:06] [test] RemoteFB__Connector::ConnectToDatabase ...OK
[THR:013768] [18.09.2016 11:22:06] [test] RemoteFB__Connector::StartTransaction ...OK
[THR:013768] [18.09.2016 11:22:06] [test] -------------------------------- pass: 1
[THR:013768] [18.09.2016 11:22:06] [test] Allocate statements ...
[THR:013768] [18.09.2016 11:22:06] [test] ----
[THR:013768] [18.09.2016 11:24:37] [test] Drop statements ...
[THR:013768] [18.09.2016 11:24:37] [test] -------------------------------- pass: 2
[THR:013768] [18.09.2016 11:24:37] [test] Allocate statements ...
[THR:013768] [18.09.2016 11:26:27] [test] ----
[THR:013768] [18.09.2016 11:28:56] [test] Drop statements ...
[THR:013768] [18.09.2016 11:28:56] [test] -------------------------------- pass: 3
[THR:013768] [18.09.2016 11:28:56] [test] Allocate statements ...
[THR:013768] [18.09.2016 11:30:47] [test] ----
[THR:013768] [18.09.2016 11:33:16] [test] Drop statements ...
[THR:013768] [18.09.2016 11:33:16] [test] RemoteFB__Connector::Commit ...OK
[THR:013768] [18.09.2016 11:33:50] [test] RemoteFB__Connector::DetachDatabase ...OK
[THR:013768] [18.09.2016 11:33:50] *
[THR:013768] [18.09.2016 11:33:50] * REAL   TIME:8831512364    [00:14:43.1512364]
[THR:013768] [18.09.2016 11:33:50] * USER   TIME:134316861     [00:00:13.4316861]
[THR:013768] [18.09.2016 11:33:50] * KERNEL TIME:131352842     [00:00:13.1352842]
[THR:013768] [18.09.2016 11:33:50] * TOTAL  TIME:265669703     [00:00:26.5669703]
[THR:013768] [18.09.2016 11:33:50] *
[THR:013768] [18.09.2016 11:33:50] * STOP TEST [RemoteFB.WORK.013.StmtAllocate.v2.ptype__lazy_send.011.check_release_of_dropped_stmts]

Но это надо раз десять тест запустить, чтобы созреть для такого подвига.

Are you prepared for Firebird 3?

Привет всем!

Увидел сегодня %subj% на firebirdnews.

Задумался…

А ведь пять лет прошло, Карл. Пять лет!

FB3, DatabaseParameterBuffer

Привет всем.

Меня тут мысль одна посетила (и ей одиноко …).

В тройке (а может и раньше, не разбирался) появилась новая версия формата буфера с параметрами подключения к базе данных — v2. В отличии от v1, в v2 можно передавать параметры с длиной вплоть до 65535 байт. В v1 длина ограничивалась 255 байтами.

Если мы подключаемся к серверу через fbclient.dll, то при выборе формата DPB мы можем опираться на версию серверного клиента.

Однако что-то я не узрел в новой fbclient.dll кода преобразования v2->v1 для случая подключения к Firebird с версией младше третьей.

Наверное плохо искал.

Но если его там действительно нет, то вторая версия DPB идет лесом. И, при работе с сервером через fbclient.dll, надо продолжать сидеть на DPB v1.

——
При подключении к серверу минуя fbclient.dll, DPB можно сформировать после определения версии протокола. Что, собственно говоря, и делается в IBProvider. И FB3 (13-ый протокол) действительно может принимать DPB v2.

FB3, Win_SSPI, Wire_Crypt=disabled

С пятницей всех.

Продолжая воспроизводить функциональность fbclient.dll (v3) в собственном клиенте для FB3, обнаружил следующие ну очень интересные вещи для SSPI-аутентификации:

При подключении с разрешенным шифрованием трафика (Wire_Crypt=enabled) обмен сообщениями с сервером на этапе инициализации выглядит так:

PROTOCOL: XDR_ENCODE (0) - op_connect (1)
PROTOCOL: XDR_DECODE (1) - op_cond_accept (98)
PROTOCOL: XDR_ENCODE (0) - op_cont_auth (92)
PROTOCOL: XDR_FREE (2) - op_cont_auth (92)
PROTOCOL: XDR_DECODE (1) - op_response (9)
PROTOCOL: XDR_ENCODE (0) - op_attach (19)
PROTOCOL: XDR_DECODE (1) - op_response (9)

А с выключенным шифрованием трафика (Wire_Crypt=disabled) вот так:

PROTOCOL: XDR_ENCODE (0) - op_connect (1)
PROTOCOL: XDR_DECODE (1) - op_accept_data (94)
PROTOCOL: XDR_ENCODE (0) - op_attach (19)
PROTOCOL: XDR_DECODE (1) - op_response (9)

Возникла мысль — куда делась передача данных из третьей строки первого варианта?

Оказалось, во втором случае это делается через op_attach и его DatabaseParameterBuffer (DPB).

В целом, эта два разных способа достижения одного результата — «трафик без шифрования». Шифрование для Win_SSPI собственными средствами сервера и клиента, насколько я понимаю, не поддерживается.

Попытка привести второй вариант к первому, то есть вместо передачи данных через DPB отправлять отдельный пакет (op_cont_auth), не работает — сервер возвращает ошибку «unavailable database».

Собственно говоря, раздражает тот факт, что похоже придется размазывать код аутентификации между op_connect (подключение к серверу) и op_attach (подключение к базе).

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

Ан нет.

В следующий раз, когда начнет казаться, сразу начну креститься.

Триал IBProvider v3.32.0 [сборка 21686]

Привет всем.

На сайт провайдера загружен новый триал, в котором появилось новое свойство инициализации — «remote:protocol». Оно относится к конфигурации встроенного клиента и позволяет задавать версию протокола соединения.

В реальной работе это свойство и пара других свойств («remote:protocol_arch», «remote:protocol_type») не нужны. Но вот для создания тестов и всякого рода глумлений экспериментов над сервером — они весьма кстати.

Пешите тесты

Привет всем.

Сегодня сообразил, что единственный (проверенный) способ перестать тупить над новым кодом — это начать писать для него тесты. Выбрал жертву. Написал сценарий, передающий некорректные данные. Выполнил. Открыл лог выполнения и узрел первый баг:

[THR:011960] [02.09.2016 22:54:14] [test] 1. [LCPI.IBProvider.3] [BUG CHECK] Ошибка конвертирование имени плагина аутентификуации из UTF8 в WSTR. Точка проверки [RemoteFB__PortInitializer_PSET02_v01::Helper__ProcessAuthResponse_P13][#001].

Поехали.

Вести с полей тестирования

— Может снимем девочек?
— Пусть еще повисят.

Вот уже несколько дней на тестовой машине висит пара окон:

Crash windows

Стек падения:

fbclient.dll!get_numeric_info(const char * * ptr=0x00000000)  Строка 923 + 0x15 байт	C++
fbclient.dll!UTLD_parse_sql_info(int * status=0x00000000, unsigned short dialect=2, const char * info=0x00000000, XSQLDA * xsqlda=0x1bbe4e10, unsigned short * return_index=0x0391f498)  Строка 226 + 0x11 байт	C++
fbclient.dll!iterative_sql_info(int * user_status=0x00000000, void * * stmt_handle=0x00000002, unsigned short item_length=62868, const char * items=0x10074764, short buffer_length=0, char * buffer=0x00000000, unsigned short dialect=1, XSQLDA * sqlda=0x1bbe4e10)  Строка 5575 + 0x13 байт	C++
fbclient.dll!isc_dsql_prepare(int * user_status=0x0391f7a0, void * * tra_handle=0x1c962398, void * * stmt_handle=0x1a7761d8, unsigned short length=26, const char * string=0x09b90f10, unsigned short dialect=1, XSQLDA * sqlda=0x1bbe4e10)  Строка 3580	C++
_IBProvider_v3_vc14xp_i.dll!ib_v5::t_ib_statement_v5::prepare(db_obj::t_db_operation_context & op_ctx={...}, db_obj::t_db_stmt_result_kind stmt_result_kind=db_stmt_result_kind__selectable, structure::t_basic_const_str_box<wchar_t> stmt={...}, db_obj::t_db_row * const row=0x1b1e17c8, const unsigned int pr_flags=0)  Строка 210 + 0xc2 байт	C++
_IBProvider_v3_vc14xp_i.dll!ibp::t_ibp_command::prepare3(db_obj::t_db_operation_context & op_ctx={...}, db_obj::t_db_stmt_result_kind stmt_result_kind=db_stmt_result_kind__selectable, structure::t_basic_const_str_box<wchar_t> text={...}, const unsigned int expected_params_count=0)  Строка 103	C++
_IBProvider_v3_vc14xp_i.dll!ib_sql_pstmt::t_ib_sql_pstmt_select_table::prepare_clone_impl(ibp::t_ibp_operation_context & op_ctx={...})  Строка 363 + 0x52 байт	C++
_IBProvider_v3_vc14xp_i.dll!ib_sql_pstmt::t_ib_sql_pstmt_select_table::prepare_sql_impl(ibp::t_ibp_operation_context & op_ctx={...})  Строка 340	C++
_IBProvider_v3_vc14xp_i.dll!ibp_sql_pstmt::t_ibp_sql_pstmt_std_base::prepare_sql(ibp::t_ibp_operation_context & op_ctx={...})  Строка 116	C++
_IBProvider_v3_vc14xp_i.dll!ibp::t_ibp_command_pstmt_data::prepare(ibp::TIBPCommand * const pCommand=0x32d400c0, const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & command_text={...}, structure::t_smart_object_ptr<ibp::t_ibp_transaction,structure::t_sptr_traits<ibp::t_ibp_transaction> > & spTrans={...})  Строка 107	C++
_IBProvider_v3_vc14xp_i.dll!ibp::TIBPCommand::Prepare(unsigned long __formal=0)  Строка 54	C++
 	ibp_oledb_test_vc14_Win32_Release_xp.exe!oledb_lib::t_db_command::prepare_ex(structure::t_str_parameter<wchar_t,std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > > text={...}, oledb_lib::t_db_row * pRow=0x00000000, unsigned long describe_flags=1)  Строка 135 + 0x18 байт	C++

Сегодня, наконец-то, решил посмотреть что там произошло.

Test process state

Все ясно — в этот раз не повезло.

Вообще говоря, использовалась та же самая тестовая база данных. И, похоже, весьма удачная.

Если бы не опечатка в батнике, вместо fbclient должен был работать встроенный клиент для FB:

1. [LCPI.IBProvider.3]: [winsock] Ошибка определения сетевого адреса хоста [locahost][порт: 3050]. Ошибка WinSock: 11001.
2. [LCPI.IBProvider.3]: Ошибка подключения к базе данных.

Но ничего, сейчас запустим 🙂

Вести с полей

Привет всем.

Медленно и печально продираюсь сквозь терни подключения к FB3 минуя fbclient.dll. Добрался до настройки шифрования подключения (op_crypt). Разобравшись что к чему, я даже немного оживился — если делать по уму, то конструкция получается достаточно красивой.
(далее…)

Стрессовое тестирование

Привет всем.

Время от времени нагрузочное тестирование 32-битной сборки IBProvider-a (как правило, отладочной) начинает плющить и оно превращается в стрессовое — не хватает оперативной памяти. Выглядит это вот так:
(далее…)

Подключение к FB через TCP/IP (inet, inet4, inet6)

Привет всем.

Сегодня, созерцая время выполнения тестов новой сборки (21500) c Firebird 2.5 немного опух — через fbclient.dll тесты отрабатывали в 5 раз быстрее чем через встроенный клиент. Подключение к серверу осуществляется через TCP/IP: localhost:d:\database\ibp_test_fb25_d3.gdb.

Результаты для fbclient.dll:

------------------------------------------- [SUMMARY INFORMATION]
[TESTS]
EXECUTED      : 17407
SUCCEEDED     : 17406
FAILED        : 0
WITH WARNINGS : 1 [ 1 warning(s) ]

- - - - - - - - - - - - - - - - - - - - - -
TEST TIMES]
REAL          : 4759506647    [00:07:55.9506647]
USER          : 1640038513    [00:02:44.0038513]
KERNEL        : 299209918     [00:00:29.9209918]
TOTAL         : 1939248431    [00:03:13.9248431]

Результаты для встроенного клиента:

------------------------------------------- [SUMMARY INFORMATION]
[TESTS]
EXECUTED      : 17407
SUCCEEDED     : 17406
FAILED        : 0
WITH WARNINGS : 1 [ 1 warning(s) ]

- - - - - - - - - - - - - - - - - - - - - -
[TEST TIMES]
REAL          : 25232635350   [00:42:03.2635350]
USER          : 1359080712    [00:02:15.9080712]
KERNEL        : 267229713     [00:00:26.7229713]
TOTAL         : 1626310425    [00:02:42.6310425]

Ну, думаю, приплыли. Раньше же такого не было.

После разбора полета обнаружилось, что встроенный клиент сначала пытается подключаться к серверу (FB2.5) через TCP/IPv6, а потом через TCP/IPv4. Из-за IPv6 задержка была такой, что спотыкание процесса выполнения тестов было видно невооруженным взглядом.

Я на эти попытки подключения через IPv6 уже обращал внимания, но не придавал им особого значения. Ну не смог подключиться, ничего страшного. А оказалось «чего».

После явного указания подключения через IPv4 (inet4://localhost/d:\database\ibp_test_fb25_d3.gdb) все нормализовалось.

Результаты перезапуска (на новой тестовой базе данных)

Для fbclient.dll:

------------------------------------------- [SUMMARY INFORMATION]
[TESTS]
EXECUTED      : 17407
SUCCEEDED     : 17405
FAILED        : 0
WITH WARNINGS : 2 [ 2 warning(s) ]

- - - - - - - - - - - - - - - - - - - - - -
[TEST TIMES]
REAL          : 3720155706    [00:06:12.0155706]
USER          : 2020212950    [00:03:22.0212950]
KERNEL        : 382202450     [00:00:38.2202450]
TOTAL         : 2402415400    [00:04:00.2415400]

Для встроенного клиента:

------------------------------------------- [SUMMARY INFORMATION]
[TESTS]
EXECUTED      : 17407
SUCCEEDED     : 17405
FAILED        : 0
WITH WARNINGS : 2 [ 4 warning(s) ]

- - - - - - - - - - - - - - - - - - - - - -
[TEST TIMES]
REAL          : 3601447761    [00:06:00.1447761]
USER          : 1941588446    [00:03:14.1588446]
KERNEL        : 357242290     [00:00:35.7242290]
TOTAL         : 2298830736    [00:03:49.8830736]

Так что, теперь надо будет себя приучать явно указывать версию TCP/IP в строке подключения. Во избежание.

« Предыдущие записи