Java-запросы к PGPool II вызывают ошибки «безымянный подготовленный оператор не существует» - PullRequest
12 голосов
/ 15 марта 2012

У меня есть приложение на 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"

Но иногда между шагами синтаксического анализа / связывания / выполнения 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 иногда выдает эти дополнительные запросы между шагами синтаксического анализа / связывания / выполнения, это приводит к выбрасыванию запроса.

Моей первой мыслью было, что, возможно, моему 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.

Ответы [ 2 ]

3 голосов
/ 15 марта 2013

Я нашел решение этой проблемы.Помещая protocolVersion = 2 в URL JDBC, он в основном говорит драйверу Postgres JDBC не использовать подготовленные операторы на стороне сервера.Это позволяет моему приложению работать при использовании PGPool II перед моей базой данных.Меня беспокоит тот факт, что я вынужден прибегнуть к протоколу JDBC версии 2, чтобы использовать PGPool.

0 голосов
/ 22 марта 2012

Что, если вы назовете свое подготовленное заявление?

И возникает еще один вопрос: зачем вы используете подготовленные заявления, если они вам не нужны?

Вы можете легко сделать "нормальные" операторы для драйвера jdbc ...

...