diff --git a/Makefile b/Makefile index f73e4e5..29aadda 100755 --- a/Makefile +++ b/Makefile @@ -3,27 +3,26 @@ # # Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # -.PHONY: all install clean +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = pg_statsinfo +top_builddir = ../.. +include $(top_builddir)/src/Makefile.global +endif -all: - make -C bin - make -C lib +SUBDIRS = bin lib -install: - make -C bin install - make -C lib install +all install installdirs uninstall distprep clean distclean maintainer-clean debug: + @for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir $@ || exit; \ + done -clean: - make -C bin clean - make -C lib clean - -debug: - make -C bin DEBUG_REORG=enable - make -C lib DEBUG_REORG=enable - -uninstall: - make -C bin uninstall - make -C lib uninstall - -installcheck: - make -C bin installcheck +# We'd like check operations to run all the subtests before failing. +check installcheck: + @CHECKERR=0; for dir in $(SUBDIRS); do \ + $(MAKE) -C $$dir $@ || CHECKERR=$$?; \ + done; \ + exit $$CHECKERR diff --git a/bin/expected/init.out b/bin/expected/init.out index c365538..43f11fa 100755 --- a/bin/expected/init.out +++ b/bin/expected/init.out @@ -1,3 +1,3 @@ -SET client_min_messages = warning; -\set ECHO none -RESET client_min_messages; +SET client_min_messages = warning; +\set ECHO none +RESET client_min_messages; diff --git a/bin/expected/reorg.out b/bin/expected/reorg.out index a89bebd..1b61d76 100755 --- a/bin/expected/reorg.out +++ b/bin/expected/reorg.out @@ -5,21 +5,21 @@ SET client_min_messages = warning; CREATE TABLE tbl_cluster ( col1 int, col2 timestamp, - ":-)" text, - PRIMARY KEY (":-)", col1) + ","")" text, + PRIMARY KEY (","")", col1) ) WITH (fillfactor = 70); -CREATE INDEX cidx_cluster ON tbl_cluster (col2, length(":-)")); -ALTER TABLE tbl_cluster CLUSTER ON cidx_cluster; +CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops); +ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; CREATE TABLE tbl_only_pkey ( col1 int PRIMARY KEY, - ":-)" text + ","")" text ); CREATE TABLE tbl_only_ckey ( col1 int, col2 timestamp, - ":-)" text + ","")" text ) WITH (fillfactor = 70); -CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ":-)"); +CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; CREATE TABLE tbl_gistkey ( id integer PRIMARY KEY, @@ -83,10 +83,10 @@ SELECT * FROM tbl_with_dropped_column; --------+-----------------------------+----------- col1 | integer | not null col2 | timestamp without time zone | - :-) | text | not null + ,") | text | not null Indexes: - "tbl_cluster_pkey" PRIMARY KEY, btree (":-)", col1) - "cidx_cluster" btree (col2, length(":-)")) CLUSTER + "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1) + ",") cluster" btree (col2, length(","")"), ","")" text_pattern_ops) CLUSTER \d tbl_gistkey Table "public.tbl_gistkey" @@ -104,16 +104,16 @@ Indexes: --------+-----------------------------+----------- col1 | integer | col2 | timestamp without time zone | - :-) | text | + ,") | text | Indexes: - "cidx_only_ckey" btree (col2, ":-)") CLUSTER + "cidx_only_ckey" btree (col2, ","")") CLUSTER \d tbl_only_pkey Table "public.tbl_only_pkey" Column | Type | Modifiers --------+---------+----------- col1 | integer | not null - :-) | text | + ,") | text | Indexes: "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) @@ -130,8 +130,8 @@ Indexes: "idx_c1c2" btree (c1, c2) "idx_c2c1" btree (c2, c1) -SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster; - col1 | to_char | :-) +SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster; + col1 | to_char | ,") ------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 2 | 2008-01-01 00:00:00 | king 5 | 2008-01-01 00:30:00 | 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488471.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049986537379859389467650347506576050756618348129606100947602187190325083145829523959832997789824508288714463832917347224163984587855397667958063818353666110843173780894378316102088305524901670023520711144288695990956365797087168498072899493296484283020786408603988738697537582317317831395992983007838702877053913369563312103707264019249106768231199288375641141422016742752102372994270831059898459475987664288897796147837958390228854852903576033852808064381972344661059689722872865264153822664698420021195484155278441181286534507035191650016689294415480846071277143999762926834629577438361895110127148638746976545982451788550975379013880664961911962222957110555242923723192197738262561631468842032853716682938649611917049738836395495938 @@ -141,14 +141,14 @@ SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster; (5 rows) SELECT * FROM tbl_only_ckey ORDER BY 1; - col1 | col2 | :-) + col1 | col2 | ,") ------+--------------------------+----- 1 | Tue Jan 01 00:00:00 2008 | abc 2 | Fri Feb 01 00:00:00 2008 | def (2 rows) SELECT * FROM tbl_only_pkey ORDER BY 1; - col1 | :-) + col1 | ,") ------+----- 1 | abc 2 | def diff --git a/bin/sql/reorg.sql b/bin/sql/reorg.sql index 467da9f..677426a 100755 --- a/bin/sql/reorg.sql +++ b/bin/sql/reorg.sql @@ -5,25 +5,25 @@ SET client_min_messages = warning; CREATE TABLE tbl_cluster ( col1 int, col2 timestamp, - ":-)" text, - PRIMARY KEY (":-)", col1) + ","")" text, + PRIMARY KEY (","")", col1) ) WITH (fillfactor = 70); -CREATE INDEX cidx_cluster ON tbl_cluster (col2, length(":-)")); -ALTER TABLE tbl_cluster CLUSTER ON cidx_cluster; +CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops); +ALTER TABLE tbl_cluster CLUSTER ON ","") cluster"; CREATE TABLE tbl_only_pkey ( col1 int PRIMARY KEY, - ":-)" text + ","")" text ); CREATE TABLE tbl_only_ckey ( col1 int, col2 timestamp, - ":-)" text + ","")" text ) WITH (fillfactor = 70); -CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ":-)"); +CREATE INDEX cidx_only_ckey ON tbl_only_ckey (col2, ","")"); ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey; CREATE TABLE tbl_gistkey ( @@ -95,7 +95,7 @@ SELECT * FROM tbl_with_dropped_column; \d tbl_only_pkey \d tbl_with_dropped_column -SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ":-)" FROM tbl_cluster; +SELECT col1, to_char(col2, 'YYYY-MM-DD HH24:MI:SS'), ","")" FROM tbl_cluster; SELECT * FROM tbl_only_ckey ORDER BY 1; SELECT * FROM tbl_only_pkey ORDER BY 1; SELECT * FROM tbl_gistkey ORDER BY 1; diff --git a/doc/index-ja.html b/doc/index-ja.html index e4c17e6..fb45e56 100755 --- a/doc/index-ja.html +++ b/doc/index-ja.html @@ -1,123 +1,124 @@ - - - - - - - - - pg_reorg: Project Home Page - - - -
-
-

pg_reorg ホームページへようこそ

-
-
-

-pg_reorg は PostgreSQL のテーブルを再編成するシェルコマンドです。 -共有ロックや排他ロックを取得しないため、再編成中であっても行の参照や更新を行うことができます。 -このモジュールは CLUSTER や VACUUM FULL コマンドのより良い代替になります。 -

-

この pg_reorg プロジェクトは PostgreSQL コミュニティによる pgFoundry の中のプロジェクトです。

- -
-Here is an English page. -
-
- -

ドキュメント

