Skip to content

Commit 02c03a8

Browse files
michail-nikolaevCommitfest Bot
authored andcommitted
Remove PROC_IN_SAFE_IC optimization
This optimization allowed concurrent index builds to ignore other indexes without expressions or predicates. With the new snapshot handling approach that periodically refreshes snapshots, this optimization is no longer necessary. The change simplifies concurrent index build code by: - removing the PROC_IN_SAFE_IC process status flag - eliminating set_indexsafe_procflags() calls and related logic - removing special case handling in GetCurrentVirtualXIDs() - removing related test cases and injection points
1 parent 15740a4 commit 02c03a8

File tree

9 files changed

+13
-237
lines changed

9 files changed

+13
-237
lines changed

src/backend/access/brin/brin.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2893,11 +2893,9 @@ _brin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
28932893
int sortmem;
28942894

28952895
/*
2896-
* The only possible status flag that can be set to the parallel worker is
2897-
* PROC_IN_SAFE_IC.
2896+
* There are no possible status flag that can be set to the parallel worker.
28982897
*/
2899-
Assert((MyProc->statusFlags == 0) ||
2900-
(MyProc->statusFlags == PROC_IN_SAFE_IC));
2898+
Assert(MyProc->statusFlags == 0);
29012899

29022900
/* Set debug_query_string for individual workers first */
29032901
sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, true);

src/backend/access/gin/gininsert.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2110,11 +2110,9 @@ _gin_parallel_build_main(dsm_segment *seg, shm_toc *toc)
21102110
int sortmem;
21112111

21122112
/*
2113-
* The only possible status flag that can be set to the parallel worker is
2114-
* PROC_IN_SAFE_IC.
2113+
* There are no possible status flag that can be set to the parallel worker.
21152114
*/
2116-
Assert((MyProc->statusFlags == 0) ||
2117-
(MyProc->statusFlags == PROC_IN_SAFE_IC));
2115+
Assert(MyProc->statusFlags == 0);
21182116

21192117
/* Set debug_query_string for individual workers first */
21202118
sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, true);

src/backend/access/nbtree/nbtsort.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,11 +1909,9 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
19091909
#endif /* BTREE_BUILD_STATS */
19101910

19111911
/*
1912-
* The only possible status flag that can be set to the parallel worker is
1913-
* PROC_IN_SAFE_IC.
1912+
* There are no possible status flag that can be set to the parallel worker.
19141913
*/
1915-
Assert((MyProc->statusFlags == 0) ||
1916-
(MyProc->statusFlags == PROC_IN_SAFE_IC));
1914+
Assert(MyProc->statusFlags == 0);
19171915

19181916
/* Set debug_query_string for individual workers first */
19191917
sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, true);

src/backend/commands/indexcmds.c

Lines changed: 4 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ static bool ReindexRelationConcurrently(const ReindexStmt *stmt,
114114
Oid relationOid,
115115
const ReindexParams *params);
116116
static void update_relispartition(Oid relationId, bool newval);
117-
static inline void set_indexsafe_procflags(void);
118117

