Вкратце
1. Вернулся из отпуска
2. Зашел отладчиком в исходный код fbclient.dll v3.0

3. Захотелось пожелать разработчикам сервера всего доброго, хорошего настроения и здоровья
1. Вернулся из отпуска
2. Зашел отладчиком в исходный код fbclient.dll v3.0
3. Захотелось пожелать разработчикам сервера всего доброго, хорошего настроения и здоровья
Слева диск «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 апреля. Участники:
Подключение: 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*
Привет всем.
В новом триале, на уровне собственного клиента к Firebird, реализована поддержка IPv6. Так что, если у вас есть FB1-FB2.5 с поддержкой IPv6 — можете подключаться к нему через IBProvider 🙂
Была мысль добавить возможность указывать желаемый протокол через строку подключения — «inet4://localhost/…», «inet6://localhost/…», но решил пока не спешить. Кстати, аналогичная идея мелькала в FB-Devel.
В целом, это все связано с предварительной пробой пера в направлении создания собственного клиента к FB3.
Привет всем.
Пару дней назад был выложен для тестирования новый триал IBProvider — v3.29.0.20828.
Главное и единственное изменение — при завершении (коммите/откате) транзакций, провайдер переводит связанные с ней курсоры и блобы в закрытое состояние.
Иными словами — провайдер наконец-то научился контролировать собственное состояние.
Привет всем.
С начала года поменял пару жестких дисков — в ноуте (17410 часов) и десктопе (>40 тыс. часов).
Ноутбучный заменил на точно такой же — «Hitachi Travelstar 7K1000». В десктопе, после ротации, появился WD RE4 4TB — удивился, но мама выпуска 2007 года (x38, ICH9R) работает с ним без проблем.
А теперь Маша о главном. Что руки, что ноги… И тут начал помирать сервер, на котором последний год работал этот блог, сайт провайдера и еще много чего. Сейчас, благодаря героическим усилиям Администратора, идет процесс переезда на новое железо. Так что, если сайты в ближайшее время будут недоступны — звиняйте.
Сами понимаете — високосный год и все такое.
Привет всем.
В процессе созерцания нового набора флагов 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. Вот почему бы не добавить возможность указания максимального «уровня» клиента? Если клиент не рюхает новые фишки, то и не надо разрешать их использовать.
Ну или явно разрешать подобные «фишки», которые клиент способен переварить.
Не знаю как лучше, но смысл, думаю, понятен.
В любом случае, полагаю, это нужно делать после подключения к базе данных, после определения типа и версии сервера.
Привет всем.
В 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 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-массивы. Но это уже другая история.
By fact, it is BREAKING NEWS!
PS. По моему, это как раз тот случай, когда надо сначала перепрыгнуть…