Страница 1 из 1

ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 01.11.2019 18:16:36
Lucifer
Имеем: PostgreSQL 9.5/9.6, все на Ubuntu. Там же PgBouncer 1.9 версии
Клиент - Win8.1 x64, Lazarus 2.0.6, FPC 3.0.4, ZeosDBO 7.2.6 (на предыдущем 7.2.4 аналогично)
Приложение многопоточное, область - неважно, в принципе. Но нужно одновременно подключаться к десяткам баз. На каждую базу - два потока, в каждом собственные коннекты Коннект ровно один на поток. Соответственно, имеем массив потоков TThread. Создается штатно через Create.
Код: Выделить всё
constructor TFirmThread.Create(fSuspended: Boolean);
begin
  inherited Create(fSuspended);
  fTerminated := False;
  CardAlreadyOpen := False;
  Priority := tpNormal;
  FreeOnTerminate := True;
  zConn_m := TZConnection.Create(dmMain);
.....
  Start;

И вроде бы все работает, все создается и подключается... Но регулярно Zeos теряет коннект, при попытке реконнекта - прога полностью впадает в ступор, то есть виснет насмерть. Убивается только из диспетчера задач. В лог самого приложения много не попадает, но заметил вот такое:
Код: Выделить всё
SQL_First   SQL Error: лишние данные в сообщении "T"
...
Database connection component is not assigned Closed

А в логах сервера при этом:
Код: Выделить всё
LOG:  could not receive data from client: Соединение разорвано другой стороной

Получается, что не сервер рвет соединение, а сими Zeos?
Вот куда рыть? Хотя бы примерно... Отказаться от боунсера не предлагать, клиентов очень много, а возможности серверов ограничены.
P.S.
UniDAC тоже пробовал - он вообще не умеет через боунсер общаться. А если и можно заставить в редкие мгновения просветления, то лучше б он вообще не работал никак.
P.P.S.
Каких-то других компонентов нет? Может, я плохо искал?

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 01.11.2019 23:02:25
alexs
Попробуй параметр у ZEOS соединения установить:
Код: Выделить всё
      FPGConnection.Properties.Values['EMULATE_PREPARES']:='True';

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 02.11.2019 12:54:44
Lucifer
Леш, ты не поверишь... Установлен! Без него еще хуже. Есть у меня подозрение, что это из-за длинных маршрутов. Сами серверы в Германии, на хэтцнере, если что. Я пробовал тестовые приложения гонять в локальной сети, просил товарища стенд поднять - работают. Но я могу быть и неправым.

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 02.11.2019 21:14:01
serbod
Найди строку текста ошибки и поставь брекпоинт туда, где эта строка используется. После остановки смотри стек вызовов, откуда эта ошибка пришла.

Если по каким-то причинам невозможно сделать это в IDE, можно сделать дамп стектрейса в лог программно.

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

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 03.11.2019 17:58:44
olegy123
Lucifer писал(а):Получается, что не сервер рвет соединение, а сими Zeos?
Zeos это всего лишь обертка libpg.
Действительно Zeos, так другие компоненты могут например при утечки памяти делать харакири..
Но также это может делать libpg.

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

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 04.11.2019 12:25:25
debi12345
Можно делать коннекты через SSH-туннели - они умеют делать SSH-реконнект и держать коннекты внутри туннелей

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 05.11.2019 10:29:03
Lucifer
SSH невозможен, к сожалению. Никто не будет давать лишнюю дыру для того, чтоб можно было все поломать.
А вот с антивирем - идея здравая. У меня нет антивиря от слова совсем, ибо виртуалка. И в случае чего она просто убивается и восстанавливается из бэкапа. Поэтому и выловить не могу.
В нутро же самого зеоса лезть не сильно хочется. Но заметил, что при обрывах его внутреннее состояние описывается очень кратко - FConnection = nil. То есть, вообще умерло все. Насмерть.

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 05.11.2019 22:05:18
debi12345
SSH невозможен, к сожалению. Никто не будет давать лишнюю дыру для того, чтоб можно было все поломать.

Для секьюрности обычно все делается ровно наоборот - дают только SSH/OpenVPN, а все остальное, если очень приспичит - внутри SSH/OpenVPN-туннеля. Очень странные Вам попались немцы, ламеры какие-то. Сучувствую.

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 06.11.2019 00:51:41
olegy123
Lucifer писал(а):FConnection = nil. То есть, вообще умерло все. Насмерть.

анука поподробнее это когда nil появляется?
Nil - вообще то означает что указатель не заезжен. Он вообще не был в работе..еще родится не успел..
Следовательно нужно искать что вверху, в начале.

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 06.11.2019 01:38:24
debi12345
Nil - вообще то означает что указатель не заезжен. Он вообще не был в работе..еще родится не успел..

Или, что более вероятно - правильно, как и должно быть, выгружен из памяти в try->finally

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 08.11.2019 17:35:03
Lucifer
Так выгружается он вместе с убийством потока в деструкторе самого потока. Однако же потоки живые, а коннект при этом становится Nil. Пока обхожусь тем, что просто пересоздаю коннект в потоке. Но очень уж часто это происходит.

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 09.11.2019 11:06:01
olegy123
Lucifer писал(а):Так выгружается он вместе с убийством потока в деструкторе самого потока. Однако же потоки живые, а коннект при этом становится Nil.
Нужен код.
Явно, что идет не так..

раз есть сомнения, то следовало бы засунуть внутрь
TFirmThread.Execute..
Код: Выделить всё
zConn_m := TZConnection.Create(dmMain);
try
// выполнение..
finality
  FreeAndNil(zConn_m);
end


Добавлено спустя 4 минуты 54 секунды:
все равно работа происходит в отдельном потоке только в процедуре Execute

возможно при работе с функционалом PostgreSQL вылетает ошибка, у меня так было когда я множил потоки в одном Connection. сервер PostgreSQL грязно ругался что вызываемая функция уже используются..

Добавлено спустя 8 минут 9 секунд:
важно прочитать
https://www.postgresql.org/docs/8.4/lib ... ading.html
PQisthreadsafe
Returns the thread safety status of the libpq library.
int PQisthreadsafe();
Returns 1 if the libpq is thread-safe and 0 if it is not.

если PQisthreadsafe() вернет 0 - то libpq не потоко-безопасна..

Добавлено спустя 8 минут 18 секунд:
A single connection to PostgreSQL does not support simultaneous queries.

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 09.11.2019 13:09:28
pupsik
Код: Выделить всё
zConn_m := TZConnection.Create(dmMain);
- поток... датамодуль ("где его искать" и "сколько их то будет")? Т.е. второй поток ЧТО и ГДЕ будет уничтожать?

п.с.
Гадание как всегда у руля. 9 дней барабаны звучат. Жость

Re: ZeosDBO, PgBouncer и многопоточность

СообщениеДобавлено: 14.11.2019 18:35:52
Lucifer
Отбой тревоги. Нашел...
Сам же выкинул таймер из потока, потому что глючило оно. И забыл выпилить процедуру OnTimer на нем. А код перенес в поток. Вот оно и ломилось по тем же самым адресам.
Осталось теперь еще заставить все это дело по ядрам гулять нормально, а не занимать одно ядро на 100%.