Большое тестирование #4

Слева диск «C» и справа диск «C» … И зачем мне два диска «C»?

Сегодня по-раздолбайству в задумчивости убил тестовый процесс, который работал уже седьмую неделю. Нажал не на ту кнопочку 🙂

Да черт с ней, с этой Голландией. Полтора месяца реальной работы — это тоже неплохо.

Тестовая машина та же, что и в прошлый раз — Q6600 / 8GB / выделенный массив 4x1TB WD RE4 в RAID0 на RS2BL040. Обновились только диски в рейде (были RE3).

Сервер: Firebird 2.5.6.26993 (x64, SuperClassic, модифицированный)
Провайдер: 3.29.0.20837 (x64)

Сервер и провайдер откомпилированы в VS2015 Upd2 (полная оптимизация).

Подключение к серверу через TCP/IP (localhost) и собственный клиент провайдера (то есть, без участия fbclient.dll).

Тесты запускались в 4 потока.

(далее…)

Вести с полей

Привет всем.

Вот так вот закопаешься в рутине и перестаешь осознавать — «что происходит и куда девается время?». Так что, хотя бы для себя лично, надо обозначить текущее состояние дел 🙂

1. Текущие триалы IBProvider-a уже поддерживают подключение к базам данных FB через собственного клиента с указанием версии IP-протокола в адресе базы данных: «inet4://» и «inet6://».

2. Медленно и печально перетряхиваю библиотеку libtommath, которую затащили в FB3 для использования SRP-аутентификации. Автор говорит — в 19 лет её накатал. Впечатляет, но для промышленного использования не пригодна.

3. Пошла шестая неделя большого тестирования — оно было запущено утром 17 апреля. Участники:

  • Firebird 2.5.6.26993 x64, SuperClassic, vc14 (полная оптимизация), модифицированный
  • IBProvider 3.29.0.20837 x64

Подключение: localhost, собственный клиент IBProvider-a для Firebird. Тесты выполняются в 4-е потока.

Точка предыдущего отказа еще не пройдена — количество тестов «немного» увеличилось. Пока полет нормальный. Но деградация производительности сервера уже на лице.

Пример пары тестов (вставка/удаление записей в одной транзакции), идентичных с точки зрения сервера:

Было:

[THR:005988] [05.05.2016 02:56:02] * START TEST [charsets.txt_params.enable_defer.user_trans.unicode.TBL_CS__UTF8.VARCHAR_ARRAY__32.cn_NONE.user_UTF8.chars_UTF8.param_adVarBinary_Array.bind_iunknown_array__std_ss.small.array_type_0]
[THR:005988] [05.05.2016 02:56:02] *
[THR:005988] [05.05.2016 02:56:02] * PREPARE
[THR:005988] [05.05.2016 02:56:02] * RUN
[THR:005988] [05.05.2016 02:56:02] [test] RelationName    :TBL_CS__UTF8
[THR:005988] [05.05.2016 02:56:02] [test] RelationField   :VARCHAR_ARRAY__32
[THR:005988] [05.05.2016 02:56:02] [test] UnicodeMode     :true
[THR:005988] [05.05.2016 02:56:02] [test] EnableDeferred  :true
[THR:005988] [05.05.2016 02:56:02] [test] AutoCommit      :false
[THR:005988] [05.05.2016 02:56:02] [test] CnCharset       :NONE
[THR:005988] [05.05.2016 02:56:02] [test] UserCharset     :UTF8
[THR:005988] [05.05.2016 02:56:02] [test] InParamType     :adArray+adVarBinary
[THR:005988] [05.05.2016 02:56:02] [test] InParamBindType :DBTYPE_IUNKNOWN | DBTYPE_ARRAY
[THR:005988] [05.05.2016 02:56:02] [test] OutParamType    :adArray+adVarBinary
[THR:005988] [05.05.2016 02:56:02] [test] OutParamBindType:DBTYPE_IUNKNOWN | DBTYPE_ARRAY
[THR:005988] [05.05.2016 02:56:02] [test] Prop_ArrayType  :0
[THR:005988] [05.05.2016 02:56:02] [test] Create connection...
[THR:005988] [05.05.2016 02:56:02] [test] create pooled data source...
[THR:005988] [05.05.2016 02:56:02] [test] set_init_prop: [array_type]=0
[THR:005988] [05.05.2016 02:56:02] [test] set_init_prop: [auto_commit]=false
[THR:005988] [05.05.2016 02:56:02] [test] set_init_prop: [ctype]=NONE
[THR:005988] [05.05.2016 02:56:02] [test] set_init_prop: [ctype_user]=UTF8
[THR:005988] [05.05.2016 02:56:02] [test] set_init_prop: [deferred_out_param]=3
[THR:005988] [05.05.2016 02:56:02] [test] set_init_prop: [unicode_mode]=true
[THR:005988] [05.05.2016 02:56:02] [test] connect to database ...OK
[THR:005988] [05.05.2016 02:56:02] [test] Create session...
[THR:005988] [05.05.2016 02:56:02] [test] START TRANSACTION ...
[THR:005988] [05.05.2016 02:56:02] [test] Create commands...
[THR:005988] [05.05.2016 02:56:02] [test] Prepare Command:

