Ситуация... Есть Firebird 2 на двух серверах с общим RAID массивом.
Под Linux-ом. Есть клиенты тоже под Linux-ом. Если мы меняем комплект
сервера, то клиенты временно теряют соединение. В зависимости от того,
в каком состоянии они в этом момент находились, на клиентской стороне
происходит либо ошибка при попытке выполнения запроса, либо SIGPIPE,
как правило, если оборвался уже выполняющийся запрос. По этим
действиям сейчас делается повторная попытка соединения. Клиент написан
на C++ с ESQL. Делается следующее...
  if (local_db) {
    EXEC SQL
      DISCONNECT local_db;

    local_db=(isc_db_handle)NULL;
  };

  EXEC SQL
    CONNECT local_db USER :UserName.c_str()
PASSWORD :Password.c_str();

  if (SQLCODE) {

    isc_sql_interprete(SQLCODE, error_message, 256);
    syslog(LOG_MAKEPRI(LOG_USER, LOG_WARNING), "Connecting local_db
error !");
    syslog(LOG_MAKEPRI(LOG_USER, LOG_WARNING), error_message);

    local_db=(isc_db_handle)NULL;
  };

  return SQLCODE;

Или если посмотреть после препроцессора...
...
   isc_detach_database (isc_status, &local_db);
...
  isc_expand_dpb (&isc_5p, &isc_5l, isc_dpb_user_name,
UserName.c_str(), isc_dpb_password, Password.c_str(),
isc_dpb_sql_role_name, (char*) 0, isc_dpb_lc_messages, (char*) 0,
isc_dpb_lc_ctype, (char*) 0, 0);
  isc_attach_database (isc_status, 0, "localhost:fdp", &local_db,
isc_5l, isc_5p);
...

Ну и это повторяется до тех пор пока не соединимся... В процедуре есть
защита от повторного входа, т.е. если на коннекте будет опять SIGPIPE,
то поворного захода в реконнекта не будет. Всё работало замечательно,
на 1.5.3. Но сейчас на 2.0 в ходе проверки выяснилось, что при этом
время от времени в недрах клиента происходит SIGSEG со строкой... Вот
примерно тут:

0xb6ee609f in strlen () from /lib/libc.so.6
#0  0xb6ee609f in strlen () from /lib/libc.so.6
#1  0xb695108d in SCH_ast () from /usr/lib/libfbclient.so.2
#2  0xb6967840 in KEYWORD_getTokens () from /usr/lib/libfbclient.so.2
#3  0xb6968830 in KEYWORD_getTokens () from /usr/lib/libfbclient.so.2
#4  0xb6968e60 in KEYWORD_getTokens () from /usr/lib/libfbclient.so.2
#5  0xb697b166 in KEYWORD_getTokens () from /usr/lib/libfbclient.so.2
#6  0xb696bd24 in KEYWORD_getTokens () from /usr/lib/libfbclient.so.2
#7  0xb6955651 in isc_receive () from /usr/lib/libfbclient.so.2

Причем довольно регулярно. В результате приложение вылетает... Клиент
скомпилирован без отладочной информации, поэтому точнее не могу
сказать, где именно происходит ошибка. Понимаю что, так вопрос
задавать тупо, но... Может я просто не знаю, а надо что то вызвать
перед попыткой повторного соединения, чтобы обнулить/очистить/
освободить внутренние переменные в библиотеке клиента firebird ? Пока
нет возможности это проверить на "живом" железе, поэтому на ноуте у
себя поставил SS вместо CS и тестил перезапуском сервера. В результате
после того как навсталял по всему коду процедуры реконнекта (с целью
найти место где валится) cout << в перемешку с isc_sql_interprete( у
меня клиентское приложение перестало валится с SIGSEG-ом... Т.е.
возникла мысль, поставит sleep, т.к. по идее, сейчас задержка между
вызовами disconnect/connect выросла. А возможно на это повлиял лишний
вызов isc_sql_interprete. Но, понятно что 100% уверенности нет.
Подскажите, если у кого опыт подобного рода имеется. Горим...

Ответить