[pgsql-jp: 36430] PostgreSQL8.1.0で大きい文字列などを登録するときの問題

Atsushi Ogawa a_ogawa @ hi-ho.ne.jp
2005年 11月 21日 (月) 21:28:31 JST


小川です。

PostgreSQL 8.1.0で、特定の条件を満たすテーブルについて、text型
などの可変長のカラムに大きなデータを登録したときに、backend 
processが異常終了したり、indexに正しいデータが登録されないことが
ある問題が見つかりました。

情報のソースは以下のURLです。
http://archives.postgresql.org/pgsql-hackers/2005-11/msg01016.php

この問題は以下の条件を満たすテーブルで発生します。
(1)text型など可変長のカラムがある
(2)可変長のカラムの後ろに、check制約を定義したカラムがある
(3)check制約で使うカラムの後ろに、indexを定義したカラムがある

エラーが発生するデータのサイズは、ブロックサイズに依存します。
ブロックサイズがデフォルトの8KBytesの場合、タプル(レコード)長が
約2Kbytesを超えると、この問題が発生します。

たとえば以下のようなテーブルです。

create table doc
(
    doc_id      integer primary key,
    body        text,
    comments    integer,
    author_id   integer,
    constraint doc_c1 check((comments >= 0))
);
create index doc_author_idx on doc(author_id);

ここでbodyに2Kbytesを超えるデータを登録すると、backendが異常終了
するか、正常に登録できたように見えてもdoc_author_idxに正しいデータが
登録されずに、正しい検索結果が得られなくなる問題が発生します。

insert into doc(doc_id, body, comments, author_id)
values(0, '大きいテキスト', 0, 0);
--> 異常終了するかもしれない

select * from doc where author_id = 0;
--> index scanが実行される場合、正しい検索結果にならない

update文でも同様の問題が発生します。

この問題の解決方法は、ソースコードにパッチを適用することです。
パッチは以下のURLにおいてあります。
http://www.hi-ho.ne.jp/a_ogawa/document/patches/tuptoast.patch
パッチは以下の情報をもとに作成したものです。
http://archives.postgresql.org/pgsql-committers/2005-11/msg00439.php

なお、この問題はPostgreSQL8.1で導入されたvirtual tuple cacheによる
ものであり、PostgreSQL8.0以前のバージョンでは発生しません。

--- 小川 淳



pgsql-jp メーリングリストの案内