Skip to content

Commit c0ad595

Browse files
committed
I attach a little patch to make CLUSTER set and reset the indisclustered
bit on the indexes. I also attach clusterdb and clusterdb.sgml; both of them are blatant rips of vacuumdb and vacuumdb.sgml, but get the job done. Please review them, as I'm probably making a lot of mistakes with SGML and I can't compile it here. vacuumdb itself is not very comfortable to use when the databases have passwords, because it has to connect once for each table (I can probably make it connect only once for each database; should I?). Because of this I added a mention of PGPASSWORDFILE in the documentation, but I don't know if that is the correct place for that. Alvaro Herrera
1 parent b7e2724 commit c0ad595

File tree

8 files changed

+509
-8
lines changed

8 files changed

+509
-8
lines changed

doc/src/sgml/ref/allfiles.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.46 2002/08/17 03:38:43 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.47 2002/08/27 03:38:27 momjian Exp $
33
PostgreSQL documentation
44
Complete list of usable sgml source files in this directory.
55
-->
@@ -120,6 +120,7 @@ Complete list of usable sgml source files in this directory.
120120
<!entity vacuum system "vacuum.sgml">
121121

122122
<!-- applications and utilities -->
123+
<!entity clusterdb system "clusterdb.sgml">
123124
<!entity createdb system "createdb.sgml">
124125
<!entity createlang system "createlang.sgml">
125126
<!entity createuser system "createuser.sgml">

