fix: drop stale ReadyForQuery expectation when server enters COPY IN mode#885
Open
NikolayS wants to merge 1 commit intopgdogdev:mainfrom
Open
fix: drop stale ReadyForQuery expectation when server enters COPY IN mode#885NikolayS wants to merge 1 commit intopgdogdev:mainfrom
NikolayS wants to merge 1 commit intopgdogdev:mainfrom
Conversation
|
|
…mode
When a client sends Bind+Execute+Sync for a COPY FROM STDIN statement,
pgdog adds a ReadyForQuery expectation for that Sync. But PostgreSQL
ignores Sync during COPY IN mode (protocol spec §55.2.6) and never sends
ReadyForQuery for it. The stale entry stays in the queue, done() never
returns true, and the connection is never returned to the pool.
Call remove_one_rfq() in forward() when we see CopyInResponse ('G') to
drop the ReadyForQuery that will never arrive.
Verified with end-to-end integration test using tokio-postgres copy_in():
- WITHOUT fix: query timeout - CopyDone hangs because state machine is desynced
- WITH fix: COPY completes, subsequent queries work normally
https://claude.ai/code/session_01PQvrbw2xJHgQBXtASWHFcv
98dfd00 to
dae4519
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
When a client sends a COPY FROM STDIN statement via extended query protocol (Parse+Bind+Execute+Sync), pgdog adds a
ReadyForQueryexpectation to its protocol state queue for that Sync. But PostgreSQL ignores Sync during COPY IN mode (protocol spec §55.2.6) and never sendsReadyForQueryfor it. The stale entry stays in the queue,done()never returnstrue, and the connection is never returned to the pool.tokio-postgres(the most popular Rust PostgreSQL client) uses exactly this pattern — it sends COPY via extended protocol: Parse+Bind+Execute+Sync, then CopyData..., then CopyDone+Sync. PostgreSQL ignores the first Sync (it's already in COPY IN mode by then), producing only oneReadyForQueryinstead of the two that pgdog expects.Exact message sequence that causes desync
Consequences
done()never returnstruequery.rs:282-289)rollback()fails withRollbackFailedVerified end-to-end
Integration test using
tokio-postgres::copy_in()through pgdog (integration/rust/tests/tokio_postgres/copy.rs):FATAL: query timeoutatsink.finish()— pgdog's state machine is desynced and can't complete the COPYSELECT count(*)returns correct results (passes in 0.09s)Fix
When
forward()receivesCopyInResponse('G'), callremove_one_rfq()to drop theReadyForQuerythat will never arrive. This makes the proxy resilient to clients that send Sync with the initial Parse+Bind+Execute for COPY statements.Note: pgdog already handles COPY via extended protocol in
prepared_statements.rs—CopyDone,CopyFail,CopyDatainhandle()(lines 180-188) andCopyInResponse('G') inforward()(line 229). The fix adds one call to the existing'G'handler.Tests
test_copy_in_with_client_double_sync— exercises the full sequence throughPreparedStatements::forward()(the real code path), asserts clean state after the COPY cycle completestest_copy_in_extended_protocol— end-to-end test usingtokio-postgres::copy_in()through pgdog, verifying both COPY completion and subsequent query successhttps://claude.ai/code/session_01PQvrbw2xJHgQBXtASWHFcv