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

Hiroki Kataoka kataoka @ interwiz.jp
2008年 1月 29日 (火) 23:25:24 JST


片岡です。

 まもなくリリースされる予定のバージョン8.3では、PL/PgSQL関数やPrepared
ステートメントのクエリプランの再評価が自動で行われるようになりましたの
で、もっともシンプルな対策は8.3のリリースをお待ちいただくことかもしれま
せん。

FUKUSHIMA Katsuaki さんは書きました:
> こんにちは。福島です。
> 
> 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 のコス
> トが結構負荷になっています。
> 
> よろしくお願いします。
> 

-- 
Hiroki Kataoka <kataoka @ interwiz.jp>



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