doc/src/sgml/ref/clusterdb.sgml

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
<!--
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/clusterdb.sgml,v 1.1 2002/08/27 03:38:27 momjian Exp $
3+
PostgreSQL documentation
4+
-->
5+
6+
<refentry id="APP-CLUSTERDB">
7+
<refmeta>
8+
<refentrytitle id="APP-CLUSTERDB-TITLE"><application>clusterdb</application></refentrytitle>
9+
<manvolnum>1</manvolnum>
10+
<refmiscinfo>Application</refmiscinfo>
11+
</refmeta>
12+
13+
<refnamediv>
14+
<refname id="clusterdb">clusterdb</refname>
15+
<refpurpose>cluster a <productname>PostgreSQL</productname> database</refpurpose>
16+
</refnamediv>
17+
18+
<refsynopsisdiv>
19+
<cmdsynopsis>
20+
<command>clusterdb</command>
21+
<arg rep="repeat"><replaceable>connection-options</replaceable></arg>
22+
<arg>--table | -t '<replaceable>table</replaceable> </arg>
23+
<arg><replaceable>dbname</replaceable></arg>
24+
<sbr>
25+
<command>clusterdb</command>
26+
<arg rep="repeat"><replaceable>connection-options</replaceable></arg>
27+
<group><arg>--all</arg><arg>-a</arg></group>
28+
</cmdsynopsis>
29+
</refsynopsisdiv>
30+
31+
32+
<refsect1>
33+
<title>Description</title>
34+
35+
<para>
36+
<application>clusterdb</application> is a utility for clustering tables inside a
37+
<productname>PostgreSQL</productname> database.
38+
</para>
39+
40+
<para>
41+
<application>clusterdb</application> is a shell script wrapper around the
42+
backend command
43+
<xref linkend="SQL-CLUSTER" endterm="SQL-CLUSTER-title"> via
44+
the <productname>PostgreSQL</productname> interactive terminal
45+
<xref linkend="APP-PSQL">. There is no effective
46+
difference between clustering databases via this or other methods.
47+
<application>psql</application> must be found by the script and
48+
a database server must be running at the targeted host. Also, any default
49+
settings and environment variables available to <application>psql</application>
50+
and the <application>libpq</application> front-end library do apply.
51+
</para>
52+
53+
<para>
54+
<application>clusterdb</application> will need to connect several times to the
55+
<productname>PostgreSQL</productname> server, asking for the password each
56+
time. It will probably be very convenient to have a PGPASSWORDFILE in that case.
57+
</para>
58+
59+
</refsect1>
60+
61+
62+
<refsect1>
63+
<title>Options</title>
64+
65+
<para>
66+
<application>clusterdb</application> accepts the following command line arguments:
67+
68+
<variablelist>
69+
<varlistentry>
70+
<term>-d <replaceable class="parameter">dbname</replaceable></term>
71+
<term>--dbname <replaceable class="parameter">dbname</replaceable></term>
72+
<listitem>
73+
<para>
74+
Specifies the name of the database to be clustered.
75+
If this is not specified and <option>-a</option> (or
76+
<option>--all</option>) is not used, the database name is read
77+
from the environment variable <envar>PGDATABASE</envar>. If
78+
that is not set, the user name specified for the connection is
79+
used.
80+
</para>
81+
</listitem>
82+
</varlistentry>
83+
84+
<varlistentry>
85+
<term>-a</term>
86+
<term>--all</term>
87+
<listitem>
88+
<para>
89+
Cluster all databases.
90+
</para>
91+
</listitem>
92+
</varlistentry>
93+
94+
<varlistentry>
95+
<term>-t <replaceable class="parameter">table</replaceable></term>
96+
<term>--table <replaceable class="parameter">table</replaceable></term>
97+
<listitem>
98+
<para>
99+
Clusters <replaceable class="parameter">table</replaceable> only.
100+
</para>
101+
</listitem>
102+
</varlistentry>
103+
104+
</variablelist>
105+
</para>
106+
107+
<para>
108+
<application>clusterdb</application> also accepts
109+
the following command line arguments for connection parameters:
110+
111+
<variablelist>
112+
<varlistentry>
113+
<term>-h <replaceable class="parameter">host</replaceable></term>
114+
<term>--host <replaceable class="parameter">host</replaceable></term>
115+
<listitem>
116+
<para>
117+
Specifies the host name of the machine on which the
118+
server
119+
is running. If host begins with a slash, it is used
120+
as the directory for the Unix domain socket.
121+
</para>
122+
</listitem>
123+
</varlistentry>
124+
125+
<varlistentry>
126+
<term>-p <replaceable class="parameter">port</replaceable></term>
127+
<term>--port <replaceable class="parameter">port</replaceable></term>
128+
<listitem>
129+
<para>
130+
Specifies the Internet TCP/IP port or local Unix domain socket file
131+
extension on which the server
132+
is listening for connections.
133+
</para>
134+
</listitem>
135+
</varlistentry>
136+
137+
<varlistentry>
138+
<term>-U <replaceable class="parameter">username</replaceable></term>
139+
<term>--username <replaceable class="parameter">username</replaceable></term>
140+
<listitem>
141+
<para>
142+
User name to connect as
143+
</para>
144+
</listitem>
145+
</varlistentry>
146+
147+
<varlistentry>
148+
<term>-W</term>
149+
<term>--password</term>
150+
<listitem>
151+
<para>
152+
Force password prompt.
153+
</para>
154+
</listitem>
155+
</varlistentry>
156+
157+
<varlistentry>
158+
<term>-e</term>
159+
<term>--echo</term>
160+
<listitem>
161+
<para>
162+
Echo the commands that <application>clusterdb</application> generates
163+
and sends to the server.
164+
</para>
165+
</listitem>
166+
</varlistentry>
167+
168+
<varlistentry>
169+
<term>-q</term>
170+
<term>--quiet</term>
171+
<listitem>
172+
<para>
173+
Do not display a response.
174+
</para>
175+
</listitem>
176+
</varlistentry>
177+
</variablelist>
178+
</para>
179+
</refsect1>
180+
181+
182+
<refsect1>
183+
<title>Diagnostics</title>
184+
185+
<para>
186+
<variablelist>
187+
<varlistentry>
188+
<term><computeroutput>CLUSTER</computeroutput></term>
189+
<listitem>
190+
<para>
191+
Everything went well.
192+
</para>
193+
</listitem>
194+
</varlistentry>
195+
196+
<varlistentry>
197+
<term><computeroutput>clusterdb: Cluster failed.</computeroutput></term>
198+
<listitem>
199+
<para>
200+
Something went wrong. <application>clusterdb</application> is only a wrapper
201+
script. See <xref linkend="SQL-CLUSTER" endterm="SQL-CLUSTER-title">
202+
and <xref linkend="APP-PSQL"> for a detailed
203+
discussion of error messages and potential problems. Note that this message
204+
may appear once per table to be clustered.
205+
</para>
206+
</listitem>
207+
</varlistentry>
208+
209+
</variablelist>
210+
</para>
211+
</refsect1>
212+
213+
214+
<refsect1>
215+
<title>Environment</title>
216+
217+
<variablelist>
218+
<varlistentry>
219+
<term><envar>PGDATABASE</envar></term>
220+
<term><envar>PGHOST</envar></term>
221+
<term><envar>PGPORT</envar></term>
222+
<term><envar>PGUSER</envar></term>
223+
224+
<listitem>
225+
<para>
226+
Default connection parameters.
227+
</para>
228+
</listitem>
229+
</varlistentry>
230+
</variablelist>
231+
</refsect1>
232+
233+
234+
<refsect1>
235+
<title>Examples</title>
236+
237+
<para>
238+
To cluster the database <literal>test</literal>:
239+
<screen>
240+
<prompt>$ </prompt><userinput>clusterdb test</userinput>
241+
</screen>
242+
</para>
243+
244+
<para>
245+
To cluster a single table
246+
<literal>foo</literal> in a database named
247+
<literal>xyzzy</literal>:
248+
<screen>
249+
<prompt>$ </prompt><userinput>clusterdb --verbose --table foo xyzzy</userinput>
250+
</screen>
251+
</para>
252+
253+
</refsect1>
254+
255+
<refsect1>
256+
<title>See Also</title>
257+
258+
<simplelist type="inline">
259+
<member><xref linkend="sql-cluster" endterm="sql-cluster-title"></member>
260+
</simplelist>
261+
</refsect1>
262+
263+
</refentry>
264+
265+
<!-- Keep this comment at the end of the file
266+
Local variables:
267+
mode: sgml
268+
sgml-omittag:nil
269+
sgml-shorttag:t
270+
sgml-minimize-attributes:nil
271+
sgml-always-quote-attributes:t
272+
sgml-indent-step:1
273+
sgml-indent-data:t
274+
sgml-parent-document:nil
275+
sgml-default-dtd-file:"../reference.ced"
276+
sgml-exposed-tags:nil
277+
sgml-local-catalogs:"/usr/lib/sgml/catalog"
278+
sgml-local-ecat-files:nil
279+
End:
280+
-->

