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