It appears that PgBouncer's transaction pooling mode does not consider
implicit transactions properly, and so in a [Parse, Flush, Bind,
Execute, Sync] sequence, Flush would be (incorrectly) considered by
PgBouncer as a transaction boundary and it will happily send the
following Bind / Execute messages to a different backend process.
This makes it so that when statement_cache_size is set to 0, asyncpg
assumes a pessimistic stance on prepared statement persistence and does
not rely on them even in implicit transactions. The above message
sequence thus becomes Parse, Flush, Parse (a second time), Bind,
Execute, Sync.
This obviously has negative performance impact due to the extraneous
Parse.
It appears that PgBouncer's
transaction
pooling mode does not consider implicit transactions properly, and so in a [Parse
,Flush
,Bind
,Execute
,Sync
] sequence,Flush
would be (incorrectly) considered by PgBouncer as a transaction boundary and it will happily send the followingBind
/Execute
messages to a different backend process.This makes it so that when
statement_cache_size
is set to0
, asyncpg assumes a pessimistic stance on prepared statement persistence and does not rely on them even in implicit transactions. The above message sequence thus becomesParse
,Flush
,Parse
(a second time),Bind
,Execute
,Sync
.This obviously has negative performance impact due to the extraneous
Parse
.Fixes: #1058 Fixes: #1041