У меня есть приложение Java, которое использует базу данных Postgres, и я пытаюсь представить PGPool для расширения моей базы данных. Я столкнулся с проблемой, когда Postgres выдает следующую ошибку: unnamed prepared statement does not exist
. После прокрутки журнала в Postgres я вижу следующее действие, которое происходит для каждого оператора select, выполняемого моим приложением:
EDTLOG: 00000: duration: 7.585 ms parse <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 0.088 ms bind <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 79.014 ms execute <unnamed>: "my select statement here"
Но иногда между этапами parse/bind/execute PGPool выполняет некоторые дополнительные запросы, поэтому журнал выглядит следующим образом:
EDTLOG: 00000: duration: 7.585 ms parse <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 0.088 ms bind <unnamed>: "my select statement here"
EDTLOG: 00000: duration: 0.328 ms statement: SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.relname = 'my_table' AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'
EDTLOG: 00000: duration: 79.014 ms execute <unnamed>: "my select statement here"
EDTERROR: 26000: unnamed prepared statement does not exist
EDTLOG: 00000: duration: 0.022 ms parse S_2: ROLLBACK
EDTLOG: 00000: duration: 0.005 ms bind S_2: ROLLBACK
EDTLOG: 00000: duration: 0.008 ms execute S_2: ROLLBACK
Из того, что я понимаю, потому что запрос неназванный, он отбрасывается Postgres, если другой запрос приходит во время этого сеанса базы данных до выполнения неназванного запроса. Поэтому, поскольку PGPool иногда выдает эти дополнительные запросы между шагами parse/bind/execute, они вызывают отбрасывание запроса.
Моя первая мысль заключалась в том, что, возможно, моему Java-приложению не нужно было отправлять инструкции parse/bind/execute для каждого запроса. Но похоже, что это поведение по умолчанию для драйвера JDBC Postgres с JDBC версии 3 и Postgres 7.4 http://jdbc.postgresql.org/documentation/head/server-prepare.html. Я предполагаю, что могу попробовать полностью отключить подготовленные инструкции на стороне сервера, но в документации не указано, как это сделать, и я не уверен, что что-то я хочу сделать в любом случае.
Моя вторая мысль заключалась в том, чтобы заставить PGPool II прекратить отправку этих метаданных. Поскольку я просто пытаюсь использовать PGPool в качестве балансировки нагрузки, я не понимаю, почему он должен знать все о моих метаданных таблицы. Я отслеживал код, который выполняет эти запросы в методе is_system_catalog источника PGPool: https://github.com/iakio/pgpool-II/blob/master/pool_select_walker.c#L256 Кажется, что PGPool хочет знать о мои связи по каким-то причинам, и, к сожалению, я не вижу возможности отключить это поведение.
Любое понимание того, как обойти эту проблему, будет с благодарностью.
Некоторая информация о моей среде:
JDBC Driver: postgresql-9.1-901.jdbc4.jar
Java version "1.6.0_31"
Spring 3.1 managed JPA
Hibernate 3.5
Postgres 9.1
UPDATE:
Я нашел обходное решение проблемы. Поместив protocolVersion=2
в URL-адрес JDBC, он в основном сообщает драйверу Postgres JDBC не использовать подготовленные операторы на стороне сервера. Это позволяет моему приложению работать при использовании PGPool II перед моей базой данных. Меня беспокоит тот факт, что я должен вернуться к протоколу JDBC версии 2 только для использования PGPool.