Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

application_name backend (not) reporting back to the client : pgbouncer, PgSQL 14+, pgbouncer 1.18+ in transaction mode #993

Closed
achix opened this issue Dec 10, 2023 · 1 comment · Fixed by #999

Comments

@achix
Copy link

achix commented Dec 10, 2023

Hello
coming from the pgsql-admin list : https://www.postgresql.org/message-id/flat/e33e0231-77d7-4dd7-4b7c-97af1d0e091b%40cloud.gatewaynet.com

After this commit postgres/postgres@2432b1a postgresql refrains from reporting back a parameter to the client if the value set is unchanged. Now in transaction mode lets describe the following scenario :

Client C1 :
psql "postgresql://amantzio@localhost:6432/dynacom?application_name="
## ^^ it is vital that the above has no value after =
SET application_name='MyApp';
## Lets call the server that pgbouncer links C1 to as S1

Client C2 :
psql "postgresql://amantzio@localhost:6432/dynacom?application_name="
## ^^ it is vital that the above has no value after =
SET application_name='MyApp';
## Lets suppose/force C2 to connect to the same S1

We will notice that the application_name for C2 is empty.

What happens :
Client C1 connects to pgbouncer. Pgbouncer starts S1 and links C1 with S1. There is no application_name in the startup packet. Then C1 issues SET application_name='MyApp'; this gets executed in S1 and the backend identifies this as a change in value, correctly, so it reports back application_name to C1 which stores it in its state. All good.
Now C2 connects, and pgbouncer links the same S1 to serve C2. There is no application_name in the startup packet. Then C2 issues SET application_name='MyApp'; this gets executed in S1 and the backend identifies this as the same value as the one already set before, so it does not report back the application_name to C1. PROBLEM. This then may break the application.

Our workaround is to define a dummy string e.g. '' in the startup packet, followed by an explicit SET application_name='OurApplicationName' so that the backend always receives two consecutive settings, and always understands the 2nd as a changed value, so it always reports the correct application_name back to pgbouncer .

I think this is a serious situation that must be either fixed or at least documented.

@achix
Copy link
Author

achix commented Dec 11, 2023

Here is a short video of the reproduction of the problem :
https://www.youtube.com/watch?v=qcrVsFszV0Y

@JelteF JelteF added bug something is broken and removed bug something is broken labels Dec 22, 2023
JelteF added a commit to JelteF/pgbouncer that referenced this issue Dec 22, 2023
It was reported in pgbouncer#993 that using an empty `application_name` on
connection startup could result in the actual application_name that was
set later not being detected. The reason was that we were explicitely
not forwarding empty strings from clients as settings to Postgres. This
is fixed by simply removing this check. Why we were explicitely ignoring
empty strings is not clear to me. But our handling of startup parameters
and GUCs has heavily changed over the years, and is able to handle them
fine like this.
JelteF added a commit that referenced this issue Dec 22, 2023
It was reported in #993 that using an empty `application_name` on
connection startup could result in the actual application_name that was
set later not being detected. The reason was that we were explicitely
not forwarding empty strings from clients as settings to Postgres. This
is fixed by simply removing this check. Why we were explicitely ignoring
empty strings is not clear to me. But our handling of startup parameters
and GUCs has heavily changed over the years, and is able to handle them
fine like this.
JelteF added a commit that referenced this issue Jan 2, 2024
It was reported in #993 that using an empty `application_name` on
connection startup could result in the actual application_name that was
set later not being detected. The reason was that we were explicitely
not forwarding empty strings from clients as settings to Postgres. This
is fixed by simply removing this check. Why we were explicitely ignoring
empty strings is not clear to me. But our handling of startup parameters
and GUCs has heavily changed over the years, and is able to handle them
fine like this.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants