Support reorganizing tables with non-default operator class.

This commit is contained in:
Takahiro Itagaki 2009-12-28 08:25:00 +00:00
parent 27e6839132
commit 038c07523a
10 changed files with 1083 additions and 957 deletions

View File

@ -3,27 +3,26 @@
# #
# Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION # 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: SUBDIRS = bin lib
make -C bin
make -C lib
install: all install installdirs uninstall distprep clean distclean maintainer-clean debug:
make -C bin install @for dir in $(SUBDIRS); do \
make -C lib install $(MAKE) -C $$dir $@ || exit; \
done
clean: # We'd like check operations to run all the subtests before failing.
make -C bin clean check installcheck:
make -C lib clean @CHECKERR=0; for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir $@ || CHECKERR=$$?; \
debug: done; \
make -C bin DEBUG_REORG=enable exit $$CHECKERR
make -C lib DEBUG_REORG=enable
uninstall:
make -C bin uninstall
make -C lib uninstall
installcheck:
make -C bin installcheck

View File

@ -1,3 +1,3 @@
SET client_min_messages = warning; SET client_min_messages = warning;
\set ECHO none \set ECHO none
RESET client_min_messages; RESET client_min_messages;

View File

@ -5,21 +5,21 @@ SET client_min_messages = warning;
CREATE TABLE tbl_cluster ( CREATE TABLE tbl_cluster (
col1 int, col1 int,
col2 timestamp, col2 timestamp,
":-)" text, ","")" text,
PRIMARY KEY (":-)", col1) PRIMARY KEY (","")", col1)
) WITH (fillfactor = 70); ) WITH (fillfactor = 70);
CREATE INDEX cidx_cluster ON tbl_cluster (col2, length(":-)")); CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops);
ALTER TABLE tbl_cluster CLUSTER ON cidx_cluster; ALTER TABLE tbl_cluster CLUSTER ON ","") cluster";
CREATE TABLE tbl_only_pkey ( CREATE TABLE tbl_only_pkey (
col1 int PRIMARY KEY, col1 int PRIMARY KEY,
":-)" text ","")" text
); );
CREATE TABLE tbl_only_ckey ( CREATE TABLE tbl_only_ckey (
col1 int, col1 int,
col2 timestamp, col2 timestamp,
":-)" text ","")" text
) WITH (fillfactor = 70); ) 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; ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey;
CREATE TABLE tbl_gistkey ( CREATE TABLE tbl_gistkey (
id integer PRIMARY KEY, id integer PRIMARY KEY,
@ -83,10 +83,10 @@ SELECT * FROM tbl_with_dropped_column;
--------+-----------------------------+----------- --------+-----------------------------+-----------
col1 | integer | not null col1 | integer | not null
col2 | timestamp without time zone | col2 | timestamp without time zone |
:-) | text | not null ,") | text | not null
Indexes: Indexes:
"tbl_cluster_pkey" PRIMARY KEY, btree (":-)", col1) "tbl_cluster_pkey" PRIMARY KEY, btree (","")", col1)
"cidx_cluster" btree (col2, length(":-)")) CLUSTER ",") cluster" btree (col2, length(","")"), ","")" text_pattern_ops) CLUSTER
\d tbl_gistkey \d tbl_gistkey
Table "public.tbl_gistkey" Table "public.tbl_gistkey"
@ -104,16 +104,16 @@ Indexes:
--------+-----------------------------+----------- --------+-----------------------------+-----------
col1 | integer | col1 | integer |
col2 | timestamp without time zone | col2 | timestamp without time zone |
:-) | text | ,") | text |
Indexes: Indexes:
"cidx_only_ckey" btree (col2, ":-)") CLUSTER "cidx_only_ckey" btree (col2, ","")") CLUSTER
\d tbl_only_pkey \d tbl_only_pkey
Table "public.tbl_only_pkey" Table "public.tbl_only_pkey"
Column | Type | Modifiers Column | Type | Modifiers
--------+---------+----------- --------+---------+-----------
col1 | integer | not null col1 | integer | not null
:-) | text | ,") | text |
Indexes: Indexes:
"tbl_only_pkey_pkey" PRIMARY KEY, btree (col1) "tbl_only_pkey_pkey" PRIMARY KEY, btree (col1)
@ -130,8 +130,8 @@ Indexes:
"idx_c1c2" btree (c1, c2) "idx_c1c2" btree (c1, c2)
"idx_c2c1" btree (c2, c1) "idx_c2c1" btree (c2, c1)
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;
col1 | to_char | :-) col1 | to_char | ,")
------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ------+---------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 | 2008-01-01 00:00:00 | king 2 | 2008-01-01 00:00:00 | king
5 | 2008-01-01 00:30:00 | 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893944370926591800311388246468157082630100594858704003186480342194897278290641045072636881313739855256117322040245091227700226941127573627280495738108967504018369868368450725799364729060762996941380475654823728997180326802474420629269124859052181004459842150591120249441341728531478105803603371077309182869314710171111683916581726889419758716582152128229518488471.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248575675626141415406703029969945094998952478811655512094373648528093231902305582067974820101084674923265015312343266903322886650672254668921837971227047131660367861588019049986537379859389467650347506576050756618348129606100947602187190325083145829523959832997789824508288714463832917347224163984587855397667958063818353666110843173780894378316102088305524901670023520711144288695990956365797087168498072899493296484283020786408603988738697537582317317831395992983007838702877053913369563312103707264019249106768231199288375641141422016742752102372994270831059898459475987664288897796147837958390228854852903576033852808064381972344661059689722872865264153822664698420021195484155278441181286534507035191650016689294415480846071277143999762926834629577438361895110127148638746976545982451788550975379013880664961911962222957110555242923723192197738262561631468842032853716682938649611917049738836395495938 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) (5 rows)
SELECT * FROM tbl_only_ckey ORDER BY 1; SELECT * FROM tbl_only_ckey ORDER BY 1;
col1 | col2 | :-) col1 | col2 | ,")
------+--------------------------+----- ------+--------------------------+-----
1 | Tue Jan 01 00:00:00 2008 | abc 1 | Tue Jan 01 00:00:00 2008 | abc
2 | Fri Feb 01 00:00:00 2008 | def 2 | Fri Feb 01 00:00:00 2008 | def
(2 rows) (2 rows)
SELECT * FROM tbl_only_pkey ORDER BY 1; SELECT * FROM tbl_only_pkey ORDER BY 1;
col1 | :-) col1 | ,")
------+----- ------+-----
1 | abc 1 | abc
2 | def 2 | def

View File

