[pgsql-jp: 39102] CE パーティショニングと PREPARE EXECUTE の問題

FUKUSHIMA Katsuaki kfukushima @ sis.seino.co.jp
2008年 1月 29日 (火) 21:26:34 JST


こんにちは。福島です。

24時間ノンストップで運用している仕組で、 CE パーティショニング化した
テーブルの子テーブルの CREATE と DROP を、日次のバッチ処理で自動化し
ております。しかし、以下のシチュエーションで問題が発生しました。
CE パーティショニング化したテーブルで PREPARE で準備した SQL を
EXECUTE で実行するのですが、PREPARE を実行してから EXECUTE を実行す
るまでの間に子テーブルを DROP すると、 "ERROR:  relation with OID
XXXXX does not exist" が発生してしまいます。これを回避する方法はあり
ますでしょうか?利用しているバージョンは 8.2.6 です。

以下、問題を発生させる例です。

テーブルの CREATE と INSERT RULE の CREATE。ここでは日付+連番という
key を想定したテーブルとしています。また日付は 20080101 〜 20080105
を想定しています。ついでレコードを数件 INSERT しています。

CREATE TABLE cetest (key VARCHAR(10) PRIMARY KEY, data VARCHAR(100));

CREATE TABLE cetest_20080101 (check(key >= '20080101' AND key <
'20080102')) INHERITS(cetest);
ALTER TABLE cetest_20080101 ADD PRIMARY KEY(key);
CREATE RULE cetest_20080101_insert AS ON INSERT TO cetest WHERE key
>= '20080101' AND key < '20080102' DO INSTEAD INSERT INTO
cetest_20080101 VALUES(NEW.key, NEW.data);

CREATE TABLE cetest_20080102 (check(key >= '20080102' AND key <
'20080103')) INHERITS(cetest);
ALTER TABLE cetest_20080102 ADD PRIMARY KEY(key);
CREATE RULE cetest_20080102_insert AS ON INSERT TO cetest WHERE key
>= '20080102' AND key < '20080103' DO INSTEAD INSERT INTO
cetest_20080102 VALUES(NEW.key, NEW.data);

CREATE TABLE cetest_20080103 (check(key >= '20080103' AND key <
'20080104')) INHERITS(cetest);
ALTER TABLE cetest_20080103 ADD PRIMARY KEY(key);
CREATE RULE cetest_20080103_insert AS ON INSERT TO cetest WHERE key
>= '20080103' AND key < '20080104' DO INSTEAD INSERT INTO
cetest_20080103 VALUES(NEW.key, NEW.data);

CREATE TABLE cetest_20080104 (check(key >= '20080104' AND key <
'20080105')) INHERITS(cetest);
ALTER TABLE cetest_20080104 ADD PRIMARY KEY(key);
CREATE RULE cetest_20080104_insert AS ON INSERT TO cetest WHERE key
>= '20080104' AND key < '20080105' DO INSTEAD INSERT INTO
cetest_20080104 VALUES(NEW.key, NEW.data);

CREATE TABLE cetest_20080105 (check(key >= '20080105' AND key <
'20080106')) INHERITS(cetest);
ALTER TABLE cetest_20080105 ADD PRIMARY KEY(key);
CREATE RULE cetest_20080105_insert AS ON INSERT TO cetest WHERE key
>= '20080105' AND key < '20080106' DO INSTEAD INSERT INTO
cetest_20080105 VALUES(NEW.key, NEW.data);

INSERT INTO cetest VALUES ('2008010101', 'abc');
INSERT INTO cetest VALUES ('2008010201', 'abc');
INSERT INTO cetest VALUES ('2008010301', 'abc');
INSERT INTO cetest VALUES ('2008010401', 'abc');
INSERT INTO cetest VALUES ('2008010501', 'abc');

次に PREPARE で SQL を準備します。

PREPARE cetest_select (VARCHAR) AS SELECT * FROM cetest WHERE key = $1;

直後に EXECUTE を実行すると、正常にレコードが返ってきます。

EXECUTE cetest_select ('2008010301');
    key     | data
------------+------
 2008010301 | abc
(1 row)

別のセッションで子テーブルの DROP を行います。

DROP TABLE cetest_20080101 CASCADE;

再び元のセッションで EXECUTE を実行すると、エラーが発生します。

EXECUTE cetest_select ('2008010301');
ERROR:  relation with OID 17142 does not exist


現状は、日時のバッチ処理で子テーブルを DROP せずに TRUNCATE し、シス
テムメンテナンス時にまとめて DROP して回避していますが、システムメン
テナンス時まで、余分な子テーブルが残ってしまう為、INSERT RULE のコス
トが結構負荷になっています。

よろしくお願いします。

-- 
---------------------------------------------------------
FUKUSHIMA Katsuaki at Seino Information Service Co., Ltd.
e-mail   kfukushima @ sis.seino.co.jp





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