Connection pooling

PostgreSQL has a resource-intensive connection processing architecture. Every incoming connection creates a new backend process. This is not efficient when dealing with large numbers of connections in a production environment. When a client sends a request to a PostgreSQL server, it creates a connection with a database. Until the server responds back to the client, the connection remains open. The memory is allocated for each of these connections. If connections are opened and closed at a high frequency, this can cause problems. This is why PgBouncer is needed. PgBouncer is a PostgreSQL connection pooler that allows you to increase the number of connections without performance degradation.

NOTE
The PgBouncer feature is available for ADPG Enterprise Edition. See Configure PgBouncer.

How ADPG/PostgreSQL establishes connections

ADPG/PostgreSQL implements a "process per user" client/server model. In this model, every client process connects to exactly one backend process. Since it is not determined how many connections will be made, the PostgreSQL server has to use a supervisor process that spawns a new backend process every time a connection is requested. This supervisor process is called postmaster and listens at a specified TCP/IP port for incoming connections. Whenever it detects a request for a connection, it spawns a new backend process. Those backend processes communicate with each other and with other processes of the server instance using semaphores and shared memory to ensure data integrity throughout concurrent data access. Each of these backend processes may grow depending on the data it is accessing.

Despite the fact that memory is allocated for each new backend process, the available memory is not the main limiting factor. A more subtle and important point is that postmaster and its internal processes share memory for communication, and some parts of this shared space are global bottlenecks. For example, here is a structure that keeps track of every current process and transaction. Operations that happen in any backend require walking the entire list of processes or transactions stored in this structure. An exclusive lock is used to add a new process to the structure. The cumulative effect is that the performance of any given backend is inversely proportional to the number of all active backends in the system.

The max_connections ADPG/PostgreSQL configuration parameter determines the maximum number of concurrent connections to the server. The default value is 100. It is highly likely that this number of connections may not be enough in a production environment.

How PgBouncer works

PgBouncer is a PostgreSQL connection pooler. The client application can connect to PgBouncer as an ADPG/PostgreSQL server. The important point is PgBouncer caches the connections.

When PgBouncer receives a client connection, it performs authentication on behalf of the PostgreSQL server. PgBouncer supports all the authentication mechanisms that PostgreSQL provides.

If authentication is successful, PgBouncer checks for a cached connection with the same username and database combination. If a cached connection is found, it returns the connection to the client. Otherwise, PgBouncer creates a new connection. This operation must not violate the restrictions set in the following parameters: default_pool_size, max_client_conn, max_db_connections, and max_user_connections. All of these values can be defined in the PgBouncer settings. If creating a new connection would violate any limits specified in these settings, PgBouncer queues the connection until a new one can be created, unless the max_client_conn is exceeded. Violating the max_client_conn constraint aborts the connection.

In the transaction or statement pooling mode, the post-authentication operations are executed only when the client starts executing a transaction or statement, respectively. The pooling modes are described below.

How PgBouncer works
How PgBouncer works
How PgBouncer works
How PgBouncer works

Before returning a connection to the pool, PgBouncer performs a reset query to remove all session information — this makes it safe to share connections between clients.

PgBouncer can help you optimize:

  • network traffic;

  • overhead of starting a new backend process and authentication.

PgBouncer does not support automated load balancing or high availability, but ADPG Enterprise Edition provides this functionality. See Load balancing.

PgBouncer has the following advantages:

  • It does not require client-side code changes.

  • It provides pass-through authentication. PgBouncer can securely authenticate users without access to their passwords. This makes PgBouncer more secure and easier to maintain — there is no need to update PgBouncer every time a user updates the password.

  • It is a single process, and all client commands and server responses pass through it without any processing. Therefore, it maintains a very small memory footprint.

  • It can significantly improve the number of transactions per second a server processes, and it scales very well to many clients.

PgBouncer modes

PgBouncer modes allow users to decide when a connection should be returned to the pool. The following modes are available:

You can set the required mode on the Primary configuration tab of the ADPG service. See Configure PgBouncer.

Session

In the session pooling mode, a connection is returned to the pool when a client closes a session. This is the default mode. This mode reduces the time and resources required to establish connections and authenticate users.

Transaction

In the transaction pooling mode, a connection is returned to the pool when a client completes a transaction. There is no guarantee that two transactions run on the same client PgBouncer connection will run on the same PgBouncer server connection. A server connection is assigned to the client connection whenever client starts a new transaction, and is released to the pool not when client disconnects, but rather — when it finishes transaction, for example, using ROLLBACK or COMMIT. Note that if you do not start a transaction explicitly, each query in PostgreSQL is executed in a single transaction. See Transactions.

The transaction mode provides better performance and allows you to reduce the number of idle transactions, in addition to reducing time spent on establishing connections and user authentication.

You need to be careful when using sequences, advisory locks, and %_SHARED in PL/Perl functions. Also, query plans created by the PREPARE statements are cashed and exist outside a transaction. Their use in the transaction mode may lead to errors or unexpected results.

This is the full list of the session-based PostgreSQL features that are not supported in the transaction mode:

For more information, see PgBouncer features.

Statement

In the statement pooling mode, a connection is returned to the pool as soon as a statement is executed. It is the most aggressive mode. This is a transaction pool with one limitation: multi-statement transactions are not allowed. This is intended to provide an autocommit mode on the client, primarily targeted at PL/Proxy.

Found a mistake? Seleсt text and press Ctrl+Enter to report it