119118
/*
120119
* callback argument type for RangeVarCallbackForReindexIndex()
@@ -417,10 +416,7 @@ CompareOpclassOptions(const Datum *opts1, const Datum *opts2, int natts)
417416
* lazy VACUUMs, because they won't be fazed by missing index entries
418417
* either. (Manual ANALYZEs, however, can't be excluded because they
419418
* might be within transactions that are going to do arbitrary operations
420-
* later.) Processes running CREATE INDEX CONCURRENTLY or REINDEX CONCURRENTLY
421-
* on indexes that are neither expressional nor partial are also safe to
422-
* ignore, since we know that those processes won't examine any data
423-
* outside the table they're indexing.
419+
* later.)
424420
*
425421
* Also, GetCurrentVirtualXIDs never reports our own vxid, so we need not
426422
* check for that.
@@ -441,8 +437,7 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
441437
VirtualTransactionId *old_snapshots;
442438

443439
old_snapshots = GetCurrentVirtualXIDs(limitXmin, true, false,
444-
PROC_IS_AUTOVACUUM | PROC_IN_VACUUM
445-
| PROC_IN_SAFE_IC,
440+
PROC_IS_AUTOVACUUM | PROC_IN_VACUUM,
446441
&n_old_snapshots);
447442
if (progress)
448443
pgstat_progress_update_param(PROGRESS_WAITFOR_TOTAL, n_old_snapshots);
@@ -462,8 +457,7 @@ WaitForOlderSnapshots(TransactionId limitXmin, bool progress)
462457

463458
newer_snapshots = GetCurrentVirtualXIDs(limitXmin,
464459
true, false,
465-
PROC_IS_AUTOVACUUM | PROC_IN_VACUUM
466-
| PROC_IN_SAFE_IC,
460+
PROC_IS_AUTOVACUUM | PROC_IN_VACUUM,
467461
&n_newer_snapshots);
468462
for (j = i; j < n_old_snapshots; j++)
469463
{
@@ -577,7 +571,6 @@ DefineIndex(Oid tableId,
577571
amoptions_function amoptions;
578572
bool exclusion;
579573
bool partitioned;
580-
bool safe_index;
581574
Datum reloptions;
582575
int16 *coloptions;
583576
IndexInfo *indexInfo;
@@ -1181,10 +1174,6 @@ DefineIndex(Oid tableId,
11811174
}
11821175
}
11831176

1184-
/* Is index safe for others to ignore? See set_indexsafe_procflags() */
1185-
safe_index = indexInfo->ii_Expressions == NIL &&
1186-
indexInfo->ii_Predicate == NIL;
1187-
11881177
/*
11891178
* Report index creation if appropriate (delay this till after most of the
11901179
* error checks)
@@ -1670,10 +1659,6 @@ DefineIndex(Oid tableId,
16701659
CommitTransactionCommand();
16711660
StartTransactionCommand();
16721661

1673-
/* Tell concurrent index builds to ignore us, if index qualifies */
1674-
if (safe_index)
1675-
set_indexsafe_procflags();
1676-
16771662
/*
16781663
* The index is now visible, so we can report the OID. While on it,
16791664
* include the report for the beginning of phase 2.
@@ -1728,9 +1713,6 @@ DefineIndex(Oid tableId,
17281713
CommitTransactionCommand();
17291714
StartTransactionCommand();
17301715

1731-
/* Tell concurrent index builds to ignore us, if index qualifies */
1732-
if (safe_index)
1733-
set_indexsafe_procflags();
17341716
pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE,
17351717
PROGRESS_CREATEIDX_PHASE_WAIT_2);
17361718
/*
@@ -1760,10 +1742,6 @@ DefineIndex(Oid tableId,
17601742
CommitTransactionCommand();
17611743
StartTransactionCommand();
17621744

1763-
/* Tell concurrent index builds to ignore us, if index qualifies */
1764-
if (safe_index)
1765-
set_indexsafe_procflags();
1766-
17671745
/*
17681746
* Phase 3 of concurrent index build
17691747
*
@@ -1789,9 +1767,7 @@ DefineIndex(Oid tableId,
17891767

17901768
CommitTransactionCommand();
17911769
StartTransactionCommand();
1792-
/* Tell concurrent index builds to ignore us, if index qualifies */
1793-
if (safe_index)
1794-
set_indexsafe_procflags();
1770+
17951771
/*
17961772
* Merge content of auxiliary and target indexes - insert any missing index entries.
17971773
*/
@@ -1808,9 +1784,6 @@ DefineIndex(Oid tableId,
18081784
CommitTransactionCommand();
18091785
StartTransactionCommand();
18101786

1811-
/* Tell concurrent index builds to ignore us, if index qualifies */
1812-
if (safe_index)
1813-
set_indexsafe_procflags();
18141787

18151788
/* We should now definitely not be advertising any xmin. */
18161789
Assert(MyProc->xmin == InvalidTransactionId);
@@ -1851,10 +1824,6 @@ DefineIndex(Oid tableId,
18511824
CommitTransactionCommand();
18521825
StartTransactionCommand();
18531826

1854-
/* Tell concurrent index builds to ignore us, if index qualifies */
1855-
if (safe_index)
1856-
set_indexsafe_procflags();
1857-
18581827
pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE,
18591828
PROGRESS_CREATEIDX_PHASE_WAIT_5);
18601829
/* Now wait for all transaction to see auxiliary as "non-ready for inserts" */
@@ -1875,10 +1844,6 @@ DefineIndex(Oid tableId,
18751844
CommitTransactionCommand();
18761845
StartTransactionCommand();
18771846

1878-
/* Tell concurrent index builds to ignore us, if index qualifies */
1879-
if (safe_index)
1880-
set_indexsafe_procflags();
1881-
18821847
pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE,
18831848
PROGRESS_CREATEIDX_PHASE_WAIT_6);
18841849
/* Now wait for all transaction to ignore auxiliary because it is dead */
@@ -3653,7 +3618,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
36533618
Oid junkAuxIndexId;
36543619
Oid tableId;
36553620
Oid amId;
3656-
bool safe; /* for set_indexsafe_procflags */
36573621
} ReindexIndexInfo;
36583622
List *heapRelationIds = NIL;
36593623
List *indexIds = NIL;
@@ -4027,17 +3991,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
40273991
save_nestlevel = NewGUCNestLevel();
40283992
RestrictSearchPath();
40293993