@ -5,25 +5,25 @@ SET client_min_messages = warning;
CREATE TABLE tbl_cluster ( CREATE TABLE tbl_cluster (
col1 int, col1 int,
col2 timestamp, col2 timestamp,
":-)" text, ","")" text,
PRIMARY KEY (":-)", col1) PRIMARY KEY (","")", col1)
) WITH (fillfactor = 70); ) WITH (fillfactor = 70);
CREATE INDEX cidx_cluster ON tbl_cluster (col2, length(":-)")); CREATE INDEX ","") cluster" ON tbl_cluster (col2, length(","")"), ","")" text_pattern_ops);
ALTER TABLE tbl_cluster CLUSTER ON cidx_cluster; ALTER TABLE tbl_cluster CLUSTER ON ","") cluster";
CREATE TABLE tbl_only_pkey ( CREATE TABLE tbl_only_pkey (
col1 int PRIMARY KEY, col1 int PRIMARY KEY,
":-)" text ","")" text
); );
CREATE TABLE tbl_only_ckey ( CREATE TABLE tbl_only_ckey (
col1 int, col1 int,
col2 timestamp, col2 timestamp,
":-)" text ","")" text
) WITH (fillfactor = 70); ) 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; ALTER TABLE tbl_only_ckey CLUSTER ON cidx_only_ckey;
CREATE TABLE tbl_gistkey ( CREATE TABLE tbl_gistkey (
@ -95,7 +95,7 @@ SELECT * FROM tbl_with_dropped_column;
\d tbl_only_pkey \d tbl_only_pkey
\d tbl_with_dropped_column \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_ckey ORDER BY 1;
SELECT * FROM tbl_only_pkey ORDER BY 1; SELECT * FROM tbl_only_pkey ORDER BY 1;
SELECT * FROM tbl_gistkey ORDER BY 1; SELECT * FROM tbl_gistkey ORDER BY 1;

View File

@ -1,123 +1,124 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head> <head>
<link rel="icon" type="image/png" href="http://pgfoundry.org/images/elephant-icon.png" /> <link rel="icon" type="image/png" href="http://pgfoundry.org/images/elephant-icon.png" />
<link rel="stylesheet" type="text/css" href="style.css" /> <link rel="stylesheet" type="text/css" href="style.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>pg_reorg: Project Home Page</title> <title>pg_reorg: Project Home Page</title>
</head> </head>
<body> <body>
<center><img style="border: none; margin-left: auto; margin-right: auto; " src="http://pgfoundry.org/images/elephantSmall.png" height="75" width="75" /> <center><img style="border: none; margin-left: auto; margin-right: auto; " src="http://pgfoundry.org/images/elephantSmall.png" height="75" width="75" />
<hr /> <hr />
<h1>pg_reorg ホームページへようこそ</h1> <h1>pg_reorg ホームページへようこそ</h1>
<hr /> <hr />
</center> </center>
<p> <p>
pg_reorg は PostgreSQL のテーブルを再編成するシェルコマンドです。 pg_reorg は PostgreSQL のテーブルを再編成するシェルコマンドです。
共有ロックや排他ロックを取得しないため、再編成中であっても行の参照や更新を行うことができます。 共有ロックや排他ロックを取得しないため、再編成中であっても行の参照や更新を行うことができます。
このモジュールは CLUSTER や VACUUM FULL コマンドのより良い代替になります。 このモジュールは CLUSTER や VACUUM FULL コマンドのより良い代替になります。
</p> </p>
<p>この pg_reorg プロジェクトは <a href="http://www.postgresql.org">PostgreSQL</a> コミュニティによる <a href="http://pgfoundry.org">pgFoundry</a> の中の<a href="http://pgfoundry.org/projects/reorg">プロジェクト</a>です。</p> <p>この pg_reorg プロジェクトは <a href="http://www.postgresql.org">PostgreSQL</a> コミュニティによる <a href="http://pgfoundry.org">pgFoundry</a> の中の<a href="http://pgfoundry.org/projects/reorg">プロジェクト</a>です。</p>
<ul> <ul>
<li><a href="http://pgfoundry.org/frs/?group_id=1000411">ダウンロード</a> : ソースコードのほか、Windows 用バイナリもダウンロードできます。</li> <li><a href="http://pgfoundry.org/frs/?group_id=1000411">ダウンロード</a> : ソースコードのほか、Windows 用バイナリもダウンロードできます。</li>
<li><a href="http://pgfoundry.org/tracker/?group_id=1000411">バグレポート</li></li> <li><a href="http://pgfoundry.org/tracker/?group_id=1000411">バグレポート</li></li>
<li><a href="http://pgfoundry.org/mail/?group_id=1000411">メーリングリスト</a> への参加</li> <li><a href="http://pgfoundry.org/mail/?group_id=1000411">メーリングリスト</a> への参加</li>
</ul> </ul>
<div> <div>
<a href="index.html">Here is an English page.</a> <a href="index.html">Here is an English page.</a>
</div> </div>
<hr /> <hr />
<h2>ドキュメント</h2> <h2>ドキュメント</h2>
<p> <p>
<a href="pg_reorg-ja.html">ドキュメントはこちら</a> <a href="pg_reorg-ja.html">ドキュメントはこちら</a>
</p> </p>
<h2>実行時間</h2> <h2>実行時間</h2>
<p> <p>
pg_reorg とclusterdb の比較に示します。 pg_reorg とclusterdb の比較に示します。
断片化のないソートされた状態 (not fragmented) では clusterdb のほうが高速ですが、完全に断片化した状態 (fully fragmented) では pg_reorg が大幅に高速です。 断片化のないソートされた状態 (not fragmented) では clusterdb のほうが高速ですが、完全に断片化した状態 (fully fragmented) では pg_reorg が大幅に高速です。
一般的に、再編成は断片化が進行した状態で実施されることを考えると、pg_reorg は clusterdb よりも実行時間が短いと言えます。 一般的に、再編成は断片化が進行した状態で実施されることを考えると、pg_reorg は clusterdb よりも実行時間が短いと言えます。
</p> </p>
<center> <center>
<div style="margin: 2em"> <div style="margin: 2em">
<img src="result.png" /> <img src="result.png" />
</div> </div>
<table border="1"> <table border="1">
<caption>測定環境</caption> <caption>測定環境</caption>
<tr> <tr>
<th>大項目</th> <th>大項目</th>
<th>小項目</th> <th>小項目</th>
<th>環境</th> <th>環境</th>
</tr> </tr>
<tr> <tr>
<td rowspan="3">ハードウェア</td> <td rowspan="3">ハードウェア</td>
<td>CPU</td> <td>CPU</td>
<td>2 × Xeon 5160 3.00GHz (Dual core)</td> <td>2 × Xeon 5160 3.00GHz (Dual core)</td>
</tr> </tr>
<tr> <tr>
<td>メモリ</td> <td>メモリ</td>
<td>2GB</td> <td>2GB</td>
</tr> </tr>
<tr> <tr>
<td>ストレージ</td> <td>ストレージ</td>
<td>Ultra320 SCSI, 15000rpm (220GB)</td> <td>Ultra320 SCSI, 15000rpm (220GB)</td>
</tr> </tr>
<tr> <tr>
<td rowspan="4">ソフトウェア</td> <td rowspan="4">ソフトウェア</td>
<td>OS</td> <td>OS</td>
<td>RHEL 5.2 (64bit) 2.6.18-92.el5</td> <td>RHEL 5.2 (64bit) 2.6.18-92.el5</td>
</tr> </tr>
<tr> <tr>
<td>DB</td> <td>DB</td>
<td>PostgreSQL 8.3.3</td> <td>PostgreSQL 8.3.3</td>
</tr> </tr>
<tr> <tr>
<td>pg_reorg</td> <td>pg_reorg</td>
<td>1.0.0</td> <td>1.0.0</td>
</tr> </tr>
<tr> <tr>
<td>clusterdb</td> <td>clusterdb</td>
<td>clusterdb (PostgreSQL) 8.3.3</td> <td>clusterdb (PostgreSQL) 8.3.3</td>
</tr> </tr>
<tr> <tr>
<td rowspan="2">データ</td> <td rowspan="2">データ</td>
<td>スキーマ</td> <td>スキーマ</td>
<td><code><pre>CREATE TABLE tbl ( <td><code><pre>CREATE TABLE tbl (
id bigserial PRIMARY KEY, id bigserial PRIMARY KEY,
seqkey timestamp NOT NULL, seqkey timestamp NOT NULL,
rndkey timestamp NOT NULL, rndkey timestamp NOT NULL,
filler char(75) NOT NULL filler char(75) NOT NULL
); );
CREATE INDEX idx_seq ON tbl (seqkey); CREATE INDEX idx_seq ON tbl (seqkey);
CREATE INDEX idx_rnd ON tbl (rndkey);</pre></code></td> CREATE INDEX idx_rnd ON tbl (rndkey);</pre></code></td>
</tr> </tr>
<tr> <tr>
<td>件数</td> <td>件数</td>
<td>1650万件 (約2GB)</td> <td>1650万件 (約2GB)</td>
</tr> </tr>
</table> </table>
</center> </center>
</div>
<hr />
<div align="right"> <hr />
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION <p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
</div>
<script type="text/javascript">
<!-- PLEASE LEAVE "Powered By GForge" on your site --> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
<br /> document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
<center> </script>
<a href="http://gforge.org/"><img src="http://gforge.org/images/pow-gforge.png" <script type="text/javascript">
alt="Powered By GForge Collaborative Development Environment" border="0" /></a> try {
</center> var pageTracker = _gat._getTracker("UA-10244036-4");
pageTracker._trackPageview();
</body> } catch(err) {}</script>
</html> </body>
</html>

View File

@ -1,123 +1,123 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<link rel="icon" type="image/png" href="http://pgfoundry.org/images/elephant-icon.png" /> <link rel="icon" type="image/png" href="http://pgfoundry.org/images/elephant-icon.png" />
<link rel="stylesheet" type="text/css" href="style.css" /> <link rel="stylesheet" type="text/css" href="style.css" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>pg_reorg: Project Home Page</title> <title>pg_reorg: Project Home Page</title>
</head> </head>
<body> <body>
<center><img style="border: none; margin-left: auto; margin-right: auto; " src="http://pgfoundry.org/images/elephantSmall.png" height="75" width="75" /> <center><img style="border: none; margin-left: auto; margin-right: auto; " src="http://pgfoundry.org/images/elephantSmall.png" height="75" width="75" />
<hr /> <hr />
<h1>Welcome to the pg_reorg Project Home Page</h1> <h1>Welcome to the pg_reorg Project Home Page</h1>
<hr /> <hr />
</center> </center>
<p> <p>
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. 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 module is developed to be a better alternative of CLUSTER and VACUUM FULL.
</p> </p>
<p> <p>
The pg_reorg project is a <a href="http://www.postgresql.org">PostgreSQL</a> Community project that is a part of the <a href="http://pgfoundry.org">pgFoundry</a>. The pg_reorg project is a <a href="http://www.postgresql.org">PostgreSQL</a> Community project that is a part of the <a href="http://pgfoundry.org">pgFoundry</a>.
</p> </p>
<p> <p>
The pgFoundry page for the project is at <a href="http://pgfoundry.org/projects/reorg">http://pgfoundry.org/projects/reorg</a>, The pgFoundry page for the project is at <a href="http://pgfoundry.org/projects/reorg">http://pgfoundry.org/projects/reorg</a>,
where you can find <a href="http://pgfoundry.org/frs/?group_id=1000411">downloads</a>, documentation, bug reports, mailing lists, and a whole lot more. where you can find <a href="http://pgfoundry.org/frs/?group_id=1000411">downloads</a>, documentation, bug reports, mailing lists, and a whole lot more.
</p> </p>
<div> <div>
<a href="index-ja.html">日本語のページはこちら。</a> <a href="index-ja.html">日本語のページはこちら。</a>
</div> </div>
<hr /> <hr />
<h2>Documentation</h2> <h2>Documentation</h2>
<p> <p>
<a href="pg_reorg.html">Documentations here</a>. <a href="pg_reorg.html">Documentations here</a>.
</p> </p>
<h2>Execution time</h2> <h2>Execution time</h2>
<p> <p>
Here is a comparison between pg_reorg and clusterdb. 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. 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. Since reorganization is needed only if tables are fragmented, pg_reorg should be faster than clusterdb.
</p> </p>
<center> <center>
<div style="margin: 2em"> <div style="margin: 2em">
<img src="result.png" /> <img src="result.png" />
</div> </div>
<table border="1"> <table border="1">
<caption>Configuration</caption> <caption>Configuration</caption>
<tr> <tr>
<th>Category</th> <th>Category</th>
<th>Item</th> <th>Item</th>
<th>Details</th> <th>Details</th>
</tr> </tr>
<tr> <tr>
<td rowspan="3">Hardware</td> <td rowspan="3">Hardware</td>
<td>CPU</td> <td>CPU</td>
<td>2 * Xeon 5160 3.00GHz (Dual core)</td> <td>2 * Xeon 5160 3.00GHz (Dual core)</td>
</tr> </tr>
<tr> <tr>
<td>Memory</td> <td>Memory</td>
<td>2GB</td> <td>2GB</td>
</tr> </tr>
<tr> <tr>
<td>Storage</td> <td>Storage</td>
<td>Ultra320 SCSI, 15000rpm (220GB)</td> <td>Ultra320 SCSI, 15000rpm (220GB)</td>
</tr> </tr>
<tr> <tr>
<td rowspan="4">Software</td> <td rowspan="4">Software</td>
<td>OS</td> <td>OS</td>
<td>RHEL 5.2 (64bit) 2.6.18-92.el5</td> <td>RHEL 5.2 (64bit) 2.6.18-92.el5</td>
</tr> </tr>
<tr> <tr>
<td>DB</td> <td>DB</td>
<td>PostgreSQL 8.3.3</td> <td>PostgreSQL 8.3.3</td>
</tr> </tr>
<tr> <tr>
<td>pg_reorg</td> <td>pg_reorg</td>
<td>1.0.0</td> <td>1.0.0</td>
</tr> </tr>
<tr> <tr>
<td>clusterdb</td> <td>clusterdb</td>
<td>clusterdb (PostgreSQL) 8.3.3</td> <td>clusterdb (PostgreSQL) 8.3.3</td>
</tr> </tr>
<tr> <tr>
<td rowspan="2">Data</td> <td rowspan="2">Data</td>
<td>Scheme</td> <td>Scheme</td>
<td><code><pre>CREATE TABLE tbl ( <td><code><pre>CREATE TABLE tbl (
id bigserial PRIMARY KEY, id bigserial PRIMARY KEY,
seqkey timestamp NOT NULL, seqkey timestamp NOT NULL,
rndkey timestamp NOT NULL, rndkey timestamp NOT NULL,
filler char(75) NOT NULL filler char(75) NOT NULL
); );
CREATE INDEX idx_seq ON tbl (seqkey); CREATE INDEX idx_seq ON tbl (seqkey);
CREATE INDEX idx_rnd ON tbl (rndkey);</pre></code></td> CREATE INDEX idx_rnd ON tbl (rndkey);</pre></code></td>
</tr> </tr>
<tr> <tr>
<td>Rows</td> <td>Rows</td>
<td>16.5 M rows (2GB)</td> <td>16.5 M rows (2GB)</td>
</tr> </tr>
</table> </table>
</center> </center>
<hr /> <hr />
<div align="right"> <p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
</div> <script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
<!-- PLEASE LEAVE "Powered By GForge" on your site --> document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
<br /> </script>
<center> <script type="text/javascript">
<a href="http://gforge.org/"><img src="http://gforge.org/images/pow-gforge.png" try {
alt="Powered By GForge Collaborative Development Environment" border="0" /></a> var pageTracker = _gat._getTracker("UA-10244036-4");
</center> pageTracker._trackPageview();
} catch(err) {}</script>
</body> </body>
</html> </html>

View File

@ -1,293 +1,293 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
<head> <head>
<title>pg_reorg</title> <title>pg_reorg</title>
<link rel="home" title="pg_reorg " href="index.html"> <link rel="home" title="pg_reorg " href="index.html">
<link rel="stylesheet" TYPE="text/css"href="style.css"> <link rel="stylesheet" TYPE="text/css"href="style.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head> </head>
<body> <body>
<h1><a name="pg_reorg"></a>pg_reorg</h1> <h1 id="pg_reorg">pg_reorg</h1>
<div><a name="name"></a> <div class="index">
<h2>名前</h2> <ol>
pg_reorg -- PostgreSQLデータベース内のテーブルに対して、参照/更新処理をブロックせずに再編成を行います。 <li><a href="#name">名前</a></li>
</div> <li><a href="#synopsis">概要</a></li>
<li><a href="#description">説明</a></li>
<div> <li><a href="#examples">使用例</a></li>
<a name="synopsis"></a> <li><a href="#options">オプション</a></li>
<h2>概要</h2> <li><a href="#environment">環境変数</a></li>
<p> <li><a href="#restrictions">使用上の注意と制約</a></li>
<tt>pg_reorg</tt> [<tt><i>connection-options</i></tt>...] [<tt><i>message-options</i></tt>...] [<tt><i>order-options</i></tt>...] [<tt><i>target-options</i></tt>...] <li><a href="#details">詳細</a></li>
</p> <li><a href="#install">インストール方法</a></li>
<p>指定できるオプションには4つのカテゴリがあります。 <li><a href="#requirement">動作環境</a></li>
詳細は<a href="#options">オプション</a>を参照してください。</p> <li><a href="#seealso">関連項目</a></li>
<dl> </ol>
<dt><tt>connection-options</tt> : 接続パラメータ</dt> </div>
<dd><tt>-h</tt> [<tt>--host</tt>] <tt><i>host</i></tt></dd>
<dd><tt>-p</tt> [<tt>--port</tt>] <tt><i>port</i></tt></dd> <h2 id="name">名前</h2>
<dd><tt>-U</tt> [<tt>--username</tt>] <tt><i>username</i></tt></dd> pg_reorg -- PostgreSQLデータベース内のテーブルに対して、参照/更新処理をブロックせずに再編成を行います。
<dd><tt>-W</tt> [<tt>--password</tt>]</dd>
<dt><tt>message-options</tt> : 出力メッセージ</dt> <h2 id="synopsis">概要</h2>
<dd><tt>-q</tt> [<tt>--quiet</tt>]</dd> <p>
<dd><tt>-v</tt> [<tt>--verbose</tt>]</dd> pg_reorg [connection-options...] [message-options...] [order-options...] [target-options...]
<dt><tt>order-options</tt> : 並び替えの基準</dt> </p>
<dd><tt>-o</tt> [<tt>--order-by</tt>] <tt><i>columns [,...]</i></tt></dd> <p>指定できるオプションには4つのカテゴリがあります。
<dd><tt>-n</tt> [<tt>--no-order</tt>]</dd> 詳細は<a href="#options">オプション</a>を参照してください。</p>
<dt><tt>target-options</tt> : 処理対象</dt> <dl>
<dd><tt>-a</tt> [<tt>--all</tt>]</dd> <dt>connection-options : 接続パラメータ</dt>
<dd><tt>-d</tt> [<tt>--dbname</tt>] <tt><i>dbname</i></tt></dd> <dd>-h [--host] host</dd>
<dd><tt>-t</tt> [<tt>--table</tt>] <tt><i>table</i></tt></dd> <dd>-p [--port] port</dd>
<dd><tt>-Z</tt> [<tt>--no-analyze</tt>]</dd> <dd>-U [--username] username</dd>
</dl> <dd>-W [--password]</dd>
</div> <dt>message-options : 出力メッセージ</dt>
<dd>-q [--quiet]</dd>
<div><a name="description"></a> <dd>-v [--verbose]</dd>
<h2>説明</h2> <dt>order-options : 並び替えの基準</dt>
<p>pg_reorg は、PostgreSQLデータベース内のテーブルを再編成(行の並び替え)するユーティリティです。 <dd>-o [--order-by] columns [,...]</dd>
<a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html"><tt>clusterdb</tt></a> と異なり、参照/更新処理をブロックしません。 <dd>-n [--no-order]</dd>
再編成の方式として、以下のいずれか1つを選択できます。</p> <dt>target-options : 処理対象</dt>
<ul> <dd>-a [--all]</dd>
<li>オンライン CLUSTER (cluster index順に行を並び替える)</li> <dd>-d [--dbname] dbname</dd>
<li>ユーザの指定した順に行を並び替える</li> <dd>-t [--table] table</dd>
<li>オンライン VACUUM FULL (行の詰め合わせを行う)</li> <dd>-Z [--no-analyze]</dd>
</ul> </dl>
<p>このユーティリティを使用するためには、以下のことに注意をしてください。</p>
<ul> <h2 id="description">説明</h2>
<li>このユーティリティは、スーパーユーザのみが実行することができます。</li> <p>pg_reorg は、PostgreSQLデータベース内のテーブルを再編成(行の並び替え)するユーティリティです。
<li>対象のテーブルはPRIMARY KEYを持っている必要があります。</li> <a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html">clusterdb</a> と異なり、参照/更新処理をブロックしません。
</ul> 再編成の方式として、以下のいずれか1つを選択できます。</p>
</div> <ul>
<li>オンライン CLUSTER (cluster index順に行を並び替える)</li>
<div><a name="examples"></a> <li>ユーザの指定した順に行を並び替える</li>
<h2></h2> <li>オンライン VACUUM FULL (行の詰め合わせを行う)</li>
<p><tt>test</tt>というデータベースをオンライン CLUSTER するには、下記のコマンドを実行します。</p> </ul>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE> <p>このユーティリティを使用するためには、以下のことに注意をしてください。</p>
<p><tt>test</tt>という名前のデータベースの<tt>foo</tt>という1つのテーブルに対してオンライン VACUUM FULL を行うには、下記のコマンドを実行します。</p> <ul>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p> <li>このユーティリティは、スーパーユーザのみが実行することができます。</li>
</p> <li>対象のテーブルはPRIMARY KEYを持っている必要があります。</li>
</div> </ul>
<div><a name="options"></a> <h2 id="examples"></h2>
<h2>オプション</h2> <p>testというデータベースをオンライン CLUSTER するには、下記のコマンドを実行します。</p>
<p>pg_reorg では、下記の4種類のコマンドライン引数を指定できます。</p> <PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE>
<div> <p>testという名前のデータベースのfooという1つのテーブルに対してオンライン VACUUM FULL を行うには、下記のコマンドを実行します。</p>
<dl> <PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p>
</p>
<h3>connection-options</h3>
<p>PostgreSQLに接続するためのパラメータです。</p> <h2 id="options">オプション</h2>
<p>pg_reorg では、下記の4種類のコマンドライン引数を指定できます。</p>
<div> <dl>
<dl>
<dt><tt>-h <tt><i>host</i></tt><br /> <h3>connection-options</h3>
<tt>--host <tt><i>host</i></tt></dt> <p>PostgreSQLに接続するためのパラメータです。</p>
<dd>サーバが稼働しているマシンのホスト名を指定します。ホスト名がスラッシュから始まる場合、Unixドメインソケット用のディレクトリとして使用されます。</dd>
<dl>
<dt><tt>-p <tt><i>port</i></tt><br /> <dt>-h host<br />
<tt>--port <tt><i>port</i></tt></dt> --host host</dt>
<dd>サーバが接続を監視するTCPポートもしくはUnixドメインソケットファイルの拡張子を指定します。</dd> <dd>サーバが稼働しているマシンのホスト名を指定します。ホスト名がスラッシュから始まる場合、Unixドメインソケット用のディレクトリとして使用されます。</dd>
<dt><tt>-U <tt><i>username</i></tt><br /> <dt>-p port<br />
<tt>--username <tt><i>username</i></tt></dt> --port port</dt>
<dd>接続するユーザ名を指定します。</dd> <dd>サーバが接続を監視するTCPポートもしくはUnixドメインソケットファイルの拡張子を指定します。</dd>
<dt><tt>-W</tt><br /><tt>--password</tt></dt> <dt>-U username<br />
<dd>データベースに接続する前に、pg_reorg は強制的にパスワード入力を促します。</dd> --username username</dt>
<dd>サーバがパスワード認証を要求する場合 pg_reorg は自動的にパスワード入力を促しますので、これが重要になることはありません。 <dd>接続するユーザ名を指定します。</dd>
しかし、pg_reorg は、サーバにパスワードが必要かどうかを判断するための接続試行を無駄に行います。
こうした余計な接続試行を防ぐために<tt>-W</tt>の入力が有意となる場合もあります。</dd> <dt>-W<br />--password</dt>
</dl> <dd>データベースに接続する前に、pg_reorg は強制的にパスワード入力を促します。</dd>
</div> <dd>サーバがパスワード認証を要求する場合 pg_reorg は自動的にパスワード入力を促しますので、これが重要になることはありません。
しかし、pg_reorg は、サーバにパスワードが必要かどうかを判断するための接続試行を無駄に行います。
<h3>message-options</h3> こうした余計な接続試行を防ぐために-Wの入力が有意となる場合もあります。</dd>
<p> </dl>
pg_reorg を実行した際に任意のメッセージを出力するためのパラメータです。
<tt>--quiet</tt>と他の2つのオプションを同時に指定した場合は、<tt>--quiet</tt>のオプションは無視されます。 <h3>message-options</h3>
</p> <p>
pg_reorg を実行した際に任意のメッセージを出力するためのパラメータです。
<dl> --quietと他の2つのオプションを同時に指定した場合は、--quietのオプションは無視されます。
<dt><tt>-q</tt><br /><tt>--quiet</tt></dt> </p>
<dd>進行メッセージを表示しません。</dd>
<dt><tt>-v</tt><br /><tt>--verbose</tt></dt> <dl>
<dd>処理中に詳細な情報を表示します。</dd> <dt>-q<br />--quiet</dt>
</dl> <dd>進行メッセージを表示しません。</dd>
<dt>-v<br />--verbose</dt>
<h3>order-options</h3> <dd>処理中に詳細な情報を表示します。</dd>
<p>pg_reorg を実行する際の並び替えの基準を指定するパラメータです。 </dl>
何も指定されていない場合は、cluster index順にオンライン CLUSTER を行います。
この2つを同時に指定することはできません。 <h3>order-options</h3>
</p> <p>pg_reorg を実行する際の並び替えの基準を指定するパラメータです。
何も指定されていない場合は、cluster index順にオンライン CLUSTER を行います。
<dl> この2つを同時に指定することはできません。
<dt><tt>-n</tt><br /><tt>--no-order</tt></dt> </p>
<dd>オンライン VACUUM FULL の処理を行います。</dd>
<dl>
<dt><tt>-o</tt> <tt><i>columns [,...]</i></tt><br /> <dt>-n<br />--no-order</dt>
<tt>--order-by</tt> <tt><i>columns [,...]</i></tt></dt> <dd>オンライン VACUUM FULL の処理を行います。</dd>
<dd>指定したカラムをキーにオンライン CLUSTER を行います。</dd>
</dl> <dt>-o columns [,...]<br />
--order-by columns [,...]</dt>
<h3>target-options</h3> <dd>指定したカラムをキーにオンライン CLUSTER を行います。</dd>
<p> </dl>
pg_reorg を実行する対象を指定するパラメータです。
<tt>--all</tt><tt>--dbname</tt>または<tt>--table</tt>を同時に指定することはできません。 <h3>target-options</h3>
</p> <p>
pg_reorg を実行する対象を指定するパラメータです。
<dl> --allと--dbnameまたは--tableを同時に指定することはできません。
<dt><tt>-a</tt><br /><tt>--all</tt></dt> </p>
<dd>対象となる全てのデータベースに対してオンライン CLUSTER、または、オンラインVACUUM FULLを行います。</dd>
<dl>
<dt> <dt>-a<br />--all</dt>
<tt>-d <tt><i>dbname</i></tt><br /> <dd>対象となる全てのデータベースに対してオンライン CLUSTER、または、オンラインVACUUM FULLを行います。</dd>
<tt>--dbname <tt><i>dbname</i></tt>
</dt> <dt>
<dd>オンライン CLUSTER、または、オンライン VACUUM FULL を行うデータベース名を指定します。 -d dbname<br />
データベース名が指定されておらず、<tt>-a</tt>(または<tt>--all</tt>)も指定されていない場合、 --dbname dbname
データベース名は<tt>PGDATABASE</tt>環境変数から読み取られます。この変数も設定されていない場合は、接続時に指定したユーザ名が使用されます。 </dt>
</dd> <dd>オンライン CLUSTER、または、オンライン VACUUM FULL を行うデータベース名を指定します。
データベース名が指定されておらず、-aまたは--allも指定されていない場合、
<dt> データベース名はPGDATABASE環境変数から読み取られます。この変数も設定されていない場合は、接続時に指定したユーザ名が使用されます。
<tt>-t</tt> <tt><i>table</i></tt><br /> </dd>
<tt>--table</tt> <tt><i>table</i></tt>
</dt> <dt>
<dd>オンライン CLUSTER 、または、オンライン VACUUM FULL を行うテーブルを指定します。 -t table<br />
このオプションが指定されていない場合は、対象となったデータベースに存在する全ての対象テーブルに対して処理を行います。 --table table
</dd> </dt>
<dd>オンライン CLUSTER 、または、オンライン VACUUM FULL を行うテーブルを指定します。
<dt><tt>-Z</tt><br /><tt>--no-analyze</tt></dt> このオプションが指定されていない場合は、対象となったデータベースに存在する全ての対象テーブルに対して処理を行います。
<dd>再編成後に ANALYZE を行いません。 </dd>
このオプションが指定されていない場合は、再編成後に ANALYZE します。</dd>
<dt>-Z<br />--no-analyze</dt>
</dl> <dd>再編成後に ANALYZE を行いません。
</div> このオプションが指定されていない場合は、再編成後に ANALYZE します。</dd>
<div><a name="environment"></a> </dl>
<h2>環境変数</h2> <div>
<dl> <h2 id="environment">環境変数</h2>
<dt> <dl>
<tt>PGDATABASE</tt><br /> <dt>
<tt>PGHOST</tt><br /> PGDATABASE<br />
<tt>PGPORT</tt><br /> PGHOST<br />
<tt>PGUSER</tt> PGPORT<br />
</dt> PGUSER
<dd>デフォルトの接続パラメータです。</dd> </dt>
</dl> <dd>デフォルトの接続パラメータです。</dd>
</div> </dl>
<p>また、このユーティリティは、他のほとんどの PostgreSQL ユーティリティと同様、
libpq でサポートされる環境変数を使用します。詳細については、<a href="http://www.postgresql.jp/document/current/html/libpq-envars.html">環境変数の項目</a>を参照してください。 <p>
</p> また、このユーティリティは、他のほとんどの PostgreSQL ユーティリティと同様、libpq でサポートされる環境変数を使用します。詳細については、<a href="http://www.postgresql.jp/document/current/html/libpq-envars.html">環境変数の項目</a>を参照してください。
</div> </p>
<div><a name="diagnostics"></a> <h2 id="diagnostics">トラブルシューティング</h2>
<h2>トラブルシューティング</h2> <p>pg_reorg の実行に失敗した場合にエラーが表示されます。
<p>pg_reorg の実行に失敗した場合にエラーが表示されます。 想像されるエラー原因と対処を示します。</p>
想像されるエラー原因と対処を示します。</p> <p>致命的なエラーで終了した場合、手動によるクリーンアップを行う必要があります。
<p>致命的なエラーで終了した場合、手動によるクリーンアップを行う必要があります。 クリーンアップは、エラーが発生したデータベースに対して、$PGHOME/share/contrib/uninstall_pg_reorg.sql を実行し、その後、$PGHOME/share/contrib/pg_reorg.sql を実行します。</p>
クリーンアップは、エラーが発生したデータベースに対して、$PGHOME/share/contrib/uninstall_pg_reorg.sql を実行し、その後、$PGHOME/share/contrib/pg_reorg.sql を実行します。</p>
<dl>
<dl> <dt>pg_reorg : reorg database "template1" ... skipped</dt>
<dt>pg_reorg : reorg database "template1" ... skipped</dt> <dd>--allオプションを指定した際に、pg_reorg がインストールされていないデータベースに対して表示されます。</dd>
<dd><tt>--all</tt>オプションを指定した際に、pg_reorg がインストールされていないデータベースに対して表示されます</dd> <dd>pg_reorg スキーマのインストールを行ってください</dd>
<dd>pg_reorg スキーマのインストールを行ってください。</dd>
<dt>ERROR: pg_reorg is not installed</dt>
<dt>ERROR: pg_reorg is not installed</dt> <dd>--dbnameで指定したデータベースにpg_reorg がインストールされていません。</dd>
<dd><tt>--dbname</tt>で指定したデータベースにpg_reorg がインストールされていません</dd> <dd>pg_reorg のインストールを行ってください</dd>
<dd>pg_reorg のインストールを行ってください。</dd>
<dt>ERROR: relation "table" has no primary key</dt>
<dt>ERROR: relation "table" has no primary key</dt> <dd>指定したテーブルにPRIMARY KEYが存在していません。</dd>
<dd>指定したテーブルにPRIMARY KEYが存在していません。</dd> <dd>対象のテーブルにPRIMARY KEYの作成を行ってください。(ALTER TABLE ADD PRIMARY KEY)</dd>
<dd>対象のテーブルにPRIMARY KEYの作成を行ってください。(ALTER TABLE ADD PRIMARY KEY)</dd>
<dt>ERROR: relation "table" has no cluster key</dt>
<dt>ERROR: relation "table" has no cluster key</dt> <dd>指定したテーブルに CLUSTER KEYが存在していません。</dd>
<dd>指定したテーブルに CLUSTER KEYが存在していません。</dd> <dd>対象のテーブルに CLUSTER KEYの作成を行ってください。(ALTER TABLE CLUSTER)</dd>
<dd>対象のテーブルに CLUSTER KEYの作成を行ってください。(ALTER TABLE CLUSTER)</dd>
<dt>pg_reorg : query failed: ERROR: column "col" does not exist</dt>
<dt>pg_reorg : query failed: ERROR: column "col" does not exist</dt> <dd>--order-by で指定したカラムが対象のテーブルに存在していません。</dd>
<dd><tt>--order-by</tt> で指定したカラムが対象のテーブルに存在していません</dd> <dd>対象のテーブルに存在するカラムを指定してください。</dd>
<dd>対象のテーブルに存在するカラムを指定してください。</dd>
<dt>ERROR: permission denied for schema reorg</dt>
<dt>ERROR: permission denied for schema reorg</dt> <dd>操作を行おうとした対象に権限がありません。</dd>
<dd>操作を行おうとした対象に権限がありません</dd> <dd>スーパーユーザで操作を行ってください</dd>
<dd>スーパーユーザで操作を行ってください。</dd>
<dt>pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists</dt>
<dt>pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists</dt> <dd>操作を行おうとした対象にpg_reorg が処理のために作成するトリガと同名のものが存在しています。</dd>
<dd>操作を行おうとした対象にpg_reorg が処理のために作成するトリガと同名のものが存在しています</dd> <dd>トリガの改名か削除を行ってください</dd>
<dd>トリガの改名か削除を行ってください。</dd>
<dt>pg_reorg : trigger conflicted for tbl</dt>
<dt>pg_reorg : trigger conflicted for tbl</dt> <dd>操作を行おうとした対象にpg_reorg が処理のために作成するトリガより後に実行されるトリガが存在しています。</dd>
<dd>操作を行おうとした対象にpg_reorg が処理のために作成するトリガより後に実行されるトリガが存在しています</dd> <dd>トリガの改名か削除を行ってください</dd>
<dd>トリガの改名か削除を行ってください。</dd> </dl>
</dl>
</div> <h2 id="restrictions">使用上の注意と制約</h2>
<p>pg_reorg を使用する際には、以下の制約があります。以下の制約に関する操作を行った場合の動作は保証されません。注意してください。</p>
<div><a name="restrictions"></a>
<h2>制約</h2> <h3>一時テーブルへの操作</h3>
<p>pg_reorg を使用する際には、以下の制約があります。以下の制約に関する操作を行った場合の動作は保証されません。注意してください</p> <p>pg_reorg では、一時テーブルは操作の対象外です</p>
<h3>一時テーブルへの操作</h3> <h3>GiSTインデックスの使用</h3>
<p>pg_reorg では、一時テーブルは操作の対象外です。</p> <p>インデックス種別がGiSTとなっているインデックスがクラスタインデックスとなっている
テーブルはpg_reorg コマンドを使用して操作を行うことはできません。
<h3>GiSTインデックスの使用</h3> これは、GiSTインデックスのソート順序は一意ではないため、ORDER BYによる
<p>インデックス種別がGiSTとなっているインデックスがクラスタインデックスとなっている ソートが行えないためです。</p>
テーブルはpg_reorg コマンドを使用して操作を行うことはできません。
これは、GiSTインデックスのソート順序は一意ではないため、<tt>ORDER BY</tt>による <h3>DDLコマンドの発行</h3>
ソートが行えないためです。</p> <p>
pg_reorg の実行中には、VACUUM と ANALYZE <STRONG>以外</STRONG> のDDL操作は行わないでください。
<h3>DDLコマンドの発行</h3> 多くの場合、pg_reorg は失敗しロールバックされます。
<p> しかし、以下の操作ではデータが破損するため、非常に危険です。
pg_reorg の実行中には、<tt>VACUUM</tt><tt>ANALYZE</tt> <STRONG>以外</STRONG> のDDL操作は行わないでください。 </p>
多くの場合、pg_reorg は失敗しロールバックされます。
しかし、以下の操作ではデータが破損するため、非常に危険です。 <dl>
</p> <dt>TRUNCATE</dt>
<dd>削除した行が pg_reorg 実行後には復元しています。操作結果が消失します。</dd>
<dl>
<dt><tt>TRUNCATE</tt></dt> <dt>CREATE INDEX</dt>
<dd>削除した行が pg_reorg 実行後には復元しています。操作結果が消失します。</dd> <dd>スワップされない索引が残る可能性があります。データの不整合が生じます。</dd>
<dt><tt>CREATE INDEX</tt></dt> <dt>ALTER TABLE ... ADD COLUMN</dt>
<dd>スワップされない索引が残る可能性があります。データの不整合が生じます。</dd> <dd>追加された値が全てNULLに置換されてしまう可能性があります。データが消失します。</dd>
<dt><tt>ALTER TABLE ... ADD COLUMN</tt></dt> <dt>ALTER TABLE ... ALTER COLUMN TYPE</dt>
<dd>追加された値が全てNULLに置換されてしまう可能性があります。データが消失します。</dd> <dd>実行するとスキーマで定義された型と実際の格納状態に齟齬をきたします。データの不整合が生じます。</dd>
<dt><tt>ALTER TABLE ... ALTER COLUMN TYPE</tt></dt> <dt>ALTER TABLE ... SET TABLESPACE</dt>
<dd>実行するとスキーマで定義された型と実際の格納状態に齟齬をきたします。データの不整合が生じます。</dd> <dd>pg_reorg 実行後にrelfilenodeとの不整合が起こるため、対象のテーブルに対する参照/更新操作時にエラーが発生します。</dd>
</dl>
<dt><tt>ALTER TABLE ... SET TABLESPACE</tt></dt>
<dd>pg_reorg 実行後にrelfilenodeとの不整合が起こるため、対象のテーブルに対する参照/更新操作時にエラーが発生します。</dd> <h2 id="details">詳細</h2>
</dl> <p>pg_reorg は reorg スキーマに作業用テーブルを作成し、そこでデータの並び替えを行います。
</div> 最後にシステムカタログを直接書き換えることで、元のテーブルと名前を交換しています。</p>
<div><a name="install"></a> <h2 id="install">インストール方法</h2>
<h2>インストール方法</h2> <p>pg_reorg のインストールは、標準のcontribモジュールと同様です。</p>
<p>pg_reorg のインストールは、標準のcontribモジュールと同様です。</p> <h3>ビルド</h3>
<h3>ビルド</h3> <p>pg_reorg のフォルダを$PGHOME/contrib/に配置し、make, make installを行ってください。</p>
<p>pg_reorg のフォルダを$PGHOME/contrib/に配置し、make, make installを行ってください。</p> <h3>データベースへの登録</h3>
<h3>データベースへの登録</h3> <p>PostgreSQLを起動し、対象のデータベースに対して $PGHOME/share/contrib にある pg_reorg.sql を実行し、インストールを行ってください。</p>
<p>PostgreSQLを起動し、対象のデータベースに対して $PGHOME/share/contrib にある pg_reorg.sql を実行し、インストールを行ってください。</p>
</div> <h2 id="requirement">動作環境</h2>
<dl>
<div><a name="requirement"></a> <dt>PostgreSQLバージョン</dt><dd>PostgreSQL 8.3</dd>
<h2>動作環境</h2> <dt>OS</dt><dd>RHEL 5.2, Windows XP SP3</dd>
<dl> <dt>ディスク容量</dt><dd>処理対象のテーブル、インデックスサイズの2倍以上のディスク空き容量</dd>
<dt>PostgreSQLバージョン</dt><dd>PostgreSQL 8.3</dd> </dl>
<dt>OS</dt><dd>RHEL 5.2, Windows XP SP3</dd>
<dt>ディスク容量</dt><dd>処理対象のテーブル、インデックスサイズの2倍以上のディスク空き容量</dd> <h2 id="seealso">関連項目</h2>
</dl> <a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html">clusterdb</a>,
</div> <a href="http://www.postgresql.jp/document/current/html/app-vacuumdb.html">vacuumdb</a>
<div><a name="seealso"></a> <hr />
<h2>関連項目</h2> <p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
<a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html"><i><tt>clusterdb</tt></i></a>,
<a href="http://www.postgresql.jp/document/current/html/app-vacuumdb.html"><i><tt>vacuumdb</tt></i></a> <script type="text/javascript">
</div> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
<hr> </script>
<script type="text/javascript">
<p align="right"><font size="2"> try {
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION var pageTracker = _gat._getTracker("UA-10244036-4");
</font></p> pageTracker._trackPageview();
} catch(err) {}</script>
</body> </body>
</html> </html>

View File

@ -1,276 +1,278 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD html 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html> <html>
<head> <head>
<title>pg_reorg</title> <title>pg_reorg</title>
<link rel="home" title="pg_reorg " href="index.html"> <link rel="home" title="pg_reorg " href="index.html">
<link rel="stylesheet" TYPE="text/css"href="style.css"> <link rel="stylesheet" TYPE="text/css"href="style.css">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head> </head>
<body> <body>
<h1><a name="pg_reorg"></a>pg_reorg</h1> <h1 id="pg_reorg">pg_reorg</h1>
<div><a name="name"></a> <div class="index">
<h2>Name</h2> <ol>
pg_reorg -- Reorganize tables in PostgreSQL databases without any locks. <li><a href="#name">Name</a></li>
</div> <li><a href="#synopsis">Synopsis</a></li>
<li><a href="#description">Description</a></li>
<div><a name="synopsis"></a> <li><a href="#examples">Examples</a></li>
<h2>Synopsis</h2> <li><a href="#options">Options</a></li>
<p> <li><a href="#environment">Environment</a></li>
<tt>pg_reorg</tt> [<tt><i>connection-options</i></tt>...] [<tt><i>message-options</i></tt>...] [<tt><i>order-options</i></tt>...] [<tt><i>target-options</i></tt>...] <li><a href="#restrictions">Restrictions</a></li>
</p> <li><a href="#details">Details</a></li>
<p>There 4 option categories. <li><a href="#install">Installations</a></li>
See also <a href="#options">options</a> for details.</p> <li><a href="#requirement">Requirements</a></li>
<dl> <li><a href="#seealso">See Also</a></li>
<dt><tt>connection-options</tt></dt> </ol>
<dd><tt>-h</tt> [<tt>--host</tt>] <tt><i>host</i></tt></dd> </div>
<dd><tt>-p</tt> [<tt>--port</tt>] <tt><i>port</i></tt></dd>
<dd><tt>-U</tt> [<tt>--username</tt>] <tt><i>username</i></tt></dd> <h2 id="name">Name</h2>
<dd><tt>-W</tt> [<tt>--password</tt>]</dd> pg_reorg -- Reorganize tables in PostgreSQL databases without any locks.
<dt><tt>message-options</tt></dt>
<dd><tt>-q</tt> [<tt>--quiet</tt>]</dd> <h2 id="synopsis">Synopsis</h2>
<dd><tt>-v</tt> [<tt>--verbose</tt>]</dd> <p>
<dt><tt>order-options</tt></dt> pg_reorg [connection-options...] [message-options...] [order-options...] [target-options...]
<dd><tt>-o</tt> [<tt>--order-by</tt>] <tt><i>columns [,...]</i></tt></dd> </p>
<dd><tt>-n</tt> [<tt>--no-order</tt>]</dd> <p>There 4 option categories.
<dt><tt>target-options</tt></dt> See also <a href="#options">options</a> for details.</p>
<dd><tt>-a</tt> [<tt>--all</tt>]</dd> <dl>
<dd><tt>-d</tt> [<tt>--dbname</tt>] <tt><i>dbname</i></tt></dd> <dt>connection-options</dt>
<dd><tt>-t</tt> [<tt>--table</tt>] <tt><i>table</i></tt></dd> <dd>-h [--host] host</dd>
<dd><tt>-Z</tt> [<tt>--no-analyze</tt>]</dd> <dd>-p [--port] port</dd>
</dl> <dd>-U [--username] username</dd>
</div> <dd>-W [--password]</dd>
<dt>message-options</dt>
<div> <dd>-q [--quiet]</dd>
<a name="description"></a> <dd>-v [--verbose]</dd>
<h2>Description</h2> <dt>order-options</dt>
<p>pg_reorg is an utility program to reorganize tables in PostgreSQL databases. <dd>-o [--order-by] columns [,...]</dd>
Unlike <a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html"><tt>clusterdb</tt></a>, it doesn't block any selections and updates during reorganization. <dd>-n [--no-order]</dd>
You can choose one of the following methods to reorganize.</p> <dt>target-options</dt>
<ul> <dd>-a [--all]</dd>
<li>Online CLUSTER (ordered by cluster index)</li> <dd>-d [--dbname] dbname</dd>
<li>Ordered by specified columns</li> <dd>-t [--table] table</dd>
<li>Online VACUUM FULL (packing rows only)</li> <dd>-Z [--no-analyze]</dd>
</ul> </dl>
<p>NOTICE:</p>
<ul> <h2 id="description">Description</h2>
<li>Only superusers can use the utility.</li> <p>pg_reorg is an utility program to reorganize tables in PostgreSQL databases.
<li>Target table must have PRIMARY KEY.</li> Unlike <a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html">clusterdb</a>, it doesn't block any selections and updates during reorganization.
</ul> You can choose one of the following methods to reorganize.</p>
</div> <ul>
<li>Online CLUSTER (ordered by cluster index)</li>
<div><a name="examples"></a> <li>Ordered by specified columns</li>
<h2>Examples</h2> <li>Online VACUUM FULL (packing rows only)</li>
<p>Execute the following command to do online CLUSTER to all tables in <tt>test</tt> database.</p> </ul>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE> <p>NOTICE:</p>
<p>Execute the following command to do online VACUUM FULL to <tt>foo</tt> table in <tt>test</tt> database.</p> <ul>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p> <li>Only superusers can use the utility.</li>
</p></div> <li>Target table must have PRIMARY KEY.</li>
</ul>
<div><a name="options"></a>
<h2>Options</h2> <h2 id="examples">Examples</h2>
<p>pg_reorg has command line options in 4 categolies.</p> <p>Execute the following command to do online CLUSTER to all tables in test database.</p>
<div> <PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE>
<dl> <p>Execute the following command to do online VACUUM FULL to foo table in test database.</p>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p>
<h3>connection-options</h3> </p>
<p>Parameters to connect PostgreSQL.</p>
<h2 id="options">Options</h2>
<div> <p>pg_reorg has command line options in 4 categolies.</p>
<dl> <div>
<dt><tt>-h <tt><i>host</i></tt><br /> <dl>
<tt>--host <tt><i>host</i></tt></dt>
<dd>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. </dd> <h3>connection-options</h3>
<p>Parameters to connect PostgreSQL.</p>
<dt><tt>-p <tt><i>port</i></tt><br />
<tt>--port <tt><i>port</i></tt></dt> <div>
<dd>Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections.</dd> <dl>
<dt>-h host<br />
<dt><tt>-U <tt><i>username</i></tt><br /> --host host</dt>
<tt>--username <tt><i>username</i></tt></dt> <dd>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. </dd>
<dd>User name to connect as. </dd>
<dt>-p port<br />
<dt><tt>-W</tt><br /><tt>--password</tt></dt> --port port</dt>
<dd>Force pg_reorg to prompt for a password before connecting to a database.</dd> <dd>Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections.</dd>
<dd>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 <tt>-W</tt> to avoid the extra connection attempt. </dd>
</dl> <dt>-U username<br />
</div> --username username</dt>
<dd>User name to connect as. </dd>
<h3>message-options</h3>
<p>Specifies message output by pg_reorg. <dt>-W<br />--password</dt>
<tt>--quiet</tt> is ignored if some of the other options are specified.</p> <dd>Force pg_reorg to prompt for a password before connecting to a database.</dd>
<dd>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. </dd>
<dl> </dl>
<dt><tt>-q</tt><br /><tt>--quiet</tt></dt>
<dd>Do not display progress messages. </dd> <h3>message-options</h3>
<dt><tt>-v</tt><br /><tt>--verbose</tt></dt> <p>Specifies message output by pg_reorg.
<dd>Print detailed information during processing.</dd> --quiet is ignored if some of the other options are specified.</p>
</dl>
<dl>
<h3>order-options</h3> <dt>-q<br />--quiet</dt>
<p>Options to order rows. <dd>Do not display progress messages. </dd>
If not specified, pg_reorg do online CLUSTER using cluster indexes. <dt>-v<br />--verbose</dt>
Only one option can be specified. <dd>Print detailed information during processing.</dd>
</p> </dl>
<dl> <h3>order-options</h3>
<dt><tt>-n</tt><br /><tt>--no-order</tt></dt> <p>Options to order rows.
<dd>Do online VACUUM FULL.</dd> If not specified, pg_reorg do online CLUSTER using cluster indexes.
Only one option can be specified.
<dt><tt>-o</tt> <tt><i>columns [,...]</i></tt><br /> </p>
<tt>--order-by</tt> <tt><i>columns [,...]</i></tt></dt>
<dd>Do online CLUSTER ordered by specified columns.</dd> <dl>
</dl> <dt>-n<br />--no-order</dt>
<dd>Do online VACUUM FULL.</dd>
<h3>target-options</h3> <dt>-o columns [,...]<br />
<p> --order-by columns [,...]</dt>
Options to specify target tables or databases. <dd>Do online CLUSTER ordered by specified columns.</dd>
You cannot use <tt>--all</tt> and <tt>--dbname</tt> or <tt>--table</tt> together. </dl>
</p>
<dl> <h3>target-options</h3>
<dt><tt>-a</tt><br /><tt>--all</tt></dt> <p>
<dd>Reorganize all databases.</dd> Options to specify target tables or databases.
You cannot use --all and --dbname or --table together.
<dt> </p>
<tt>-d <tt><i>dbname</i></tt><br />
<tt>--dbname <tt><i>dbname</i></tt> <dl>
</dt> <dt>-a<br />--all</dt>
<dd>Specifies the name of the database to be reorganized. If this is not specified and <tt>-a</tt> (or <tt>--all</tt>) is not used, the database name is read from the environment variable <tt>PGDATABASE</tt>. If that is not set, the user name specified for the connection is used. </dd> <dd>Reorganize all databases.</dd>
<dt> <dt>
<tt>-t</tt> <tt><i>table</i></tt><br /> -d dbname<br />
<tt>--table</tt> <tt><i>table</i></tt> --dbname dbname
</dt> </dt>
<dd>Reorganize <tt><i>table</i></tt> only. If you don't specify this option, all tables in specified databases are reorganized.</dd> <dd>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. </dd>
<dt><tt>-Z</tt><br /><tt>--no-analyze</tt></dt> <dt>
<dd>Do ANALYZE after reorganization. If you don't specify this option, ANALYZE is performed automatically after reorg.</dd> -t table<br />
--table table
</dl> </dt>
</div> <dd>Reorganize table only. If you don't specify this option, all tables in specified databases are reorganized.</dd>
<div><a name="environment"></a> <dt>-Z<br />--no-analyze</dt>
<h2>Environment</h2> <div> <dd>Do ANALYZE after reorganization. If you don't specify this option, ANALYZE is performed automatically after reorg.</dd>
<dl>
<dt> </dl>
<tt>PGDATABASE</tt><br />
<tt>PGHOST</tt><br /> <h2 id="environment">Environment</h2>
<tt>PGPORT</tt><br /> <dl>
<tt>PGUSER</tt> <dt>
</dt> PGDATABASE<br />
<dd>Default connection parameters</dd> PGHOST<br />
</dl> PGPORT<br />
</div> PGUSER
<p>This utility, like most other PostgreSQL utilities, also uses the environment variables supported by libpq (see <a href="http://developer.postgresql.org/pgdocs/postgres/libpq-envars.html">Environment Variables</a>).</p> </dt>
</div> <dd>Default connection parameters</dd>
</dl>
<div><a name="diagnostics"></a> <p>This utility, like most other PostgreSQL utilities, also uses the environment variables supported by libpq (see <a href="http://developer.postgresql.org/pgdocs/postgres/libpq-envars.html">Environment Variables</a>).</p>
<h2>Diagnostics</h2>
<p>Error messages are reported when pg_reorg fails. <h2 id="diagnostics">Diagnostics</h2>
The following list shows the cause of errors.</p> <p>Error messages are reported when pg_reorg fails.
<p>You need to cleanup by hand after fatal erros. The following list shows the cause of errors.</p>
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.)</p> <p>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.)</p>
<dl>
<dt>pg_reorg : reorg database "template1" ... skipped</dt> <dl>
<dd>pg_reorg is not installed in the database when <tt>--all</tt> option is specified.</dd> <dt>pg_reorg : reorg database "template1" ... skipped</dt>
<dd>Do register pg_reorg to the database.</dd> <dd>pg_reorg is not installed in the database when --all option is specified.</dd>
<dd>Do register pg_reorg to the database.</dd>
<dt>ERROR: pg_reorg is not installed</dt>
<dd>pg_reorg is not installed in the database specified by <tt>--dbname</tt>.</dd> <dt>ERROR: pg_reorg is not installed</dt>
<dd>Do register pg_reorg to the database.</dd> <dd>pg_reorg is not installed in the database specified by --dbname.</dd>
<dd>Do register pg_reorg to the database.</dd>
<dt>ERROR: relation "table" has no primary key</dt>
<dd>The target table doesn't have PRIMARY KEY.</dd> <dt>ERROR: relation "table" has no primary key</dt>
<dd>Define PRIMARY KEY to the table. (ALTER TABLE ADD PRIMARY KEY)</dd> <dd>The target table doesn't have PRIMARY KEY.</dd>
<dd>Define PRIMARY KEY to the table. (ALTER TABLE ADD PRIMARY KEY)</dd>
<dt>ERROR: relation "table" has no cluster key</dt>
<dd>The target table doesn't have CLUSTER KEY.</dd> <dt>ERROR: relation "table" has no cluster key</dt>
<dd>Define CLUSTER KEY to the table. (ALTER TABLE CLUSTER)</dd> <dd>The target table doesn't have CLUSTER KEY.</dd>
<dd>Define CLUSTER KEY to the table. (ALTER TABLE CLUSTER)</dd>
<dt>pg_reorg : query failed: ERROR: column "col" does not exist</dt>
<dd>The target table doesn't have columns specified by <tt>--order-by</tt> option.</dd> <dt>pg_reorg : query failed: ERROR: column "col" does not exist</dt>
<dd>Specify existing columns.</dd> <dd>The target table doesn't have columns specified by --order-by option.</dd>
<dd>Specify existing columns.</dd>
<dt>ERROR: permission denied for schema reorg</dt>
<dd>Permission error.</dd> <dt>ERROR: permission denied for schema reorg</dt>
<dd>pg_reorg must be executed by superusers.</dd> <dd>Permission error.</dd>
<dd>pg_reorg must be executed by superusers.</dd>
<dt>pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists</dt>
<dd>The target table already has a trigger named "z_reorg_trigger".</dd> <dt>pg_reorg : query failed: ERROR: trigger "z_reorg_trigger" for relation "tbl" already exists</dt>
<dd>Delete or rename the trigger.</dd> <dd>The target table already has a trigger named "z_reorg_trigger".</dd>
<dd>Delete or rename the trigger.</dd>
<dt>pg_reorg : trigger conflicted for tbl</dt>
<dd>The target table already has a trigger which follows by "z_reorg_trigger" in alphabetical order.</dd> <dt>pg_reorg : trigger conflicted for tbl</dt>
<dd>Delete or rename the trigger.</dd> <dd>The target table already has a trigger which follows by "z_reorg_trigger" in alphabetical order.</dd>
</dl> <dd>Delete or rename the trigger.</dd>
</div> </dl>
<div><a name="restrictions"></a> <h2 id="restrictions">Restrictions</h2>
<h2>Restrictions</h2> <p>pg_reorg has the following restrictions.
<p>pg_reorg has the following restrictions. Be careful to avoid data corruptions.</p>
Be careful to avoid data corruptions.</p>
<h3>Temp tables</h3>
<h3>Temp tables</h3> <p>pg_reorg cannot reorganize temp tables.</p>
<p>pg_reorg cannot reorganize temp tables.</p>
<h3>GiST indexes</h3>
<h3>GiST indexes</h3> <p>pg_reorg cannot reorganize tables using GiST indexes.</p>
<p>pg_reorg cannot reorganize tables using GiST indexes.</p>
<h3>DDL commands</h3>
<h3>DDL commands</h3> <p>You cannot do DDL commands <strong>except</strong> VACUUM and ANALYZE during pg_reorg.
<p>You cannot do DDL commands <strong>except</strong> <tt>VACUUM</tt> and <tt>ANALYZE</tt> during pg_reorg. In many case pg_reorg would fail and rollback collectly, but there are some cases ending with data-corruption .</p>
In many case pg_reorg would fail and rollback collectly, but there are some cases ending with data-corruption .</p>
<dl>
<dl> <dt>TRUNCATE</dt>
<dt><tt>TRUNCATE</tt></dt> <dd>TRUNCATE is lost. Deleted rows still exist after pg_reorg.</dd>
<dd><tt>TRUNCATE</tt> is lost. Deleted rows still exist after pg_reorg.</dd>
<dt>CREATE INDEX</dt>
<dt><tt>CREATE INDEX</tt></dt> <dd>It causes index corruptions.</dd>
<dd>It causes index corruptions.</dd>
<dt>ALTER TABLE ... ADD COLUMN</dt>
<dt><tt>ALTER TABLE ... ADD COLUMN</tt></dt> <dd>It causes lost of data. Newly added columns are initialized with NULLs.</dd>
<dd>It causes lost of data. Newly added columns are initialized with NULLs.</dd>
<dt>ALTER TABLE ... ALTER COLUMN TYPE</dt>
<dt><tt>ALTER TABLE ... ALTER COLUMN TYPE</tt></dt> <dd>It causes data corruptions.</dd>
<dd>It causes data corruptions.</dd>
<dt>ALTER TABLE ... SET TABLESPACE</dt>
<dt><tt>ALTER TABLE ... SET TABLESPACE</tt></dt> <dd>It causes data corruptions by wrong relfilenode.</dd>
<dd>It causes data corruptions by wrong relfilenode.</dd> </dl>
</dl>
</div> <h2 id="details">Details</h2>
<p>pg_reorg creates a work table in reorg schema and sorts rows in it.
<div><a name="install"></a> Then, it updates system catalog directly to swap the work table and the original one.</p>
<h2>Installations</h2>
<p>pg_reorg can be installed like standard contrib modules.</p> <h2 id="install">Installations</h2>
<h3>Build from source</h3> <p>pg_reorg can be installed like standard contrib modules.</p>
<p>Place pg_reorg to $PGHOME/contrib/ and input make, make install.</p> <h3>Build from source</h3>
<h3>Register to database</h3> <p>Place pg_reorg to $PGHOME/contrib/ and input make, make install.</p>
<p>Start PostgreSQL and execute pg_reorg.sql in $PGHOME/share/contrib.</p> <h3>Register to database</h3>
</div> <p>Start PostgreSQL and execute pg_reorg.sql in $PGHOME/share/contrib.</p>
<div><a name="requirement"></a> <h2 id="requirement">Requirements</h2>
<h2>Requirements</h2> <dl>
<dl> <dt>PostgreSQL version</dt><dd>PostgreSQL 8.3</dd>
<dt>PostgreSQL version</dt><dd>PostgreSQL 8.3</dd> <dt>OS</dt><dd>RHEL 5.2, Windows XP SP3</dd>
<dt>OS</dt><dd>RHEL 5.2, Windows XP SP3</dd> <dt>Disks</dt><dd>Requires amount of disks twice larger than target table and indexes.</dd>
<dt>Disks</dt><dd>Requires amount of disks twice larger than target table and indexes.</dd> </dl>
</dl>
</div> <h2 id="seealso">See Also</h2>
<a href="http://developer.postgresql.org/pgdocs/postgres/app-clusterdb.html">clusterdb</a>,
<div><a name="seealso"></a> <a href="http://developer.postgresql.org/pgdocs/postgres/app-vacuumdb.html">vacuumdb</a>
<h2>See Also</h2>
<a href="http://developer.postgresql.org/pgdocs/postgres/app-clusterdb.html"><i><tt>clusterdb</tt></i></a>, <hr />
<a href="http://developer.postgresql.org/pgdocs/postgres/app-vacuumdb.html"><i><tt>vacuumdb</tt></i></a> <p class="footer">Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION</p>
</div>
<script type="text/javascript">
<hr> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
<p align="right"><font size="2"> </script>
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION <script type="text/javascript">
</font></p> try {
var pageTracker = _gat._getTracker("UA-10244036-4");
</body> pageTracker._trackPageview();
</html> } catch(err) {}</script>
</body>
</html>

