[pgpool-general-jp: 1021] 【質問】pgpoolに対しJDBCからアクセスする際の手法について
tsujihra @ nttdata.co.jp
tsujihra @ nttdata.co.jp
2011年 12月 2日 (金) 20:50:52 JST
はじめまして。辻と申します。
pgpool-IIに対するJDBCアクセスに関して質問させてください。
現在、OSSによる大量データINSERTの実証を行っており、PostgreSQLならびに
pgpool-IIの利用を考えております。
実装したいアーキテクチャとしては、
・PostgreSQLをシェアードナッシングで並列に並べ、APからは透過的に1つの
大きなDBに見せるべく、APとDBの間に振り分けのモジュールを挟む
ということを考えており、pgpoolが備えているパラレルクエリの機能が利用で
きるのではないかという考えに至りました。
質問したい事柄を初めに端的に述べますと、JavaのAPからJDBC経由(V2プロト
コル)でpgpoolにアクセスしたときに、後ろのPostgreSQLまでは正常に処理が
行われているのですが、PostgreSQLからpgpoolに返ってきた通信を受け取った
際にpgpoolがエラーになる(環境によってはハングする)という状況が起こっ
ており、それの対策をお伺いしたく思います。
現在、検証を行っている環境の構成を簡単にご説明します。
■APサーバ(CentOS(5.4))
【AP】Java(OpenJDK1.6.0)
【JDBC】postgresql-8.4-701.jdbc4.jar
【振り分け】pgpool-II(3.1)
■DBサーバ(CentOS(5.4))
【DB】PostgresSQL8.4.2
【HA】Heartbeat(2.1.4)
※DBサーバは2台によるHA構成を3セット
※構成補足
・pgpoolはパラレルモードのみを使用。(レプリケーションモードは使用し
ていない)
・パラレルモードを利用するにあたり、「pgpool-II チュートリアル」によ
ると「JDBCなどのような拡張問い合わせプロトコルには対応していません」
とあったため、簡易問い合わせプロトコルを利用すべく、JDBCのオプショ
ンとして「protocolVersion=2」を付けて実行。
エラーの経緯を詳細に説明します。
1.JavaアプリケーションからJDBC経由でSQL(単純なSELECT文)を発行
2.pgpoolはそれを受け取り、3台のPostgreSQLと認証などの交渉を行う
3.PostgreSQLからReadyForQueryが返ってくる
4.pgpoolはまず1台のPostgreSQLにSQLを投げる
5.PostgreSQLから返ってきたメッセージを受け取る際に、以下のような
エラーが発生
ERROR: pid 7701: pool_read2: failed to realloc
このような事象が発生する場合、何か良い対策はありますでしょうか。
(ちなみにプロトコルv2にこだわっているわけではないので、そのような根本
から変更するようなアプローチでも構いません。)
ちなみに、同じ状況でJavaAP→PostgreSQLという形で直接SQLを投げた場合、
PostgreSQLは上記と同じ内容のパケットを返してくるのですが、javaAPは正常
終了します。
また、psqlで同じSQLをpgpoolに向かって発行した場合、こちらの想定通りの
動作(3つのPostgreSQL全てからデータを集めてくる、つまりパラレルクエリ
モードの正常な動き)をします。ただし、この場合、PostgreSQLから返ってく
るパケットは上記とは異なっています。
また、「SELECT AID FROM PGBENCH_ACCOUNTS WHERE AID = 1」のように、
Where句で振り分けのキーになっているカラムを限定するなどした際も同じく
エラーになります。
また、「SELECT 1」のようなSQLの場合はJavaAP含めて全て正常に終了します。
以下に、Javaのアプリケーションの抜粋とログの抜粋を貼ります。
Java AP
---
package Test;
import java.sql.*;
import java.util.Properties;
public class PostgresTestSelect {
/**
* @param args
*/
final private static String PostgresJDBCDriver = "org.postgresql.Driver";
// DBNAME, DBDIR, USER, PASS, JDBCDriver, DBURL
final private static String DBNAME = "bench_parallel";
final private static String USER = "postgres";
final private static String PASS = "postgres";
final private static String JDBCDriver = PostgresJDBCDriver;
final private static String DBURL = "jdbc:postgresql://192.168.198.31:9999/" + DBNAME;
public static void main(String[] args) throws SQLException{
try{
System.out.println("SELECT:");
connect(USER, PASS);
ResultSet rs;
int count;
// SELECT
Statement stmt = conn.createStatement();
rs = stmt.executeQuery("select * from pgbench_accounts;");
// rs = stmt.executeQuery("select aid from pgbench_accounts where aid = 1;");
// rs = stmt.executeQuery("select 1;");
count = 0;
while(rs.next())
{
int n = rs.getInt("aid");
int a = rs.getInt("bid");
int b = rs.getInt("abalance");
String c = rs.getString("filler");
System.out.println(n + ", " + a+ ", " + b+ ", " + c);
count++;
}
System.out.println(count+"件取得しました。");
rs.close();
stmt.close();
disconnect();
}catch(Exception e){
(中略)
static Connection conn = null;
//
// database open
//
public static void connect(String user, String pass)
throws SQLException, ClassNotFoundException
{
try{
Class.forName(JDBCDriver).newInstance();
System.setProperty("jdbc.driver", JDBCDriver);
}
catch(Exception e){
System.out.print(e.toString());
if (e instanceof SQLException)
{
System.out.println("Error Code:"+((SQLException)e).getErrorCode());
}
e.printStackTrace();
}
try{
if (user.isEmpty() && pass.isEmpty())
{
conn = DriverManager.getConnection(DBURL);
}
else
{
Properties prop = new Properties();
prop.put("user", user);
prop.put("password", pass);
prop.put("protocolVersion", "2");
(以下略)
---
pgpoolログ
---
2011-11-30 06:28:39 LOG: pid 7701: connection received: host=192.168.198.11 port=35270
2011-11-30 06:28:39 DEBUG: pid 7701: Protocol Major: 2 Minor: 0 database: bench_parallel user: postgres
2011-11-30 06:28:39 DEBUG: pid 7701: new_connection: connecting 0 backend
2011-11-30 06:28:39 DEBUG: pid 7701: new_connection: connecting 1 backend
2011-11-30 06:28:39 DEBUG: pid 7701: new_connection: connecting 2 backend
(中略)
2011-11-30 06:28:39 DEBUG: pid 7701: ProcessFrontendResponse: kind from frontend Q(51)
2011-11-30 06:28:39 DEBUG: pid 7701: pool_read_string: read all from pending data. po:0 len:0
2011-11-30 06:28:39 DEBUG: pid 7701: pool_unset_doing_extended_query_message: done
2011-11-30 06:28:39 LOG: pid 7701: statement: select * from pgbench_accounts;
2011-11-30 06:28:39 DEBUG: pid 7701: pool_set_query_in_progress: done
2011-11-30 06:28:39 DEBUG: pid 7701: initSelectStmt: ANALYZE now(0)
2011-11-30 06:28:39 DEBUG: pid 7701: inside build_range_info num= 1 current_select=0
2011-11-30 06:28:39 DEBUG: pid 7701: inside build_range_info dist 0
2011-11-30 06:28:39 DEBUG: pid 7701: inside build_virtual_info dist state=P pgbench_accounts
2011-11-30 06:28:39 DEBUG: pid 7701: append_virtual_table select=0, no=0,col=aid,type=integer,table=pgbench_accounts,state=P,valid=-1
2011-11-30 06:28:39 DEBUG: pid 7701: append_virtual_table select=0, no=1,col=bid,type=integer,table=pgbench_accounts,state=P,valid=-1
2011-11-30 06:28:39 DEBUG: pid 7701: append_virtual_table select=0, no=2,col=abalance,type=integer,table=pgbench_accounts,state=P,valid=-1
2011-11-30 06:28:39 DEBUG: pid 7701: append_virtual_table select=0, no=3,col=filler,type=character(84),table=pgbench_accounts,state=P,valid=-1
2011-11-30 06:28:39 DEBUG: pid 7701: AnalyzeReturnRecord: current_select=0
2011-11-30 06:28:39 DEBUG: pid 7701: append_all_virtual: analyze[0] col=aid,type=integer
2011-11-30 06:28:39 DEBUG: pid 7701: append_all_virtual: analyze[0] col=bid,type=integer
2011-11-30 06:28:39 DEBUG: pid 7701: append_all_virtual: analyze[0] col=abalance,type=integer
2011-11-30 06:28:39 DEBUG: pid 7701: append_all_virtual: analyze[0] col=filler,type=character(84)
2011-11-30 06:28:39 DEBUG: pid 7701: _rewriteSelectStmt select_no=0 state=PPPPPPPP
2011-11-30 06:28:39 DEBUG: pid 7701: analyze_debug :select no(0), last select(-1), last_part(-1), state(P)
2011-11-30 06:28:39 DEBUG: pid 7701: can pool_parallel_exec SELECT * FROM "pgbench_accounts"
2011-11-30 06:28:39 DEBUG: pid 7701: pool_parallel_query: 0 th FD_SET: 11
2011-11-30 06:28:39 DEBUG: pid 7701: pool_parallel_query: 1 th FD_SET: 12
2011-11-30 06:28:39 DEBUG: pid 7701: pool_parallel_query: 2 th FD_SET: 13
2011-11-30 06:28:39 DEBUG: pid 7701: pool_parallel_query: num_fds: 14
2011-11-30 06:28:39 DEBUG: pid 7701: read_kind_from_one_backend: read kind from 0 th backend P
2011-11-30 06:28:39 ERROR: pid 7701: pool_read2: failed to realloc
2011-11-30 06:28:39 DEBUG: pid 7572: reap_handler called
2011-11-30 06:28:39 DEBUG: pid 7572: reap_handler: call wait3
2011-11-30 06:28:39 DEBUG: pid 7572: child 7701 exits with status 256
(以下略)
---
以上です。
よろしくお願いします。
pgpool-general-jp メーリングリストの案内