-

-ドキュメントはこちら。 -

- -

実行時間

-

-pg_reorg とclusterdb の比較に示します。 -断片化のないソートされた状態 (not fragmented) では clusterdb のほうが高速ですが、完全に断片化した状態 (fully fragmented) では pg_reorg が大幅に高速です。 -一般的に、再編成は断片化が進行した状態で実施されることを考えると、pg_reorg は clusterdb よりも実行時間が短いと言えます。 -

- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
測定環境
大項目小項目環境
ハードウェアCPU2 × Xeon 5160 3.00GHz (Dual core)
メモリ2GB
ストレージUltra320 SCSI, 15000rpm (220GB)
ソフトウェアOSRHEL 5.2 (64bit) 2.6.18-92.el5
DBPostgreSQL 8.3.3
pg_reorg1.0.0
clusterdbclusterdb (PostgreSQL) 8.3.3
データスキーマ
CREATE TABLE tbl (
- id bigserial PRIMARY KEY,
- seqkey timestamp NOT NULL,
- rndkey timestamp NOT NULL,
- filler char(75) NOT NULL
-);
-CREATE INDEX idx_seq ON tbl (seqkey);
-CREATE INDEX idx_rnd ON tbl (rndkey);
件数1650万件 (約2GB)
- -
- -
-
-Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION -
- - -
-
- -
- - - + + + + + + + + + pg_reorg: Project Home Page + + + +
+
+

pg_reorg ホームページへようこそ

+
+
+

+pg_reorg は PostgreSQL のテーブルを再編成するシェルコマンドです。 +共有ロックや排他ロックを取得しないため、再編成中であっても行の参照や更新を行うことができます。 +このモジュールは CLUSTER や VACUUM FULL コマンドのより良い代替になります。 +

+

この pg_reorg プロジェクトは PostgreSQL コミュニティによる pgFoundry の中のプロジェクトです。

+ +
+Here is an English page. +
+
+ +

ドキュメント

+

+ドキュメントはこちら。 +

+ +

実行時間

+

+pg_reorg とclusterdb の比較に示します。 +断片化のないソートされた状態 (not fragmented) では clusterdb のほうが高速ですが、完全に断片化した状態 (fully fragmented) では pg_reorg が大幅に高速です。 +一般的に、再編成は断片化が進行した状態で実施されることを考えると、pg_reorg は clusterdb よりも実行時間が短いと言えます。 +

+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
測定環境
大項目小項目環境
ハードウェアCPU2 × Xeon 5160 3.00GHz (Dual core)
メモリ2GB
ストレージUltra320 SCSI, 15000rpm (220GB)
ソフトウェアOSRHEL 5.2 (64bit) 2.6.18-92.el5
DBPostgreSQL 8.3.3
pg_reorg1.0.0
clusterdbclusterdb (PostgreSQL) 8.3.3
データスキーマ
CREATE TABLE tbl (
+ id bigserial PRIMARY KEY,
+ seqkey timestamp NOT NULL,
+ rndkey timestamp NOT NULL,
+ filler char(75) NOT NULL
+);
+CREATE INDEX idx_seq ON tbl (seqkey);
+CREATE INDEX idx_rnd ON tbl (rndkey);
件数1650万件 (約2GB)
+ +
+ + +
+ + + + + + diff --git a/doc/index.html b/doc/index.html index 006718d..af99460 100755 --- a/doc/index.html +++ b/doc/index.html @@ -1,123 +1,123 @@ - - - - - - - - - pg_reorg: Project Home Page - - - -
-
-

Welcome to the pg_reorg Project Home Page

-
-
-

-pg_reorg can re-organize tables on a postgres database without any locks so that you can retrieve or update rows in tables being reorganized. -The module is developed to be a better alternative of CLUSTER and VACUUM FULL. -

-

-The pg_reorg project is a PostgreSQL Community project that is a part of the pgFoundry. -

-

-The pgFoundry page for the project is at http://pgfoundry.org/projects/reorg, -where you can find downloads, documentation, bug reports, mailing lists, and a whole lot more. -

-
-日本語のページはこちら。 -
-
- -

Documentation

-

-Documentations here. -

- -

Execution time

-

-Here is a comparison between pg_reorg and clusterdb. -Clusterdb is faster on not fragmented conditions, but pg_reorg is faster on fully fragmented conditions. -Since reorganization is needed only if tables are fragmented, pg_reorg should be faster than clusterdb. -

- -
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Configuration
CategoryItemDetails
HardwareCPU2 * Xeon 5160 3.00GHz (Dual core)
Memory2GB
StorageUltra320 SCSI, 15000rpm (220GB)
SoftwareOSRHEL 5.2 (64bit) 2.6.18-92.el5
DBPostgreSQL 8.3.3
pg_reorg1.0.0
clusterdbclusterdb (PostgreSQL) 8.3.3
DataScheme
CREATE TABLE tbl (
- id bigserial PRIMARY KEY,
- seqkey timestamp NOT NULL,
- rndkey timestamp NOT NULL,
- filler char(75) NOT NULL
-);
-CREATE INDEX idx_seq ON tbl (seqkey);
-CREATE INDEX idx_rnd ON tbl (rndkey);
Rows16.5 M rows (2GB)
- -
- -
-
-Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION -
- - -
-
- -
- - - + + + + + + + + + pg_reorg: Project Home Page + + + +
+
+

Welcome to the pg_reorg Project Home Page

+
+
+

+pg_reorg can re-organize tables on a postgres database without any locks so that you can retrieve or update rows in tables being reorganized. +The module is developed to be a better alternative of CLUSTER and VACUUM FULL. +

+

+The pg_reorg project is a PostgreSQL Community project that is a part of the pgFoundry. +

+

+The pgFoundry page for the project is at http://pgfoundry.org/projects/reorg, +where you can find downloads, documentation, bug reports, mailing lists, and a whole lot more. +

+
+日本語のページはこちら。 +
+
+ +

Documentation

+

+Documentations here. +

+ +

Execution time

+

+Here is a comparison between pg_reorg and clusterdb. +Clusterdb is faster on not fragmented conditions, but pg_reorg is faster on fully fragmented conditions. +Since reorganization is needed only if tables are fragmented, pg_reorg should be faster than clusterdb. +

+ +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Configuration
CategoryItemDetails
HardwareCPU2 * Xeon 5160 3.00GHz (Dual core)
Memory2GB
StorageUltra320 SCSI, 15000rpm (220GB)
SoftwareOSRHEL 5.2 (64bit) 2.6.18-92.el5
DBPostgreSQL 8.3.3
pg_reorg1.0.0
clusterdbclusterdb (PostgreSQL) 8.3.3
DataScheme
CREATE TABLE tbl (
+ id bigserial PRIMARY KEY,
+ seqkey timestamp NOT NULL,
+ rndkey timestamp NOT NULL,
+ filler char(75) NOT NULL
+);
+CREATE INDEX idx_seq ON tbl (seqkey);
+CREATE INDEX idx_rnd ON tbl (rndkey);
Rows16.5 M rows (2GB)
+ +
+ +
+ + + + + + diff --git a/doc/pg_reorg-ja.html b/doc/pg_reorg-ja.html index 90bda39..4edd09b 100755 --- a/doc/pg_reorg-ja.html +++ b/doc/pg_reorg-ja.html @@ -1,293 +1,293 @@ - - - -pg_reorg - - - - - - -

pg_reorg

- -
-

名前

-pg_reorg -- PostgreSQLデータベース内のテーブルに対して、参照/更新処理をブロックせずに再編成を行います。 -
- -
- -

