Support VERBOSE option in REINDEX command.
When this option is specified, a progress report is printed as each index is reindexed. Per discussion, we agreed on the following syntax for the extensibility of the options. REINDEX (flexible options) { INDEX | ... } name Sawada Masahiko. Reviewed by Robert Haas, Fabrízio Mello, Alvaro Herrera, Kyotaro Horiguchi, Jim Nasby and me. Discussion: CAD21AoA0pK3YcOZAFzMae+2fcc3oGp5zoRggDyMNg5zoaWDhdQ@mail.gmail.com
This commit is contained in:
parent
4b8f797f67
commit
ecd222e770
@ -21,7 +21,7 @@ PostgreSQL documentation
|
||||
|
||||
<refsynopsisdiv>
|
||||
<synopsis>
|
||||
REINDEX { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } <replaceable class="PARAMETER">name</replaceable>
|
||||
REINDEX [ ( { VERBOSE } [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } <replaceable class="PARAMETER">name</replaceable>
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -150,6 +150,15 @@ REINDEX { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } <replaceable class="PARAM
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>VERBOSE</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Prints a progress report as each index is reindexed.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "utils/inval.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/pg_rusage.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "utils/tuplesort.h"
|
||||
#include "utils/snapmgr.h"
|
||||
@ -3184,13 +3185,17 @@ IndexGetRelation(Oid indexId, bool missing_ok)
|
||||
* reindex_index - This routine is used to recreate a single index
|
||||
*/
|
||||
void
|
||||
reindex_index(Oid indexId, bool skip_constraint_checks, char persistence)
|
||||
reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
|
||||
int options)
|
||||
{
|
||||
Relation iRel,
|
||||
heapRelation;
|
||||
Oid heapId;
|
||||
IndexInfo *indexInfo;
|
||||
volatile bool skipped_constraint = false;
|
||||
PGRUsage ru0;
|
||||
|
||||
pg_rusage_init(&ru0);
|
||||
|
||||
/*
|
||||
* Open and lock the parent heap relation. ShareLock is sufficient since
|
||||
@ -3334,6 +3339,14 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence)
|
||||
heap_close(pg_index, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/* Log what we did */
|
||||
if (options & REINDEXOPT_VERBOSE)
|
||||
ereport(INFO,
|
||||
(errmsg("index \"%s\" was reindexed",
|
||||
get_rel_name(indexId)),
|
||||
errdetail("%s.",
|
||||
pg_rusage_show(&ru0))));
|
||||
|
||||
/* Close rels, but keep locks */
|
||||
index_close(iRel, NoLock);
|
||||
heap_close(heapRelation, NoLock);
|
||||
@ -3375,7 +3388,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence)
|
||||
* index rebuild.
|
||||
*/
|
||||
bool
|
||||
reindex_relation(Oid relid, int flags)
|
||||
reindex_relation(Oid relid, int flags, int options)
|
||||
{
|
||||
Relation rel;
|
||||
Oid toast_relid;
|
||||
@ -3466,7 +3479,7 @@ reindex_relation(Oid relid, int flags)
|
||||
RelationSetIndexList(rel, doneIndexes, InvalidOid);
|
||||
|
||||
reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
|
||||
persistence);
|
||||
persistence, options);
|
||||
|
||||
CommandCounterIncrement();
|
||||
|
||||
@ -3501,7 +3514,7 @@ reindex_relation(Oid relid, int flags)
|
||||
* still hold the lock on the master table.
|
||||
*/
|
||||
if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
|
||||
result |= reindex_relation(toast_relid, flags);
|
||||
result |= reindex_relation(toast_relid, flags, options);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1532,7 +1532,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
|
||||
else if (newrelpersistence == RELPERSISTENCE_PERMANENT)
|
||||
reindex_flags |= REINDEX_REL_FORCE_INDEXES_PERMANENT;
|
||||
|
||||
reindex_relation(OIDOldHeap, reindex_flags);
|
||||
reindex_relation(OIDOldHeap, reindex_flags, 0);
|
||||
|
||||
/*
|
||||
* If the relation being rebuild is pg_class, swap_relation_files()
|
||||
|
@ -1681,7 +1681,7 @@ ChooseIndexColumnNames(List *indexElems)
|
||||
* Recreate a specific index.
|
||||
*/
|
||||
Oid
|
||||
ReindexIndex(RangeVar *indexRelation)
|
||||
ReindexIndex(RangeVar *indexRelation, int options)
|
||||
{
|
||||
Oid indOid;
|
||||
Oid heapOid = InvalidOid;
|
||||
@ -1706,7 +1706,7 @@ ReindexIndex(RangeVar *indexRelation)
|
||||
persistence = irel->rd_rel->relpersistence;
|
||||
index_close(irel, NoLock);
|
||||
|
||||
reindex_index(indOid, false, persistence);
|
||||
reindex_index(indOid, false, persistence, options);
|
||||
|
||||
return indOid;
|
||||
}
|
||||
@ -1775,7 +1775,7 @@ RangeVarCallbackForReindexIndex(const RangeVar *relation,
|
||||
* Recreate all indexes of a table (and of its toast table, if any)
|
||||
*/
|
||||
Oid
|
||||
ReindexTable(RangeVar *relation)
|
||||
ReindexTable(RangeVar *relation, int options)
|
||||
{
|
||||
Oid heapOid;
|
||||
|
||||
@ -1785,7 +1785,8 @@ ReindexTable(RangeVar *relation)
|
||||
|
||||
if (!reindex_relation(heapOid,
|
||||
REINDEX_REL_PROCESS_TOAST |
|
||||
REINDEX_REL_CHECK_CONSTRAINTS))
|
||||
REINDEX_REL_CHECK_CONSTRAINTS,
|
||||
options))
|
||||
ereport(NOTICE,
|
||||
(errmsg("table \"%s\" has no indexes",
|
||||
relation->relname)));
|
||||
@ -1802,7 +1803,8 @@ ReindexTable(RangeVar *relation)
|
||||
* That means this must not be called within a user transaction block!
|
||||
*/
|
||||
void
|
||||
ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind)
|
||||
ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
|
||||
int options)
|
||||
{
|
||||
Oid objectOid;
|
||||
Relation relationRelation;
|
||||
@ -1938,11 +1940,14 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind)
|
||||
PushActiveSnapshot(GetTransactionSnapshot());
|
||||
if (reindex_relation(relid,
|
||||
REINDEX_REL_PROCESS_TOAST |
|
||||
REINDEX_REL_CHECK_CONSTRAINTS))
|
||||
ereport(DEBUG1,
|
||||
(errmsg("table \"%s.%s\" was reindexed",
|
||||
get_namespace_name(get_rel_namespace(relid)),
|
||||
get_rel_name(relid))));
|
||||
REINDEX_REL_CHECK_CONSTRAINTS,
|
||||
options))
|
||||
|
||||
if (options & REINDEXOPT_VERBOSE)
|
||||
ereport(INFO,
|
||||
(errmsg("table \"%s.%s\" was reindexed",
|
||||
get_namespace_name(get_rel_namespace(relid)),
|
||||
get_rel_name(relid))));
|
||||
PopActiveSnapshot();
|
||||
CommitTransactionCommand();
|
||||
}
|
||||
|
@ -1234,7 +1234,7 @@ ExecuteTruncate(TruncateStmt *stmt)
|
||||
/*
|
||||
* Reconstruct the indexes to match, and we're done.
|
||||
*/
|
||||
reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST);
|
||||
reindex_relation(heap_relid, REINDEX_REL_PROCESS_TOAST, 0);
|
||||
}
|
||||
|
||||
pgstat_count_truncate(rel);
|
||||
|
@ -3856,6 +3856,7 @@ _copyReindexStmt(const ReindexStmt *from)
|
||||
COPY_SCALAR_FIELD(kind);
|
||||
COPY_NODE_FIELD(relation);
|
||||
COPY_STRING_FIELD(name);
|
||||
COPY_SCALAR_FIELD(options);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
@ -1935,6 +1935,7 @@ _equalReindexStmt(const ReindexStmt *a, const ReindexStmt *b)
|
||||
COMPARE_SCALAR_FIELD(kind);
|
||||
COMPARE_NODE_FIELD(relation);
|
||||
COMPARE_STRING_FIELD(name);
|
||||
COMPARE_SCALAR_FIELD(options);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -463,6 +463,10 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
|
||||
%type <node> explain_option_arg
|
||||
%type <defelt> explain_option_elem
|
||||
%type <list> explain_option_list
|
||||
|
||||
%type <ival> reindex_target_type reindex_target_multitable
|
||||
%type <ival> reindex_option_list reindex_option_elem
|
||||
|
||||
%type <node> copy_generic_opt_arg copy_generic_opt_arg_list_item
|
||||
%type <defelt> copy_generic_opt_elem
|
||||
%type <list> copy_generic_opt_list copy_generic_opt_arg_list
|
||||
@ -7387,52 +7391,63 @@ DropTransformStmt: DROP TRANSFORM opt_if_exists FOR Typename LANGUAGE name opt_d
|
||||
*
|
||||
* QUERY:
|
||||
*
|
||||
* REINDEX type <name>
|
||||
* REINDEX [ (options) ] type <name>
|
||||
*****************************************************************************/
|
||||
|
||||
ReindexStmt:
|
||||
REINDEX INDEX qualified_name
|
||||
REINDEX reindex_target_type qualified_name
|
||||
{
|
||||
ReindexStmt *n = makeNode(ReindexStmt);
|
||||
n->kind = REINDEX_OBJECT_INDEX;
|
||||
n->kind = $2;
|
||||
n->relation = $3;
|
||||
n->name = NULL;
|
||||
n->options = 0;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| REINDEX TABLE qualified_name
|
||||
| REINDEX reindex_target_multitable name
|
||||
{
|
||||
ReindexStmt *n = makeNode(ReindexStmt);
|
||||
n->kind = REINDEX_OBJECT_TABLE;
|
||||
n->relation = $3;
|
||||
n->kind = $2;
|
||||
n->name = $3;
|
||||
n->relation = NULL;
|
||||
n->options = 0;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| REINDEX '(' reindex_option_list ')' reindex_target_type qualified_name
|
||||
{
|
||||
ReindexStmt *n = makeNode(ReindexStmt);
|
||||
n->kind = $5;
|
||||
n->relation = $6;
|
||||
n->name = NULL;
|
||||
n->options = $3;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| REINDEX SCHEMA name
|
||||
| REINDEX '(' reindex_option_list ')' reindex_target_multitable name
|
||||
{
|
||||
ReindexStmt *n = makeNode(ReindexStmt);
|
||||
n->kind = REINDEX_OBJECT_SCHEMA;
|
||||
n->name = $3;
|
||||
n->relation = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| REINDEX SYSTEM_P name
|
||||
{
|
||||
ReindexStmt *n = makeNode(ReindexStmt);
|
||||
n->kind = REINDEX_OBJECT_SYSTEM;
|
||||
n->name = $3;
|
||||
n->relation = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| REINDEX DATABASE name
|
||||
{
|
||||
ReindexStmt *n = makeNode(ReindexStmt);
|
||||
n->kind = REINDEX_OBJECT_DATABASE;
|
||||
n->name = $3;
|
||||
n->kind = $5;
|
||||
n->name = $6;
|
||||
n->relation = NULL;
|
||||
n->options = $3;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
reindex_target_type:
|
||||
INDEX { $$ = REINDEX_OBJECT_INDEX; }
|
||||
| TABLE { $$ = REINDEX_OBJECT_TABLE; }
|
||||
;
|
||||
reindex_target_multitable:
|
||||
SCHEMA { $$ = REINDEX_OBJECT_SCHEMA; }
|
||||
| SYSTEM_P { $$ = REINDEX_OBJECT_SYSTEM; }
|
||||
| DATABASE { $$ = REINDEX_OBJECT_DATABASE; }
|
||||
;
|
||||
reindex_option_list:
|
||||
reindex_option_elem { $$ = $1; }
|
||||
| reindex_option_list ',' reindex_option_elem { $$ = $1 | $3; }
|
||||
;
|
||||
reindex_option_elem:
|
||||
VERBOSE { $$ = REINDEXOPT_VERBOSE; }
|
||||
;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
@ -762,10 +762,10 @@ standard_ProcessUtility(Node *parsetree,
|
||||
switch (stmt->kind)
|
||||
{
|
||||
case REINDEX_OBJECT_INDEX:
|
||||
ReindexIndex(stmt->relation);
|
||||
ReindexIndex(stmt->relation, stmt->options);
|
||||
break;
|
||||
case REINDEX_OBJECT_TABLE:
|
||||
ReindexTable(stmt->relation);
|
||||
ReindexTable(stmt->relation, stmt->options);
|
||||
break;
|
||||
case REINDEX_OBJECT_SCHEMA:
|
||||
case REINDEX_OBJECT_SYSTEM:
|
||||
@ -781,7 +781,7 @@ standard_ProcessUtility(Node *parsetree,
|
||||
(stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
|
||||
(stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
|
||||
"REINDEX DATABASE");
|
||||
ReindexMultipleTables(stmt->name, stmt->kind);
|
||||
ReindexMultipleTables(stmt->name, stmt->kind, stmt->options);
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unrecognized object type: %d",
|
||||
|
@ -115,7 +115,7 @@ extern void validate_index(Oid heapId, Oid indexId, Snapshot snapshot);
|
||||
extern void index_set_state_flags(Oid indexId, IndexStateFlagsAction action);
|
||||
|
||||
extern void reindex_index(Oid indexId, bool skip_constraint_checks,
|
||||
char relpersistence);
|
||||
char relpersistence, int options);
|
||||
|
||||
/* Flag bits for reindex_relation(): */
|
||||
#define REINDEX_REL_PROCESS_TOAST 0x01
|
||||
@ -124,7 +124,7 @@ extern void reindex_index(Oid indexId, bool skip_constraint_checks,
|
||||
#define REINDEX_REL_FORCE_INDEXES_UNLOGGED 0x08
|
||||
#define REINDEX_REL_FORCE_INDEXES_PERMANENT 0x10
|
||||
|
||||
extern bool reindex_relation(Oid relid, int flags);
|
||||
extern bool reindex_relation(Oid relid, int flags, int options);
|
||||
|
||||
extern bool ReindexIsProcessingHeap(Oid heapOid);
|
||||
extern bool ReindexIsProcessingIndex(Oid indexOid);
|
||||
|
@ -29,9 +29,10 @@ extern ObjectAddress DefineIndex(Oid relationId,
|
||||
bool check_rights,
|
||||
bool skip_build,
|
||||
bool quiet);
|
||||
extern Oid ReindexIndex(RangeVar *indexRelation);
|
||||
extern Oid ReindexTable(RangeVar *relation);
|
||||
extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind);
|
||||
extern Oid ReindexIndex(RangeVar *indexRelation, int options);
|
||||
extern Oid ReindexTable(RangeVar *relation, int options);
|
||||
extern void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
|
||||
int options);
|
||||
extern char *makeObjectName(const char *name1, const char *name2,
|
||||
const char *label);
|
||||
extern char *ChooseRelationName(const char *name1, const char *name2,
|
||||
|
@ -2782,6 +2782,10 @@ typedef struct ConstraintsSetStmt
|
||||
* REINDEX Statement
|
||||
* ----------------------
|
||||
*/
|
||||
|
||||
/* Reindex options */
|
||||
#define REINDEXOPT_VERBOSE 1 << 0 /* print progress info */
|
||||
|
||||
typedef enum ReindexObjectType
|
||||
{
|
||||
REINDEX_OBJECT_INDEX, /* index */
|
||||
@ -2797,6 +2801,7 @@ typedef struct ReindexStmt
|
||||
ReindexObjectType kind; /* REINDEX_OBJECT_INDEX, REINDEX_OBJECT_TABLE, etc. */
|
||||
RangeVar *relation; /* Table or index to reindex */
|
||||
const char *name; /* name of database to reindex */
|
||||
int options; /* Reindex options flags */
|
||||
} ReindexStmt;
|
||||
|
||||
/* ----------------------
|
||||
|
@ -2831,6 +2831,14 @@ explain (costs off)
|
||||
Index Cond: ((thousand = 1) AND (tenthous = 1001))
|
||||
(2 rows)
|
||||
|
||||
--
|
||||
-- REINDEX (VERBOSE)
|
||||
--
|
||||
CREATE TABLE reindex_verbose(id integer primary key);
|
||||
\set VERBOSITY terse
|
||||
REINDEX (VERBOSE) TABLE reindex_verbose;
|
||||
INFO: index "reindex_verbose_pkey" was reindexed
|
||||
DROP TABLE reindex_verbose;
|
||||
--
|
||||
-- REINDEX SCHEMA
|
||||
--
|
||||
|
@ -965,6 +965,14 @@ RESET enable_indexscan;
|
||||
explain (costs off)
|
||||
select * from tenk1 where (thousand, tenthous) in ((1,1001), (null,null));
|
||||
|
||||
--
|
||||
-- REINDEX (VERBOSE)
|
||||
--
|
||||
CREATE TABLE reindex_verbose(id integer primary key);
|
||||
\set VERBOSITY terse
|
||||
REINDEX (VERBOSE) TABLE reindex_verbose;
|
||||
DROP TABLE reindex_verbose;
|
||||
|
||||
--
|
||||
-- REINDEX SCHEMA
|
||||
--
|
||||
|
Loading…
x
Reference in New Issue
Block a user