Re: Extensibility of the PostgreSQL wire protocol

From: Jan Wieck <jan(at)wi3ck(dot)info>
To: Damir Simunic <damir(dot)simunic(at)gmail(dot)com>, Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Robert Haas <robertmhaas(at)gmail(dot)com>, "Jonah H(dot) Harris" <jonah(dot)harris(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: Extensibility of the PostgreSQL wire protocol
Date: 2021-02-19 18:30:54
Message-ID: 84ad6e59-7202-595b-0d00-ad51d6037bb2@wi3ck.info
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 2/19/21 12:18 PM, Damir Simunic wrote:
>
>> On 19 Feb 2021, at 14:48, Heikki Linnakangas <hlinnaka(at)iki(dot)fi> wrote:
>>
>> For example, there has been discussion elsewhere about integrating connection pooling into the server itself. For that, you want to have a custom process that listens for incoming connections, and launches backends independently of the incoming connections. These hooks would not help with that.
>>
>
> Not clear how the connection polling in the core is linked to discussing pluggable wire protocols.

It isn't per se. But there are things pluggable wire protocols can help
with in regards to connection pooling. For example a connection pool
like pgbouncer can be configured to switch client-backend association on
a transaction level. It therefore scans the traffic for the in
transaction state. This however only works if an application uses
identical session states across all connections in a pool. The JDBC
driver for example only really prepares PreparedStatements after a
number of executions and then assigns a name based on a counter to them.
So it is neither guaranteed that a certain backend has the same
statements prepared, nor that they are named the same. Therefore JDBC
based applications cannot use PreparedStatements through pgbouncer in
transaction mode.

An "extended" libpq protocol could allow the pool to give clients a
unique ID. The protocol handler would then maintain maps with the SQL of
prepared statements and what the client thinks their prepared statement
name is. So when a client sends a P packet, the protocol handler would
lookup the mapping and see if it already has that statement prepared.
Just add the mapping info or actually create a new statement entry in
the maps. These maps are of course shared across backends. So if then
another client sends bind+execute and the backend doesn't have a plan
for that query, it would internally create one.

There are security implications here, so things like the search path
might have to be part of the maps, but those are implementation details.

At the end this would allow a project like pgbouncer to create an
extended version of libpq protocol that caters to the very special needs
of that pool.

Most of that would of course be possible on the pool side itself. But
the internal structure of pgbouncer isn't suitable for that. It is very
lightweight and for long SQL queries may never have the complete 'P'
message in memory. It would also not have direct access to security
related information like the search path, which would require extra
round trips between the pool and the backend to retrieve it.

So while not suitable to create a built in pool by itself, loadable wire
protocols can definitely help with connection pooling.

I also am not sure if building a connection pool into a background
worker or postmaster is a good idea to begin with. One of the important
features of a pool is to be able to suspend traffic and make the server
completely idle to for example be able to restart the postmaster without
forcibly disconnecting all clients. A pool built into a background
worker cannot do that.

Regards, Jan

--
Jan Wieck
Principle Database Engineer
Amazon Web Services

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Alvaro Herrera 2021-02-19 18:35:09 Re: PATCH: Batch/pipelining support for libpq
Previous Message Damir Simunic 2021-02-19 17:18:48 Re: Extensibility of the PostgreSQL wire protocol