View File

@ -1,12 +1,13 @@
BODY { body {
margin-top: 3; font-family:
margin-left: 3; Lucida Grande, Verdana, Arial, Helvetica,
margin-right: 3; 'メイリオ',
margin-bottom: 3; 'Meiryo',
} 'ヒラギノ角ゴ Pro W3',
'Hiragino Kaku Gothic Pro',
TT,OL,UL,P,BODY,TR,TD,TH,FORM { 'Osaka',
font-family: arial,helvetica,sans-serif; ' Pゴシック',
sans-serif;
color: #202020; color: #202020;
} }
@ -16,11 +17,11 @@ HR { margin: 5px 0px 5px 0px }
h2, h3, h4, h5, h6 { h2, h3, h4, h5, h6 {
color: Black; color: Black;
background: none; background: none;
padding-top: 0.5em; padding-top: 0.5em;
padding-bottom: 0.17em; padding-bottom: 0.17em;
border-bottom: 1px solid #aaaaaa; border-bottom: 1px solid #aaaaaa;
} }
H1 { font-size: x-large; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; } 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; } 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; } 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; } H6 { padding-left: 4em; font-size: xx-small; font-family: Lucida Grande,verdana,arial,helvetica,sans-serif; }
dt { pre {
font-size: 110%;
padding-top: 0.5em;
padding-bottom: 0.5em;
}
PRE {
font-family: courier,sans-serif; font-family: courier,sans-serif;
background-color: #FBFBFD; background-color: #FBFBFD;
border: 1px dashed #7E7ECB; border: 1px dashed #7E7ECB;
@ -44,63 +39,43 @@ PRE {
overflow: auto; overflow: auto;
} }
A:link { text-decoration:none; color:#0000EE } li {
A:visited { text-decoration:none color:#551A8B} line-height: 1.4em;
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;
} }
A.showsource { table {
color: #000000; background: #f9f9f9;
text-decoration: none; border: 1px solid #aaa;
font-size: small; border-collapse: collapse;
} }
A.showsource:visited {
color: #000000; th, td {
text-decoration: none; border: 1px solid #aaa;
font-size: small; padding: 0.2em;
} }
A.showsource:hover {
color: #000000; thead th {
text-decoration: none; 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; font-size: small;
} }