doc/src/sgml/reference.sgml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!-- reference.sgml
2-
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.35 2002/08/17 03:38:43 tgl Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/reference.sgml,v 1.36 2002/08/27 03:38:27 momjian Exp $
33

44
PostgreSQL Reference Manual
55
-->
@@ -165,6 +165,7 @@ Disable this chapter until we have more functions documented.
165165
</para>
166166
</partintro>
167167

168+
&clusterdb;
168169
&createdb;
169170
&createlang;
170171
&createuser;

src/backend/commands/cluster.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.86 2002/08/11 21:17:34 tgl Exp $
14+
* $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.87 2002/08/27 03:38:27 momjian Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -45,11 +45,12 @@ typedef struct
4545
IndexInfo *indexInfo;
4646
Oid accessMethodOID;
4747
Oid *classOID;
48+
bool isclustered;
4849
} IndexAttrs;
4950

5051
static Oid make_new_heap(Oid OIDOldHeap, const char *NewName);
5152
static void copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex);
52-
static List *get_indexattr_list(Relation OldHeap);
53+
static List *get_indexattr_list(Relation OldHeap, Oid OldIndex);
5354
static void recreate_indexattr(Oid OIDOldHeap, List *indexes);
5455
static void swap_relfilenodes(Oid r1, Oid r2);
5556

@@ -121,7 +122,7 @@ cluster(RangeVar *oldrelation, char *oldindexname)
121122
RelationGetRelationName(OldHeap));
122123

123124
/* Save the information of all indexes on the relation. */
124-
indexes = get_indexattr_list(OldHeap);
125+
indexes = get_indexattr_list(OldHeap, OIDOldIndex);
125126

126127
/* Drop relcache refcnts, but do NOT give up the locks */
127128
index_close(OldIndex);
@@ -274,7 +275,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex)
274275
* return a list of IndexAttrs structures.
275276
*/
276277
static List *
277-
get_indexattr_list(Relation OldHeap)
278+
get_indexattr_list(Relation OldHeap, Oid OldIndex)
278279
{
279280
List *indexes = NIL;
280281
List *indlist;
@@ -305,6 +306,12 @@ get_indexattr_list(Relation OldHeap)
305306
memcpy(attrs->classOID, indexForm->indclass,
306307
sizeof(Oid) * attrs->indexInfo->ii_NumIndexAttrs);
307308

309+
/* We'll set indisclustered at index creation time on the
310+
* index we are currently clustering, and reset it on other
311+
* indexes.
312+
*/
313+
attrs->isclustered = (OldIndex == indexOID ? true : false);
314+
308315
/* Name and access method of each index come from pg_class */
309316
classTuple = SearchSysCache(RELOID,
310317
ObjectIdGetDatum(indexOID),
@@ -343,6 +350,9 @@ recreate_indexattr(Oid OIDOldHeap, List *indexes)
343350
Oid newIndexOID;
344351
char newIndexName[NAMEDATALEN];
345352
ObjectAddress object;
353+
Form_pg_index index;
354+
HeapTuple tuple;
355+
Relation pg_index;
346356

347357
/* Create the new index under a temporary name */
348358
snprintf(newIndexName, NAMEDATALEN, "pg_temp_%u", attrs->indexOID);
@@ -364,6 +374,20 @@ recreate_indexattr(Oid OIDOldHeap, List *indexes)
364374

365375
CommandCounterIncrement();
366376

377+
/* Set indisclustered to the correct value. Only one index is
378+
* allowed to be clustered.
379+
*/
380+
pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
381+
tuple = SearchSysCacheCopy(INDEXRELID,
382+
ObjectIdGetDatum(attrs->indexOID),
383+
0, 0, 0);
384+
index = (Form_pg_index) GETSTRUCT(tuple);
385+
index->indisclustered = attrs->isclustered;
386+
simple_heap_update(pg_index, &tuple->t_self, tuple);
387+
CatalogUpdateIndexes(pg_index, tuple);
388+
heap_freetuple(tuple);
389+
heap_close(pg_index, NoLock);
390+
367391
/* Destroy new index with old filenode */
368392
object.classId = RelOid_pg_class;
369393
object.objectId = newIndexOID;

0 commit comments

Comments
 (0)