mirror of
https://github.com/postgres/postgres.git
synced 2026-04-21 06:08:26 -04:00
Make index_concurrently_create_copy more general
Also rename it to index_create_copy. Add a 'boolean concurrent' option, and make it work for both cases: in concurrent mode, just create the catalog entries; caller is responsible for the actual building later. In non-concurrent mode, the index is built right away. This allows it to be reused for other purposes -- specifically, for concurrent REPACK. (With the CONCURRENTLY option, REPACK cannot simply swap the heap file and rebuild its indexes. Instead, it needs to build a separate set of indexes, including their system catalog entries, *before* the actual swap, to reduce the time AccessExclusiveLock needs to be held for. This approach is different from what CREATE INDEX CONCURRENTLY does.) Per a suggestion from Mihail Nikalayeu. Author: Antonin Houska <ah@cybertec.at> Reviewed-by: Mihail Nikalayeu <mihailnikalayeu@gmail.com> Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de> Discussion: https://postgr.es/m/41104.1754922120@localhost
This commit is contained in:
parent
2d3490dd99
commit
33bf7318f9
3 changed files with 36 additions and 21 deletions
|
|
@ -1289,17 +1289,17 @@ index_create(Relation heapRelation,
|
|||
}
|
||||
|
||||
/*
|
||||
* index_concurrently_create_copy
|
||||
* index_create_copy
|
||||
*
|
||||
* Create concurrently an index based on the definition of the one provided by
|
||||
* caller. The index is inserted into catalogs and needs to be built later
|
||||
* on. This is called during concurrent reindex processing.
|
||||
* Create an index based on the definition of the one provided by caller. The
|
||||
* index is inserted into catalogs. If 'concurrently' is TRUE, it needs to be
|
||||
* built later on; otherwise it's built immediately.
|
||||
*
|
||||
* "tablespaceOid" is the tablespace to use for this index.
|
||||
*/
|
||||
Oid
|
||||
index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
|
||||
Oid tablespaceOid, const char *newName)
|
||||
index_create_copy(Relation heapRelation, bool concurrently,
|
||||
Oid oldIndexId, Oid tablespaceOid, const char *newName)
|
||||
{
|
||||
Relation indexRelation;
|
||||
IndexInfo *oldInfo,
|
||||
|
|
@ -1318,6 +1318,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
|
|||
List *indexColNames = NIL;
|
||||
List *indexExprs = NIL;
|
||||
List *indexPreds = NIL;
|
||||
int flags = 0;
|
||||
|
||||
indexRelation = index_open(oldIndexId, RowExclusiveLock);
|
||||
|
||||
|
|
@ -1328,7 +1329,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
|
|||
* Concurrent build of an index with exclusion constraints is not
|
||||
* supported.
|
||||
*/
|
||||
if (oldInfo->ii_ExclusionOps != NULL)
|
||||
if (oldInfo->ii_ExclusionOps != NULL && concurrently)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("concurrent index creation for exclusion constraints is not supported")));
|
||||
|
|
@ -1384,9 +1385,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
|
|||
}
|
||||
|
||||
/*
|
||||
* Build the index information for the new index. Note that rebuild of
|
||||
* indexes with exclusion constraints is not supported, hence there is no
|
||||
* need to fill all the ii_Exclusion* fields.
|
||||
* Build the index information for the new index.
|
||||
*/
|
||||
newInfo = makeIndexInfo(oldInfo->ii_NumIndexAttrs,
|
||||
oldInfo->ii_NumIndexKeyAttrs,
|
||||
|
|
@ -1395,11 +1394,24 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
|
|||
indexPreds,
|
||||
oldInfo->ii_Unique,
|
||||
oldInfo->ii_NullsNotDistinct,
|
||||
false, /* not ready for inserts */
|
||||
true,
|
||||
!concurrently, /* isready */
|
||||
concurrently, /* concurrent */
|
||||
indexRelation->rd_indam->amsummarizing,
|
||||
oldInfo->ii_WithoutOverlaps);
|
||||
|
||||
/* fetch exclusion constraint info if any */
|
||||
if (indexRelation->rd_index->indisexclusion)
|
||||
{
|
||||
/*
|
||||
* XXX Beware: we're making newInfo point to oldInfo-owned memory. It
|
||||
* would be more orthodox to palloc+memcpy, but we don't need that
|
||||
* here at present.
|
||||
*/
|
||||
newInfo->ii_ExclusionOps = oldInfo->ii_ExclusionOps;
|
||||
newInfo->ii_ExclusionProcs = oldInfo->ii_ExclusionProcs;
|
||||
newInfo->ii_ExclusionStrats = oldInfo->ii_ExclusionStrats;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the list of column names and the column numbers for the new
|
||||
* index information. All this information will be used for the index
|
||||
|
|
@ -1436,6 +1448,9 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
|
|||
stattargets[i].isnull = isnull;
|
||||
}
|
||||
|
||||
if (concurrently)
|
||||
flags = INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT;
|
||||
|
||||
/*
|
||||
* Now create the new index.
|
||||
*
|
||||
|
|
@ -1459,7 +1474,7 @@ index_concurrently_create_copy(Relation heapRelation, Oid oldIndexId,
|
|||
indcoloptions->values,
|
||||
stattargets,
|
||||
reloptionsDatum,
|
||||
INDEX_CREATE_SKIP_BUILD | INDEX_CREATE_CONCURRENT,
|
||||
flags,
|
||||
0,
|
||||
true, /* allow table to be a system catalog? */
|
||||
false, /* is_internal? */
|
||||
|
|
|
|||
|
|
@ -3989,10 +3989,11 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
|
|||
tablespaceid = indexRel->rd_rel->reltablespace;
|
||||
|
||||
/* Create new index definition based on given index */
|
||||
newIndexId = index_concurrently_create_copy(heapRel,
|
||||
idx->indexId,
|
||||
tablespaceid,
|
||||
concurrentName);
|
||||
newIndexId = index_create_copy(heapRel,
|
||||
true,
|
||||
idx->indexId,
|
||||
tablespaceid,
|
||||
concurrentName);
|
||||
|
||||
/*
|
||||
* Now open the relation of the new index, a session-level lock is
|
||||
|
|
|
|||
|
|
@ -101,10 +101,9 @@ extern Oid index_create(Relation heapRelation,
|
|||
#define INDEX_CONSTR_CREATE_REMOVE_OLD_DEPS (1 << 4)
|
||||
#define INDEX_CONSTR_CREATE_WITHOUT_OVERLAPS (1 << 5)
|
||||
|
||||
extern Oid index_concurrently_create_copy(Relation heapRelation,
|
||||
Oid oldIndexId,
|
||||
Oid tablespaceOid,
|
||||
const char *newName);
|
||||
extern Oid index_create_copy(Relation heapRelation, bool concurrently,
|
||||
Oid oldIndexId, Oid tablespaceOid,
|
||||
const char *newName);
|
||||
|
||||
extern void index_concurrently_build(Oid heapRelationId,
|
||||
Oid indexRelationId);
|
||||
|
|
|
|||
Loading…
Reference in a new issue