Сводка по тестированию IBProvider c Firebird 2.5
Поскольку автоматизированное нагрузочное тестирование IBProvider осуществляется практически в режиме 7×24 с минимальными простоями тестового сервера, мы перестали уделять этому особое внимание.
Однако некоторые вещи могут быть интересны тем, кто уже использует наш провайдер в критических системах или пока только ищет надежное решение для доступа к Firebird и InterBase.
Нагрузочное тестирование
В течении лета 2016 года мы провели «большое» нагрузочное многопоточное тестирование нашего OLE DB провайдера.
Конфигурация
- IBProvider 3.30.0.21186 (64bit, vc14xp)
- Firebird 2.5.6.26993 (64bit, SuperClassic, модифицированный, сборка в VS2015)
- Подключение через localhost
- Windows Vista x64, Q6600, 8GB, выделенный RAID0 4x1TB (RS2BL040)
Особенности
- Использовался собственный клиент для Firebird (dbclient_type=fb.direct)
Общие сведения о режиме тестирования
- Тесты работали в 4 потока
- Применялся пул подключений
- Интенсивно использовалась асинхронная загрузка
Продолжительность работы
- Тесты работали с 4 июня по 2 августа 2016 года
- Firebird наработал 960 часов процессорного времени. Сведения о процессе: screenshot1, screenshot2
- Тестовая система наработала 579 часов процессорного времени. Сведения о процессе: screenshot3, screenshot4
Статистика базы данных
Database "d:\database\IBP_TEST_FB25_D3_all.GDB" Database header page information: Flags 0 Checksum 12345 Generation 44209884 Page size 8192 ODS version 11.2 Oldest transaction 44023029 Oldest active 44023030 Oldest snapshot 44023021 Next transaction 44023046 Bumped transaction 1 Sequence number 0 Next attachment ID 161122 Implementation ID 26 Shadow count 0 Page buffers 0 Next header page 0 Database dialect 3 Creation date Jun 4, 2016 17:13:01 Attributes Variable header data: *END*
Успешно пройдена точка, в которой ранее происходило зацикливание внутри Firebird – CORE-4384.
Было выполнено порядка 790 тысяч тестов (из 7.7 млн).
Тесты были прерваны из-за проблем с электропитанием.
Стрессовое тестирование
Время от времени, после многократных запусков тестов на одной и той же базе данных, нагрузочное тестирование превращается в стрессовое – возникает ошибка нехватки памяти (OUTOFMEMORY).
Это тоже достаточно полезный режим тестирования, который проверяет качество и общую устойчивость кода к нештатным ситуациям.
При работе с Firebird через fbclient.dll вы рискуете получить AV внутри процесса. Например, с таким стеком:
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++
Проблема в основном касается 32-битных процессов, в которых есть ограничение на размер адресного пространства – 2GB (4GB на 64-битной платформе).
Конкретно в данном случае, состояние тестового процесса было таким:
Однако 64-битных процессы также не защищены от подобных неприятностей.
Про остальные причины можете прочитать здесь.
Общие рекомендации по работе с Firebird
- Используйте 64-битные сборки сервера
- Если выработаете с сервером через fbclient.dll, то лучше это делать из 64-битного процесса
- Подключайтесь к Firebird через встроенный клиент провайдера. Для этого нужно указать в строке подключения «dbclient_type=fb.direct»
В итоге
В целом, все эти эксперименты подтверждают единственную критическую проблему IBProvider:
И это реально удивительно, если принять во внимание общий объем и сложность его кода.
Но мы к этому очень стремились все 16 лет с момента старта этого проекта.