View File

@ -8,12 +8,14 @@
#include <unistd.h> #include <unistd.h>
#include "access/genam.h"
#include "access/transam.h" #include "access/transam.h"
#include "access/xact.h" #include "access/xact.h"
#include "catalog/dependency.h" #include "catalog/dependency.h"
#include "catalog/indexing.h" #include "catalog/indexing.h"
#include "catalog/namespace.h" #include "catalog/namespace.h"
#include "catalog/pg_namespace.h" #include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "commands/tablecmds.h" #include "commands/tablecmds.h"
#include "commands/trigger.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) \ #define copy_tuple(tuple, desc) \
PointerGetDatum(SPI_returntuple((tuple), (desc))) PointerGetDatum(SPI_returntuple((tuple), (desc)))
#define IsToken(c) \
(IS_HIGHBIT_SET((c)) || isalnum((unsigned char) (c)) || (c) == '_')
/* check access authority */ /* check access authority */
static void static void
must_be_superuser(const char *func) must_be_superuser(const char *func)
@ -313,11 +318,32 @@ skip_const(Oid index, char *sql, const char *arg1, const char *arg2)
static char * static char *
skip_ident(Oid index, char *sql) skip_ident(Oid index, char *sql)
{ {
sql = strchr(sql, ' '); while (*sql && isspace((unsigned char) *sql))
if (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'; *sql = '\0';
return sql + 2; return sql + 1;
} }
/* error */ /* error */
@ -325,12 +351,13 @@ skip_ident(Oid index, char *sql)
} }
static char * static char *
skip_columns(Oid index, char *sql) skip_until(Oid index, char *sql, char end)
{ {
char instr = 0; 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) if (instr)
{ {
@ -342,9 +369,7 @@ skip_columns(Oid index, char *sql)
instr = 0; instr = 0;
} }
else if (sql[0] == '\\') else if (sql[0] == '\\')
{ sql++; /* next char is always string */
sql++; // next char is always string
}
} }
else else
{ {
@ -364,10 +389,10 @@ skip_columns(Oid index, char *sql)
} }
} }
if (nopen == 0) if (nopen == 0 && instr == 0)
{ {
sql[-1] = '\0'; *sql = '\0';
return sql; return sql + 1;
} }
/* error */ /* error */
@ -395,11 +420,14 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table)
/* USING */ /* USING */
sql = skip_const(index, sql, "USING", NULL); sql = skip_const(index, sql, "USING", NULL);
/* type */ /* type */
stmt->type= sql; stmt->type = sql;
sql = skip_ident(index, sql); sql = skip_ident(index, sql);
/* (columns) */ /* (columns) */
if ((sql = strchr(sql, '(')) == NULL)
parse_error(index);
sql++;
stmt->columns = sql; stmt->columns = sql;
sql = skip_columns(index, sql); sql = skip_until(index, sql, ')');
/* options */ /* options */
stmt->options = sql; stmt->options = sql;
} }
@ -413,6 +441,9 @@ parse_indexdef(IndexDef *stmt, Oid index, Oid table)
* @param index Oid of target index. * @param index Oid of target index.
* @param table Oid of table of the index. * @param table Oid of table of the index.
* @retval Create index DDL for temp table. * @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 Datum
reorg_get_index_keys(PG_FUNCTION_ARGS) 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 index = PG_GETARG_OID(0);
Oid table = PG_GETARG_OID(1); Oid table = PG_GETARG_OID(1);
IndexDef stmt; IndexDef stmt;
char *token;
char *next;
StringInfoData str;
Relation indexRel = NULL;
int nattr;
parse_indexdef(&stmt, index, table); 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); natts2 - natts1, SPI_processed);
/* renumber attnum */ /* 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, execute_with_format(SPI_OK_UPDATE,
"UPDATE pg_catalog.pg_attribute" "UPDATE pg_catalog.pg_attribute"
" SET attnum = (SELECT count(*) FROM pg_attribute a" " 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 */ /* adjust key attnum if the target table has dropped columns */
if (natts1 != natts2) 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, execute_with_format(SPI_OK_UPDATE,
"UPDATE pg_catalog.pg_index SET indkey = n.indkey" "UPDATE pg_catalog.pg_index SET indkey = n.indkey"
" FROM pg_catalog.pg_index n" " FROM pg_catalog.pg_index n"
" WHERE pg_catalog.pg_index.indexrelid = %u" " WHERE pg_catalog.pg_index.indexrelid = %u"
" AND n.indexrelid = 'reorg.index_%u'::regclass", " AND n.indexrelid = 'reorg.index_%u'::regclass",
idx1, idx1); idx1, idx1);
#endif
if (SPI_processed != 1) if (SPI_processed != 1)
elog(ERROR, "failed to update pg_index.indkey (%u rows updated)", SPI_processed); elog(ERROR, "failed to update pg_index.indkey (%u rows updated)", SPI_processed);
} }