概要

-

-pg_reorg [connection-options...] [message-options...] [order-options...] [target-options...] -

-

指定できるオプションには4つのカテゴリがあります。 -詳細はオプションを参照してください。

-
-
connection-options : 接続パラメータ
-
-h [--host] host
-
-p [--port] port
-
-U [--username] username
-
-W [--password]
-
message-options : 出力メッセージ
-
-q [--quiet]
-
-v [--verbose]
-
order-options : 並び替えの基準
-
-o [--order-by] columns [,...]
-
-n [--no-order]
-
target-options : 処理対象
-
-a [--all]
-
-d [--dbname] dbname
-
-t [--table] table
-
-Z [--no-analyze]
-
-
- -
-

説明

-

pg_reorg は、PostgreSQLデータベース内のテーブルを再編成(行の並び替え)するユーティリティです。 -clusterdb と異なり、参照/更新処理をブロックしません。 -再編成の方式として、以下のいずれか1つを選択できます。

- -

このユーティリティを使用するためには、以下のことに注意をしてください。

- -
- -
-

-

testというデータベースをオンライン CLUSTER するには、下記のコマンドを実行します。

-
$ pg_reorg test
-

testという名前のデータベースのfooという1つのテーブルに対してオンライン VACUUM FULL を行うには、下記のコマンドを実行します。

-
$ pg_reorg --no-order --table foo -d test

-

-
- -
-

オプション

-

pg_reorg では、下記の4種類のコマンドライン引数を指定できます。

-
-
- -

connection-options

-

PostgreSQLに接続するためのパラメータです。

- -
-
-
-h host
---host host
-
サーバが稼働しているマシンのホスト名を指定します。ホスト名がスラッシュから始まる場合、Unixドメインソケット用のディレクトリとして使用されます。
- -
-p port
---port port
-
サーバが接続を監視するTCPポートもしくはUnixドメインソケットファイルの拡張子を指定します。
- -
-U username
---username username
-
接続するユーザ名を指定します。
- -
-W
--password
-
データベースに接続する前に、pg_reorg は強制的にパスワード入力を促します。
-
サーバがパスワード認証を要求する場合 pg_reorg は自動的にパスワード入力を促しますので、これが重要になることはありません。 -しかし、pg_reorg は、サーバにパスワードが必要かどうかを判断するための接続試行を無駄に行います。 -こうした余計な接続試行を防ぐために-Wの入力が有意となる場合もあります。
-
-
- -

message-options

-

-pg_reorg を実行した際に任意のメッセージを出力するためのパラメータです。 ---quietと他の2つのオプションを同時に指定した場合は、--quietのオプションは無視されます。 -

- -
-
-q
--quiet
-
進行メッセージを表示しません。
-
-v
--verbose
-
処理中に詳細な情報を表示します。
-
- -

order-options

-

pg_reorg を実行する際の並び替えの基準を指定するパラメータです。 -何も指定されていない場合は、cluster index順にオンライン CLUSTER を行います。 -この2つを同時に指定することはできません。 -

- -
-
-n
--no-order
-
オンライン VACUUM FULL の処理を行います。
- -
-o columns [,...]
---order-by columns [,...]
-
指定したカラムをキーにオンライン CLUSTER を行います。
-
- -

target-options

-

-pg_reorg を実行する対象を指定するパラメータです。 ---all--dbnameまたは--tableを同時に指定することはできません。 -

- -
-
-a
--all
-
対象となる全てのデータベースに対してオンライン CLUSTER、または、オンラインVACUUM FULLを行います。
- -
--d dbname
---dbname dbname -
-
オンライン CLUSTER、または、オンライン VACUUM FULL を行うデータベース名を指定します。 -データベース名が指定されておらず、-a(または--all)も指定されていない場合、 -データベース名はPGDATABASE環境変数から読み取られます。この変数も設定されていない場合は、接続時に指定したユーザ名が使用されます。 -
- -
--t table
---table table -
-
オンライン CLUSTER 、または、オンライン VACUUM FULL を行うテーブルを指定します。 -このオプションが指定されていない場合は、対象となったデータベースに存在する全ての対象テーブルに対して処理を行います。 -
- -
-Z
--no-analyze
-
再編成後に ANALYZE を行いません。 -このオプションが指定されていない場合は、再編成後に ANALYZE します。
- -
-
- -
-

環境変数

-
-
- PGDATABASE
- PGHOST
- PGPORT
- PGUSER -
-
デフォルトの接続パラメータです。
-
-
-

また、このユーティリティは、他のほとんどの PostgreSQL ユーティリティと同様、 - libpq でサポートされる環境変数を使用します。詳細については、環境変数の項目を参照してください。 -

-
- -
-

トラブルシューティング

-

pg_reorg の実行に失敗した場合にエラーが表示されます。 -想像されるエラー原因と対処を示します。

-

致命的なエラーで終了した場合、手動によるクリーンアップを行う必要があります。 -クリーンアップは、エラーが発生したデータベースに対して、$PGHOME/share/contrib/uninstall_pg_reorg.sql を実行し、その後、$PGHOME/share/contrib/pg_reorg.sql を実行します。

- -
-
pg_reorg : reorg database "template1" ... skipped
-
--allオプションを指定した際に、pg_reorg がインストールされていないデータベースに対して表示されます。
-
pg_reorg スキーマのインストールを行ってください。
- -
ERROR: pg_reorg is not installed
-
--dbnameで指定したデータベースにpg_reorg がインストールされていません。
-
pg_reorg のインストールを行ってください。
- -
ERROR: relation "table" has no primary key
-
指定したテーブルにPRIMARY KEYが存在していません。
-
対象のテーブルにPRIMARY KEYの作成を行ってください。(ALTER TABLE ADD PRIMARY KEY)
- -
ERROR: relation "table" has no cluster key
-
指定したテーブルに CLUSTER KEYが存在していません。
-
対象のテーブルに CLUSTER KEYの作成を行ってください。(ALTER TABLE CLUSTER)
- -
pg_reorg : query failed: ERROR: column "col" does not exist
-
--order-by で指定したカラムが対象のテーブルに存在していません。
-
対象のテーブルに存在するカラムを指定してください。
- -
ERROR: permission denied for schema reorg
-
操作を行おうとした対象に権限がありません。
-
スーパーユーザで操作を行ってください。
- -
pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists
-
操作を行おうとした対象にpg_reorg が処理のために作成するトリガと同名のものが存在しています。
-
トリガの改名か削除を行ってください。
- -
pg_reorg : trigger conflicted for tbl
-
操作を行おうとした対象にpg_reorg が処理のために作成するトリガより後に実行されるトリガが存在しています。
-
トリガの改名か削除を行ってください。
-
-
- -
-

制約

-

pg_reorg を使用する際には、以下の制約があります。以下の制約に関する操作を行った場合の動作は保証されません。注意してください。

- -

一時テーブルへの操作

-

pg_reorg では、一時テーブルは操作の対象外です。

- -

GiSTインデックスの使用

-

インデックス種別がGiSTとなっているインデックスがクラスタインデックスとなっている -テーブルはpg_reorg コマンドを使用して操作を行うことはできません。 -これは、GiSTインデックスのソート順序は一意ではないため、ORDER BYによる -ソートが行えないためです。

- -

DDLコマンドの発行

-

-pg_reorg の実行中には、VACUUMANALYZE 以外 のDDL操作は行わないでください。 -多くの場合、pg_reorg は失敗しロールバックされます。 -しかし、以下の操作ではデータが破損するため、非常に危険です。 -

