Postgresデータベースを使用するJavaアプリがあり、データベースをスケールアップするために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バージョン3およびPostgres7.4http://jdbc.postgresql.org/documentation/head/server-prepare.html以降のPostgresJDBCドライバーのデフォルトの動作のようです。サーバー側のプリペアドステートメントを完全に無効にしてみることができると思いますが、ドキュメントにはその方法が指定されておらず、とにかくそれがやりたいことかどうかはわかりません。
私の2番目の考えは、PGPoolIIにこれらのメタデータクエリの送信を停止させることでした。PGPoolをロードバランサーとして使用しようとしているだけなので、テーブルのメタデータについてすべてを知る必要がある理由がわかりません。PGPoolソースのis_system_catalogメソッドでこれらのクエリを実行しているコードをここで追跡しました:https ://github.com/iakio/pgpool-II/blob/master/pool_select_walker.c#L256PGPool が知りたがっているようです何らかの理由でテーブルの関係についてですが、残念ながら、その動作を無効にする方法がわかりません。
この問題を回避する方法についての洞察をいただければ幸いです。
私の環境に関するいくつかの情報:
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
更新:
この問題の回避策を見つけました。protocolVersion=2
JDBC URLに配置することにより、基本的にPostgresJDBCドライバーにサーバー側のプリペアドステートメントを使用しないように指示します。これにより、データベースの前でPGPoolIIを使用しながらアプリを実行できます。ただし、PGPoolを使用するためだけにJDBCバージョン2プロトコルにフォールバックする必要があるという事実に悩まされています。