Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 507a6ed

Browse files
committed
Allow REINDEX to change tablespace
REINDEX already does full relation rewrite, this patch adds a possibility to specify a new tablespace where new relfilenode will be created.
1 parent eff5b24 commit 507a6ed

File tree

15 files changed

+354
-33
lines changed

15 files changed

+354
-33
lines changed

doc/src/sgml/ref/reindex.sgml

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] <replaceable class="parameter">name</replaceable>
24+
REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { INDEX | TABLE | SCHEMA | DATABASE | SYSTEM } [ CONCURRENTLY ] <replaceable class="parameter">name</replaceable> [ TABLESPACE <replaceable class="parameter">new_tablespace</replaceable> ]
2525

2626
<phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
2727

@@ -174,6 +174,28 @@ REINDEX [ ( <replaceable class="parameter">option</replaceable> [, ...] ) ] { IN
174174
</listitem>
175175
</varlistentry>
176176

177+
<varlistentry>
178+
<term><literal>TABLESPACE</literal></term>
179+
<listitem>
180+
<para>
181+
This specifies a tablespace, where all rebuilt indexes will be created.
182+
Cannot be used with "mapped" relations. If <literal>SCHEMA</literal>,
183+
<literal>DATABASE</literal> or <literal>SYSTEM</literal> is specified, then
184+
all unsuitable relations will be skipped and a single <literal>WARNING</literal>
185+
will be generated.
186+
</para>
187+
</listitem>
188+
</varlistentry>
189+
190+
<varlistentry>
191+
<term><replaceable class="parameter">new_tablespace</replaceable></term>
192+
<listitem>
193+
<para>
194+
The name of a specific tablespace to store rebuilt indexes.
195+
</para>
196+
</listitem>
197+
</varlistentry>
198+
177199
<varlistentry>
178200
<term><literal>VERBOSE</literal></term>
179201
<listitem>

src/backend/catalog/index.c

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,9 +1235,13 @@ index_create(Relation heapRelation,
12351235
* Create concurrently an index based on the definition of the one provided by
12361236
* caller. The index is inserted into catalogs and needs to be built later
12371237
* on. This is called during concurrent reindex processing.
1238+
*
1239+
* "tablespaceOid" is the new tablespace to use for this index. If
1240+
* InvalidOid, use the tablespace in-use instead.
12381241
*/
12391242
Oid
1240-
index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char *newName)
1243+
index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
1244+
Oid tablespaceOid, const char *newName)
12411245
{
12421246
Relation indexRelation;
12431247
IndexInfo *oldInfo,
@@ -1367,7 +1371,8 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId, const char
13671371
newInfo,
13681372
indexColNames,
13691373
indexRelation->rd_rel->relam,
1370-
indexRelation->rd_rel->reltablespace,
1374+
OidIsValid(tablespaceOid) ?
1375+
tablespaceOid : indexRelation->rd_rel->reltablespace,
13711376
indexRelation->rd_indcollation,
13721377
indclass->values,
13731378
indcoloptions->values,
@@ -3415,10 +3420,12 @@ IndexGetRelation(Oid indexId, bool missing_ok)
34153420

34163421
/*
34173422
* reindex_index - This routine is used to recreate a single index
3423+
*
3424+
* See comments of reindex_relation() for details about "tablespaceOid".
34183425
*/
34193426
void
3420-
reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
3421-
int options)
3427+
reindex_index(Oid indexId, Oid tablespaceOid, bool skip_constraint_checks,
3428+
char persistence, int options)
34223429
{
34233430
Relation iRel,
34243431
heapRelation;
@@ -3427,6 +3434,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
34273434
volatile bool skipped_constraint = false;
34283435
PGRUsage ru0;
34293436
bool progress = (options & REINDEXOPT_REPORT_PROGRESS) != 0;
3437+
bool set_tablespace = OidIsValid(tablespaceOid);
34303438

34313439
pg_rusage_init(&ru0);
34323440

@@ -3465,6 +3473,27 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
34653473
elog(ERROR, "unsupported relation kind for index \"%s\"",
34663474
RelationGetRelationName(iRel));
34673475

3476+
/*
3477+
* We don't support moving system relations into different tablespaces,
3478+
* unless allow_system_table_mods=1.
3479+
*/
3480+
if (set_tablespace &&
3481+
!allowSystemTableMods && IsSystemRelation(iRel))
3482+
ereport(ERROR,
3483+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
3484+
errmsg("permission denied: \"%s\" is a system catalog",
3485+
RelationGetRelationName(iRel))));
3486+
3487+
/*
3488+
* We cannot support moving mapped relations into different tablespaces.
3489+
* (In particular this eliminates all shared catalogs.)
3490+
*/
3491+
if (set_tablespace && RelationIsMapped(iRel))
3492+
ereport(ERROR,
3493+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
3494+
errmsg("cannot change tablespace of mapped relation \"%s\"",
3495+
RelationGetRelationName(iRel))));
3496+
34683497
/*
34693498
* Don't allow reindex on temp tables of other backends ... their local
34703499
* buffer manager is not going to cope.
@@ -3491,6 +3520,47 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
34913520
*/
34923521
CheckTableNotInUse(iRel, "REINDEX INDEX");
34933522

