Modify LOCK to LOCK-NOWAIT-and-loop at swap tables to avoid holding exclusive locks long time. Suggested by Kenny Gorman.

This commit is contained in:
Takahiro Itagaki 2009-04-16 06:01:01 +00:00
parent 942180c2d8
commit e1011e11fe
6 changed files with 849 additions and 680 deletions

View File

@ -74,7 +74,7 @@ typedef struct reorg_index
static void reorg_all_databases(const char *orderby); static void reorg_all_databases(const char *orderby);
static bool reorg_one_database(const char *orderby, const char *table); static bool reorg_one_database(const char *orderby, const char *table);
static void reorg_one_table(const reorg_table *table, const char* orderby); static void reorg_one_table(const reorg_table *table, const char *orderby);
static void reconnect(void); static void reconnect(void);
static void disconnect(void); static void disconnect(void);
@ -93,6 +93,13 @@ static void PrintVersion(void);
static char *getstr(PGresult *res, int row, int col); static char *getstr(PGresult *res, int row, int col);
static Oid getoid(PGresult *res, int row, int col); static Oid getoid(PGresult *res, int row, int col);
#define SQLSTATE_INVALID_SCHEMA_NAME "3F000"
#define SQLSTATE_LOCK_NOT_AVAILABLE "55P03"
static bool sqlstate_equals(PGresult *res, const char *state)
{
return strcmp(PQresultErrorField(res, PG_DIAG_SQLSTATE), state) == 0;
}
static const char *progname = NULL; static const char *progname = NULL;
static bool echo = false; static bool echo = false;
@ -390,8 +397,7 @@ reorg_one_database(const char *orderby, const char *table)
if (PQresultStatus(res) != PGRES_TUPLES_OK) if (PQresultStatus(res) != PGRES_TUPLES_OK)
{ {
const char *state = PQresultErrorField(res, PG_DIAG_SQLSTATE); if (sqlstate_equals(res, SQLSTATE_INVALID_SCHEMA_NAME))
if (state && strcmp(state, "3F000") == 0)
{ {
/* Schema reorg does not exist. Skip the database. */ /* Schema reorg does not exist. Skip the database. */
ret = false; ret = false;
@ -657,8 +663,32 @@ reorg_one_table(const reorg_table *table, const char *orderby)
if (verbose) if (verbose)
fprintf(stderr, "---- swap ----\n"); fprintf(stderr, "---- swap ----\n");
command("BEGIN ISOLATION LEVEL READ COMMITTED", 0, NULL); for (;;)
command(table->lock_table, 0, NULL); {
command("BEGIN ISOLATION LEVEL READ COMMITTED", 0, NULL);
res = execute_nothrow(table->lock_table, 0, NULL);
if (PQresultStatus(res) == PGRES_COMMAND_OK)
{
PQclear(res);
break;
}
else if (sqlstate_equals(res, SQLSTATE_LOCK_NOT_AVAILABLE))
{
/* retry if lock conflicted */
PQclear(res);
command("ROLLBACK", 0, NULL);
sleep(1);
continue;
}
else
{
/* exit otherwise */
printf("%s", PQerrorMessage(current_conn));
PQclear(res);
exit_with_cleanup(1);
}
}
apply_log(table, 0); apply_log(table, 0);
params[0] = utoa(table->target_oid, buffer); params[0] = utoa(table->target_oid, buffer);
command("SELECT reorg.reorg_swap($1)", 1, params); command("SELECT reorg.reorg_swap($1)", 1, params);
@ -761,7 +791,7 @@ execute_nothrow(const char *query, int nParams, const char **params)
} }
/* /*
* execute - Execute a SQL and discard the result, or exit() if failed. * execute - Execute a SQL and return the result, or exit() if failed.
*/ */
static PGresult * static PGresult *
execute(const char *query, int nParams, const char **params) execute(const char *query, int nParams, const char **params)
@ -834,7 +864,6 @@ static void
PrintVersion(void) PrintVersion(void)
{ {
fprintf(stderr, "pg_reorg " REORG_VERSION "\n"); fprintf(stderr, "pg_reorg " REORG_VERSION "\n");
return;
} }
/* /*

View File

@ -1,53 +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="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 />
<p> <h2>ドキュメント</h2>
<a href="pg_reorg-ja.html">ドキュメントはこちら</a> <p>
</p> <a href="pg_reorg-ja.html">ドキュメントはこちら</a>
</p>
<hr />
<div align="right"> <h2>実行時間</h2>
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION <p>
</div> pg_reorg とclusterdb の比較に示します。
断片化のないソートされた状態 (not fragmented) では clusterdb のほうが高速ですが、完全に断片化した状態 (fully fragmented) では pg_reorg が大幅に高速です。
<!-- PLEASE LEAVE "Powered By GForge" on your site --> 一般的に、再編成は断片化が進行した状態で実施されることを考えると、pg_reorg は clusterdb よりも実行時間が短いと言えます。
<br /> </p>
<center>
<a href="http://gforge.org/"><img src="http://gforge.org/images/pow-gforge.png" <center>
alt="Powered By GForge Collaborative Development Environment" border="0" /></a> <div style="margin: 2em">
</center> <img src="result.png" />
</div>
</body>
</html> <table border="1">
<caption>測定環境</caption>
<tr>
<th>大項目</th>
<th>小項目</th>
<th>環境</th>
</tr>
<tr>
<td rowspan="3">ハードウェア</td>
<td>CPU</td>
<td>2 × Xeon 5160 3.00GHz (Dual core)</td>
</tr>
<tr>
<td>メモリ</td>
<td>2GB</td>
</tr>
<tr>
<td>ストレージ</td>
<td>Ultra320 SCSI, 15000rpm (220GB)</td>
</tr>
<tr>
<td rowspan="4">ソフトウェア</td>
<td>OS</td>
<td>RHEL 5.2 (64bit) 2.6.18-92.el5</td>
</tr>
<tr>
<td>DB</td>
<td>PostgreSQL 8.3.3</td>
</tr>
<tr>
<td>pg_reorg</td>
<td>1.0.0</td>
</tr>
<tr>
<td>clusterdb</td>
<td>clusterdb (PostgreSQL) 8.3.3</td>
</tr>
<tr>
<td rowspan="2">データ</td>
<td>スキーマ</td>
<td><code><pre>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);</pre></code></td>
</tr>
<tr>
<td>件数</td>
<td>1650万件 (約2GB)</td>
</tr>
</table>
</center>
<hr />
<div align="right">
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
</div>
<!-- PLEASE LEAVE "Powered By GForge" on your site -->
<br />
<center>
<a href="http://gforge.org/"><img src="http://gforge.org/images/pow-gforge.png"
alt="Powered By GForge Collaborative Development Environment" border="0" /></a>
</center>
</body>
</html>

View File

@ -1,53 +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 />
<p> <h2>Documentation</h2>
<a href="pg_reorg.html">Documentations here</a>. <p>
</p> <a href="pg_reorg.html">Documentations here</a>.
</p>
<hr />
<div align="right"> <h2>Execution time</h2>
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION <p>
</div> 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.
<!-- PLEASE LEAVE "Powered By GForge" on your site --> Since reorganization is needed only if tables are fragmented, pg_reorg should be faster than clusterdb.
<br /> </p>
<center>
<a href="http://gforge.org/"><img src="http://gforge.org/images/pow-gforge.png" <center>
alt="Powered By GForge Collaborative Development Environment" border="0" /></a> <div style="margin: 2em">
</center> <img src="result.png" />
</div>
</body>
</html> <table border="1">
<caption>Configuration</caption>
<tr>
<th>Category</th>
<th>Item</th>
<th>Details</th>
</tr>
<tr>
<td rowspan="3">Hardware</td>
<td>CPU</td>
<td>2 * Xeon 5160 3.00GHz (Dual core)</td>
</tr>
<tr>
<td>Memory</td>
<td>2GB</td>
</tr>
<tr>
<td>Storage</td>
<td>Ultra320 SCSI, 15000rpm (220GB)</td>
</tr>
<tr>
<td rowspan="4">Software</td>
<td>OS</td>
<td>RHEL 5.2 (64bit) 2.6.18-92.el5</td>
</tr>
<tr>
<td>DB</td>
<td>PostgreSQL 8.3.3</td>
</tr>
<tr>
<td>pg_reorg</td>
<td>1.0.0</td>
</tr>
<tr>
<td>clusterdb</td>
<td>clusterdb (PostgreSQL) 8.3.3</td>
</tr>
<tr>
<td rowspan="2">Data</td>
<td>Scheme</td>
<td><code><pre>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);</pre></code></td>
</tr>
<tr>
<td>Rows</td>
<td>16.5 M rows (2GB)</td>
</tr>
</table>
</center>
<hr />
<div align="right">
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
</div>
<!-- PLEASE LEAVE "Powered By GForge" on your site -->
<br />
<center>
<a href="http://gforge.org/"><img src="http://gforge.org/images/pow-gforge.png"
alt="Powered By GForge Collaborative Development Environment" border="0" /></a>
</center>
</body>
</html>

View File

@ -1,291 +1,291 @@
<!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><a name="pg_reorg"></a>pg_reorg</h1>
<div><a name="name"></a> <div><a name="name"></a>
<h2>名前</h2> <h2>名前</h2>
pg_reorg -- PostgreSQLデータベース内のテーブルに対して、参照/更新処理をブロックせずに再編成を行います。 pg_reorg -- PostgreSQLデータベース内のテーブルに対して、参照/更新処理をブロックせずに再編成を行います。
</div> </div>
<div> <div>
<a name="synopsis"></a> <a name="synopsis"></a>
<h2>概要</h2> <h2>概要</h2>
<p> <p>
<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>...] <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>...]
</p> </p>
<p>指定できるオプションには4つのカテゴリがあります。 <p>指定できるオプションには4つのカテゴリがあります。
詳細は<a href="#options">オプション</a>を参照してください。</p> 詳細は<a href="#options">オプション</a>を参照してください。</p>
<dl> <dl>
<dt><tt>connection-options</tt> : 接続パラメータ</dt> <dt><tt>connection-options</tt> : 接続パラメータ</dt>
<dd><tt>-h</tt> [<tt>--host</tt>] <tt><i>host</i></tt></dd> <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> <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> <dd><tt>-U</tt> [<tt>--username</tt>] <tt><i>username</i></tt></dd>
<dd><tt>-W</tt> [<tt>--password</tt>]</dd> <dd><tt>-W</tt> [<tt>--password</tt>]</dd>
<dt><tt>message-options</tt> : 出力メッセージ</dt> <dt><tt>message-options</tt> : 出力メッセージ</dt>
<dd><tt>-e</tt> [<tt>--echo</tt>]</dd> <dd><tt>-e</tt> [<tt>--echo</tt>]</dd>
<dd><tt>-q</tt> [<tt>--quiet</tt>]</dd> <dd><tt>-q</tt> [<tt>--quiet</tt>]</dd>
<dd><tt>-v</tt> [<tt>--verbose</tt>]</dd> <dd><tt>-v</tt> [<tt>--verbose</tt>]</dd>
<dt><tt>order-options</tt> : 並び替えの基準</dt> <dt><tt>order-options</tt> : 並び替えの基準</dt>
<dd><tt>-o</tt> [<tt>--order-by</tt>] <tt><i>columns [,...]</i></tt></dd> <dd><tt>-o</tt> [<tt>--order-by</tt>] <tt><i>columns [,...]</i></tt></dd>
<dd><tt>-n</tt> [<tt>--no-order</tt>]</dd> <dd><tt>-n</tt> [<tt>--no-order</tt>]</dd>
<dt><tt>target-options</tt> : 処理対象</dt> <dt><tt>target-options</tt> : 処理対象</dt>
<dd><tt>-a</tt> [<tt>--all</tt>]</dd> <dd><tt>-a</tt> [<tt>--all</tt>]</dd>
<dd><tt>-d</tt> [<tt>--dbname</tt>] <tt><i>dbname</i></tt></dd> <dd><tt>-d</tt> [<tt>--dbname</tt>] <tt><i>dbname</i></tt></dd>
<dd><tt>-t</tt> [<tt>--table</tt>] <tt><i>table</i></tt></dd> <dd><tt>-t</tt> [<tt>--table</tt>] <tt><i>table</i></tt></dd>
</dl> </dl>
</div> </div>
<div><a name="description"></a> <div><a name="description"></a>
<h2>説明</h2> <h2>説明</h2>
<p>pg_reorg は、PostgreSQLデータベース内のテーブルを再編成(行の並び替え)するユーティリティです。 <p>pg_reorg は、PostgreSQLデータベース内のテーブルを再編成(行の並び替え)するユーティリティです。
<a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html"><tt>clusterdb</tt></a> と異なり、参照/更新処理をブロックしません。 <a href="http://www.postgresql.jp/document/current/html/app-clusterdb.html"><tt>clusterdb</tt></a> と異なり、参照/更新処理をブロックしません。
再編成の方式として、以下のいずれか1つを選択できます。</p> 再編成の方式として、以下のいずれか1つを選択できます。</p>
<ul> <ul>
<li>オンライン CLUSTER (cluster index順に行を並び替える)</li> <li>オンライン CLUSTER (cluster index順に行を並び替える)</li>
<li>ユーザの指定した順に行を並び替える</li> <li>ユーザの指定した順に行を並び替える</li>
<li>オンライン VACUUM FULL (行の詰め合わせを行う)</li> <li>オンライン VACUUM FULL (行の詰め合わせを行う)</li>
</ul> </ul>
<p>このユーティリティを使用するためには、以下のことに注意をしてください。</p> <p>このユーティリティを使用するためには、以下のことに注意をしてください。</p>
<ul> <ul>
<li>このユーティリティは、スーパーユーザのみが実行することができます。</li> <li>このユーティリティは、スーパーユーザのみが実行することができます。</li>
<li>対象のテーブルはPRIMARY KEYを持っている必要があります。</li> <li>対象のテーブルはPRIMARY KEYを持っている必要があります。</li>
<li>pg_reorg 実行後のデータの状態は、統計情報に反映されていません。統計情報を最新化するため、pg_reorg 実行後に<tt><a href="http://www.postgresql.jp/document/current/html/sql-analyze.html">ANALYZE</a></tt>を実行してください。</li> <li>pg_reorg 実行後のデータの状態は、統計情報に反映されていません。統計情報を最新化するため、pg_reorg 実行後に<tt><a href="http://www.postgresql.jp/document/current/html/sql-analyze.html">ANALYZE</a></tt>を実行してください。</li>
</ul> </ul>
</div> </div>
<div><a name="examples"></a> <div><a name="examples"></a>
<h2></h2> <h2></h2>
<p><tt>test</tt>というデータベースをオンライン CLUSTER するには、下記のコマンドを実行します。</p> <p><tt>test</tt>というデータベースをオンライン CLUSTER するには、下記のコマンドを実行します。</p>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE> <PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE>
<p><tt>test</tt>という名前のデータベースの<tt>foo</tt>という1つのテーブルに対してオンライン VACUUM FULL を行うには、下記のコマンドを実行します。</p> <p><tt>test</tt>という名前のデータベースの<tt>foo</tt>という1つのテーブルに対してオンライン VACUUM FULL を行うには、下記のコマンドを実行します。</p>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p> <PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p>
</p> </p>
</div> </div>
<div><a name="options"></a> <div><a name="options"></a>
<h2>オプション</h2> <h2>オプション</h2>
<p>pg_reorg では、下記の4種類のコマンドライン引数を指定できます。</p> <p>pg_reorg では、下記の4種類のコマンドライン引数を指定できます。</p>
<div> <div>
<dl> <dl>
<h3>connection-options</h3> <h3>connection-options</h3>
<p>PostgreSQLに接続するためのパラメータです。</p> <p>PostgreSQLに接続するためのパラメータです。</p>
<div> <div>
<dl> <dl>
<dt><tt>-h <tt><i>host</i></tt><br /> <dt><tt>-h <tt><i>host</i></tt><br />
<tt>--host <tt><i>host</i></tt></dt> <tt>--host <tt><i>host</i></tt></dt>
<dd>サーバが稼働しているマシンのホスト名を指定します。ホスト名がスラッシュから始まる場合、Unixドメインソケット用のディレクトリとして使用されます。</dd> <dd>サーバが稼働しているマシンのホスト名を指定します。ホスト名がスラッシュから始まる場合、Unixドメインソケット用のディレクトリとして使用されます。</dd>
<dt><tt>-p <tt><i>port</i></tt><br /> <dt><tt>-p <tt><i>port</i></tt><br />
<tt>--port <tt><i>port</i></tt></dt> <tt>--port <tt><i>port</i></tt></dt>
<dd>サーバが接続を監視するTCPポートもしくはUnixドメインソケットファイルの拡張子を指定します。</dd> <dd>サーバが接続を監視するTCPポートもしくはUnixドメインソケットファイルの拡張子を指定します。</dd>
<dt><tt>-U <tt><i>username</i></tt><br /> <dt><tt>-U <tt><i>username</i></tt><br />
<tt>--username <tt><i>username</i></tt></dt> <tt>--username <tt><i>username</i></tt></dt>
<dd>接続するユーザ名を指定します。</dd> <dd>接続するユーザ名を指定します。</dd>
<dt><tt>-W</tt><br /><tt>--password</tt></dt> <dt><tt>-W</tt><br /><tt>--password</tt></dt>
<dd>データベースに接続する前に、pg_reorg は強制的にパスワード入力を促します。</dd> <dd>データベースに接続する前に、pg_reorg は強制的にパスワード入力を促します。</dd>
<dd>サーバがパスワード認証を要求する場合 pg_reorg は自動的にパスワード入力を促しますので、これが重要になることはありません。 <dd>サーバがパスワード認証を要求する場合 pg_reorg は自動的にパスワード入力を促しますので、これが重要になることはありません。
しかし、pg_reorg は、サーバにパスワードが必要かどうかを判断するための接続試行を無駄に行います。 しかし、pg_reorg は、サーバにパスワードが必要かどうかを判断するための接続試行を無駄に行います。
こうした余計な接続試行を防ぐために<tt>-W</tt>の入力が有意となる場合もあります。</dd> こうした余計な接続試行を防ぐために<tt>-W</tt>の入力が有意となる場合もあります。</dd>
</dl> </dl>
</div> </div>
<h3>message-options</h3> <h3>message-options</h3>
<p> <p>
pg_reorg を実行した際に任意のメッセージを出力するためのパラメータです。 pg_reorg を実行した際に任意のメッセージを出力するためのパラメータです。
<tt>--quiet</tt>と他の2つのオプションを同時に指定した場合は、<tt>--quiet</tt>のオプションは無視されます。 <tt>--quiet</tt>と他の2つのオプションを同時に指定した場合は、<tt>--quiet</tt>のオプションは無視されます。
</p> </p>
<dl> <dl>
<dt><tt>-e</tt><br /><tt>--echo</tt></dt> <dt><tt>-e</tt><br /><tt>--echo</tt></dt>
<dd>pg_reorg が生成し、サーバに送るコマンドをエコー表示します。</dd> <dd>pg_reorg が生成し、サーバに送るコマンドをエコー表示します。</dd>
<dt><tt>-q</tt><br /><tt>--quiet</tt></dt> <dt><tt>-q</tt><br /><tt>--quiet</tt></dt>
<dd>進行メッセージを表示しません。</dd> <dd>進行メッセージを表示しません。</dd>
<dt><tt>-v</tt><br /><tt>--verbose</tt></dt> <dt><tt>-v</tt><br /><tt>--verbose</tt></dt>
<dd>処理中に詳細な情報を表示します。</dd> <dd>処理中に詳細な情報を表示します。</dd>
</dl> </dl>
<h3>order-options</h3> <h3>order-options</h3>
<p>pg_reorg を実行する際の並び替えの基準を指定するパラメータです。 <p>pg_reorg を実行する際の並び替えの基準を指定するパラメータです。
何も指定されていない場合は、cluster index順にオンライン CLUSTER を行います。 何も指定されていない場合は、cluster index順にオンライン CLUSTER を行います。
この2つを同時に指定することはできません。 この2つを同時に指定することはできません。
</p> </p>
<dl> <dl>
<dt><tt>-n</tt><br /><tt>--no-order</tt></dt> <dt><tt>-n</tt><br /><tt>--no-order</tt></dt>
<dd>オンライン VACUUM FULL の処理を行います。</dd> <dd>オンライン VACUUM FULL の処理を行います。</dd>
<dt><tt>-o</tt> <tt><i>columns [,...]</i></tt><br /> <dt><tt>-o</tt> <tt><i>columns [,...]</i></tt><br />
<tt>--order-by</tt> <tt><i>columns [,...]</i></tt></dt> <tt>--order-by</tt> <tt><i>columns [,...]</i></tt></dt>
<dd>指定したカラムをキーにオンライン CLUSTER を行います。</dd> <dd>指定したカラムをキーにオンライン CLUSTER を行います。</dd>
</dl> </dl>
<h3>target-options</h3> <h3>target-options</h3>
<p> <p>
pg_reorg を実行する対象を指定するパラメータです。 pg_reorg を実行する対象を指定するパラメータです。
<tt>--all</tt><tt>--dbname</tt>または<tt>--table</tt>を同時に指定することはできません。 <tt>--all</tt><tt>--dbname</tt>または<tt>--table</tt>を同時に指定することはできません。
</p> </p>
<dl> <dl>
<dt><tt>-a</tt><br /><tt>--all</tt></dt> <dt><tt>-a</tt><br /><tt>--all</tt></dt>
<dd>対象となる全てのデータベースに対してオンライン CLUSTER、または、オンラインVACUUM FULLを行います。</dd> <dd>対象となる全てのデータベースに対してオンライン CLUSTER、または、オンラインVACUUM FULLを行います。</dd>
<dt> <dt>
<tt>-d <tt><i>dbname</i></tt><br /> <tt>-d <tt><i>dbname</i></tt><br />
<tt>--dbname <tt><i>dbname</i></tt> <tt>--dbname <tt><i>dbname</i></tt>
</dt> </dt>
<dd>オンライン CLUSTER、または、オンライン VACUUM FULL を行うデータベース名を指定します。 <dd>オンライン CLUSTER、または、オンライン VACUUM FULL を行うデータベース名を指定します。
データベース名が指定されておらず、<tt>-a</tt>(または<tt>--all</tt>)も指定されていない場合、 データベース名が指定されておらず、<tt>-a</tt>(または<tt>--all</tt>)も指定されていない場合、
データベース名は<tt>PGDATABASE</tt>環境変数から読み取られます。この変数も設定されていない場合は、接続時に指定したユーザ名が使用されます。 データベース名は<tt>PGDATABASE</tt>環境変数から読み取られます。この変数も設定されていない場合は、接続時に指定したユーザ名が使用されます。
</dd> </dd>
<dt> <dt>
<tt>-t</tt> <tt><i>table</i></tt><br /> <tt>-t</tt> <tt><i>table</i></tt><br />
<tt>--table</tt> <tt><i>table</i></tt> <tt>--table</tt> <tt><i>table</i></tt>
</dt> </dt>
<dd>オンライン CLUSTER 、または、オンライン VACUUM FULL を行うテーブルを指定します。 <dd>オンライン CLUSTER 、または、オンライン VACUUM FULL を行うテーブルを指定します。
このオプションが指定されていない場合は、対象となったデータベースに存在する全ての対象テーブルに対して処理を行います。 このオプションが指定されていない場合は、対象となったデータベースに存在する全ての対象テーブルに対して処理を行います。
</dd> </dd>
</dl> </dl>
</div> </div>
<div><a name="environment"></a> <div><a name="environment"></a>
<h2>環境変数</h2> <div> <h2>環境変数</h2> <div>
<dl> <dl>
<dt> <dt>
<tt>PGDATABASE</tt><br /> <tt>PGDATABASE</tt><br />
<tt>PGHOST</tt><br /> <tt>PGHOST</tt><br />
<tt>PGPORT</tt><br /> <tt>PGPORT</tt><br />
<tt>PGUSER</tt> <tt>PGUSER</tt>
</dt> </dt>
<dd>デフォルトの接続パラメータです。</dd> <dd>デフォルトの接続パラメータです。</dd>
</dl> </dl>
</div> </div>
<p>また、このユーティリティは、他のほとんどの PostgreSQL ユーティリティと同様、 <p>また、このユーティリティは、他のほとんどの PostgreSQL ユーティリティと同様、
libpq でサポートされる環境変数を使用します。詳細については、<a href="http://www.postgresql.jp/document/current/html/libpq-envars.html">環境変数の項目</a>を参照してください。 libpq でサポートされる環境変数を使用します。詳細については、<a href="http://www.postgresql.jp/document/current/html/libpq-envars.html">環境変数の項目</a>を参照してください。
</p> </p>
</div> </div>
<div><a name="diagnostics"></a> <div><a name="diagnostics"></a>
<h2>トラブルシューティング</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><tt>--all</tt>オプションを指定した際に、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><tt>--dbname</tt>で指定したデータベースに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><tt>--order-by</tt> で指定したカラムが対象のテーブルに存在していません。</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> </div>
<div><a name="restrictions"></a> <div><a name="restrictions"></a>
<h2>制約</h2> <h2>制約</h2>
<p>pg_reorg を使用する際には、以下の制約があります。以下の制約に関する操作を行った場合の動作は保証されません。注意してください。</p> <p>pg_reorg を使用する際には、以下の制約があります。以下の制約に関する操作を行った場合の動作は保証されません。注意してください。</p>
<h3>一時テーブルへの操作</h3> <h3>一時テーブルへの操作</h3>
<p>pg_reorg では、一時テーブルは操作の対象外です。</p> <p>pg_reorg では、一時テーブルは操作の対象外です。</p>
<h3>GiSTインデックスの使用</h3> <h3>GiSTインデックスの使用</h3>
<p>インデックス種別がGiSTとなっているインデックスがクラスタインデックスとなっている <p>インデックス種別がGiSTとなっているインデックスがクラスタインデックスとなっている
テーブルはpg_reorg コマンドを使用して操作を行うことはできません。 テーブルはpg_reorg コマンドを使用して操作を行うことはできません。
これは、GiSTインデックスのソート順序は一意ではないため、<tt>ORDER BY</tt>による これは、GiSTインデックスのソート順序は一意ではないため、<tt>ORDER BY</tt>による
ソートが行えないためです。</p> ソートが行えないためです。</p>
<h3>DDLコマンドの発行</h3> <h3>DDLコマンドの発行</h3>
<p> <p>
pg_reorg の実行中には、<tt>VACUUM</tt><tt>ANALYZE</tt> <STRONG>以外</STRONG> のDDL操作は行わないでください。 pg_reorg の実行中には、<tt>VACUUM</tt><tt>ANALYZE</tt> <STRONG>以外</STRONG> のDDL操作は行わないでください。
多くの場合、pg_reorg は失敗しロールバックされます。 多くの場合、pg_reorg は失敗しロールバックされます。
しかし、以下の操作ではデータが破損するため、非常に危険です。 しかし、以下の操作ではデータが破損するため、非常に危険です。
</p> </p>
<dl> <dl>
<dt><tt>TRUNCATE</tt></dt> <dt><tt>TRUNCATE</tt></dt>
<dd><tt>TRUNCATE</tt>により削除した行が、pg_reorg 実行後には復元しています。操作結果が消失します。</dd> <dd>削除した行が pg_reorg 実行後には復元しています。操作結果が消失します。</dd>
<dt><tt>CREATE INDEX</tt></dt> <dt><tt>CREATE INDEX</tt></dt>
<dd><tt>CREATE INDEX</tt>は、スワップされない索引が残る可能性があります。データの不整合が生じます。</dd> <dd>スワップされない索引が残る可能性があります。データの不整合が生じます。</dd>
<dt><tt>ADD COLUMN</tt></dt> <dt><tt>ALTER TABLE ... ADD COLUMN</tt></dt>
<dd><tt>ADD COLUMN</tt>は、追加された値が全てNULLに置換されてしまう可能性があります。データが消失します。</dd> <dd>追加された値が全てNULLに置換されてしまう可能性があります。データが消失します。</dd>
<dt><tt>ALTER COLUMN TYPE</tt></dt> <dt><tt>ALTER TABLE ... ALTER COLUMN TYPE</tt></dt>
<dd><tt>ALTER COLUMN TYPE</tt>は、実行するとスキーマで定義された型と実際の格納状態に齟齬をきたします。データの不整合が生じます。</dd> <dd>実行するとスキーマで定義された型と実際の格納状態に齟齬をきたします。データの不整合が生じます。</dd>
<dt><tt>ALTER TABLE SET TABLESPACE</tt></dt> <dt><tt>ALTER TABLE ... SET TABLESPACE</tt></dt>
<dd><tt>ALTER TABLE SET TABLE SPACE</tt>は、pg_reorg 実行後にrelfilenodeとの不整合が起こるため、対象のテーブルに対する参照/更新操作時にエラーが発生します。</dd> <dd>pg_reorg 実行後にrelfilenodeとの不整合が起こるため、対象のテーブルに対する参照/更新操作時にエラーが発生します。</dd>
</dl> </dl>
</div> </div>
<div><a name="install"></a> <div><a name="install"></a>
<h2>インストール方法</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> </div>
<div><a name="requirement"></a> <div><a name="requirement"></a>
<h2>動作環境</h2> <h2>動作環境</h2>
<dl> <dl>
<dt>PostgreSQLバージョン</dt><dd>PostgreSQL 8.3</dd> <dt>PostgreSQLバージョン</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>ディスク容量</dt><dd>処理対象のテーブル、インデックスサイズの2倍以上のディスク空き容量</dd> <dt>ディスク容量</dt><dd>処理対象のテーブル、インデックスサイズの2倍以上のディスク空き容量</dd>
</dl> </dl>
</div> </div>
<div><a name="seealso"></a> <div><a name="seealso"></a>
<h2>関連項目</h2> <h2>関連項目</h2>
<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-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> <a href="http://www.postgresql.jp/document/current/html/app-vacuumdb.html"><i><tt>vacuumdb</tt></i></a>
</div> </div>
<hr> <hr>
<p align="right"><font size="2"> <p align="right"><font size="2">
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
</font></p> </font></p>
</body> </body>
</html> </html>

View File

@ -1,275 +1,275 @@
<!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><a name="pg_reorg"></a>pg_reorg</h1>
<div><a name="name"></a> <div><a name="name"></a>
<h2>Name</h2> <h2>Name</h2>
pg_reorg -- Reorganize tables in PostgreSQL databases without any locks. pg_reorg -- Reorganize tables in PostgreSQL databases without any locks.
</div> </div>
<div><a name="synopsis"></a> <div><a name="synopsis"></a>
<h2>Synopsis</h2> <h2>Synopsis</h2>
<p> <p>
<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>...] <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>...]
</p> </p>
<p>There 4 option categories. <p>There 4 option categories.
See also <a href="#options">options</a> for details.</p> See also <a href="#options">options</a> for details.</p>
<dl> <dl>
<dt><tt>connection-options</tt></dt> <dt><tt>connection-options</tt></dt>
<dd><tt>-h</tt> [<tt>--host</tt>] <tt><i>host</i></tt></dd> <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> <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> <dd><tt>-U</tt> [<tt>--username</tt>] <tt><i>username</i></tt></dd>
<dd><tt>-W</tt> [<tt>--password</tt>]</dd> <dd><tt>-W</tt> [<tt>--password</tt>]</dd>
<dt><tt>message-options</tt></dt> <dt><tt>message-options</tt></dt>
<dd><tt>-e</tt> [<tt>--echo</tt>]</dd> <dd><tt>-e</tt> [<tt>--echo</tt>]</dd>
<dd><tt>-q</tt> [<tt>--quiet</tt>]</dd> <dd><tt>-q</tt> [<tt>--quiet</tt>]</dd>
<dd><tt>-v</tt> [<tt>--verbose</tt>]</dd> <dd><tt>-v</tt> [<tt>--verbose</tt>]</dd>
<dt><tt>order-options</tt></dt> <dt><tt>order-options</tt></dt>
<dd><tt>-o</tt> [<tt>--order-by</tt>] <tt><i>columns [,...]</i></tt></dd> <dd><tt>-o</tt> [<tt>--order-by</tt>] <tt><i>columns [,...]</i></tt></dd>
<dd><tt>-n</tt> [<tt>--no-order</tt>]</dd> <dd><tt>-n</tt> [<tt>--no-order</tt>]</dd>
<dt><tt>target-options</tt></dt> <dt><tt>target-options</tt></dt>
<dd><tt>-a</tt> [<tt>--all</tt>]</dd> <dd><tt>-a</tt> [<tt>--all</tt>]</dd>
<dd><tt>-d</tt> [<tt>--dbname</tt>] <tt><i>dbname</i></tt></dd> <dd><tt>-d</tt> [<tt>--dbname</tt>] <tt><i>dbname</i></tt></dd>
<dd><tt>-t</tt> [<tt>--table</tt>] <tt><i>table</i></tt></dd> <dd><tt>-t</tt> [<tt>--table</tt>] <tt><i>table</i></tt></dd>
</dl> </dl>
</div> </div>
<div> <div>
<a name="description"></a> <a name="description"></a>
<h2>Description</h2> <h2>Description</h2>
<p>pg_reorg is an utility program to reorganize tables in PostgreSQL databases. <p>pg_reorg is an utility program to reorganize tables in PostgreSQL databases.
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. 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.
You can choose one of the following methods to reorganize.</p> You can choose one of the following methods to reorganize.</p>
<ul> <ul>
<li>Online CLUSTER (ordered by cluster index)</li> <li>Online CLUSTER (ordered by cluster index)</li>
<li>Ordered by specified columns</li> <li>Ordered by specified columns</li>
<li>Online VACUUM FULL (packing rows only)</li> <li>Online VACUUM FULL (packing rows only)</li>
</ul> </ul>
<p>NOTICE:</p> <p>NOTICE:</p>
<ul> <ul>
<li>Only superusers can use the utility.</li> <li>Only superusers can use the utility.</li>
<li>Target table must have PRIMARY KEY.</li> <li>Target table must have PRIMARY KEY.</li>
<li>You'd better to do <tt><a href="http://www.postgresql.jp/document/current/html/sql-analyze.html">ANALYZE</a></tt> after pg_reorg is completed.</li> <li>You'd better to do <tt><a href="http://www.postgresql.jp/document/current/html/sql-analyze.html">ANALYZE</a></tt> after pg_reorg is completed.</li>
</ul> </ul>
</div> </div>
<div><a name="examples"></a> <div><a name="examples"></a>
<h2>Examples</h2> <h2>Examples</h2>
<p>Execute the following command to do online CLUSTER to all tables in <tt>test</tt> database.</p> <p>Execute the following command to do online CLUSTER to all tables in <tt>test</tt> database.</p>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE> <PRE><SAMP>$ </SAMP><KBD>pg_reorg test</KBD></PRE>
<p>Execute the following command to do online VACUUM FULL to <tt>foo</tt> table in <tt>test</tt> database.</p> <p>Execute the following command to do online VACUUM FULL to <tt>foo</tt> table in <tt>test</tt> database.</p>
<PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p> <PRE><SAMP>$ </SAMP><KBD>pg_reorg --no-order --table foo -d test</KBD></PRE><p>
</p></div> </p></div>
<div><a name="options"></a> <div><a name="options"></a>
<h2>Options</h2> <h2>Options</h2>
<p>pg_reorg has command line options in 4 categolies.</p> <p>pg_reorg has command line options in 4 categolies.</p>
<div> <div>
<dl> <dl>
<h3>connection-options</h3> <h3>connection-options</h3>
<p>Parameters to connect PostgreSQL.</p> <p>Parameters to connect PostgreSQL.</p>
<div> <div>
<dl> <dl>
<dt><tt>-h <tt><i>host</i></tt><br /> <dt><tt>-h <tt><i>host</i></tt><br />
<tt>--host <tt><i>host</i></tt></dt> <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> <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>
<dt><tt>-p <tt><i>port</i></tt><br /> <dt><tt>-p <tt><i>port</i></tt><br />
<tt>--port <tt><i>port</i></tt></dt> <tt>--port <tt><i>port</i></tt></dt>
<dd>Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections.</dd> <dd>Specifies the TCP port or local Unix domain socket file extension on which the server is listening for connections.</dd>
<dt><tt>-U <tt><i>username</i></tt><br /> <dt><tt>-U <tt><i>username</i></tt><br />
<tt>--username <tt><i>username</i></tt></dt> <tt>--username <tt><i>username</i></tt></dt>
<dd>User name to connect as. </dd> <dd>User name to connect as. </dd>
<dt><tt>-W</tt><br /><tt>--password</tt></dt> <dt><tt>-W</tt><br /><tt>--password</tt></dt>
<dd>Force pg_reorg to prompt for a password before connecting to a database.</dd> <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 <tt>-W</tt> to avoid the extra connection attempt. </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> </dl>
</div> </div>
<h3>message-options</h3> <h3>message-options</h3>
<p>Specifies message output by pg_reorg. <p>Specifies message output by pg_reorg.
<tt>--quiet</tt> is ignored if some of the other options are specified.</p> <tt>--quiet</tt> is ignored if some of the other options are specified.</p>
<dl> <dl>
<dt><tt>-e</tt><br /><tt>--echo</tt></dt> <dt><tt>-e</tt><br /><tt>--echo</tt></dt>
<dd>Echo the commands that pg_reorg generates and sends to the server.</dd> <dd>Echo the commands that pg_reorg generates and sends to the server.</dd>
<dt><tt>-q</tt><br /><tt>--quiet</tt></dt> <dt><tt>-q</tt><br /><tt>--quiet</tt></dt>
<dd>Do not display progress messages. </dd> <dd>Do not display progress messages. </dd>
<dt><tt>-v</tt><br /><tt>--verbose</tt></dt> <dt><tt>-v</tt><br /><tt>--verbose</tt></dt>
<dd>Print detailed information during processing.</dd> <dd>Print detailed information during processing.</dd>
</dl> </dl>
<h3>order-options</h3> <h3>order-options</h3>
<p>Options to order rows. <p>Options to order rows.
If not specified, pg_reorg do online CLUSTER using cluster indexes. If not specified, pg_reorg do online CLUSTER using cluster indexes.
Only one option can be specified. Only one option can be specified.
</p> </p>
<dl> <dl>
<dt><tt>-n</tt><br /><tt>--no-order</tt></dt> <dt><tt>-n</tt><br /><tt>--no-order</tt></dt>
<dd>Do online VACUUM FULL.</dd> <dd>Do online VACUUM FULL.</dd>
<dt><tt>-o</tt> <tt><i>columns [,...]</i></tt><br /> <dt><tt>-o</tt> <tt><i>columns [,...]</i></tt><br />
<tt>--order-by</tt> <tt><i>columns [,...]</i></tt></dt> <tt>--order-by</tt> <tt><i>columns [,...]</i></tt></dt>
<dd>Do online CLUSTER ordered by specified columns.</dd> <dd>Do online CLUSTER ordered by specified columns.</dd>
</dl> </dl>
<h3>target-options</h3> <h3>target-options</h3>
<p> <p>
Options to specify target tables or databases. Options to specify target tables or databases.
You cannot use <tt>--all</tt> and <tt>--dbname</tt> or <tt>--table</tt> together. You cannot use <tt>--all</tt> and <tt>--dbname</tt> or <tt>--table</tt> together.
</p> </p>
<dl> <dl>
<dt><tt>-a</tt><br /><tt>--all</tt></dt> <dt><tt>-a</tt><br /><tt>--all</tt></dt>
<dd>Reorganize all databases.</dd> <dd>Reorganize all databases.</dd>
<dt> <dt>
<tt>-d <tt><i>dbname</i></tt><br /> <tt>-d <tt><i>dbname</i></tt><br />
<tt>--dbname <tt><i>dbname</i></tt> <tt>--dbname <tt><i>dbname</i></tt>
</dt> </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>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>
<dt> <dt>
<tt>-t</tt> <tt><i>table</i></tt><br /> <tt>-t</tt> <tt><i>table</i></tt><br />
<tt>--table</tt> <tt><i>table</i></tt> <tt>--table</tt> <tt><i>table</i></tt>
</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>Reorganize <tt><i>table</i></tt> only. If you don't specify this option, all tables in specified databases are reorganized.</dd>
</dl> </dl>
</div> </div>
<div><a name="environment"></a> <div><a name="environment"></a>
<h2>Environment</h2> <div> <h2>Environment</h2> <div>
<dl> <dl>
<dt> <dt>
<tt>PGDATABASE</tt><br /> <tt>PGDATABASE</tt><br />
<tt>PGHOST</tt><br /> <tt>PGHOST</tt><br />
<tt>PGPORT</tt><br /> <tt>PGPORT</tt><br />
<tt>PGUSER</tt> <tt>PGUSER</tt>
</dt> </dt>
<dd>Default connection parameters</dd> <dd>Default connection parameters</dd>
</dl> </dl>
</div> </div>
<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> <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>
</div> </div>
<div><a name="diagnostics"></a> <div><a name="diagnostics"></a>
<h2>Diagnostics</h2> <h2>Diagnostics</h2>
<p>Error messages are reported when pg_reorg fails. <p>Error messages are reported when pg_reorg fails.
The following list shows the cause of errors.</p> The following list shows the cause of errors.</p>
<p>You need to cleanup by hand after fatal erros. <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> 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> <dl>
<dt>pg_reorg : reorg database "template1" ... skipped</dt> <dt>pg_reorg : reorg database "template1" ... skipped</dt>
<dd>pg_reorg is not installed in the database when <tt>--all</tt> option is specified.</dd> <dd>pg_reorg is not installed in the database when <tt>--all</tt> option is specified.</dd>
<dd>Do register pg_reorg to the database.</dd> <dd>Do register pg_reorg to the database.</dd>
<dt>ERROR: pg_reorg is not installed</dt> <dt>ERROR: pg_reorg is not installed</dt>
<dd>pg_reorg is not installed in the database specified by <tt>--dbname</tt>.</dd> <dd>pg_reorg is not installed in the database specified by <tt>--dbname</tt>.</dd>
<dd>Do register pg_reorg to the database.</dd> <dd>Do register pg_reorg to the database.</dd>
<dt>ERROR: relation "table" has no primary key</dt> <dt>ERROR: relation "table" has no primary key</dt>
<dd>The target table doesn't have 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> <dd>Define PRIMARY KEY to the table. (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>The target table doesn't have CLUSTER KEY.</dd> <dd>The target table doesn't have CLUSTER KEY.</dd>
<dd>Define CLUSTER KEY to the table. (ALTER TABLE CLUSTER)</dd> <dd>Define CLUSTER KEY to the table. (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>The target table doesn't have columns specified by <tt>--order-by</tt> option.</dd> <dd>The target table doesn't have columns specified by <tt>--order-by</tt> option.</dd>
<dd>Specify existing columns.</dd> <dd>Specify existing columns.</dd>
<dt>ERROR: permission denied for schema reorg</dt> <dt>ERROR: permission denied for schema reorg</dt>
<dd>Permission error.</dd> <dd>Permission error.</dd>
<dd>pg_reorg must be executed by superusers.</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> <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> <dd>The target table already has a trigger named "z_reorg_trigger".</dd>
<dd>Delete or rename the trigger.</dd> <dd>Delete or rename the trigger.</dd>
<dt>pg_reorg : trigger conflicted for tbl</dt> <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> <dd>The target table already has a trigger which follows by "z_reorg_trigger" in alphabetical order.</dd>
<dd>Delete or rename the trigger.</dd> <dd>Delete or rename the trigger.</dd>
</dl> </dl>
</div> </div>
<div><a name="restrictions"></a> <div><a name="restrictions"></a>
<h2>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> <tt>VACUUM</tt> and <tt>ANALYZE</tt> 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><tt>TRUNCATE</tt></dt> <dt><tt>TRUNCATE</tt></dt>
<dd><tt>TRUNCATE</tt> 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><tt>CREATE INDEX</tt></dt> <dt><tt>CREATE INDEX</tt></dt>
<dd><tt>CREATE INDEX</tt> causes index corruptions.</dd> <dd>It causes index corruptions.</dd>
<dt><tt>ADD COLUMN</tt></dt> <dt><tt>ALTER TABLE ... ADD COLUMN</tt></dt>
<dd><tt>ADD COLUMN</tt> 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><tt>ALTER COLUMN TYPE</tt></dt> <dt><tt>ALTER TABLE ... ALTER COLUMN TYPE</tt></dt>
<dd><tt>ALTER COLUMN TYPE</tt> causes data corruptions.</dd> <dd>It causes data corruptions.</dd>
<dt><tt>ALTER TABLE SET TABLESPACE</tt></dt> <dt><tt>ALTER TABLE ... SET TABLESPACE</tt></dt>
<dd><tt>ALTER TABLE SET TABLE SPACE</tt> causes data corruptions by wrong relfilenode.</dd> <dd>It causes data corruptions by wrong relfilenode.</dd>
</dl> </dl>
</div> </div>
<div><a name="install"></a> <div><a name="install"></a>
<h2>Installations</h2> <h2>Installations</h2>
<p>pg_reorg can be installed like standard contrib modules.</p> <p>pg_reorg can be installed like standard contrib modules.</p>
<h3>Build from source</h3> <h3>Build from source</h3>
<p>Place pg_reorg to $PGHOME/contrib/ and input make, make install.</p> <p>Place pg_reorg to $PGHOME/contrib/ and input make, make install.</p>
<h3>Register to database</h3> <h3>Register to database</h3>
<p>Start PostgreSQL and execute pg_reorg.sql in $PGHOME/share/contrib.</p> <p>Start PostgreSQL and execute pg_reorg.sql in $PGHOME/share/contrib.</p>
</div> </div>
<div><a name="requirement"></a> <div><a name="requirement"></a>
<h2>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> </div>
<div><a name="seealso"></a> <div><a name="seealso"></a>
<h2>See Also</h2> <h2>See Also</h2>
<a href="http://developer.postgresql.org/pgdocs/postgres/app-clusterdb.html"><i><tt>clusterdb</tt></i></a>, <a href="http://developer.postgresql.org/pgdocs/postgres/app-clusterdb.html"><i><tt>clusterdb</tt></i></a>,
<a href="http://developer.postgresql.org/pgdocs/postgres/app-vacuumdb.html"><i><tt>vacuumdb</tt></i></a> <a href="http://developer.postgresql.org/pgdocs/postgres/app-vacuumdb.html"><i><tt>vacuumdb</tt></i></a>
</div> </div>
<hr> <hr>
<p align="right"><font size="2"> <p align="right"><font size="2">
Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION Copyright (c) 2008-2009, NIPPON TELEGRAPH AND TELEPHONE CORPORATION
</font></p> </font></p>
</body> </body>
</html> </html>

View File

@ -114,7 +114,7 @@ CREATE VIEW reorg.tables AS
reorg.get_create_trigger(R.oid, PK.indexrelid) AS create_trigger, reorg.get_create_trigger(R.oid, PK.indexrelid) AS create_trigger,
'CREATE TABLE reorg.table_' || R.oid || ' WITH (' || array_to_string(array_append(R.reloptions, 'oids=' || CASE WHEN R.relhasoids THEN 'true' ELSE 'false' END), ',') || ') TABLESPACE ' || coalesce(quote_ident(S.spcname), 'pg_default') || ' AS SELECT * FROM ONLY ' || reorg.oid2text(R.oid) AS create_table, 'CREATE TABLE reorg.table_' || R.oid || ' WITH (' || array_to_string(array_append(R.reloptions, 'oids=' || CASE WHEN R.relhasoids THEN 'true' ELSE 'false' END), ',') || ') TABLESPACE ' || coalesce(quote_ident(S.spcname), 'pg_default') || ' AS SELECT * FROM ONLY ' || reorg.oid2text(R.oid) AS create_table,
'DELETE FROM reorg.log_' || R.oid AS delete_log, 'DELETE FROM reorg.log_' || R.oid AS delete_log,
'LOCK TABLE ' || reorg.oid2text(R.oid) || ' IN ACCESS EXCLUSIVE MODE' AS lock_table, 'LOCK TABLE ' || reorg.oid2text(R.oid) || ' IN ACCESS EXCLUSIVE MODE NOWAIT' AS lock_table,
reorg.get_index_keys(CK.indexrelid, R.oid) AS ckey, reorg.get_index_keys(CK.indexrelid, R.oid) AS ckey,
'SELECT * FROM reorg.log_' || R.oid || ' ORDER BY id LIMIT $1' AS sql_peek, 'SELECT * FROM reorg.log_' || R.oid || ' ORDER BY id LIMIT $1' AS sql_peek,
'INSERT INTO reorg.table_' || R.oid || ' VALUES ($1.*)' AS sql_insert, 'INSERT INTO reorg.table_' || R.oid || ' VALUES ($1.*)' AS sql_insert,