12

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=2JDBC URLに配置することにより、基本的にPostgresJDBCドライバーにサーバー側のプリペアドステートメントを使用しないように指示します。これにより、データベースの前でPGPoolIIを使用しながらアプリを実行できます。ただし、PGPoolを使用するためだけにJDBCバージョン2プロトコルにフォールバックする必要があるという事実に悩まされています。

4

2 に答える 2

3

この問題の回避策を見つけました。JDBCURLにprotocolVersion=2を配置することにより、基本的にPostgresJDBCドライバーにサーバー側のプリペアドステートメントを使用しないように指示します。これにより、データベースの前でPGPoolIIを使用しながらアプリを実行できます。ただし、PGPoolを使用するためだけにJDBCバージョン2プロトコルにフォールバックする必要があるという事実に悩まされています。

于 2013-03-15T16:15:59.450 に答える
-1

プリペアドステートメントに名前を付けるとどうなりますか?

そして、別の疑問が生じます。必要がないのに、なぜプリペアドステートメントを使用するのですか?

jdbcドライバーに対して「通常の」ステートメントを簡単に作成できます。

于 2012-03-21T23:01:02.817 に答える