3523+
if (tablespaceOid == MyDatabaseTableSpace)
3524+
tablespaceOid = InvalidOid;
3525+
3526+
/*
3527+
* Set the new tablespace for the relation. Do that only in the
3528+
* case where the reindex caller wishes to enforce a new tablespace.
3529+
*/
3530+
if (set_tablespace &&
3531+
tablespaceOid != iRel->rd_rel->reltablespace)
3532+
{
3533+
Relation pg_class;
3534+
Form_pg_class rd_rel;
3535+
HeapTuple tuple;
3536+
3537+
/* First get a modifiable copy of the relation's pg_class row */
3538+
pg_class = table_open(RelationRelationId, RowExclusiveLock);
3539+
3540+
tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(indexId));
3541+
if (!HeapTupleIsValid(tuple))
3542+
elog(ERROR, "cache lookup failed for relation %u", indexId);
3543+
rd_rel = (Form_pg_class) GETSTRUCT(tuple);
3544+
3545+
/*
3546+
* Mark the relation as ready to be dropped at transaction commit,
3547+
* before making visible the new tablespace change so as this won't
3548+
* miss things.
3549+
*/
3550+
RelationDropStorage(iRel);
3551+
3552+
/* Update the pg_class row */
3553+
rd_rel->reltablespace = tablespaceOid;
3554+
CatalogTupleUpdate(pg_class, &tuple->t_self, tuple);
3555+
3556+
heap_freetuple(tuple);
3557+
3558+
table_close(pg_class, RowExclusiveLock);
3559+
3560+
/* Make sure the reltablespace change is visible */
3561+
CommandCounterIncrement();
3562+
}
3563+
34943564
/*
34953565
* All predicate locks on the index are about to be made invalid. Promote
34963566
* them to relation locks on the heap.
@@ -3629,6 +3699,10 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
36293699
* reindex_relation - This routine is used to recreate all indexes
36303700
* of a relation (and optionally its toast relation too, if any).
36313701
*
3702+
* "tablespaceOid" defines the new tablespace where the indexes of
3703+
* the relation will be rebuilt. If InvalidOid is used, the current
3704+
* tablespace of each index is used instead.
3705+
*
36323706
* "flags" is a bitmask that can include any combination of these bits:
36333707
*
36343708
* REINDEX_REL_PROCESS_TOAST: if true, process the toast table too (if any).
@@ -3661,7 +3735,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
36613735
* index rebuild.
36623736
*/
36633737
bool
3664-
reindex_relation(Oid relid, int flags, int options)
3738+
reindex_relation(Oid relid, Oid tablespaceOid, int flags, int options)
36653739
{
36663740
Relation rel;
36673741
Oid toast_relid;
@@ -3752,7 +3826,8 @@ reindex_relation(Oid relid, int flags, int options)
37523826
continue;
37533827
}
37543828

3755-
reindex_index(indexOid, !(flags & REINDEX_REL_CHECK_CONSTRAINTS),
3829+
reindex_index(indexOid, tablespaceOid,
3830+
!(flags & REINDEX_REL_CHECK_CONSTRAINTS),
37563831
persistence, options);
37573832

37583833
CommandCounterIncrement();
@@ -3785,7 +3860,7 @@ reindex_relation(Oid relid, int flags, int options)
37853860
* still hold the lock on the master table.
37863861
*/
37873862
if ((flags & REINDEX_REL_PROCESS_TOAST) && OidIsValid(toast_relid))
3788-
result |= reindex_relation(toast_relid, flags, options);
3863+
result |= reindex_relation(toast_relid, tablespaceOid, flags, options);
37893864

37903865
return result;
37913866
}

src/backend/commands/cluster.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
14061406
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,
14071407
PROGRESS_CLUSTER_PHASE_REBUILD_INDEX);
14081408

1409-
reindex_relation(OIDOldHeap, reindex_flags, 0);
1409+
reindex_relation(OIDOldHeap, InvalidOid, reindex_flags, 0);
14101410

14111411
/* Report that we are now doing clean up */
14121412
pgstat_progress_update_param(PROGRESS_CLUSTER_PHASE,

0 commit comments

Comments
 (0)