[pgpool-general-jp: 72] Re: pgpoolのprepared_listについて
Kenichi Sawada
k @ sawada.cc
2007年 1月 12日 (金) 17:43:08 JST
澤田です。
先程のメール、patchのdiffの引数が逆になっていたようです。
大変失礼致しました。適宜読み替えて頂ければと存じます。
宜しくお願い致します。
--澤田 研一
--k @ sawada.cc
From: Kenichi Sawada <k @ sawada.cc>
Date: Fri, 12 Jan 2007 17:31:18 +0900 (JST)
> はじめまして。澤田と申します。
> pgpool、いつも大変便利に利用させて頂いております。ありがとうございます。
>
> さて、PostgreSQL-8.1.4, Perl-5.8.5, DBI-1.51, DBD-Pg-1.49 という環境にて、
> pgpool-3.1.1 をport 9999上で動作させている状況で、
> create testdbとしてtestdbを作成してリスト1のスクリプトを実行させると、
> PostgreSQL側に
> ERROR: prepared statement "dbdpg_1" does not exist
> というエラーログが出るようです(ログ1:PostgreSQL側ログをご参照ください)
>
> これはpool_process_query.cの中でextended queryのstatement_nameについて
> 常に二重引用符を付加しているために発生する現象ではないかと思いますが、
> これは末尾Patch for 3.1.1のようにして回避しても問題ないものでしょうか?
>
> また、pgpool-3.1.2 にて同様の実験を実施したところ、今回の問題に関係なく
> extended queryでない通常のDEALLOCATE文を実行した時点で常にエラーと
> なるようです(ログ2:pgpool側ログをご参照ください)
> これは恐らくpool_process_query.cの670行目からのif文:
>
> pending_prepared_stmt->statement_name = strdup(name);
> pending_prepared_stmt->portal_name = NULL;
> if (pending_prepared_stmt->portal_name == NULL ||
> pending_prepared_stmt->statement_name == NULL)
> {
> pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
> return POOL_END;
>
> が、(pending_prepared_stmt->portal_nameがvolatileではないので)
> 恒真となってしまっているためと思われます。
> この問題に加え、上記二重引用符の問題の回避を加えたpatchを
> 末尾Patch for 3.1.2として作成しましたが、こちらにつきましても
> 回避方法として適切かどうかにつきまして、皆様の御意見を頂ければ幸いです。
> どうぞ宜しくお願い致します。
>
> --澤田 研一
> --k @ sawada.cc
>
>
> ----リスト1
> #!/usr/bin/perl
> use DBI;
> my $dbh = DBI->connect("DBI:Pg:dbname=testdb;port=9999","postgres","");
> my $sth = $dbh->prepare("select 1 = ?");
> $sth->execute(1);
> $sth->finish;
> undef $sth;
> $dbh->disconnect;
> ----リスト1ここまで
>
>
> ----ログ1
> LOG: statement: PREPARE dbdpg_1 AS select 1 = $1
> LOG: statement: <BIND>
> LOG: statement: EXECUTE <unnamed> [PREPARE: select 1 = $1]
> LOG: statement: DEALLOCATE dbdpg_1
> LOG: statement: RESET ALL
> LOG: statement: SET SESSION AUTHORIZATION DEFAULT
> LOG: statement: DEALLOCATE "dbdpg_1"
> ERROR: prepared statement "dbdpg_1" does not exist
> ----ログ1ここまで
>
>
> ----ログ2
> ERROR: pid 10245: SimpleForwardToBackend: strdup failed: Success
> LOG: pid 10245: do_child: exits with status 1 due to error
> ----ログ2ここまで
>
>
> ----Patch for 3.1.1
> *** pool_process_query.c 2007-01-12 16:32:47.000000000 +0900
> --- pool_process_query.c.org 2007-01-12 16:28:44.000000000 +0900
> ***************
> *** 2519,2545 ****
>
> if (kind == 'P' && *p)
> {
> ! name_len = strlen(p) + 1;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "%s", p);
> pending_function = add_prepared_list;
> pending_prepared_name = name;
> }
> else if (kind == 'C' && *p == 'S' && *(p + 1))
> {
> ! name_len = strlen(p + 1) + 1;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "%s", p + 1);
> pending_function = del_prepared_list;
> pending_prepared_name = name;
> }
> --- 2519,2545 ----
>
> if (kind == 'P' && *p)
> {
> ! name_len = strlen(p) + 3;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "\"%s\"", p);
> pending_function = add_prepared_list;
> pending_prepared_name = name;
> }
> else if (kind == 'C' && *p == 'S' && *(p + 1))
> {
> ! name_len = strlen(p + 1) + 3;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "\"%s\"", p + 1);
> pending_function = del_prepared_list;
> pending_prepared_name = name;
> }
> ----Patch for 3.1.1ここまで
>
>
> ----Patch for 3.1.2
> *** pool_process_query.c 2007-01-12 16:37:56.000000000 +0900
> --- pool_process_query.c.org 2007-01-12 16:28:44.000000000 +0900
> ***************
> *** 667,673 ****
>
> pending_prepared_stmt->statement_name = strdup(name);
> pending_prepared_stmt->portal_name = NULL;
> ! if (pending_prepared_stmt->statement_name == NULL)
> {
> pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
> return POOL_END;
> --- 667,674 ----
>
> pending_prepared_stmt->statement_name = strdup(name);
> pending_prepared_stmt->portal_name = NULL;
> ! if (pending_prepared_stmt->portal_name == NULL ||
> ! pending_prepared_stmt->statement_name == NULL)
> {
> pool_error("SimpleForwardToBackend: strdup failed: %s", strerror(errno));
> return POOL_END;
> ***************
> *** 2658,2671 ****
> {
> char *stmt;
>
> ! name_len = strlen(p) + 1;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "%s", p);
>
> pending_prepared_stmt = malloc(sizeof(PreparedStatement));
> if (pending_prepared_stmt == NULL)
> --- 2659,2672 ----
> {
> char *stmt;
>
> ! name_len = strlen(p) + 3;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "\"%s\"", p);
>
> pending_prepared_stmt = malloc(sizeof(PreparedStatement));
> if (pending_prepared_stmt == NULL)
> ***************
> *** 2711,2724 ****
> stmt = unnamed_statement;
> else
> {
> ! name = malloc(strlen(stmt_name) + 1);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
>
> ! sprintf(name, "%s", stmt_name);
> stmt = lookup_prepared_statement_by_statement(&prepared_list, name);
> free(name);
> }
> --- 2712,2725 ----
> stmt = unnamed_statement;
> else
> {
> ! name = malloc(strlen(stmt_name) + 3);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
>
> ! sprintf(name, "\"%s\"", stmt_name);
> stmt = lookup_prepared_statement_by_statement(&prepared_list, name);
> free(name);
> }
> ***************
> *** 2737,2750 ****
> }
> else if (kind == 'C' && *p == 'S' && *(p + 1))
> {
> ! name_len = strlen(p + 1) + 1;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "%s", p + 1);
> pending_function = del_prepared_list;
> pending_prepared_stmt = malloc(sizeof(PreparedStatement));
> if (pending_prepared_stmt == NULL)
> --- 2738,2751 ----
> }
> else if (kind == 'C' && *p == 'S' && *(p + 1))
> {
> ! name_len = strlen(p + 1) + 3;
> name = malloc(name_len);
> if (name == NULL)
> {
> pool_error("SimpleForwardToBackend: malloc failed: %s", strerror(errno));
> return POOL_END;
> }
> ! sprintf(name, "\"%s\"", p + 1);
> pending_function = del_prepared_list;
> pending_prepared_stmt = malloc(sizeof(PreparedStatement));
> if (pending_prepared_stmt == NULL)
> ----Patch for 3.1.2ここまで
>
>
>
pgpool-general-jp メーリングリストの案内