- -
-
TRUNCATE
-
削除した行が pg_reorg 実行後には復元しています。操作結果が消失します。
- -
CREATE INDEX
-
スワップされない索引が残る可能性があります。データの不整合が生じます。
- -
ALTER TABLE ... ADD COLUMN
-
追加された値が全てNULLに置換されてしまう可能性があります。データが消失します。
- -
ALTER TABLE ... ALTER COLUMN TYPE
-
実行するとスキーマで定義された型と実際の格納状態に齟齬をきたします。データの不整合が生じます。
- -
ALTER TABLE ... SET TABLESPACE
-
pg_reorg 実行後にrelfilenodeとの不整合が起こるため、対象のテーブルに対する参照/更新操作時にエラーが発生します。
-
-
- -
-

インストール方法

-

pg_reorg のインストールは、標準のcontribモジュールと同様です。

-

ビルド

-

pg_reorg のフォルダを$PGHOME/contrib/に配置し、make, make installを行ってください。

-

データベースへの登録

-

PostgreSQLを起動し、対象のデータベースに対して $PGHOME/share/contrib にある pg_reorg.sql を実行し、インストールを行ってください。

-
- -
-

動作環境

-
-
PostgreSQLバージョン
PostgreSQL 8.3
-
OS
RHEL 5.2, Windows XP SP3
-
ディスク容量
処理対象のテーブル、インデックスサイズの2倍以上のディスク空き容量
-
-
- -
-

関連項目

-clusterdb, -vacuumdb -
- -
- -

-Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION -

- - - + + + +pg_reorg + + + + + + +

pg_reorg

+ + + +

名前

+pg_reorg -- PostgreSQLデータベース内のテーブルに対して、参照/更新処理をブロックせずに再編成を行います。 + +

概要

+

+pg_reorg [connection-options...] [message-options...] [order-options...] [target-options...] +

+

指定できるオプションには4つのカテゴリがあります。 +詳細はオプションを参照してください。

+
+
connection-options : 接続パラメータ
+
-h [--host] host
+
-p [--port] port
+
-U [--username] username
+
-W [--password]
+
message-options : 出力メッセージ
+
-q [--quiet]
+
-v [--verbose]
+
order-options : 並び替えの基準
+
-o [--order-by] columns [,...]
+
-n [--no-order]
+
target-options : 処理対象
+
-a [--all]
+
-d [--dbname] dbname
+
-t [--table] table
+
-Z [--no-analyze]
+
+ +

説明

+

pg_reorg は、PostgreSQLデータベース内のテーブルを再編成(行の並び替え)するユーティリティです。 +clusterdb と異なり、参照/更新処理をブロックしません。 +再編成の方式として、以下のいずれか1つを選択できます。

+
    +
  • オンライン CLUSTER (cluster index順に行を並び替える)
  • +
  • ユーザの指定した順に行を並び替える
  • +
  • オンライン VACUUM FULL (行の詰め合わせを行う)
  • +
+

このユーティリティを使用するためには、以下のことに注意をしてください。

+
    +
  • このユーティリティは、スーパーユーザのみが実行することができます。
  • +
  • 対象のテーブルはPRIMARY KEYを持っている必要があります。
  • +
+ +

+

testというデータベースをオンライン CLUSTER するには、下記のコマンドを実行します。

+
$ pg_reorg test
+

testという名前のデータベースのfooという1つのテーブルに対してオンライン VACUUM FULL を行うには、下記のコマンドを実行します。

+
$ pg_reorg --no-order --table foo -d test

+

+ +

オプション

+

pg_reorg では、下記の4種類のコマンドライン引数を指定できます。

+
+ +

connection-options

+

PostgreSQLに接続するためのパラメータです。

+ +
+
-h host
+--host host
+
サーバが稼働しているマシンのホスト名を指定します。ホスト名がスラッシュから始まる場合、Unixドメインソケット用のディレクトリとして使用されます。
+ +
-p port
+--port port
+
サーバが接続を監視するTCPポートもしくはUnixドメインソケットファイルの拡張子を指定します。
+ +
-U username
+--username username
+
接続するユーザ名を指定します。
+ +
-W
--password
+
データベースに接続する前に、pg_reorg は強制的にパスワード入力を促します。
+
サーバがパスワード認証を要求する場合 pg_reorg は自動的にパスワード入力を促しますので、これが重要になることはありません。 +しかし、pg_reorg は、サーバにパスワードが必要かどうかを判断するための接続試行を無駄に行います。 +こうした余計な接続試行を防ぐために-Wの入力が有意となる場合もあります。
+
+ +

message-options

+

+pg_reorg を実行した際に任意のメッセージを出力するためのパラメータです。 +--quietと他の2つのオプションを同時に指定した場合は、--quietのオプションは無視されます。 +

+ +
+
-q
--quiet
+
進行メッセージを表示しません。
+
-v
--verbose
+
処理中に詳細な情報を表示します。
+
+ +

order-options

+

pg_reorg を実行する際の並び替えの基準を指定するパラメータです。 +何も指定されていない場合は、cluster index順にオンライン CLUSTER を行います。 +この2つを同時に指定することはできません。 +

+ +
+
-n
--no-order
+
オンライン VACUUM FULL の処理を行います。
+ +
-o columns [,...]
+--order-by columns [,...]
+
指定したカラムをキーにオンライン CLUSTER を行います。
+
+ +

target-options

+

+pg_reorg を実行する対象を指定するパラメータです。 +--allと--dbnameまたは--tableを同時に指定することはできません。 +

+ +
+
-a
--all
+
対象となる全てのデータベースに対してオンライン CLUSTER、または、オンラインVACUUM FULLを行います。
+ +
+-d dbname
+--dbname dbname +
+
オンライン CLUSTER、または、オンライン VACUUM FULL を行うデータベース名を指定します。 +データベース名が指定されておらず、-a(または--all)も指定されていない場合、 +データベース名はPGDATABASE環境変数から読み取られます。この変数も設定されていない場合は、接続時に指定したユーザ名が使用されます。 +
+ +
+-t table
+--table table +
+
オンライン CLUSTER 、または、オンライン VACUUM FULL を行うテーブルを指定します。 +このオプションが指定されていない場合は、対象となったデータベースに存在する全ての対象テーブルに対して処理を行います。 +
+ +
-Z
--no-analyze
+
再編成後に ANALYZE を行いません。 +このオプションが指定されていない場合は、再編成後に ANALYZE します。
+ +
+ +

環境変数

+
+
+ PGDATABASE
+ PGHOST
+ PGPORT
+ PGUSER +
+
デフォルトの接続パラメータです。
+
+ +

+また、このユーティリティは、他のほとんどの PostgreSQL ユーティリティと同様、libpq でサポートされる環境変数を使用します。詳細については、環境変数の項目を参照してください。 +

+ +

トラブルシューティング

+

pg_reorg の実行に失敗した場合にエラーが表示されます。 +想像されるエラー原因と対処を示します。

+

致命的なエラーで終了した場合、手動によるクリーンアップを行う必要があります。 +クリーンアップは、エラーが発生したデータベースに対して、$PGHOME/share/contrib/uninstall_pg_reorg.sql を実行し、その後、$PGHOME/share/contrib/pg_reorg.sql を実行します。