4030-
/* determine safety of this index for set_indexsafe_procflags */
4031-
idx->safe = (RelationGetIndexExpressions(indexRel) == NIL &&
4032-
RelationGetIndexPredicate(indexRel) == NIL);
4033-
4034-
#ifdef USE_INJECTION_POINTS
4035-
if (idx->safe)
4036-
INJECTION_POINT("reindex-conc-index-safe", NULL);
4037-
else
4038-
INJECTION_POINT("reindex-conc-index-not-safe", NULL);
4039-
#endif
4040-
40413994
idx->tableId = RelationGetRelid(heapRel);
40423995
idx->amId = indexRel->rd_rel->relam;
40433996

@@ -4103,7 +4056,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
41034056
newidx->indexId = newIndexId;
41044057
newidx->auxIndexId = auxIndexId;
41054058
newidx->junkAuxIndexId = junkAuxIndexId;
4106-
newidx->safe = idx->safe;
41074059
newidx->tableId = idx->tableId;
41084060
newidx->amId = idx->amId;
41094061

@@ -4204,11 +4156,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
42044156
CommitTransactionCommand();
42054157
StartTransactionCommand();
42064158

4207-
/*
4208-
* Because we don't take a snapshot in this transaction, there's no need
4209-
* to set the PROC_IN_SAFE_IC flag here.
4210-
*/
4211-
42124159
/*
42134160
* Phase 2 of REINDEX CONCURRENTLY
42144161
*
@@ -4240,10 +4187,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
42404187
*/
42414188
CHECK_FOR_INTERRUPTS();
42424189

4243-
/* Tell concurrent indexing to ignore us, if index qualifies */
4244-
if (newidx->safe)
4245-
set_indexsafe_procflags();
4246-
42474190
/* Build auxiliary index, it is fast - without any actual heap scan, just an empty index. */
42484191
index_concurrently_build(newidx->tableId, newidx->auxIndexId);
42494192

@@ -4252,11 +4195,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
42524195

42534196
StartTransactionCommand();
42544197

4255-
/*
4256-
* Because we don't take a snapshot in this transaction, there's no need
4257-
* to set the PROC_IN_SAFE_IC flag here.
4258-
*/
4259-
42604198
pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE,
42614199
PROGRESS_CREATEIDX_PHASE_WAIT_2);
42624200
/*
@@ -4281,10 +4219,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
42814219
*/
42824220
CHECK_FOR_INTERRUPTS();
42834221

4284-
/* Tell concurrent indexing to ignore us, if index qualifies */
4285-
if (newidx->safe)
4286-
set_indexsafe_procflags();
4287-
42884222
/*
42894223
* Update progress for the index to build, with the correct parent
42904224
* table involved.
@@ -4304,11 +4238,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
43044238

43054239
StartTransactionCommand();
43064240

4307-
/*
4308-
* Because we don't take a snapshot or Xid in this transaction, there's no
4309-
* need to set the PROC_IN_SAFE_IC flag here.
4310-
*/
4311-
43124241
pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE,
43134242
PROGRESS_CREATEIDX_PHASE_WAIT_3);
43144243
WaitForLockersMultiple(lockTags, ShareLock, true);
@@ -4330,10 +4259,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
43304259
*/
43314260
CHECK_FOR_INTERRUPTS();
43324261

