Skip to content

Conversation

@JelteF
Copy link
Member

@JelteF JelteF commented Feb 16, 2024

In #845 full tracking of expected responses was implemented. This turned out to have bugs when sending COPY FROM STDIN queries using the extended protocol. The protocol explicitly allows sending Sync messages after sending an Execute message for a COPY FROM STDIN command. Such Sync messages are ignored by the server until a CopyDone or CopyFail message is received. The new command queue tracking did not take this into account, and was incorrectly expecting more ReadyForQuery messages from the server.

This could lead to two problems for the server connection on which the COPY FROM STDIN was sent:

  1. The server connection would never be unassigned from the client.
  2. Memory usage for this server connection would continue to increase until the client disconnects.
  3. If max_prepared_statements was non-zero, then clients might receive ParseComplete and CloseComplete responses in the wrong order. This wouldn't result in wrong behaviour by the server, but the client might get confused and close the connection.

This PR fixes these issues. It also removes the rfq_count tracking, since it's now only keeping track of a strict subset of what the outstanding request queue was tracking.

Fixes #1023
Fixes #1024

src/server.c Outdated
if (!clear_outstanding_requests_until(server, "cf"))
return false;
} else {
server->query_failed = true;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should happen always probably, otherwise we won't pop a later received CopyDone message in case of failure.

Copy link
Member

@eulerto eulerto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Don't forget to include test_copy.py into EXTRA_DIST target (I submitted another PR #1026 that included some recent tests into it.)

In pgbouncer#854 full tracking of expected responses was implemented. This turned
out this have bugs when sending `COPY FROM STDIN` queries using the
extended protocol. The protocol explicitely allows sending `Sync`
messages after sending an `Execute` message for a `COPY FROM STDIN`
command. Such Sync messages are ignored by the server until a CopyDone
or CopyFail message is received. The new command queue tracking did not
take this into account, and was incorrectly expecting more ReadyForQuery
messages from the server.

This PR fixes that issue. It also removes the rfq_count tracking, since
it's now only keeping track of a strict subset of what the outstanding
request queue was tracking.

Fixes pgbouncer#1023
Fixes pgbouncer#1024

TODO:
- [ ] Add tests for COPY TO STDOUT
@JelteF JelteF force-pushed the fix-copy-in-prepared-statement branch from e3048a3 to 0c7ca30 Compare February 22, 2024 09:23
@JelteF JelteF force-pushed the fix-copy-in-prepared-statement branch from 0c7ca30 to 3c25bae Compare February 22, 2024 11:10
@eulerto
Copy link
Member

eulerto commented Feb 22, 2024

There are some tests that still refers to table "t".

@JelteF
Copy link
Member Author

JelteF commented Feb 22, 2024

There are some tests that still refers to table "t".

ugh, fixed

Copy link
Member

@eulerto eulerto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@JelteF JelteF enabled auto-merge (squash) February 22, 2024 12:29
@JelteF JelteF merged commit e913a15 into pgbouncer:master Feb 22, 2024
JelteF added a commit to JelteF/pgbouncer that referenced this pull request Mar 6, 2024
I realized I was a bit too trigger-happy when removing all references to
expected_rfq_count in pgbouncer#1025. One occurrence should have been replaced
with adding an outstanding request.
JelteF added a commit to JelteF/pgbouncer that referenced this pull request Mar 6, 2024
I realized I was a bit too trigger-happy when removing all references to
expected_rfq_count in pgbouncer#1025. One occurrence should have been replaced
with adding an outstanding request.
JelteF added a commit that referenced this pull request Apr 10, 2024
I realized I was a bit too trigger-happy when removing all references to
`expected_rfq_count` in #1025. One occurrence should have been replaced
with adding an outstanding request. Normally this isn't an issue, but it
could cause the server connection not to be closed if the client
disconnects before the auth_query is finished running.

To be clear, #1025 did not introduce a regression in this respect.
Because `expect_rfq_count` being non-zero on would not cause
a server connection closure when the server was released.
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 this pull request may close these issues.

FIXME: query end, but query_start == 0 closing because: client disconnect while server was not ready when set max_prepared_statement>0

2 participants