+ +
+
pg_reorg : reorg database "template1" ... skipped
+
--allオプションを指定した際に、pg_reorg がインストールされていないデータベースに対して表示されます。
+
pg_reorg スキーマのインストールを行ってください。
+ +
ERROR: pg_reorg is not installed
+
--dbnameで指定したデータベースにpg_reorg がインストールされていません。
+
pg_reorg のインストールを行ってください。
+ +
ERROR: relation "table" has no primary key
+
指定したテーブルにPRIMARY KEYが存在していません。
+
対象のテーブルにPRIMARY KEYの作成を行ってください。(ALTER TABLE ADD PRIMARY KEY)
+ +
ERROR: relation "table" has no cluster key
+
指定したテーブルに CLUSTER KEYが存在していません。
+
対象のテーブルに CLUSTER KEYの作成を行ってください。(ALTER TABLE CLUSTER)
+ +
pg_reorg : query failed: ERROR: column "col" does not exist
+
--order-by で指定したカラムが対象のテーブルに存在していません。
+
対象のテーブルに存在するカラムを指定してください。
+ +
ERROR: permission denied for schema reorg
+
操作を行おうとした対象に権限がありません。
+
スーパーユーザで操作を行ってください。
+ +
pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists
+
操作を行おうとした対象にpg_reorg が処理のために作成するトリガと同名のものが存在しています。
+
トリガの改名か削除を行ってください。
+ +
pg_reorg : trigger conflicted for tbl
+
操作を行おうとした対象にpg_reorg が処理のために作成するトリガより後に実行されるトリガが存在しています。
+
トリガの改名か削除を行ってください。
+
+ +

使用上の注意と制約

+

pg_reorg を使用する際には、以下の制約があります。以下の制約に関する操作を行った場合の動作は保証されません。注意してください。

+ +

一時テーブルへの操作

+

pg_reorg では、一時テーブルは操作の対象外です。

+ +

GiSTインデックスの使用

+

インデックス種別がGiSTとなっているインデックスがクラスタインデックスとなっている +テーブルはpg_reorg コマンドを使用して操作を行うことはできません。 +これは、GiSTインデックスのソート順序は一意ではないため、ORDER BYによる +ソートが行えないためです。

+ +

DDLコマンドの発行

+

+pg_reorg の実行中には、VACUUM と ANALYZE 以外 のDDL操作は行わないでください。 +多くの場合、pg_reorg は失敗しロールバックされます。 +しかし、以下の操作ではデータが破損するため、非常に危険です。 +

+ +
+
TRUNCATE
+
削除した行が pg_reorg 実行後には復元しています。操作結果が消失します。
+ +
CREATE INDEX
+
スワップされない索引が残る可能性があります。データの不整合が生じます。
+ +
ALTER TABLE ... ADD COLUMN
+
追加された値が全てNULLに置換されてしまう可能性があります。データが消失します。
+ +
ALTER TABLE ... ALTER COLUMN TYPE
+
実行するとスキーマで定義された型と実際の格納状態に齟齬をきたします。データの不整合が生じます。
+ +
ALTER TABLE ... SET TABLESPACE
+
pg_reorg 実行後にrelfilenodeとの不整合が起こるため、対象のテーブルに対する参照/更新操作時にエラーが発生します。
+
+ +

詳細

+

pg_reorg は reorg スキーマに作業用テーブルを作成し、そこでデータの並び替えを行います。 +最後にシステムカタログを直接書き換えることで、元のテーブルと名前を交換しています。

+ +

インストール方法

+

pg_reorg のインストールは、標準のcontribモジュールと同様です。

+

ビルド

+

pg_reorg のフォルダを$PGHOME/contrib/に配置し、make, make installを行ってください。

+

データベースへの登録

+

PostgreSQLを起動し、対象のデータベースに対して $PGHOME/share/contrib にある pg_reorg.sql を実行し、インストールを行ってください。

+ +

動作環境

+
+
PostgreSQLバージョン
PostgreSQL 8.3
+
OS
RHEL 5.2, Windows XP SP3
+
ディスク容量
処理対象のテーブル、インデックスサイズの2倍以上のディスク空き容量
+
+ +

関連項目

+clusterdb, +vacuumdb + +
+ + + + + + diff --git a/doc/pg_reorg.html b/doc/pg_reorg.html index 10756e9..3318598 100755 --- a/doc/pg_reorg.html +++ b/doc/pg_reorg.html @@ -1,276 +1,278 @@ - - - -pg_reorg - - - - - - -

pg_reorg

- -
-

Name

-pg_reorg -- Reorganize tables in PostgreSQL databases without any locks. -
- -
-

Synopsis

-

-pg_reorg [connection-options...] [message-options...] [order-options...] [target-options...] -

-

There 4 option categories. -See also options for details.

-
-
connection-options
-
-h [--host] host
-
-p [--port] port
-
-U [--username] username
-
-W [--password]
-
message-options
-
-q [--quiet]
-
-v [--verbose]
-
order-options
-
-o [--order-by] columns [,...]
-
-n [--no-order]
-
target-options
-
-a [--all]
-
-d [--dbname] dbname
-
-t [--table] table
-
-Z [--no-analyze]
-
-
- -
- -

Description

-

pg_reorg is an utility program to reorganize tables in PostgreSQL databases. -Unlike clusterdb, it doesn't block any selections and updates during reorganization. -You can choose one of the following methods to reorganize.

-
    -
  • Online CLUSTER (ordered by cluster index)
  • -
  • Ordered by specified columns
  • -
  • Online VACUUM FULL (packing rows only)
  • -
-

NOTICE:

-
    -
  • Only superusers can use the utility.
  • -
  • Target table must have PRIMARY KEY.
  • -
-
- -
-

Examples

-

Execute the following command to do online CLUSTER to all tables in test database.

-
$ pg_reorg test
-

Execute the following command to do online VACUUM FULL to foo table in test database.

-
$ pg_reorg --no-order --table foo -d test

-

- -
-

Options

-

pg_reorg has command line options in 4 categolies.

-
-
- -

connection-options

-

Parameters to connect PostgreSQL.

- -
-
-
-h host
---host host
-
Specifies the host name of the machine on which the server is running. If the value begins with a slash, it is used as the directory for the Unix domain socket.
- -
-p port
---port port
-
Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections.
- -
-U username
---username username
-
User name to connect as.
- -
-W
--password
-
Force pg_reorg to prompt for a password before connecting to a database.
-
This option is never essential, since pg_reorg will automatically prompt for a password if the server demands password authentication. However, vacuumdb will waste a connection attempt finding out that the server wants a password. In some cases it is worth typing -W to avoid the extra connection attempt.
-
-
- -

message-options

-

Specifies message output by pg_reorg. ---quiet is ignored if some of the other options are specified.

- -
-
-q
--quiet
-
Do not display progress messages.
-
-v
--verbose
-
Print detailed information during processing.
-
- -

order-options

-

Options to order rows. -If not specified, pg_reorg do online CLUSTER using cluster indexes. -Only one option can be specified. -

- -
-
-n
--no-order
-
Do online VACUUM FULL.
- -
-o columns [,...]
---order-by columns [,...]
-
Do online CLUSTER ordered by specified columns.
-
- - -

target-options

-

-Options to specify target tables or databases. -You cannot use --all and --dbname or --table together. -

- -
-
-a
--all
-
Reorganize all databases.
- -
--d dbname
---dbname dbname -
-
Specifies the name of the database to be reorganized. If this is not specified and -a (or --all) is not used, the database name is read from the environment variable PGDATABASE. If that is not set, the user name specified for the connection is used.
- -
--t table
---table table -
-
Reorganize table only. If you don't specify this option, all tables in specified databases are reorganized.
- -
-Z
--no-analyze
-
Do ANALYZE after reorganization. If you don't specify this option, ANALYZE is performed automatically after reorg.
- -
-
- -
-

Environment

-
-
- PGDATABASE
- PGHOST
- PGPORT
- PGUSER -
-
Default connection parameters
-
-
-

This utility, like most other PostgreSQL utilities, also uses the environment variables supported by libpq (see Environment Variables).

-
- -
-

Diagnostics

-

Error messages are reported when pg_reorg fails. -The following list shows the cause of errors.

-

You need to cleanup by hand after fatal erros. -To cleanup, execute $PGHOME/share/contrib/uninstall_pg_reorg.sql to the database where the error occured and then execute $PGHOME/share/contrib/pg_reorg.sql. (Do uninstall and reinstall.)

- -
-
pg_reorg : reorg database "template1" ... skipped
-
pg_reorg is not installed in the database when --all option is specified.
-
Do register pg_reorg to the database.
- -
ERROR: pg_reorg is not installed
-
pg_reorg is not installed in the database specified by --dbname.
-
Do register pg_reorg to the database.
- -
ERROR: relation "table" has no primary key
-
The target table doesn't have PRIMARY KEY.
-
Define PRIMARY KEY to the table. (ALTER TABLE ADD PRIMARY KEY)
- -
ERROR: relation "table" has no cluster key
-
The target table doesn't have CLUSTER KEY.
-
Define CLUSTER KEY to the table. (ALTER TABLE CLUSTER)
- -
pg_reorg : query failed: ERROR: column "col" does not exist
-
The target table doesn't have columns specified by --order-by option.
-
Specify existing columns.
- -
ERROR: permission denied for schema reorg
-
Permission error.
-
pg_reorg must be executed by superusers.
- -
pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists
-
The target table already has a trigger named "z_reorg_trigger".
-
Delete or rename the trigger.
- -
pg_reorg : trigger conflicted for tbl
-
The target table already has a trigger which follows by "z_reorg_trigger" in alphabetical order.
-
Delete or rename the trigger.
-
-
- -
-

Restrictions

-

pg_reorg has the following restrictions. -Be careful to avoid data corruptions.

- -

Temp tables

-

pg_reorg cannot reorganize temp tables.

- -

GiST indexes

-

pg_reorg cannot reorganize tables using GiST indexes.

- -

DDL commands

-

You cannot do DDL commands except VACUUM and ANALYZE during pg_reorg. -In many case pg_reorg would fail and rollback collectly, but there are some cases ending with data-corruption .

- -
-
TRUNCATE
-
TRUNCATE is lost. Deleted rows still exist after pg_reorg.
- -
CREATE INDEX
-
It causes index corruptions.
- -
ALTER TABLE ... ADD COLUMN
-
It causes lost of data. Newly added columns are initialized with NULLs.
- -
ALTER TABLE ... ALTER COLUMN TYPE
-
It causes data corruptions.
- -
ALTER TABLE ... SET TABLESPACE
-
It causes data corruptions by wrong relfilenode.
-
-
- -
-

Installations

-

pg_reorg can be installed like standard contrib modules.

-

Build from source

-

Place pg_reorg to $PGHOME/contrib/ and input make, make install.

-

Register to database

-

Start PostgreSQL and execute pg_reorg.sql in $PGHOME/share/contrib.

-
- -
-

Requirements

-
-
PostgreSQL version
PostgreSQL 8.3
-
OS
RHEL 5.2, Windows XP SP3
-
Disks
Requires amount of disks twice larger than target table and indexes.
-
-
- -
-

See Also

-clusterdb, -vacuumdb -
- -
- -

-Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION -

- - - + + + +pg_reorg + + + + + + +

pg_reorg

+ + + +

Name

+pg_reorg -- Reorganize tables in PostgreSQL databases without any locks. + +

Synopsis

+

+pg_reorg [connection-options...] [message-options...] [order-options...] [target-options...] +

+

There 4 option categories. +See also options for details.

+
+
connection-options
+
-h [--host] host
+
-p [--port] port
+
-U [--username] username
+
-W [--password]
+
message-options
+
-q [--quiet]
+
-v [--verbose]
+
order-options
+
-o [--order-by] columns [,...]
+
-n [--no-order]
+
target-options
+
-a [--all]
+
-d [--dbname] dbname
+
-t [--table] table
+
-Z [--no-analyze]
+
+ +

Description

+

pg_reorg is an utility program to reorganize tables in PostgreSQL databases. +Unlike clusterdb, it doesn't block any selections and updates during reorganization. +You can choose one of the following methods to reorganize.

+
    +
  • Online CLUSTER (ordered by cluster index)
  • +
  • Ordered by specified columns
  • +
  • Online VACUUM FULL (packing rows only)
  • +
+

NOTICE:

+
    +
  • Only superusers can use the utility.
  • +
  • Target table must have PRIMARY KEY.
  • +
+ +

Examples

+

Execute the following command to do online CLUSTER to all tables in test database.

+
$ pg_reorg test
+

Execute the following command to do online VACUUM FULL to foo table in test database.

+
$ pg_reorg --no-order --table foo -d test

+

+ +

Options

+

pg_reorg has command line options in 4 categolies.

+
+
+ +

connection-options

+

Parameters to connect PostgreSQL.

+ +
+
+
-h host
+--host host
+
Specifies the host name of the machine on which the server is running. If the value begins with a slash, it is used as the directory for the Unix domain socket.
+ +
-p port
+--port port
+
Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections.
+ +
-U username
+--username username
+
User name to connect as.
+ +
-W
--password
+
Force pg_reorg to prompt for a password before connecting to a database.
+
This option is never essential, since pg_reorg will automatically prompt for a password if the server demands password authentication. However, vacuumdb will waste a connection attempt finding out that the server wants a password. In some cases it is worth typing -W to avoid the extra connection attempt.
+
+ +

message-options

+

Specifies message output by pg_reorg. +--quiet is ignored if some of the other options are specified.

+ +
+
-q
--quiet
+
Do not display progress messages.
+
-v
--verbose
+
Print detailed information during processing.
+
+ +

order-options

+

Options to order rows. +If not specified, pg_reorg do online CLUSTER using cluster indexes. +Only one option can be specified. +

+ +
+
-n
--no-order
+
Do online VACUUM FULL.
+ +
-o columns [,...]
+--order-by columns [,...]
+
Do online CLUSTER ordered by specified columns.
+
+ + +

target-options

+

+Options to specify target tables or databases. +You cannot use --all and --dbname or --table together. +

+ +
+
-a
--all
+
Reorganize all databases.
+ +
+-d dbname
+--dbname dbname +
+
Specifies the name of the database to be reorganized. If this is not specified and -a (or --all) is not used, the database name is read from the environment variable PGDATABASE. If that is not set, the user name specified for the connection is used.
+ +
+-t table
+--table table +
+
Reorganize table only. If you don't specify this option, all tables in specified databases are reorganized.
+ +
-Z
--no-analyze
+
Do ANALYZE after reorganization. If you don't specify this option, ANALYZE is performed automatically after reorg.
+ +
+ +

Environment

+
+
+ PGDATABASE
+ PGHOST
+ PGPORT
+ PGUSER +
+
Default connection parameters
+
+

This utility, like most other PostgreSQL utilities, also uses the environment variables supported by libpq (see Environment Variables).

+ +

Diagnostics

+

Error messages are reported when pg_reorg fails. +The following list shows the cause of errors.

+

You need to cleanup by hand after fatal erros. +To cleanup, execute $PGHOME/share/contrib/uninstall_pg_reorg.sql to the database where the error occured and then execute $PGHOME/share/contrib/pg_reorg.sql. (Do uninstall and reinstall.)

+ +
+
pg_reorg : reorg database "template1" ... skipped
+
pg_reorg is not installed in the database when --all option is specified.
+
Do register pg_reorg to the database.
+ +
ERROR: pg_reorg is not installed
+
pg_reorg is not installed in the database specified by --dbname.
+
Do register pg_reorg to the database.
+ +
ERROR: relation "table" has no primary key
+
The target table doesn't have PRIMARY KEY.
+
Define PRIMARY KEY to the table. (ALTER TABLE ADD PRIMARY KEY)
+ +
ERROR: relation "table" has no cluster key
+
The target table doesn't have CLUSTER KEY.
+
Define CLUSTER KEY to the table. (ALTER TABLE CLUSTER)
+ +
pg_reorg : query failed: ERROR: column "col" does not exist
+
The target table doesn't have columns specified by --order-by option.
+
Specify existing columns.
+ +
ERROR: permission denied for schema reorg
+
Permission error.
+
pg_reorg must be executed by superusers.
+ +
pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists
+
The target table already has a trigger named "z_reorg_trigger".
+
Delete or rename the trigger.
+ +
pg_reorg : trigger conflicted for tbl
+
The target table already has a trigger which follows by "z_reorg_trigger" in alphabetical order.
+
Delete or rename the trigger.
+
+ +

Restrictions

+

pg_reorg has the following restrictions. +Be careful to avoid data corruptions.

+ +

Temp tables

+

pg_reorg cannot reorganize temp tables.

+ +

GiST indexes

+

pg_reorg cannot reorganize tables using GiST indexes.

+ +

DDL commands

+

You cannot do DDL commands except VACUUM and ANALYZE during pg_reorg. +In many case pg_reorg would fail and rollback collectly, but there are some cases ending with data-corruption .

+ +
+
TRUNCATE
+
TRUNCATE is lost. Deleted rows still exist after pg_reorg.
+ +
CREATE INDEX
+
It causes index corruptions.
+ +
ALTER TABLE ... ADD COLUMN
+
It causes lost of data. Newly added columns are initialized with NULLs.
+ +
ALTER TABLE ... ALTER COLUMN TYPE
+
It causes data corruptions.
+ +
ALTER TABLE ... SET TABLESPACE
+
It causes data corruptions by wrong relfilenode.
+
+ +

Details

+

pg_reorg creates a work table in reorg schema and sorts rows in it. +Then, it updates system catalog directly to swap the work table and the original one.

+ +

Installations

+

pg_reorg can be installed like standard contrib modules.

+

Build from source

+

Place pg_reorg to $PGHOME/contrib/ and input make, make install.

+

Register to database

+

Start PostgreSQL and execute pg_reorg.sql in $PGHOME/share/contrib.

+ +

Requirements

+
+
PostgreSQL version
PostgreSQL 8.3
+
OS
RHEL 5.2, Windows XP SP3
+
Disks
Requires amount of disks twice larger than target table and indexes.
+
+ +

See Also

+clusterdb, +vacuumdb + +
+ + + + + + diff --git a/doc/style.css b/doc/style.css index aca10f8..98a9bbb 100755 --- a/doc/style.css +++ b/doc/style.css @@ -1,12 +1,13 @@ -BODY { - margin-top: 3; - margin-left: 3; - margin-right: 3; - margin-bottom: 3; -} - -TT,OL,UL,P,BODY,TR,TD,TH,FORM { - font-family: arial,helvetica,sans-serif; +body { + font-family: + Lucida Grande, Verdana, Arial, Helvetica, + 'メイリオ', + 'Meiryo', + 'ヒラギノ角ゴ Pro W3', + 'Hiragino Kaku Gothic Pro', + 'Osaka', + 'MS Pゴシック', + sans-serif; color: #202020; } @@ -16,11 +17,11 @@ HR { margin: 5px 0px 5px 0px } h2, h3, h4, h5, h6 { - color: Black; - background: none; - padding-top: 0.5em; - padding-bottom: 0.17em; - border-bottom: 1px solid #aaaaaa; + color: Black; + background: none; + padding-top: 0.5em; + padding-bottom: 0.17em; + border-bottom: 1px solid #aaaaaa; } H1 { font-size: x-large; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } H2 { font-size: large; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } @@ -29,13 +30,7 @@ H4 { padding-left: 2em; font-size: small; font-family: Lucida Grande,verdana,ari H5 { padding-left: 3em; font-size: x-small; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } H6 { padding-left: 4em; font-size: xx-small; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } -dt { - font-size: 110%; - padding-top: 0.5em; - padding-bottom: 0.5em; -} - -PRE { +pre { font-family: courier,sans-serif; background-color: #FBFBFD; border: 1px dashed #7E7ECB; @@ -44,63 +39,43 @@ PRE { overflow: auto; } -A:link { text-decoration:none; color:#0000EE } -A:visited { text-decoration:none color:#551A8B} -A:active { text-decoration:none; color:#00ff00 } -A:hover { text-decoration:underline; color:#008000 } - -.titlebar { color: #000000; text-decoration: none; font-weight: bold; } - - -A.tablink { - color: #000000; - text-decoration: none; - font-weight: bold; - font-size: small; -} -A.tablink:visited { - color: #000000; - text-decoration: none; - font-weight: bold; - font-size: small; -} -A.tablink:hover { - text-decoration: none; - color: #000000; - font-weight: bold; - font-size: small; -} -A.tabsellink { - color: #ffffcc; - text-decoration: none; - font-weight: bold; - font-size: small; -} -A.tabsellink:visited { - color: #ffffcc; - text-decoration: none; - font-weight: bold; - font-size: small; -} -A.tabsellink:hover { - text-decoration: none; - color: #ffffcc; - font-weight: bold; - font-size: small; +li { + line-height: 1.4em; } -A.showsource { - color: #000000; - text-decoration: none; - font-size: small; -} -A.showsource:visited { - color: #000000; - text-decoration: none; - font-size: small; -} -A.showsource:hover { - color: #000000; - text-decoration: none; +table { + background: #f9f9f9; + border: 1px solid #aaa; + border-collapse: collapse; +} + +th, td { + border: 1px solid #aaa; + padding: 0.2em; +} + +thead th { + background: #f2f2f2; + text-align: center; +} + +tbody th { + background: #f2f2f2; + text-align: left; +} + +div.index { + float:right; + border:thin solid black; + background-color: white; + padding-top: 0.2em; + padding-bottom: 0.2em; + padding-left: 1em; + padding-right: 1em; + margin-left: 0.5em; +} + +p.footer { + text-align: right; font-size: small; } diff --git a/lib/reorg.c b/lib/reorg.c index cd754e7..50d0451 100755 --- a/lib/reorg.c +++ b/lib/reorg.c @@ -8,12 +8,14 @@ #include +#include "access/genam.h" #include "access/transam.h" #include "access/xact.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_namespace.h" +#include "catalog/pg_opclass.h" #include "catalog/pg_type.h" #include "commands/tablecmds.h" #include "commands/trigger.h" @@ -55,6 +57,9 @@ static void swap_heap_or_index_files(Oid r1, Oid r2); #define copy_tuple(tuple, desc) \ PointerGetDatum(SPI_returntuple((tuple), (desc))) +#define IsToken(c) \ + (IS_HIGHBIT_SET((c)) || isalnum((unsigned char) (c)) || (c) == '_') + /* check access authority */ static void must_be_superuser(const char *func) @@ -313,11 +318,32 @@ skip_const(Oid index, char *sql, const char *arg1, const char *arg2) static char * skip_ident(Oid index, char *sql) { - sql = strchr(sql, ' '); - if (sql) + while (*sql && isspace((unsigned char) *sql)) + sql++; + + if (*sql == '"') { + sql++; + for (;;) + { + char *end = strchr(sql, '"'); + if (end == NULL) + return parse_error(index); + else if (end[1] != '"') + { + end[1] = '\0'; + return end + 2; + } + else /* escaped quote ("") */ + sql = end + 2; + } + } + else + { + while (*sql && IsToken(*sql)) + sql++; *sql = '\0'; - return sql + 2; + return sql + 1; } /* error */ @@ -325,12 +351,13 @@ skip_ident(Oid index, char *sql) } static char * -skip_columns(Oid index, char *sql) +skip_until(Oid index, char *sql, char end) { char instr = 0; - int nopen = 1; + int nopen = 0; - for (; *sql && nopen > 0; sql++) + sql++; + for (; *sql && (nopen > 0 || instr != 0 || *sql != end); sql++) { if (instr) { @@ -342,9 +369,7 @@ skip_columns(Oid index, char *sql) instr = 0; } else if (sql[0] == '\\') - { - sql++; // next char is always string - } + sql++; /* next char is always string */ } else { @@ -364,10 +389,10 @@ skip_columns(Oid index, char *sql) } } - if (nopen == 0) + if (nopen == 0 && instr == 0) { - sql[-1] = '\0'; - return sql; + *sql = '\0'; + return sql + 1; } /* error */ @@ -395,11 +420,14 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table) /* USING */ sql = skip_const(index, sql, "USING", NULL); /* type */ - stmt->type= sql; + stmt->type = sql; sql = skip_ident(index, sql); /* (columns) */ + if ((sql = strchr(sql, '(')) == NULL) + parse_error(index); + sql++; stmt->columns = sql; - sql = skip_columns(index, sql); + sql = skip_until(index, sql, ')'); /* options */ stmt->options = sql; } @@ -413,6 +441,9 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table) * @param index Oid of target index. * @param table Oid of table of the index. * @retval Create index DDL for temp table. + * + * FIXME: this function is named get_index_keys, but actually returns + * an expression for ORDER BY clause. get_order_by() might be a better name. */ Datum reorg_get_index_keys(PG_FUNCTION_ARGS) @@ -420,10 +451,107 @@ reorg_get_index_keys(PG_FUNCTION_ARGS) Oid index = PG_GETARG_OID(0); Oid table = PG_GETARG_OID(1); IndexDef stmt; + char *token; + char *next; + StringInfoData str; + Relation indexRel = NULL; + int nattr; parse_indexdef(&stmt, index, table); - PG_RETURN_TEXT_P(cstring_to_text(stmt.columns)); + /* + * FIXME: this is very unreliable implementation but I don't want to + * re-implement customized versions of pg_get_indexdef_string... + * + * TODO: Support ASC/DESC and NULL FIRST/LAST. + */ + + initStringInfo(&str); + for (nattr = 0, next = stmt.columns; *next; nattr++) + { + char *opcname; + + token = next; + next = skip_until(index, next, ','); + + opcname = token + strlen(token); + if (opcname[-1] == '"') + { + opcname--; + for (;;) + { + char *beg = strrchr(opcname, '"'); + if (beg == NULL) + parse_error(index); + else if (beg[-1] != '"') + break; + else /* escaped quote ("") */ + opcname = beg - 1; + } + } + else + { + while (opcname > token && IsToken(opcname[-1])) + opcname--; + } + + if (opcname > token && *opcname) + { + /* lookup default operator name from operator class */ + + Oid opclass; + Oid oprid; + int16 strategy = BTLessStrategyNumber; +#if PG_VERSION_NUM >= 80300 + Oid opcintype; + Oid opfamily; + HeapTuple tp; + Form_pg_opclass opclassTup; +#endif + + opclass = OpclassnameGetOpcid(BTREE_AM_OID, opcname); + +#if PG_VERSION_NUM >= 80300 + /* Retrieve operator information. */ + tp = SearchSysCache(CLAOID, ObjectIdGetDatum(opclass), 0, 0, 0); + if (!HeapTupleIsValid(tp)) + elog(ERROR, "cache lookup failed for opclass %u", opclass); + opclassTup = (Form_pg_opclass) GETSTRUCT(tp); + opfamily = opclassTup->opcfamily; + opcintype = opclassTup->opcintype; + ReleaseSysCache(tp); + + if (!OidIsValid(opcintype)) + { + if (indexRel == NULL) + indexRel = index_open(index, NoLock); + + opcintype = RelationGetDescr(indexRel)->attrs[nattr]->atttypid; + } + + oprid = get_opfamily_member(opfamily, opcintype, opcintype, strategy); + if (!OidIsValid(oprid)) + elog(ERROR, "missing operator %d(%u,%u) in opfamily %u", + strategy, opcintype, opcintype, opfamily); +#else + oprid = get_opclass_member(opclass, 0, strategy); + if (!OidIsValid(oprid)) + elog(ERROR, "missing operator %d for %s", strategy, opcname); +#endif + + opcname[-1] = '\0'; + appendStringInfo(&str, "%s USING %s", token, get_opname(oprid)); + } + else + appendStringInfoString(&str, token); + if (*next) + appendStringInfoChar(&str, ','); + } + + if (indexRel != NULL) + index_close(indexRel, NoLock); + + PG_RETURN_TEXT_P(cstring_to_text(str.data)); } /** @@ -481,7 +609,19 @@ remove_dropped_columns_and_adjust_attnum(Oid oid, int16 natts1, int16 natts2) natts2 - natts1, SPI_processed); /* renumber attnum */ -#if PG_VERSION_NUM >= 80300 +#if PG_VERSION_NUM >= 80500 + execute_with_format(SPI_OK_UPDATE, + "UPDATE pg_catalog.pg_attribute m" + " SET attnum = (SELECT count(*) FROM pg_attribute a" + " WHERE m.attrelid = a.attrelid" + " AND m.attnum >= a.attnum" + " AND a.attnum > 0 AND NOT a.attisdropped)" + " WHERE attrelid = %u AND attnum > 0 AND NOT attisdropped", + oid); + if (SPI_processed != natts2) + elog(ERROR, "cannot update %d columns (%u columns updated)", + natts2, SPI_processed); +#elif PG_VERSION_NUM >= 80300 execute_with_format(SPI_OK_UPDATE, "UPDATE pg_catalog.pg_attribute" " SET attnum = (SELECT count(*) FROM pg_attribute a" @@ -676,12 +816,21 @@ reorg_swap(PG_FUNCTION_ARGS) /* adjust key attnum if the target table has dropped columns */ if (natts1 != natts2) { +#if PG_VERSION_NUM >= 80500 + execute_with_format(SPI_OK_UPDATE, + "UPDATE pg_catalog.pg_index m SET indkey = n.indkey" + " FROM pg_catalog.pg_index n" + " WHERE m.indexrelid = %u" + " AND n.indexrelid = 'reorg.index_%u'::regclass", + idx1, idx1); +#else execute_with_format(SPI_OK_UPDATE, "UPDATE pg_catalog.pg_index SET indkey = n.indkey" " FROM pg_catalog.pg_index n" " WHERE pg_catalog.pg_index.indexrelid = %u" " AND n.indexrelid = 'reorg.index_%u'::regclass", idx1, idx1); +#endif if (SPI_processed != 1) elog(ERROR, "failed to update pg_index.indkey (%u rows updated)", SPI_processed); }