Как можно настроить предварительно подготовленное утверждение в pgbouncer?

Могли бы вы помочь мне решить эту проблему? При использовании последней версии PgBouncer 1.21.0, которая поддерживает prepared statements, в своем проекте (Laravel, PostgreSql + PgBouncer), я встретил ошибку, несмотря на настройку max_prepared_statements на ограничение в 100, как было указано в руководстве. Ошибка: "SQLSTATE[25P02]: In failed sql transaction: 7 ERROR:  current transaction is aborted, commands ignored until end of transaction block". И даже увеличивая это значение в 10 раз, проблема не была решена. Какова может быть причина такой ошибки?
  • 1 декабря 2023 г. 16:00
Ответы на вопрос 2
Причиной такой ошибки может быть то, что транзакция была отклонена из-за какой-то ошибки, и все последующие команды будут игнорироваться до конца блока транзакции. В таком случае, вы должны решить первоначальную проблему, которая привела к ошибке.

В случае с PgBouncer, причиной может быть то, что он не поддерживает prepared statements в режиме сессии. Другими словами, он может "подготавливать" запросы, только если они будут выполнены в той же сессии, где они были подготовлены.

Вы также можете попробовать отключить использование подготовленных запросов в Laravel, установив значение `emulate_prepares` в `true` в конфигурации вашего соединения с базой данных. Это сделает так, что Laravel будет эмулировать подготовленные выражения, отправляя SQL-запросы как обычные строки, без использования подготовленных выражений на стороне сервера.

Пример:

```php
'default' => [
    'driver' => 'pgsql',
    'host' => env('DB_HOST', 'localhost'),
    // ...
    'options' => [
        PDO::ATTR_EMULATE_PREPARES => true,
    ],
],
```

С другой стороны, если ваше приложение зависит от использования подготовленных выражений и вы не можете их отключить, другой вариант может заключаться в том, чтобы использовать PGBouncer в режиме "session pooling" вместо "transaction pooling". Это позволит каждой сессии иметь свой собственный набор подготовленных выражений. Следует отметить, что это может повысить нагрузку на ваш сервер базы данных. 

В любом случае, важно помнить, что PgBouncer является простым связующим звеном, его задача - управлять соединениями, а не обрабатывать SQL-транзакции или "понимать" SQL-код. Ошибки, которые происходят внутри SQL-транзакций, должны быть обработаны вашим приложением или сервером базы данных.
PHP PDOнесовместимс max_prepared_statements фичей баунсера.PDO отправляет deallocate как SQL запрос, а не как команду протокола.
Похожие вопросы