Fastpath и large objects
Используйте эту страницу, если pgjdbc или Hibernate работают с PostgreSQL large objects через pg_doorman в режиме transaction pool.
pgjdbc LargeObjectManager вызывает функции PostgreSQL large object через
Fastpath FunctionCall (F): lo_creat, lo_open, lo_read, lo_write,
lo_close и другие. PostgreSQL отвечает FunctionCallResponse (V), а затем
ReadyForQuery (Z). В V лежит результат функции. Состояние транзакции
приходит в следующем ReadyForQuery.
До 3.10.7 pg_doorman не передавал FunctionCall в transaction pooling. Клиент
мог отправить вызов функции large object и навсегда ждать ответа. Начиная с
3.10.7 pg_doorman передаёт вызов в PostgreSQL, возвращает клиенту
FunctionCallResponse и освобождает backend только после ReadyForQuery, если
PostgreSQL сообщил idle-состояние.
Transaction pooling
Дескрипторы large object живут внутри PostgreSQL-транзакции. Если после
fastpath-вызова ReadyForQuery вернул статус T или E, pg_doorman оставляет
за клиентом тот же backend. Backend освобождается только после idle-статуса
I, обычно после COMMIT или ROLLBACK.
Fastpath-вызовы в autocommit освобождают backend сразу после ReadyForQuery со
статусом idle.
Это соответствует поведению PgBouncer в transaction pooling для трафика
FunctionCall.
Размер пула
Каждый активный вызов функции large object занимает один backend до
ReadyForQuery. Считайте размер пула по числу одновременных чтений и записей
large objects, а не только по обычному темпу SQL-запросов.
После включения такого трафика следите за:
SHOW POOLS: активные клиенты, активные серверы и ожидающие клиенты.- Ошибками
query_wait_timeout. - Перцентилями задержек для пулов с large object трафиком.
Если всплески вызовов large object подводят клиентов к query_wait_timeout,
увеличьте пул для нужной пары user/database или уменьшите параллелизм large
object операций в приложении.
Большие чтения
pg_doorman передаёт большие DataRow, CopyData и FunctionCallResponse
потоково, если они превышают general.message_size_to_be_stream. Большой
fastpath-ответ lo_read уходит клиенту без предварительного буферизования
всего ответа в памяти pg_doorman.
Потоковая передача ограничивает расход heap в pg_doorman, но не делает большие
одиночные чтения бесплатными. Большой lo_read всё равно удерживает backend и
сокетные буферы, пока PostgreSQL отправляет ответ. Лимиты сообщений протокола
PostgreSQL тоже остаются. Читайте large objects порциями на стороне приложения.
Таймауты
server_lifetime применяется к idle backend в пуле. Он не прерывает backend,
который выполняет чтение или запись large object.
Дескрипторы large object зависят от состояния PostgreSQL-транзакции. Если
приложение оставляет large object транзакцию idle между fastpath-вызовами,
PostgreSQL idle_in_transaction_session_timeout может закрыть backend.
pg_doorman вернёт клиенту ошибку соединения. Держите large object транзакции
короткими или настройте PostgreSQL-таймауты для сессий, которые работают с
large objects.