You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: mirror prepared statement mode in session pooling (#827)
This might be a two bug layer. First, it's might be an issue with
DEALLOCATE sent as a simple query that doesn't get rewritten, which
causes a transaction failure and messes up the whole mirroring.
But I'm using pgdog in session mode with mirroring to test performance
to see if I can switch the database to a cheaper one so I'm not affected
by the DEALLOCATE bug on the source. What I noticed is that the mirror
traffic gets this error:
```
ERROR: prepared statement "pdo_stmt_00000001" does not exist
STATEMENT: DEALLOCATE pdo_stmt_00000001
```
I also included a fix to speed up the dockerfile build with caches since
I iterated on the dockerfile with the fix.
I also have a repro with a docker-compose and a simple php app here:
https://github.com/costi/pgdog-pdo-repro
The flow is like this:
1. In session mode, the client path uses the **effective**
prepared-statements setting from:
```rust
config.prepared_statements()
```
2. `ConfigAndUsers::prepared_statements()` disables prepared statements
in session mode:
```rust
pub fn prepared_statements(&self) -> PreparedStatements {
if self.config.general.pooler_mode == PoolerMode::Session {
PreparedStatements::Disabled
} else {
self.config.general.prepared_statements
}
}
```
3. The mirror path was not using that effective value. It constructed
its prepared-statement state with the raw default/configured level
instead.
4. So with:
```toml
pooler_mode = "session"
prepared_statements = "extended"
```
the source/client path effectively ran with `Disabled`, while the mirror
path still ran with `Extended`.
5. That caused the mirror path to rewrite extended-protocol prepared
statement names to `__pgdog_*`, while the source path kept the original
PDO names like `pdo_stmt_00000001`.
6. Later, PDO sent simple SQL cleanup:
```sql
DEALLOCATE pdo_stmt_00000001
```
7. The mirror backend only knew the prepared statement under the
rewritten `__pgdog_*` name, so PostgreSQL correctly errored:
```text
ERROR: prepared statement "pdo_stmt_00000001" does not exist
STATEMENT: DEALLOCATE pdo_stmt_00000001
```
0 commit comments