diff --git a/doc/src/sgml/maintenance.sgml b/doc/src/sgml/maintenance.sgml index d68cd817c31e1f28569e112896b56883ee80b460..b9ce518554b78e0b339c4acbfbdf7c47228b6e65 100644 --- a/doc/src/sgml/maintenance.sgml +++ b/doc/src/sgml/maintenance.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.44 2005/06/13 02:40:04 neilc Exp $ +$PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.45 2005/06/22 21:14:28 tgl Exp $ --> <chapter id="maintenance"> @@ -468,8 +468,7 @@ HINT: Stop the postmaster and use a standalone backend to VACUUM in "mydb". <para> In some situations it is worthwhile to rebuild indexes periodically - with the <command>REINDEX</> command. (There is also - <filename>contrib/reindexdb</> which can reindex an entire database.) + with the <command>REINDEX</> command. However, <productname>PostgreSQL</> 7.4 has substantially reduced the need for this activity compared to earlier releases. </para> diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index 9579b95e237eac1eb5afbacf31db249e4947177e..4bb6b9ff75630eefe2f830e0712d362f57ac7fb8 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -1,5 +1,5 @@ <!-- -$PostgreSQL: pgsql/doc/src/sgml/ref/reindex.sgml,v 1.26 2005/01/22 23:22:19 momjian Exp $ +$PostgreSQL: pgsql/doc/src/sgml/ref/reindex.sgml,v 1.27 2005/06/22 21:14:28 tgl Exp $ PostgreSQL documentation --> @@ -20,7 +20,7 @@ PostgreSQL documentation <refsynopsisdiv> <synopsis> -REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replaceable> [ FORCE ] +REINDEX { INDEX | TABLE | DATABASE | SYSTEM } <replaceable class="PARAMETER">name</replaceable> [ FORCE ] </synopsis> </refsynopsisdiv> @@ -28,7 +28,7 @@ REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replac <title>Description</title> <para> - <command>REINDEX</command> rebuilds an index based on the data + <command>REINDEX</command> rebuilds an index using the data stored in the index's table, replacing the old copy of the index. There are two main reasons to use <command>REINDEX</command>: @@ -63,12 +63,10 @@ REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replac <variablelist> <varlistentry> - <term><literal>DATABASE</literal></term> + <term><literal>INDEX</literal></term> <listitem> <para> - Recreate all system indexes of a specified database. Indexes on - user tables are not processed. Also, indexes on shared system - catalogs are skipped except in stand-alone mode (see below). + Recreate the specified index. </para> </listitem> </varlistentry> @@ -77,17 +75,30 @@ REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replac <term><literal>TABLE</literal></term> <listitem> <para> - Recreate all indexes of a specified table. If the table has a + Recreate all indexes of the specified table. If the table has a secondary <quote>TOAST</> table, that is reindexed as well. </para> </listitem> </varlistentry> <varlistentry> - <term><literal>INDEX</literal></term> + <term><literal>DATABASE</literal></term> <listitem> <para> - Recreate a specified index. + Recreate all indexes within the current database. + Indexes on shared system catalogs are skipped except in stand-alone mode + (see below). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>SYSTEM</literal></term> + <listitem> + <para> + Recreate all indexes on system catalogs within the current database. + Indexes on user tables are not processed. Also, indexes on shared + system catalogs are skipped except in stand-alone mode (see below). </para> </listitem> </varlistentry> @@ -96,10 +107,11 @@ REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replac <term><replaceable class="PARAMETER">name</replaceable></term> <listitem> <para> - The name of the specific database, table, or index to be - reindexed. Table and index names may be schema-qualified. - Presently, <command>REINDEX DATABASE</> can only reindex the current - database, so its parameter must match the current database's name. + The name of the specific index, table, or database to be + reindexed. Index and table names may be schema-qualified. + Presently, <command>REINDEX DATABASE</> and <command>REINDEX SYSTEM</> + can only reindex the current database, so their parameter must match + the current database's name. </para> </listitem> </varlistentry> @@ -139,10 +151,10 @@ REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replac One way to do this is to shut down the postmaster and start a stand-alone <productname>PostgreSQL</productname> server with the <option>-P</option> option included on its command line. - Then, <command>REINDEX DATABASE</>, + Then, <command>REINDEX DATABASE</>, <command>REINDEX SYSTEM</>, <command>REINDEX TABLE</>, or <command>REINDEX INDEX</> can be issued, depending on how much you want to reconstruct. If in - doubt, use <command>REINDEX DATABASE</> to select + doubt, use <command>REINDEX SYSTEM</> to select reconstruction of all system indexes in the database. Then quit the standalone server session and restart the regular server. See the <xref linkend="app-postgres"> reference page for more @@ -199,6 +211,21 @@ REINDEX { DATABASE | TABLE | INDEX } <replaceable class="PARAMETER">name</replac <command>REINDEX</> does not. </para> + <para> + Reindexing a single index or table requires being the owner of that + index or table. Reindexing a database requires being the owner of + the database (note that the owner can therefore rebuild indexes of + tables owned by other users). Of course, superusers can always + reindex anything. + </para> + + <para> + Prior to <productname>PostgreSQL</productname> 8.1, <command>REINDEX + DATABASE</> processed only system indexes, not all indexes as one would + expect from the name. This has been changed to reduce the surprise + factor. The old behavior is available as <command>REINDEX SYSTEM</>. + </para> + <para> Prior to <productname>PostgreSQL</productname> 7.4, <command>REINDEX TABLE</> did not automatically process TOAST tables, and so those had @@ -227,8 +254,8 @@ REINDEX INDEX my_index; </para> <para> - Rebuild all system indexes in a particular database, without trusting them - to be valid already: + Rebuild all indexes in a particular database, without trusting the + system indexes to be valid already: <programlisting> $ <userinput>export PGOPTIONS="-P"</userinput> diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 07adceb022852c9862ac314784b2a40e8d0f81a9..6bfa8a04e249c6a2f1b2671519fefb31e24b5426 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.132 2005/06/21 00:35:05 neilc Exp $ + * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.133 2005/06/22 21:14:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -898,10 +898,10 @@ RemoveIndex(RangeVar *relation, DropBehavior behavior) /* * ReindexIndex - * Recreate an index. + * Recreate a specific index. */ void -ReindexIndex(RangeVar *indexRelation, bool force /* currently unused */ ) +ReindexIndex(RangeVar *indexRelation) { Oid indOid; HeapTuple tuple; @@ -931,10 +931,10 @@ ReindexIndex(RangeVar *indexRelation, bool force /* currently unused */ ) /* * ReindexTable - * Recreate indexes of a table. + * Recreate all indexes of a table (and of its toast table, if any) */ void -ReindexTable(RangeVar *relation, bool force /* currently unused */ ) +ReindexTable(RangeVar *relation) { Oid heapOid; HeapTuple tuple; @@ -981,8 +981,7 @@ ReindexTable(RangeVar *relation, bool force /* currently unused */ ) * separate transaction, so we can release the lock on it right away. */ void -ReindexDatabase(const char *dbname, bool force /* currently unused */ , - bool all) +ReindexDatabase(const char *databaseName, bool do_system, bool do_user) { Relation relationRelation; HeapScanDesc scan; @@ -992,23 +991,23 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */ , List *relids = NIL; ListCell *l; - AssertArg(dbname); + AssertArg(databaseName); - if (strcmp(dbname, get_database_name(MyDatabaseId)) != 0) + if (strcmp(databaseName, get_database_name(MyDatabaseId)) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("can only reindex the currently open database"))); if (!pg_database_ownercheck(MyDatabaseId, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_DATABASE, - dbname); + databaseName); /* * We cannot run inside a user transaction block; if we were inside a * transaction, then our commit- and start-transaction-command calls * would not have the intended effect! */ - PreventTransactionChain((void *) dbname, "REINDEX DATABASE"); + PreventTransactionChain((void *) databaseName, "REINDEX DATABASE"); /* * Create a memory context that will survive forced transaction @@ -1028,9 +1027,12 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */ , * before we process any other tables. This is critical because * reindexing itself will try to update pg_class. */ - old = MemoryContextSwitchTo(private_context); - relids = lappend_oid(relids, RelationRelationId); - MemoryContextSwitchTo(old); + if (do_system) + { + old = MemoryContextSwitchTo(private_context); + relids = lappend_oid(relids, RelationRelationId); + MemoryContextSwitchTo(old); + } /* * Scan pg_class to build a list of the relations we need to reindex. @@ -1047,9 +1049,15 @@ ReindexDatabase(const char *dbname, bool force /* currently unused */ , if (classtuple->relkind != RELKIND_RELATION) continue; - if (!all) /* only system tables? */ + /* Check user/system classification, and optionally skip */ + if (IsSystemClass(classtuple)) + { + if (!do_system) + continue; + } + else { - if (!IsSystemClass(classtuple)) + if (!do_user) continue; } diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 2e0d8dbc1a2124790932ee886610182c81bc479b..2ce9edac7079498b8653879a84c44fe14704387f 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.307 2005/06/17 22:32:43 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.308 2005/06/22 21:14:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2467,8 +2467,8 @@ _copyReindexStmt(ReindexStmt *from) COPY_SCALAR_FIELD(kind); COPY_NODE_FIELD(relation); COPY_STRING_FIELD(name); - COPY_SCALAR_FIELD(force); - COPY_SCALAR_FIELD(all); + COPY_SCALAR_FIELD(do_system); + COPY_SCALAR_FIELD(do_user); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index a991cf5eed3b98fdebe5360ef530f32e5d44a5b0..e66ac81b7550bd1a42811ab7b05f413c77e9c905 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -18,7 +18,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.244 2005/06/17 22:32:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.245 2005/06/22 21:14:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1372,8 +1372,8 @@ _equalReindexStmt(ReindexStmt *a, ReindexStmt *b) COMPARE_SCALAR_FIELD(kind); COMPARE_NODE_FIELD(relation); COMPARE_STRING_FIELD(name); - COMPARE_SCALAR_FIELD(force); - COMPARE_SCALAR_FIELD(all); + COMPARE_SCALAR_FIELD(do_system); + COMPARE_SCALAR_FIELD(do_user); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index d12fa9fa0527c3df0e8b707232a6d0dff8f6837c..2603a652922a9f2208f47536c792ab84adb7987f 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.495 2005/06/17 22:32:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.496 2005/06/22 21:14:29 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -400,7 +400,7 @@ static void doNegateFloat(Value *v); SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SYMMETRIC - SYSID + SYSID SYSTEM_P TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP TO TOAST TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P @@ -3641,8 +3641,9 @@ DropCastStmt: DROP CAST '(' Typename AS Typename ')' opt_drop_behavior * * QUERY: * - * REINDEX type <typename> [FORCE] [ALL] + * REINDEX type <name> [FORCE] * + * FORCE no longer does anything, but we accept it for backwards compatibility *****************************************************************************/ ReindexStmt: @@ -3652,7 +3653,16 @@ ReindexStmt: n->kind = $2; n->relation = $3; n->name = NULL; - n->force = $4; + $$ = (Node *)n; + } + | REINDEX SYSTEM_P name opt_force + { + ReindexStmt *n = makeNode(ReindexStmt); + n->kind = OBJECT_DATABASE; + n->name = $3; + n->relation = NULL; + n->do_system = true; + n->do_user = false; $$ = (Node *)n; } | REINDEX DATABASE name opt_force @@ -3661,7 +3671,8 @@ ReindexStmt: n->kind = OBJECT_DATABASE; n->name = $3; n->relation = NULL; - n->force = $4; + n->do_system = true; + n->do_user = true; $$ = (Node *)n; } ; @@ -7915,6 +7926,7 @@ unreserved_keyword: | STDOUT | STORAGE | SYSID + | SYSTEM_P | STRICT_P | TABLESPACE | TEMP diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c index 1e0c63a9ce2830b7c219e7f930c2b8b586f74125..009cc2e7ba6df1dd67e16bf165d9cfee85b843e2 100644 --- a/src/backend/parser/keywords.c +++ b/src/backend/parser/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.157 2005/06/17 22:32:44 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.158 2005/06/22 21:14:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -300,6 +300,7 @@ static const ScanKeyword ScanKeywords[] = { {"substring", SUBSTRING}, {"symmetric", SYMMETRIC}, {"sysid", SYSID}, + {"system", SYSTEM_P}, {"table", TABLE}, {"tablespace", TABLESPACE}, {"temp", TEMP}, diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index f948b0f854ed0c9b73c341ca81ed32c8b4a7d496..82bd8eafc1185ba8b91f0b58483379bdb0bc341f 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.237 2005/06/17 22:32:46 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.238 2005/06/22 21:14:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1011,13 +1011,14 @@ ProcessUtility(Node *parsetree, switch (stmt->kind) { case OBJECT_INDEX: - ReindexIndex(stmt->relation, stmt->force); + ReindexIndex(stmt->relation); break; case OBJECT_TABLE: - ReindexTable(stmt->relation, stmt->force); + ReindexTable(stmt->relation); break; case OBJECT_DATABASE: - ReindexDatabase(stmt->name, stmt->force, false); + ReindexDatabase(stmt->name, + stmt->do_system, stmt->do_user); break; default: elog(ERROR, "unrecognized object type: %d", diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index fed2275f46919ad44565a0f4b5ed6cbc77bc6794..741eb45f851e0e480693a0ce3d0f08f0e31324c9 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.103 2005/06/17 22:32:47 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.104 2005/06/22 21:14:30 tgl Exp $ */ #include "postgres_fe.h" #include "common.h" @@ -1246,9 +1246,9 @@ command_no_begin(const char *query) return true; /* - * Note: these tests will match REINDEX TABLESPACE, which isn't really - * a valid command so we don't care much. The other five possible - * matches are correct. + * Note: these tests will match CREATE SYSTEM, DROP SYSTEM, and + * REINDEX TABLESPACE, which aren't really valid commands so we don't + * care much. The other six possible matches are correct. */ if ((wordlen == 6 && pg_strncasecmp(query, "create", 6) == 0) || (wordlen == 4 && pg_strncasecmp(query, "drop", 4) == 0) || @@ -1264,6 +1264,8 @@ command_no_begin(const char *query) if (wordlen == 8 && pg_strncasecmp(query, "database", 8) == 0) return true; + if (wordlen == 6 && pg_strncasecmp(query, "system", 6) == 0) + return true; if (wordlen == 10 && pg_strncasecmp(query, "tablespace", 10) == 0) return true; } diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 4700cc79bda1d200092f47632f8deb899d61056e..648ccadd4f68b2addf833ebf8d980723b88c933b 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -3,7 +3,7 @@ * * Copyright (c) 2000-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.132 2005/06/21 00:48:33 neilc Exp $ + * $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.133 2005/06/22 21:14:30 tgl Exp $ */ /*---------------------------------------------------------------------- @@ -1456,7 +1456,7 @@ psql_completion(char *text, int start, int end) else if (pg_strcasecmp(prev_wd, "REINDEX") == 0) { static const char *const list_REINDEX[] = - {"TABLE", "DATABASE", "INDEX", NULL}; + {"TABLE", "INDEX", "SYSTEM", "DATABASE", NULL}; COMPLETE_WITH_LIST(list_REINDEX); } @@ -1464,10 +1464,11 @@ psql_completion(char *text, int start, int end) { if (pg_strcasecmp(prev_wd, "TABLE") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tables, NULL); - else if (pg_strcasecmp(prev_wd, "DATABASE") == 0) - COMPLETE_WITH_QUERY(Query_for_list_of_databases); else if (pg_strcasecmp(prev_wd, "INDEX") == 0) COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_indexes, NULL); + else if (pg_strcasecmp(prev_wd, "SYSTEM") == 0 || + pg_strcasecmp(prev_wd, "DATABASE") == 0) + COMPLETE_WITH_QUERY(Query_for_list_of_databases); } /* SELECT */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 359c5af700c1bab15d904c5f3d40d2e7650f5838..1ae5649c137c5606d4b0735621985a5daf87129b 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.64 2005/04/14 01:38:21 tgl Exp $ + * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.65 2005/06/22 21:14:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -34,9 +34,10 @@ extern void DefineIndex(RangeVar *heapRelation, bool skip_build, bool quiet); extern void RemoveIndex(RangeVar *relation, DropBehavior behavior); -extern void ReindexIndex(RangeVar *indexRelation, bool force); -extern void ReindexTable(RangeVar *relation, bool force); -extern void ReindexDatabase(const char *databaseName, bool force, bool all); +extern void ReindexIndex(RangeVar *indexRelation); +extern void ReindexTable(RangeVar *relation); +extern void ReindexDatabase(const char *databaseName, + bool do_system, bool do_user); extern char *makeObjectName(const char *name1, const char *name2, const char *label); extern char *ChooseRelationName(const char *name1, const char *name2, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 993a240faa1b0f9ceaa36417c30697e062928d41..e011bb9f97855435cb4ffd1e719571644db70219 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.282 2005/06/17 22:32:49 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.283 2005/06/22 21:14:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1758,8 +1758,8 @@ typedef struct ReindexStmt * OBJECT_DATABASE */ RangeVar *relation; /* Table or index to reindex */ const char *name; /* name of database to reindex */ - bool force; - bool all; + bool do_system; /* include system tables in database case */ + bool do_user; /* include user tables in database case */ } ReindexStmt; /* ----------------------