"insert into TBL_CS__UTF8 (VARCHAR_ARRAY__32) values (?) returning VARCHAR_ARRAY__32,test_id"

[THR:005988] [05.05.2016 02:56:02] [test] cmd.describe_params(param)
[THR:005988] [05.05.2016 02:56:02] [test] cmd.set_param_info(param)
[THR:005988] [05.05.2016 02:56:02] [test] Create command ...
[THR:005988] [05.05.2016 02:56:02] [test] Prepare Command:

"delete from TBL_CS__UTF8 where test_id=?"

[THR:005988] [05.05.2016 02:56:02] [test] cmd.describe_params(param)
[THR:005988] [05.05.2016 03:28:02] [test] Total pass number:524297
[THR:005988] [05.05.2016 03:28:02] [test] COMMIT TRANSACTION [RETAINING=false]...
[THR:005988] [05.05.2016 03:28:02] *
[THR:005988] [05.05.2016 03:28:02] * REAL   TIME:19203220000   [00:32:00.3220000]
[THR:005988] [05.05.2016 03:28:02] * USER   TIME:2506624068    [00:04:10.6624068]
[THR:005988] [05.05.2016 03:28:02] * KERNEL TIME:1080618927    [00:01:48.0618927]
[THR:005988] [05.05.2016 03:28:02] * TOTAL  TIME:3587242995    [00:05:58.7242995]
[THR:005988] [05.05.2016 03:28:02] *
[THR:005988] [05.05.2016 03:28:02] * STOP TEST [charsets.txt_params.enable_defer.user_trans.unicode.TBL_CS__UTF8.VARCHAR_ARRAY__32.cn_NONE.user_UTF8.chars_UTF8.param_adVarBinary_Array.bind_iunknown_array__std_ss.small.array_type_0]

Стало:

