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

Commit 9353d94

Browse files
Handle parallel index builds on mapped relations.
Commit 9da0cc3, which introduced parallel CREATE INDEX, failed to propagate relmapper.c backend local cache state to parallel worker processes. This could result in parallel index builds against mapped catalog relations where the leader process (participating as a worker) scans the new, pristine relfilenode, while worker processes scan the obsolescent relfilenode. When this happened, the final index structure was typically not consistent with the owning table's structure. The final index structure could contain entries formed from both heap relfilenodes. Only rebuilds on mapped catalog relations that occur as part of a VACUUM FULL or CLUSTER could become corrupt in practice, since their mapped relation relfilenode swap is what allows the inconsistency to arise. On master, fix the problem by propagating the required relmapper.c backend state as part of standard parallel initialization (Cf. commit 29d58fd). On v11, simply disallow builds against mapped catalog relations by deeming them parallel unsafe. Author: Peter Geoghegan Reported-By: "death lock" Reviewed-By: Tom Lane, Amit Kapila Bug: #15309 Discussion: https://postgr.es/m/153329671686.1405.18298309097348420351@wrigleys.postgresql.org Backpatch: 11-, where parallel CREATE INDEX was introduced.
1 parent 1b9d1b0 commit 9353d94

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

src/backend/optimizer/plan/planner.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6093,11 +6093,13 @@ plan_create_index_workers(Oid tableOid, Oid indexOid)
60936093
/*
60946094
* Determine if it's safe to proceed.
60956095
*
6096-
* Currently, parallel workers can't access the leader's temporary tables.
6097-
* Furthermore, any index predicate or index expressions must be parallel
6098-
* safe.
6096+
* Currently, parallel workers can't access the leader's temporary tables,
6097+
* or the leader's relmapper.c state, which is needed for builds on mapped
6098+
* relations. Furthermore, any index predicate or index expressions must
6099+
* be parallel safe.
60996100
*/
61006101
if (heap->rd_rel->relpersistence == RELPERSISTENCE_TEMP ||
6102+
RelationIsMapped(heap) ||
61016103
!is_parallel_safe(root, (Node *) RelationGetIndexExpressions(index)) ||
61026104
!is_parallel_safe(root, (Node *) RelationGetIndexPredicate(index)))
61036105
{

src/backend/utils/cache/relmapper.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,13 +263,17 @@ RelationMapUpdateMap(Oid relationId, Oid fileNode, bool shared,
263263
else
264264
{
265265
/*
266-
* We don't currently support map changes within subtransactions. This
267-
* could be done with more bookkeeping infrastructure, but it doesn't
268-
* presently seem worth it.
266+
* We don't currently support map changes within subtransactions, and
267+
* parallel workers must avoid relying on mapping state, since it
268+
* isn't propagated from the leader. This could be done with more
269+
* bookkeeping infrastructure, but it doesn't presently seem worth it.
269270
*/
270271
if (GetCurrentTransactionNestLevel() > 1)
271272
elog(ERROR, "cannot change relation mapping within subtransaction");
272273

274+
if (IsInParallelMode())
275+
elog(ERROR, "cannot change relation mapping in parallel mode");
276+
273277
if (immediate)
274278
{
275279
/* Make it active, but only locally */

0 commit comments

Comments
 (0)