PostgreSQL
September 10, 2022

Изменить режим работы пулера соединений

Для своей работы Managed PostgreSQL использует пуллер соединений Odyssey. Разбор того как работает пуллер соединений будет позже. Пока достаточно понимать, что перед каждым кластером postgres в облаке установлен пуллер соединений и отключить его нельзя.

По-умолчанию используется сессионый режим работы пуллера. О режимах работы напишу чуть ниже. А пока поменяем режим работы на транзакционный.

Поехали!

export POSTGRES=$(yc postgresql cluster get cam-postgres1 --format=json | jq -r ".id")
export FOLDER_ID=$(yc config get folder-id)
yc postgres cluster update $POSTGRES \
  --folder-id $FOLDER_ID \
  --connection-pooling-mode transaction \
  --async

Готово!

PostgreSQL выделяет отдельный процесс на каждое установленное соединение. При большом количестве клиентских соединений СУБД создает множество процессов и управляет разделяемыми структурами данных. Из-за этого может возникнуть нехватка вычислительных ресурсов, которая сказывается на производительности СУБД.

Чтобы решить проблему нехватки ресурсов, перед кластером PostgreSQL часто размещают пулеры соединений (connection pooler, например, PgPool-II или PgBouncer). Пулеры управляют соединениями, позволяя подключиться к СУБД большому числу клиентов без деградации производительности. Между пулером и СУБД поддерживается относительно небольшое количество соединений, которые можно переиспользовать. После отключения клиента соединение возвращается в пул и может быть повторно использовано тем же самым или новым клиентом.

Такая схема развертывания усложняет администрирование, т. к. к инфраструктуре СУБД добавляются серверы, на которых расположен пулер.

Odyssey поддерживает три режима управления соединениями:

  • Сессионный (по умолчанию): В этом режиме клиентское соединение устанавливается при первом запросе к базе данных и поддерживается до тех пор, пока клиент не разорвет сессию. Затем это соединение может быть использовано другим или этим же клиентом. Такой подход позволяет хорошо переживать момент установления большого количества клиентских соединений к СУБД (например, при старте приложений, обращающихся к базам данных).Такой режим поддерживается всеми клиентами PostgreSQL, но является менее производительным, чем транзакционный режим.
  • Транзакционный: В этом режиме клиентское соединение устанавливается при первом запросе к базе данных и поддерживается до завершения транзакции. Затем это соединение может быть использовано другим или этим же клиентом. Такой подход позволяет поддерживать небольшое количество серверных соединений между пулером и хостами PostgreSQL при большом количестве клиентских соединений.Транзакционный режим обеспечивает высокую производительность и позволяет максимально эффективно нагрузить СУБД. Однако такой режим поддерживается не всеми клиентами PostgreSQL, и в нем недоступно использование:
    • временных таблиц (temporary tables), курсоров (cursors) и рекомендательных блокировок (advisory locks), которые существуют дольше одной транзакции;
    • подготовленных операторов (prepared statements).
  • Режим запроса: В этом режиме клиентское соединение поддерживается только при выполнении запроса к базе данных. Затем это соединение может быть использовано другим или этим же клиентом. За раз выполняется только один запрос. Транзакции с несколькими запросами запрещены и при обращении завершаются неудачей.Такой подход полезен при включенном режиме AUTOCOMMIT для клиентских сессий, когда каждая транзакция уже ограничена одним запросом. Однако режим запроса поддерживается не всеми клиентами PostgreSQL, а при одновременном включении режима AUTOCOMMIT и настройки synchronous_commit = remote_apply производительность такого кластера существенно снижается.