When running in the regular mode, Postgres Pro
spawns a separate backend for each connection request. With connection
pooling enabled, the number of backends that can be used for each
database is limited by the session_pool_size value.
Once this limit is reached, postmaster
stops spawning new backend processes for the corresponding
sessions and redirects further connection requests
to one of the backends that has already been started.
Since each Postgres Pro backend can
work with a single database only, built-in connection pooler
has to maintain separate connection pools for
each database. The number of pools is unlimited:
each time a new database needs to be served, a new pool is added.
To assign sessions to an appropriate pool,
postmaster needs to know the target database for the
client connection, which requires receiving and parsing a startup packet
from the client. To avoid a bottleneck at this stage,
postmaster delegates the task of reading
the startup packet to one of the listener processes.
The listener fetches the startup packet and returns the result back to
postmaster. Based on the received information,
postmaster chooses the pool for this client and
redirects the connection to this pool using the file descriptor
transfer mechanism.
You can disable connection pooling for some databases and users by specifying them in the dedicated_databases and dedicated_users parameters, respectively. Such databases and users can use an unlimited number of dedicated backends, thus getting priority access to available system resources.
To avoid substantial changes in Postgres Pro locking mechanism, only transaction-level pooling policy is supported. In this mode, the backend can be rescheduled to another session only after it has completed the current transaction. However, the built-in pooler provides session semantics for pooled connections, so that all changes in the session context made by a client application, such as session configuration parameters, preparing statements, or creating temporary tables, are saved/restored by Postgres Pro when the backend is rescheduled to another session. By contrast, pgbouncer can provide session semantics only in the session pooling mode, which does not limit the number of launched backends.
Pooled sessions are bound to backends and cannot be migrated between them. Migrating a session would also require serialization and transfer of the complete session context, which is a non-trivial task. By default, pooled backends continue running even if all sessions assigned to them have been already terminated. To change this behavior, you can set restart_pooler_on_reload or idle_pool_worker_timeout configuration parameters.