diff --git a/doc/src/sgml/ref/reindex.sgml b/doc/src/sgml/ref/reindex.sgml index 336ca24b31..143847dfa9 100644 --- a/doc/src/sgml/ref/reindex.sgml +++ b/doc/src/sgml/ref/reindex.sgml @@ -21,7 +21,8 @@ PostgreSQL documentation -REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] name +REINDEX [ ( option [, ...] ) ] { INDEX | TABLE | SCHEMA } [ CONCURRENTLY ] name +REINDEX [ ( option [, ...] ) ] { DATABASE | SYSTEM } [ CONCURRENTLY ] [ name ] where option can be one of: @@ -126,8 +127,9 @@ REINDEX [ ( option [, ...] ) ] { IN DATABASE - Recreate all indexes within the current database. - Indexes on shared system catalogs are also processed. + Recreate all indexes within the current database, except system + catalogs. + Indexes on shared system catalogs are not processed. This form of REINDEX cannot be executed inside a transaction block. @@ -155,7 +157,7 @@ REINDEX [ ( option [, ...] ) ] { IN reindexed. Index and table names can be schema-qualified. Presently, REINDEX DATABASE and REINDEX SYSTEM can only reindex the current database, so their parameter must match - the current database's name. + the current database's name, if supplied, though supplying the name is optional. diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 99f5ab83c3..df10262f73 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -2877,10 +2877,13 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, bool concurrent_warning = false; bool tablespace_warning = false; - AssertArg(objectName); Assert(objectKind == REINDEX_OBJECT_SCHEMA || objectKind == REINDEX_OBJECT_SYSTEM || objectKind == REINDEX_OBJECT_DATABASE); + /* + * This matches the options enforced by the grammar. + */ + AssertArg(objectName || objectKind != REINDEX_OBJECT_SCHEMA); if (objectKind == REINDEX_OBJECT_SYSTEM && (params->options & REINDEXOPT_CONCURRENTLY) != 0) @@ -2906,13 +2909,13 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, { objectOid = MyDatabaseId; - if (strcmp(objectName, get_database_name(objectOid)) != 0) + if (objectName && strcmp(objectName, get_database_name(objectOid)) != 0) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("can only reindex the currently open database"))); if (!pg_database_ownercheck(objectOid, GetUserId())) aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE, - objectName); + get_database_name(objectOid)); } /* @@ -2970,10 +2973,24 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, !isTempNamespace(classtuple->relnamespace)) continue; - /* Check user/system classification, and optionally skip */ - if (objectKind == REINDEX_OBJECT_SYSTEM && - !IsSystemClass(relid, classtuple)) - continue; + /* + * Check user/system classification, and skip appropriately. + */ + if (objectKind == REINDEX_OBJECT_SYSTEM) + { + if (!IsSystemClass(relid, classtuple)) + continue; + } + else if (objectKind == REINDEX_OBJECT_DATABASE) + { + /* + * You might think it would be good to include catalogs, + * but doing that can deadlock, so isn't much use in real world, + * nor can we safely test that it even works. + */ + if (IsSystemClass(relid, classtuple)) + continue; + } /* * The table can be reindexed if the user is superuser, the table diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 969c9c158f..25a5192595 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -560,7 +560,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query); %type generic_option_elem alter_generic_option_elem %type generic_option_list alter_generic_option_list -%type reindex_target_type reindex_target_multitable +%type reindex_target_type reindex_target_multitable reindex_name_optional %type copy_generic_opt_arg copy_generic_opt_arg_list_item %type copy_generic_opt_elem @@ -9105,6 +9105,24 @@ ReindexStmt: makeDefElem("concurrently", NULL, @3)); $$ = (Node *) n; } + | REINDEX reindex_name_optional + { + ReindexStmt *n = makeNode(ReindexStmt); + n->kind = $2; + n->name = NULL; + n->relation = NULL; + n->params = NIL; + $$ = (Node *)n; + } + | REINDEX '(' utility_option_list ')' reindex_name_optional + { + ReindexStmt *n = makeNode(ReindexStmt); + n->kind = $5; + n->name = NULL; + n->relation = NULL; + n->params = $3; + $$ = (Node *)n; + } | REINDEX '(' utility_option_list ')' reindex_target_type opt_concurrently qualified_name { ReindexStmt *n = makeNode(ReindexStmt); @@ -9141,6 +9159,11 @@ reindex_target_multitable: | SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } ; +/* For these options the name is optional */ +reindex_name_optional: + SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; } + | DATABASE { $$ = REINDEX_OBJECT_DATABASE; } + ; /***************************************************************************** * diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c index f3b03ec325..0e93a4eeff 100644 --- a/src/bin/scripts/reindexdb.c +++ b/src/bin/scripts/reindexdb.c @@ -360,18 +360,6 @@ reindex_one_database(ConnParams *cparams, ReindexType type, { case REINDEX_DATABASE: - /* - * Database-wide parallel reindex requires special processing. - * If multiple jobs were asked, we have to reindex system - * catalogs first as they cannot be processed in parallel. - */ - if (concurrently) - pg_log_warning("cannot reindex system catalogs concurrently, skipping all"); - else - run_reindex_command(conn, REINDEX_SYSTEM, PQdb(conn), echo, - verbose, concurrently, false, - tablespace); - /* Build a list of relations from the database */ process_list = get_parallel_object_list(conn, process_type, user_list, echo); diff --git a/src/bin/scripts/t/090_reindexdb.pl b/src/bin/scripts/t/090_reindexdb.pl index 398fc4e6bb..fd422b3d3d 100644 --- a/src/bin/scripts/t/090_reindexdb.pl +++ b/src/bin/scripts/t/090_reindexdb.pl @@ -176,11 +176,6 @@ $node->command_fails( $node->command_fails( [ 'reindexdb', '-j', '2', '-i', 'i1', 'postgres' ], 'parallel reindexdb cannot process indexes'); -$node->issues_sql_like( - [ 'reindexdb', '-j', '2', 'postgres' ], - qr/statement:\ REINDEX SYSTEM postgres; -.*statement:\ REINDEX TABLE public\.test1/s, - 'parallel reindexdb for database issues REINDEX SYSTEM first'); # Note that the ordering of the commands is not stable, so the second # command for s2.t2 is not checked after. $node->issues_sql_like( @@ -190,13 +185,8 @@ $node->issues_sql_like( $node->command_ok( [ 'reindexdb', '-j', '2', '-S', 's3' ], 'parallel reindexdb with empty schema'); -$node->command_checks_all( +$node->command_ok( [ 'reindexdb', '-j', '2', '--concurrently', '-d', 'postgres' ], - 0, - [qr/^$/], - [ - qr/^reindexdb: warning: cannot reindex system catalogs concurrently, skipping all/s - ], - 'parallel reindexdb for system with --concurrently skips catalogs'); + 'parallel reindexdb with empty schema, concurrently'); done_testing(); diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index d55aec3a1d..e697da6e81 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -2808,6 +2808,12 @@ ERROR: REINDEX SCHEMA cannot run inside a transaction block END; -- concurrently REINDEX SCHEMA CONCURRENTLY schema_to_reindex; +-- unqualified reindex database +-- if you want to test REINDEX DATABASE, uncomment the following line, +-- but note that this adds about 0.5s to the regression tests and the +-- results are volatile when run in parallel to other tasks. Note also +-- that REINDEX SYSTEM is specifically not tested because it can deadlock. +-- REINDEX (VERBOSE) DATABASE; -- Failure for unauthorized user CREATE ROLE regress_reindexuser NOLOGIN; SET SESSION ROLE regress_reindexuser; diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql index d8fded3d93..19abc1d210 100644 --- a/src/test/regress/sql/create_index.sql +++ b/src/test/regress/sql/create_index.sql @@ -1235,6 +1235,13 @@ END; -- concurrently REINDEX SCHEMA CONCURRENTLY schema_to_reindex; +-- unqualified reindex database +-- if you want to test REINDEX DATABASE, uncomment the following line, +-- but note that this adds about 0.5s to the regression tests and the +-- results are volatile when run in parallel to other tasks. Note also +-- that REINDEX SYSTEM is specifically not tested because it can deadlock. +-- REINDEX (VERBOSE) DATABASE; + -- Failure for unauthorized user CREATE ROLE regress_reindexuser NOLOGIN; SET SESSION ROLE regress_reindexuser;