[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 メーリングリストの案内