Commit c6c4b373 authored by Alvaro Herrera's avatar Alvaro Herrera

Invent struct ReindexIndexInfo

This struct is used by ReindexRelationConcurrently to keep track of the
relations to process.  This saves having to obtain some data repeatedly,
and has future uses as well.
Reviewed-by: default avatarDmitry Dolgov <9erthalion6@gmail.com>
Reviewed-by: default avatarHamid Akhtar <hamid.akhtar@gmail.com>
Reviewed-by: default avatarMasahiko Sawada <sawada.mshk@gmail.com>
Discussion: https://postgr.es/m/20201130195439.GA24598@alvherre.pgsql
parent 9eabfe30
...@@ -3061,6 +3061,12 @@ ReindexMultipleInternal(List *relids, int options) ...@@ -3061,6 +3061,12 @@ ReindexMultipleInternal(List *relids, int options)
static bool static bool
ReindexRelationConcurrently(Oid relationOid, int options) ReindexRelationConcurrently(Oid relationOid, int options)
{ {
typedef struct ReindexIndexInfo
{
Oid indexId;
Oid tableId;
Oid amId;
} ReindexIndexInfo;
List *heapRelationIds = NIL; List *heapRelationIds = NIL;
List *indexIds = NIL; List *indexIds = NIL;
List *newIndexIds = NIL; List *newIndexIds = NIL;
...@@ -3170,10 +3176,16 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3170,10 +3176,16 @@ ReindexRelationConcurrently(Oid relationOid, int options)
get_rel_name(cellOid)))); get_rel_name(cellOid))));
else else
{ {
ReindexIndexInfo *idx;
/* Save the list of relation OIDs in private context */ /* Save the list of relation OIDs in private context */
oldcontext = MemoryContextSwitchTo(private_context); oldcontext = MemoryContextSwitchTo(private_context);
indexIds = lappend_oid(indexIds, cellOid); idx = palloc(sizeof(ReindexIndexInfo));
idx->indexId = cellOid;
/* other fields set later */
indexIds = lappend(indexIds, idx);
MemoryContextSwitchTo(oldcontext); MemoryContextSwitchTo(oldcontext);
} }
...@@ -3210,13 +3222,18 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3210,13 +3222,18 @@ ReindexRelationConcurrently(Oid relationOid, int options)
get_rel_name(cellOid)))); get_rel_name(cellOid))));
else else
{ {
ReindexIndexInfo *idx;
/* /*
* Save the list of relation OIDs in private * Save the list of relation OIDs in private
* context * context
*/ */
oldcontext = MemoryContextSwitchTo(private_context); oldcontext = MemoryContextSwitchTo(private_context);
indexIds = lappend_oid(indexIds, cellOid); idx = palloc(sizeof(ReindexIndexInfo));
idx->indexId = cellOid;
indexIds = lappend(indexIds, idx);
/* other fields set later */
MemoryContextSwitchTo(oldcontext); MemoryContextSwitchTo(oldcontext);
} }
...@@ -3235,6 +3252,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3235,6 +3252,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
Oid heapId = IndexGetRelation(relationOid, Oid heapId = IndexGetRelation(relationOid,
(options & REINDEXOPT_MISSING_OK) != 0); (options & REINDEXOPT_MISSING_OK) != 0);
Relation heapRelation; Relation heapRelation;
ReindexIndexInfo *idx;
/* if relation is missing, leave */ /* if relation is missing, leave */
if (!OidIsValid(heapId)) if (!OidIsValid(heapId))
...@@ -3285,7 +3303,10 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3285,7 +3303,10 @@ ReindexRelationConcurrently(Oid relationOid, int options)
* Save the list of relation OIDs in private context. Note * Save the list of relation OIDs in private context. Note
* that invalid indexes are allowed here. * that invalid indexes are allowed here.
*/ */
indexIds = lappend_oid(indexIds, relationOid); idx = palloc(sizeof(ReindexIndexInfo));
idx->indexId = relationOid;
indexIds = lappend(indexIds, idx);
/* other fields set later */
MemoryContextSwitchTo(oldcontext); MemoryContextSwitchTo(oldcontext);
break; break;
...@@ -3344,31 +3365,36 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3344,31 +3365,36 @@ ReindexRelationConcurrently(Oid relationOid, int options)
foreach(lc, indexIds) foreach(lc, indexIds)
{ {
char *concurrentName; char *concurrentName;
Oid indexId = lfirst_oid(lc); ReindexIndexInfo *idx = lfirst(lc);
ReindexIndexInfo *newidx;
Oid newIndexId; Oid newIndexId;
Relation indexRel; Relation indexRel;
Relation heapRel; Relation heapRel;
Relation newIndexRel; Relation newIndexRel;
LockRelId *lockrelid; LockRelId *lockrelid;
indexRel = index_open(indexId, ShareUpdateExclusiveLock); indexRel = index_open(idx->indexId, ShareUpdateExclusiveLock);
heapRel = table_open(indexRel->rd_index->indrelid, heapRel = table_open(indexRel->rd_index->indrelid,
ShareUpdateExclusiveLock); ShareUpdateExclusiveLock);
idx->tableId = RelationGetRelid(heapRel);
idx->amId = indexRel->rd_rel->relam;
/* This function shouldn't be called for temporary relations. */ /* This function shouldn't be called for temporary relations. */
if (indexRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) if (indexRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
elog(ERROR, "cannot reindex a temporary table concurrently"); elog(ERROR, "cannot reindex a temporary table concurrently");
pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX,
RelationGetRelid(heapRel)); idx->tableId);
progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY; progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY;
progress_vals[1] = 0; /* initializing */ progress_vals[1] = 0; /* initializing */
progress_vals[2] = indexId; progress_vals[2] = idx->indexId;
progress_vals[3] = indexRel->rd_rel->relam; progress_vals[3] = idx->amId;
pgstat_progress_update_multi_param(4, progress_index, progress_vals); pgstat_progress_update_multi_param(4, progress_index, progress_vals);
/* Choose a temporary relation name for the new index */ /* Choose a temporary relation name for the new index */
concurrentName = ChooseRelationName(get_rel_name(indexId), concurrentName = ChooseRelationName(get_rel_name(idx->indexId),
NULL, NULL,
"ccnew", "ccnew",
get_rel_namespace(indexRel->rd_index->indrelid), get_rel_namespace(indexRel->rd_index->indrelid),
...@@ -3376,7 +3402,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3376,7 +3402,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
/* Create new index definition based on given index */ /* Create new index definition based on given index */
newIndexId = index_concurrently_create_copy(heapRel, newIndexId = index_concurrently_create_copy(heapRel,
indexId, idx->indexId,
concurrentName); concurrentName);
/* /*
...@@ -3390,7 +3416,12 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3390,7 +3416,12 @@ ReindexRelationConcurrently(Oid relationOid, int options)
*/ */
oldcontext = MemoryContextSwitchTo(private_context); oldcontext = MemoryContextSwitchTo(private_context);
newIndexIds = lappend_oid(newIndexIds, newIndexId); newidx = palloc(sizeof(ReindexIndexInfo));
newidx->indexId = newIndexId;
newidx->tableId = idx->tableId;
newidx->amId = idx->amId;
newIndexIds = lappend(newIndexIds, newidx);
/* /*
* Save lockrelid to protect each relation from drop then close * Save lockrelid to protect each relation from drop then close
...@@ -3471,10 +3502,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3471,10 +3502,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
foreach(lc, newIndexIds) foreach(lc, newIndexIds)
{ {
Relation newIndexRel; ReindexIndexInfo *newidx = lfirst(lc);
Oid newIndexId = lfirst_oid(lc);
Oid heapId;
Oid indexam;
/* Start new transaction for this index's concurrent build */ /* Start new transaction for this index's concurrent build */
StartTransactionCommand(); StartTransactionCommand();
...@@ -3489,28 +3517,19 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3489,28 +3517,19 @@ ReindexRelationConcurrently(Oid relationOid, int options)
/* Set ActiveSnapshot since functions in the indexes may need it */ /* Set ActiveSnapshot since functions in the indexes may need it */
PushActiveSnapshot(GetTransactionSnapshot()); PushActiveSnapshot(GetTransactionSnapshot());
/*
* Index relation has been closed by previous commit, so reopen it to
* get its information.
*/
newIndexRel = index_open(newIndexId, ShareUpdateExclusiveLock);
heapId = newIndexRel->rd_index->indrelid;
indexam = newIndexRel->rd_rel->relam;
index_close(newIndexRel, NoLock);
/* /*
* Update progress for the index to build, with the correct parent * Update progress for the index to build, with the correct parent
* table involved. * table involved.
*/ */
pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, heapId); pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, newidx->tableId);
progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY; progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY;
progress_vals[1] = PROGRESS_CREATEIDX_PHASE_BUILD; progress_vals[1] = PROGRESS_CREATEIDX_PHASE_BUILD;
progress_vals[2] = newIndexId; progress_vals[2] = newidx->indexId;
progress_vals[3] = indexam; progress_vals[3] = newidx->amId;
pgstat_progress_update_multi_param(4, progress_index, progress_vals); pgstat_progress_update_multi_param(4, progress_index, progress_vals);
/* Perform concurrent build of new index */ /* Perform concurrent build of new index */
index_concurrently_build(heapId, newIndexId); index_concurrently_build(newidx->tableId, newidx->indexId);
PopActiveSnapshot(); PopActiveSnapshot();
CommitTransactionCommand(); CommitTransactionCommand();
...@@ -3532,12 +3551,9 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3532,12 +3551,9 @@ ReindexRelationConcurrently(Oid relationOid, int options)
foreach(lc, newIndexIds) foreach(lc, newIndexIds)
{ {
Oid newIndexId = lfirst_oid(lc); ReindexIndexInfo *newidx = lfirst(lc);
Oid heapId;
TransactionId limitXmin; TransactionId limitXmin;
Snapshot snapshot; Snapshot snapshot;
Relation newIndexRel;
Oid indexam;
StartTransactionCommand(); StartTransactionCommand();
...@@ -3555,27 +3571,19 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3555,27 +3571,19 @@ ReindexRelationConcurrently(Oid relationOid, int options)
snapshot = RegisterSnapshot(GetTransactionSnapshot()); snapshot = RegisterSnapshot(GetTransactionSnapshot());
PushActiveSnapshot(snapshot); PushActiveSnapshot(snapshot);
/*
* Index relation has been closed by previous commit, so reopen it to
* get its information.
*/
newIndexRel = index_open(newIndexId, ShareUpdateExclusiveLock);
heapId = newIndexRel->rd_index->indrelid;
indexam = newIndexRel->rd_rel->relam;
index_close(newIndexRel, NoLock);
/* /*
* Update progress for the index to build, with the correct parent * Update progress for the index to build, with the correct parent
* table involved. * table involved.
*/ */
pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX, heapId); pgstat_progress_start_command(PROGRESS_COMMAND_CREATE_INDEX,
newidx->tableId);
progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY; progress_vals[0] = PROGRESS_CREATEIDX_COMMAND_REINDEX_CONCURRENTLY;
progress_vals[1] = PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN; progress_vals[1] = PROGRESS_CREATEIDX_PHASE_VALIDATE_IDXSCAN;
progress_vals[2] = newIndexId; progress_vals[2] = newidx->indexId;
progress_vals[3] = indexam; progress_vals[3] = newidx->amId;
pgstat_progress_update_multi_param(4, progress_index, progress_vals); pgstat_progress_update_multi_param(4, progress_index, progress_vals);
validate_index(heapId, newIndexId, snapshot); validate_index(newidx->tableId, newidx->indexId, snapshot);
/* /*
* We can now do away with our active snapshot, we still need to save * We can now do away with our active snapshot, we still need to save
...@@ -3622,10 +3630,9 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3622,10 +3630,9 @@ ReindexRelationConcurrently(Oid relationOid, int options)
forboth(lc, indexIds, lc2, newIndexIds) forboth(lc, indexIds, lc2, newIndexIds)
{ {
ReindexIndexInfo *oldidx = lfirst(lc);
ReindexIndexInfo *newidx = lfirst(lc2);
char *oldName; char *oldName;
Oid oldIndexId = lfirst_oid(lc);
Oid newIndexId = lfirst_oid(lc2);
Oid heapId;
/* /*
* Check for user-requested abort. This is inside a transaction so as * Check for user-requested abort. This is inside a transaction so as
...@@ -3634,27 +3641,25 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3634,27 +3641,25 @@ ReindexRelationConcurrently(Oid relationOid, int options)
*/ */
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
heapId = IndexGetRelation(oldIndexId, false);
/* Choose a relation name for old index */ /* Choose a relation name for old index */
oldName = ChooseRelationName(get_rel_name(oldIndexId), oldName = ChooseRelationName(get_rel_name(oldidx->indexId),
NULL, NULL,
"ccold", "ccold",
get_rel_namespace(heapId), get_rel_namespace(oldidx->tableId),
false); false);
/* /*
* Swap old index with the new one. This also marks the new one as * Swap old index with the new one. This also marks the new one as
* valid and the old one as not valid. * valid and the old one as not valid.
*/ */
index_concurrently_swap(newIndexId, oldIndexId, oldName); index_concurrently_swap(newidx->indexId, oldidx->indexId, oldName);
/* /*
* Invalidate the relcache for the table, so that after this commit * Invalidate the relcache for the table, so that after this commit
* all sessions will refresh any cached plans that might reference the * all sessions will refresh any cached plans that might reference the
* index. * index.
*/ */
CacheInvalidateRelcacheByRelid(heapId); CacheInvalidateRelcacheByRelid(oldidx->tableId);
/* /*
* CCI here so that subsequent iterations see the oldName in the * CCI here so that subsequent iterations see the oldName in the
...@@ -3684,8 +3689,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3684,8 +3689,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
foreach(lc, indexIds) foreach(lc, indexIds)
{ {
Oid oldIndexId = lfirst_oid(lc); ReindexIndexInfo *oldidx = lfirst(lc);
Oid heapId;
/* /*
* Check for user-requested abort. This is inside a transaction so as * Check for user-requested abort. This is inside a transaction so as
...@@ -3694,8 +3698,7 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3694,8 +3698,7 @@ ReindexRelationConcurrently(Oid relationOid, int options)
*/ */
CHECK_FOR_INTERRUPTS(); CHECK_FOR_INTERRUPTS();
heapId = IndexGetRelation(oldIndexId, false); index_concurrently_set_dead(oldidx->tableId, oldidx->indexId);
index_concurrently_set_dead(heapId, oldIndexId);
} }
/* Commit this transaction to make the updates visible. */ /* Commit this transaction to make the updates visible. */
...@@ -3719,11 +3722,11 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3719,11 +3722,11 @@ ReindexRelationConcurrently(Oid relationOid, int options)
foreach(lc, indexIds) foreach(lc, indexIds)
{ {
Oid oldIndexId = lfirst_oid(lc); ReindexIndexInfo *idx = lfirst(lc);
ObjectAddress object; ObjectAddress object;
object.classId = RelationRelationId; object.classId = RelationRelationId;
object.objectId = oldIndexId; object.objectId = idx->indexId;
object.objectSubId = 0; object.objectSubId = 0;
add_exact_object_address(&object, objects); add_exact_object_address(&object, objects);
...@@ -3766,7 +3769,8 @@ ReindexRelationConcurrently(Oid relationOid, int options) ...@@ -3766,7 +3769,8 @@ ReindexRelationConcurrently(Oid relationOid, int options)
{ {
foreach(lc, newIndexIds) foreach(lc, newIndexIds)
{ {
Oid indOid = lfirst_oid(lc); ReindexIndexInfo *idx = lfirst(lc);
Oid indOid = idx->indexId;
ereport(INFO, ereport(INFO,
(errmsg("index \"%s.%s\" was reindexed", (errmsg("index \"%s.%s\" was reindexed",
......
...@@ -2061,6 +2061,7 @@ Regis ...@@ -2061,6 +2061,7 @@ Regis
RegisNode RegisNode
RegisteredBgWorker RegisteredBgWorker
ReindexErrorInfo ReindexErrorInfo
ReindexIndexInfo
ReindexObjectType ReindexObjectType
ReindexStmt ReindexStmt
ReindexType ReindexType
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment