0002-Refactor-index-concurrent-build-into-its-own-routine.patch
text/x-diff
Filename: 0002-Refactor-index-concurrent-build-into-its-own-routine.patch
Type: text/x-diff
Part: 1
Patch
Format: format-patch
Series: patch 0002
Subject: Refactor index concurrent build into its own routine
| File | + | − |
|---|---|---|
| src/backend/bootstrap/bootstrap.c | 1 | 1 |
| src/backend/catalog/heap.c | 1 | 1 |
| src/backend/catalog/index.c | 54 | 4 |
| src/backend/commands/indexcmds.c | 2 | 26 |
| src/include/catalog/index.h | 2 | 1 |
From b4dc21e928cd38f6e641144f08c60ccd0b2d0d4e Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Thu, 17 Jan 2019 12:25:26 +0900
Subject: [PATCH 2/3] Refactor index concurrent build into its own routine
This is used by CREATE INDEX CONCURRENTLY, and finds its uses for other
concurrent-safe operations as the index building step happens in an
independent transaction, like REINDEX CONCURRENTLY.
This simplifies at the same time index_build() which has been including
a flag to track primary indexes, but this was not used. This is
removed, simplifying this refactoring on the way.
---
src/backend/bootstrap/bootstrap.c | 2 +-
src/backend/catalog/heap.c | 2 +-
src/backend/catalog/index.c | 58 ++++++++++++++++++++++++++++---
src/backend/commands/indexcmds.c | 28 ++-------------
src/include/catalog/index.h | 3 +-
5 files changed, 60 insertions(+), 33 deletions(-)
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 63bb134949..a3242cae50 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -1131,7 +1131,7 @@ build_indices(void)
heap = heap_open(ILHead->il_heap, NoLock);
ind = index_open(ILHead->il_ind, NoLock);
- index_build(heap, ind, ILHead->il_info, false, false, false);
+ index_build(heap, ind, ILHead->il_info, false, false);
index_close(ind, NoLock);
heap_close(heap, NoLock);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index d7ccf2bfbe..f1364d29de 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -3063,7 +3063,7 @@ RelationTruncateIndexes(Relation heapRelation)
/* Initialize the index and rebuild */
/* Note: we do not need to re-establish pkey setting */
- index_build(heapRelation, currentIndex, indexInfo, false, true, false);
+ index_build(heapRelation, currentIndex, indexInfo, true, false);
/* We're done with this index */
index_close(currentIndex, NoLock);
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 8701e3a791..2447952f59 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -1190,8 +1190,7 @@ index_create(Relation heapRelation,
}
else
{
- index_build(heapRelation, indexRelation, indexInfo, isprimary, false,
- true);
+ index_build(heapRelation, indexRelation, indexInfo, false, true);
}
/*
@@ -2236,7 +2235,6 @@ void
index_build(Relation heapRelation,
Relation indexRelation,
IndexInfo *indexInfo,
- bool isprimary,
bool isreindex,
bool parallel)
{
@@ -2398,6 +2396,58 @@ index_build(Relation heapRelation,
}
+/*
+ * index_build_concurrent - build index for a concurrent operation.
+ *
+ * Low-level locks are taken when this operation is performed to prevent
+ * only schema changes, but they need to be kept until the end of the
+ * transaction performing this operation. 'indexOid' refers to an index
+ * relation OID already created as part of previous processing, and
+ * 'heapOid' refers to its parent heap relation.
+ */
+void
+index_build_concurrent(Oid heapOid, Oid indexOid)
+{
+ Relation heapRel,
+ indexRelation;
+ IndexInfo *indexInfo;
+
+ /* This had better make sure that a snapshot is active */
+ Assert(ActiveSnapshotSet());
+
+ /* Open and lock the parent heap relation */
+ heapRel = heap_open(heapOid, ShareUpdateExclusiveLock);
+
+ /* And the target index relation */
+ indexRelation = index_open(indexOid, RowExclusiveLock);
+
+ /*
+ * We have to re-build the IndexInfo struct, since it was lost in the
+ * commit of the transaction where this concurrent index was created at
+ * the catalog level.
+ */
+ indexInfo = BuildIndexInfo(indexRelation);
+ Assert(!indexInfo->ii_ReadyForInserts);
+ indexInfo->ii_Concurrent = true;
+ indexInfo->ii_BrokenHotChain = false;
+
+ /* Now build the index */
+ index_build(heapRel, indexRelation, indexInfo, false, true);
+
+ /* Close both relations, and keep the locks */
+ heap_close(heapRel, NoLock);
+ index_close(indexRelation, NoLock);
+
+ /*
+ * Update the pg_index row to mark the index as ready for inserts. Once
+ * we commit this transaction, any new transactions that open the table
+ * must insert new entries into the index for insertions and non-HOT
+ * updates.
+ */
+ index_set_state_flags(indexOid, INDEX_CREATE_SET_READY);
+}
+
+
/*
* IndexBuildHeapScan - scan the heap relation to find tuples to be indexed
*
@@ -3703,7 +3753,7 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence,
/* Initialize the index and rebuild */
/* Note: we do not need to re-establish pkey setting */
- index_build(heapRelation, iRel, indexInfo, false, true, true);
+ index_build(heapRelation, iRel, indexInfo, true, true);
}
PG_CATCH();
{
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index a81e656059..930d4d9880 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -347,7 +347,6 @@ DefineIndex(Oid relationId,
List *indexColNames;
List *allIndexParams;
Relation rel;
- Relation indexRelation;
HeapTuple tuple;
Form_pg_am accessMethodForm;
IndexAmRoutine *amRoutine;
@@ -1151,34 +1150,11 @@ DefineIndex(Oid relationId,
* HOT-chain or the extension of the chain is HOT-safe for this index.
*/
- /* Open and lock the parent heap relation */
- rel = heap_open(relationId, ShareUpdateExclusiveLock);
-
- /* And the target index relation */
- indexRelation = index_open(indexRelationId, RowExclusiveLock);
-
/* Set ActiveSnapshot since functions in the indexes may need it */
PushActiveSnapshot(GetTransactionSnapshot());
- /* We have to re-build the IndexInfo struct, since it was lost in commit */
- indexInfo = BuildIndexInfo(indexRelation);
- Assert(!indexInfo->ii_ReadyForInserts);
- indexInfo->ii_Concurrent = true;
- indexInfo->ii_BrokenHotChain = false;
-
- /* Now build the index */
- index_build(rel, indexRelation, indexInfo, stmt->primary, false, true);
-
- /* Close both the relations, but keep the locks */
- heap_close(rel, NoLock);
- index_close(indexRelation, NoLock);
-
- /*
- * Update the pg_index row to mark the index as ready for inserts. Once we
- * commit this transaction, any new transactions that open the table must
- * insert new entries into the index for insertions and non-HOT updates.
- */
- index_set_state_flags(indexRelationId, INDEX_CREATE_SET_READY);
+ /* Perform concurrent build of index */
+ index_build_concurrent(relationId, indexRelationId);
/* we can do away with our snapshot */
PopActiveSnapshot();
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 8daac5663c..129c00fd0c 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -107,10 +107,11 @@ extern void FormIndexDatum(IndexInfo *indexInfo,
extern void index_build(Relation heapRelation,
Relation indexRelation,
IndexInfo *indexInfo,
- bool isprimary,
bool isreindex,
bool parallel);
+extern void index_build_concurrent(Oid heapOid, Oid indexOid);
+
extern double IndexBuildHeapScan(Relation heapRelation,
Relation indexRelation,
IndexInfo *indexInfo,
--
2.20.1