[THR:005980] [23.05.2016 06:06:10] * START TEST [charsets.txt_params.disable_defer.user_trans.unicode.TBL_CS__UTF8.VARCHAR_ARRAY__32.cn_NONE.user_UTF8.chars_UTF8.param_adVarBinary_Array.bind_iunknown_array__std_ss.small.array_type_0]
[THR:005980] [23.05.2016 06:06:10] *
[THR:005980] [23.05.2016 06:06:10] * PREPARE
[THR:005980] [23.05.2016 06:06:10] * RUN
[THR:005980] [23.05.2016 06:06:10] [test] RelationName    :TBL_CS__UTF8
[THR:005980] [23.05.2016 06:06:10] [test] RelationField   :VARCHAR_ARRAY__32
[THR:005980] [23.05.2016 06:06:10] [test] UnicodeMode     :true
[THR:005980] [23.05.2016 06:06:10] [test] EnableDeferred  :false
[THR:005980] [23.05.2016 06:06:10] [test] AutoCommit      :false
[THR:005980] [23.05.2016 06:06:10] [test] CnCharset       :NONE
[THR:005980] [23.05.2016 06:06:10] [test] UserCharset     :UTF8
[THR:005980] [23.05.2016 06:06:10] [test] InParamType     :adArray+adVarBinary
[THR:005980] [23.05.2016 06:06:10] [test] InParamBindType :DBTYPE_IUNKNOWN | DBTYPE_ARRAY
[THR:005980] [23.05.2016 06:06:10] [test] OutParamType    :adArray+adVarBinary
[THR:005980] [23.05.2016 06:06:10] [test] OutParamBindType:DBTYPE_IUNKNOWN | DBTYPE_ARRAY
[THR:005980] [23.05.2016 06:06:10] [test] Prop_ArrayType  :0
[THR:005980] [23.05.2016 06:06:10] [test] Create connection...
[THR:005980] [23.05.2016 06:06:10] [test] create pooled data source...
[THR:005980] [23.05.2016 06:06:10] [test] set_init_prop: [array_type]=0
[THR:005980] [23.05.2016 06:06:10] [test] set_init_prop: [auto_commit]=false
[THR:005980] [23.05.2016 06:06:10] [test] set_init_prop: [ctype]=NONE
[THR:005980] [23.05.2016 06:06:10] [test] set_init_prop: [ctype_user]=UTF8
[THR:005980] [23.05.2016 06:06:10] [test] set_init_prop: [deferred_out_param]=0
[THR:005980] [23.05.2016 06:06:10] [test] set_init_prop: [unicode_mode]=true
[THR:005980] [23.05.2016 06:06:10] [test] connect to database ...OK
[THR:005980] [23.05.2016 06:06:10] [test] Create session...
[THR:005980] [23.05.2016 06:06:10] [test] START TRANSACTION ...
[THR:005980] [23.05.2016 06:06:10] [test] Create commands...
[THR:005980] [23.05.2016 06:06:10] [test] Prepare Command:

"insert into TBL_CS__UTF8 (VARCHAR_ARRAY__32) values (?) returning VARCHAR_ARRAY__32,test_id"

[THR:005980] [23.05.2016 06:06:10] [test] cmd.describe_params(param)
[THR:005980] [23.05.2016 06:06:10] [test] cmd.set_param_info(param)
[THR:005980] [23.05.2016 06:06:10] [test] Create command ...
[THR:005980] [23.05.2016 06:06:10] [test] Prepare Command:

"delete from TBL_CS__UTF8 where test_id=?"

[THR:005980] [23.05.2016 06:06:11] [test] cmd.describe_params(param)
[THR:005980] [23.05.2016 07:13:22] [test] Total pass number:524297
[THR:005980] [23.05.2016 07:13:22] [test] COMMIT TRANSACTION [RETAINING=false]...
[THR:005980] [23.05.2016 07:13:22] *
[THR:005980] [23.05.2016 07:13:22] * REAL   TIME:40327720000   [01:07:12.7720000]
[THR:005980] [23.05.2016 07:13:22] * USER   TIME:2285570651    [00:03:48.5570651]
[THR:005980] [23.05.2016 07:13:22] * KERNEL TIME:966114193     [00:01:36.6114193]
[THR:005980] [23.05.2016 07:13:22] * TOTAL  TIME:3251684844    [00:05:25.1684844]

База опухла до 1TB.

Текущая статистика выглядит так:

Database "d:\Database\IBP_TEST_FB25_D3_2.GDB"
Database header page information:
        Flags                   0
        Checksum                12345
        Generation              42630329
        Page size               8192
        ODS version             11.2
        Oldest transaction      42477575
        Oldest active           42477576
        Oldest snapshot         42477572
        Next transaction        42477583
        Bumped transaction      1
        Sequence number         0
        Next attachment ID      137038
        Implementation ID       26
        Shadow count            0
        Page buffers            0
        Next header page        0
        Database dialect        3
        Creation date           Apr 16, 2016 21:08:36
        Attributes

    Variable header data:
        *END*

Новый триал IBProvider [сборка #20881]. Поддержка IPv6

Привет всем.

В новом триале, на уровне собственного клиента к Firebird, реализована поддержка IPv6. Так что, если у вас есть FB1-FB2.5 с поддержкой IPv6 — можете подключаться к нему через IBProvider 🙂

Была мысль добавить возможность указывать желаемый протокол через строку подключения — «inet4://localhost/…», «inet6://localhost/…», но решил пока не спешить. Кстати, аналогичная идея мелькала в FB-Devel.

В целом, это все связано с предварительной пробой пера в направлении создания собственного клиента к FB3.

Новый триал IBProvider [сборка #20828]

Привет всем.

Пару дней назад был выложен для тестирования новый триал IBProvider — v3.29.0.20828.

Главное и единственное изменение — при завершении (коммите/откате) транзакций, провайдер переводит связанные с ней курсоры и блобы в закрытое состояние.

Иными словами — провайдер наконец-то научился контролировать собственное состояние.

Вести с полей

Привет всем.

С начала года поменял пару жестких дисков — в ноуте (17410 часов) и десктопе (>40 тыс. часов).

Ноутбучный заменил на точно такой же — «Hitachi Travelstar 7K1000». В десктопе, после ротации, появился WD RE4 4TB — удивился, но мама выпуска 2007 года (x38, ICH9R) работает с ним без проблем.

А теперь Маша о главном. Что руки, что ноги… И тут начал помирать сервер, на котором последний год работал этот блог, сайт провайдера и еще много чего. Сейчас, благодаря героическим усилиям Администратора, идет процесс переезда на новое железо. Так что, если сайты в ближайшее время будут недоступны — звиняйте.

Сами понимаете — високосный год и все такое.

Обратная совместимость ISC API

Привет всем.

В процессе созерцания нового набора флагов IB12 (XE7) для XSQLVAR::sqlind

#define SQLIND_NULL         (short) (1 << 15)
#define SQLIND_INSERT       (1 << 0)
#define SQLIND_UPDATE       (1 << 1)
#define SQLIND_DELETE       (1 << 2)
#define SQLIND_CHANGE       (1 << 3)
#define SQLIND_CHANGE_VIEW  (1 << 5)

возникло две мысли:

1. Молодцы, что не боятся ломать существующий код. В предыдущих версиях sqlind принимал два значения: 0 и -1.

2. Вот почему бы не добавить возможность указания максимального «уровня» клиента? Если клиент не рюхает новые фишки, то и не надо разрешать их использовать.

Ну или явно разрешать подобные «фишки», которые клиент способен переварить.

Не знаю как лучше, но смысл, думаю, понятен.

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

XSQLVAR::sqltype и XSQLVAR::sqlind

Привет всем.

В ISC API, для представления описаний и значений колонок (параметров запроса), определена структура XSQLVAR.

typedef struct
{
 ISC_SHORT  sqltype;          /* datatype of field */
 ISC_SHORT  sqlscale;         /* scale factor */
 ISC_SHORT  sqlsubtype;       /* datatype subtype - currently BLOBs only */
 ISC_SHORT  sqllen;           /* length of data area */
 ISC_SCHAR* sqldata;          /* address of data */
 ISC_SHORT* sqlind;           /* address of indicator variable */
 ISC_SHORT  sqlname_length;   /* length of sqlname field */
 ISC_SCHAR  sqlname[32];      /* name of field, name length + space for NULL */
 ISC_SHORT  relname_length;   /* length of relation name */
 ISC_SCHAR  relname[32];      /* field's relation name + space for NULL */
 ISC_SHORT  ownname_length;   /* length of owner name */
 ISC_SCHAR  ownname[32];      /* relation's owner name + space for NULL */
 ISC_SHORT  aliasname_length; /* length of alias name */
 ISC_SCHAR  aliasname[32];    /* relation's alias name + space for NULL */
} XSQLVAR; 

Идентификатор типа указывается в поле XSQLVAR::sqltype и в случае NOT NULL колонки представляет собой четное число. Для Firebird 2.5 определен следующий набор идентификаторов типов данных:

#define SQL_TEXT         452
#define SQL_VARYING      448
#define SQL_SHORT        500
#define SQL_LONG         496
#define SQL_FLOAT        482
#define SQL_DOUBLE       480
#define SQL_D_FLOAT      530
#define SQL_TIMESTAMP    510
#define SQL_BLOB         520
#define SQL_ARRAY        540
#define SQL_QUAD         550
#define SQL_TYPE_TIME    560
#define SQL_TYPE_DATE    570
#define SQL_INT64        580
#define SQL_NULL       32766

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

Само значение индикатора NULL-состояние доступно по указателю XSQLVAR::sqlind. Минус один (-1) для NULL и ноль (0) для NOT NULL состояния.

Если идентификатор типа (XSQLVAR::sqltype) описывает обнуляемый тип, то XSQLVAR::sqlind должен содержать ненулевой указатель. Иначе возникнут проблемы.

Если идентификатор типа (XSQLVAR::sqltype) описывает NOT NULL колонку, то XSQLVAR::sqlind игнорируется.

Вот здесь мы подошли к вопросу, который регулярно появляется в моей голове, когда я вожусь с этим самым «XSQLVAR::sqlind»:

Какому гению пришло в голову увязывать наличие/отсутствие индикатора NULL-состояния (sqlind) значения с описанием типа (sqltype)?

Это же две несвязанные вещи!
(далее…)

Поддержка массивов в IBProvider

Привет всем.

На сайт выгружен новый триал IBProvider v3.28 с собственным механизмом чтения/записи массивов базы данных. Как я тут уже ранее писал — все это затеяно ради исправления бага с VARCHAR-массивами. Вкратце — клиент вместо VARCHAR-массивов должен был работать с CSTRING-массивами.

Исправление доступно только для серверов (FB/IB/YA), работающих на Windows (winnt_x86, winnt_amd64). Для остальных операционных систем и процессоров будет задействован старый добрый ISC API с одним ограничением — без поддержки чтения/записи VARCHAR-массивов.

Если есть пожелание добавить другие платформы — напишите, добавлю. Здесь только одна проблема — нужно будет прогнать тесты.

Настройка

По умолчанию, провайдер сам выбирает подходящий режим чтения/записи массивов с учетом платформы сервера и ODS базы данных.

Процессом выбора можно порулить с помощью нового свойства инициализации — «array_rw_mode». Допустимые значения: «api» или «direct».

Настройка распространяется на все колонки с массивами. Выборочная настройка для отдельных колонок не доступна.

Отмечу, что в случае IB7.1+ новый механизм нужно включать явно. По умолчанию, провайдер будет работать через ISC API. Это связано с шифрованием содержимого колонок, которое IBProvider, понятное дело, обеспечить не может.

Для FB (на Windows, x86/amd64), по умолчанию, будет использоваться новый механизм.

Это точно работает правильно?

Собственный механизм чтения/записи массивов был проверен практически на всех выпущенных версиях FB/IB. В том числе и с помощью перекрестных проверок.

Немного о внутренностях

Массивы в базе данных хранятся в блобах. Так что, новый механизм — это код, напрямую работающий с этими блобами.

Счастье наступило?

Лично для меня — да.

А в целом — нет. Потому что gbak работает через ISC API и, соответственно, он не сможет правильно сохранить и восстановить VARCHAR-массивы. Но это уже другая история.

«NEWS»: Firebird/Java Engine Plug-in in development

By fact, it is BREAKING NEWS!

facepalm
Adriano читает firebirdnews.org

PS. По моему, это как раз тот случай, когда надо сначала перепрыгнуть…

Дежавю

Привет Типа утро доброе.

Подошел Приполз утром к компьютеру.

И слышу характерное «плям!».

Напрягся.

[16.02.2016 23:01:19] [info] Provider DLL    :_IBProvider_v3_vc14xp_w64_d.dll
[16.02.2016 23:01:19] [info] Provider Version:3.27.3.20014
[16.02.2016 23:01:19] [info] Server Name     :Firebird
[16.02.2016 23:01:19] [info] Server Version  :3.0.0.32332
[16.02.2016 23:01:19] [info] Client Name     :Firebird
[16.02.2016 23:01:19] [info] Client Version  :3.0.0.32332
[16.02.2016 23:01:19] [info] Database ODS    :12.0
[16.02.2016 23:01:19] [info] Database Dialect:3
....
[17.02.2016 07:11:03] [Thread #2] [START  ] rowset.asynch.003.cancel_active_loader.read_only.random_access_v1.non_blocking_fetch.fetch_first_row.reexec_1 [#120]
Assertion (statement->haveException() == 0) failure: ..\..\..\src\remote\client\interface.cpp 2278