[pgpool-general-jp: 1146] 拡張問い合わせプロトコルでセグメンテーションフォルト
Naoya Anzai
anzai-naoya @ mxu.nes.nec.co.jp
2013年 3月 14日 (木) 19:13:42 JST
安西と申します。
pgpool-II 3.1.6にて、レプリケーションモードで拡張問い合わせ
プロトコルを使用したトランザクションを実行中に、子プロセスが
SIGSEGVで落ちる現象が発生しました。
添付のsegv.sql内に記載されているクエリを実行することで、
発生します。(INSERT,SELECTをより多く繰り返さないと発生しない
可能性もあります。)
調査したところ、Parse処理中のnow()の書き換え処理を行う部分で、
不正な処理と思われる箇所を発見いたしました。
pool_proto_modules.c:L774
---
rewrite_query = rewrite_timestamp(backend, node, rewrite_to_params,
msg);
if (rewrite_query != NULL)
{
int alloc_len = len - strlen(stmt) + strlen(rewrite_query);
★contents = palloc(alloc_len);
strcpy(contents, name);
(略)
●msg->contents = contents;
---
msg->contentsには元々pool_create_sent_messageでセッション
コンテキストで管理しているメモリを割り当てています。
★印のpallocはクエリコンテキストのメモリを割り当てており、
●印の箇所でセッションコンテキストの管理する領域にクエリ
コンテキストのメモリが格納されます。
msg->contentsのメモリチャンクはクエリ処理終了後にセッション
コンテキストのメモリプールに戻され、再利用されるかと思います。
また、クエリコンテキストのメモリチャンクはクエリ処理終了後に
ブロックごと削除(free)されるかと思います。
そのため●の影響によって、セッションコンテキストのメモリ
プールに戻されたメモリチャンクがクエリコンテキストの
削除によってfreeされ、そのメモリチャンクをセッション
コンテキストで再利用するタイミングで問題が発生するようです。
本障害が発生する条件は最低でも以下の4つがあります。
・レプリケーションモード
・拡張問い合わせプロトコル
・更新系クエリでnow()等を含むクエリを発行
・同一セッションで複数のクエリを発行
本現象は3.0.5 , 3.1.4 , 3.2.3でも発生することを確認しています。
修正パッチを作成してみましたので、ご確認いただければと思います。
以上、よろしくお願い致します。
-----------------------------------------------------------
NECソフト株式会社
PFシステム事業部 テーマソフトウェアG
安西 直也
外線:(03)5534-2353 内線:8-57-40364
E-mail:anzai-naoya @ mxu.nes.nec.co.jp
-----------------------------------------------------------
-------------- next part --------------
CREATE TABLE segv (c1 int, c2 date, c3 time, c4 timestamp, c5 timestamptz);
INSERT INTO segv VALUES (1, now(), now(), now(), now()) ;
SELECT pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv'), pg_relation_size('segv');
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: pool_proto_modules.patch
型: application/octet-stream
サイズ: 601 バイト
説明: 無し
URL: <http://www.sraoss.jp/pipermail/pgpool-general-jp/attachments/20130314/701af1e7/attachment-0001.obj>
pgpool-general-jp メーリングリストの案内