4333-
/* Tell concurrent indexing to ignore us, if index qualifies */
4334-
if (newidx->safe)
4335-
set_indexsafe_procflags();
4336-
43374262
/*
43384263
* Updating pg_index might involve TOAST table access, so ensure we
43394264
* have a valid snapshot.
@@ -4369,10 +4294,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
43694294
*/
43704295
CHECK_FOR_INTERRUPTS();
43714296

4372-
/* Tell concurrent indexing to ignore us, if index qualifies */
4373-
if (newidx->safe)
4374-
set_indexsafe_procflags();
4375-
43764297
/*
43774298
* Update progress for the index to build, with the correct parent
43784299
* table involved.
@@ -4400,9 +4321,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
44004321
* interesting tuples. But since it might not contain tuples deleted
44014322
* just before the latest snap was taken, we have to wait out any
44024323
* transactions that might have older snapshots.
4403-
*
4404-
* Because we don't take a snapshot or Xid in this transaction,
4405-
* there's no need to set the PROC_IN_SAFE_IC flag here.
44064324
*/
44074325
pgstat_progress_update_param(PROGRESS_CREATEIDX_PHASE,
44084326
PROGRESS_CREATEIDX_PHASE_WAIT_4);
@@ -4424,13 +4342,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
44244342
INJECTION_POINT("reindex_relation_concurrently_before_swap", NULL);
44254343
StartTransactionCommand();
44264344

4427-
/*
4428-
* Because this transaction only does catalog manipulations and doesn't do
4429-
* any index operations, we can set the PROC_IN_SAFE_IC flag here
4430-
* unconditionally.
4431-
*/
4432-
set_indexsafe_procflags();
4433-
44344345
forboth(lc, indexIds, lc2, newIndexIds)
44354346
{
44364347
ReindexIndexInfo *oldidx = lfirst(lc);
@@ -4486,12 +4397,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
44864397
CommitTransactionCommand();
44874398
StartTransactionCommand();
44884399

4489-
/*
4490-
* While we could set PROC_IN_SAFE_IC if all indexes qualified, there's no
4491-
* real need for that, because we only acquire an Xid after the wait is
4492-
* done, and that lasts for a very short period.
4493-
*/
4494-
44954400
/*
44964401
* Phase 5 of REINDEX CONCURRENTLY
44974402
*
@@ -4555,12 +4460,6 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
45554460
CommitTransactionCommand();
45564461
StartTransactionCommand();
45574462

4558-
/*
4559-
* While we could set PROC_IN_SAFE_IC if all indexes qualified, there's no
4560-
* real need for that, because we only acquire an Xid after the wait is
4561-
* done, and that lasts for a very short period.
4562-
*/
4563-
45644463
/*
45654464
* Phase 6 of REINDEX CONCURRENTLY
45664465
*
@@ -4828,36 +4727,3 @@ update_relispartition(Oid relationId, bool newval)
48284727
table_close(classRel, RowExclusiveLock);
48294728
}
48304729

4831-
/*
4832-
* Set the PROC_IN_SAFE_IC flag in MyProc->statusFlags.
4833-
*
4834-
* When doing concurrent index builds, we can set this flag
4835-
* to tell other processes concurrently running CREATE
4836-
* INDEX CONCURRENTLY or REINDEX CONCURRENTLY to ignore us when
4837-
* doing their waits for concurrent snapshots. On one hand it
4838-
* avoids pointlessly waiting for a process that's not interesting
4839-
* anyway; but more importantly it avoids deadlocks in some cases.
4840-
*
4841-
* This can be done safely only for indexes that don't execute any
4842-
* expressions that could access other tables, so index must not be
4843-
* expressional nor partial. Caller is responsible for only calling
4844-
* this routine when that assumption holds true.
4845-
*
4846-
* (The flag is reset automatically at transaction end, so it must be
4847-
* set for each transaction.)
4848-
*/
4849-
static inline void
4850-
set_indexsafe_procflags(void)
4851-
{
4852-
/*
4853-
* This should only be called before installing xid or xmin in MyProc;
4854-
* otherwise, concurrent processes could see an Xmin that moves backwards.
4855-
*/
4856-
Assert(MyProc->xid == InvalidTransactionId &&
4857-
MyProc->xmin == InvalidTransactionId);
4858-
4859-
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
4860-
MyProc->statusFlags |= PROC_IN_SAFE_IC;
4861-
ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
4862-
LWLockRelease(ProcArrayLock);
4863-
}

0 commit comments

Comments
 (0)