Skip to content

Commit 9a3cebe

Browse files
committed
Change executor to just Assert that table locks were already obtained.
Instead of locking tables during executor startup, just Assert that suitable locks were obtained already during the parse/plan pipeline (or re-obtained by the plan cache). This must be so, else we have a hazard that concurrent DDL has invalidated the plan. This is pretty inefficient as well as undercommented, but it's all going to go away shortly, so I didn't try hard. This commit is just another attempt to use the buildfarm to see if we've missed anything in the plan to simplify the executor's table management. Note that the change needed here in relation_open() exposes that parallel workers now really are accessing tables without holding any lock of their own, whereas they were not doing that before this commit. This does not give me a warm fuzzy feeling about that aspect of parallel query; it does not seem like a good design, and we now know that it's had exactly no actual testing. I think that we should modify parallel query so that that change can be reverted. Discussion: https://postgr.es/m/468c85d9-540e-66a2-1dde-fec2b741e688@lab.ntt.co.jp
1 parent c03c144 commit 9a3cebe

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

src/backend/access/heap/heapam.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,9 +1140,13 @@ relation_open(Oid relationId, LOCKMODE lockmode)
11401140
/*
11411141
* If we didn't get the lock ourselves, assert that caller holds one,
11421142
* except in bootstrap mode where no locks are used.
1143+
*
1144+
* Also, parallel workers currently assume that their parent holds locks
1145+
* for tables used in the parallel query (a mighty shaky assumption).
11431146
*/
11441147
Assert(lockmode != NoLock ||
11451148
IsBootstrapProcessingMode() ||
1149+
IsParallelWorker() ||
11461150
CheckRelationLockedByMe(r, AccessShareLock, true));
11471151

11481152
/* Make note that we've accessed a temporary relation */

src/backend/executor/execMain.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -849,8 +849,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
849849
Relation resultRelation;
850850

851851
resultRelationOid = getrelid(resultRelationIndex, rangeTable);
852-
Assert(rt_fetch(resultRelationIndex, rangeTable)->rellockmode == RowExclusiveLock);
853-
resultRelation = heap_open(resultRelationOid, RowExclusiveLock);
852+
resultRelation = heap_open(resultRelationOid, NoLock);
853+
Assert(CheckRelationLockedByMe(resultRelation, RowExclusiveLock, true));
854854

855855
InitResultRelInfo(resultRelInfo,
856856
resultRelation,
@@ -890,8 +890,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
890890
Relation resultRelDesc;
891891

892892
resultRelOid = getrelid(resultRelIndex, rangeTable);
893-
Assert(rt_fetch(resultRelIndex, rangeTable)->rellockmode == RowExclusiveLock);
894-
resultRelDesc = heap_open(resultRelOid, RowExclusiveLock);
893+
resultRelDesc = heap_open(resultRelOid, NoLock);
894+
Assert(CheckRelationLockedByMe(resultRelDesc, RowExclusiveLock, true));
895895
InitResultRelInfo(resultRelInfo,
896896
resultRelDesc,
897897
lfirst_int(l),
@@ -903,7 +903,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
903903
estate->es_root_result_relations = resultRelInfos;
904904
estate->es_num_root_result_relations = num_roots;
905905

906-
/* Simply lock the rest of them. */
906+
/* Simply check the rest of them are locked. */
907+
#ifdef USE_ASSERT_CHECKING
907908
foreach(l, plannedstmt->nonleafResultRelations)
908909
{
909910
Index resultRelIndex = lfirst_int(l);
@@ -912,11 +913,15 @@ InitPlan(QueryDesc *queryDesc, int eflags)
912913
if (!list_member_int(plannedstmt->rootResultRelations,
913914
resultRelIndex))
914915
{
915-
Assert(rt_fetch(resultRelIndex, rangeTable)->rellockmode == RowExclusiveLock);
916-
LockRelationOid(getrelid(resultRelIndex, rangeTable),
917-
RowExclusiveLock);
916+
Relation resultRelDesc;
917+
918+
resultRelDesc = heap_open(getrelid(resultRelIndex, rangeTable),
919+
NoLock);
920+
Assert(CheckRelationLockedByMe(resultRelDesc, RowExclusiveLock, true));
921+
heap_close(resultRelDesc, NoLock);
918922
}
919923
}
924+
#endif
920925
}
921926
}
922927
else
@@ -945,7 +950,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
945950
{
946951
PlanRowMark *rc = (PlanRowMark *) lfirst(l);
947952
Oid relid;
948-
LOCKMODE rellockmode;
949953
Relation relation;
950954
ExecRowMark *erm;
951955

@@ -963,8 +967,10 @@ InitPlan(QueryDesc *queryDesc, int eflags)
963967
case ROW_MARK_SHARE:
964968
case ROW_MARK_KEYSHARE:
965969
case ROW_MARK_REFERENCE:
966-
rellockmode = rt_fetch(rc->rti, rangeTable)->rellockmode;
967-
relation = heap_open(relid, rellockmode);
970+
relation = heap_open(relid, NoLock);
971+
Assert(CheckRelationLockedByMe(relation,
972+
rt_fetch(rc->rti, rangeTable)->rellockmode,
973+
true));
968974
break;
969975
case ROW_MARK_COPY:
970976
/* no physical table access is required */

src/backend/executor/execUtils.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
#include "postgres.h"
4444

45+
#include "access/parallel.h"
4546
#include "access/relscan.h"
4647
#include "access/transam.h"
4748
#include "executor/executor.h"
@@ -648,12 +649,14 @@ ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
648649
{
649650
Relation rel;
650651
Oid reloid;
651-
LOCKMODE lockmode;
652652

653-
/* Open the relation and acquire lock as needed */
653+
/* Open the relation and verify lock was obtained upstream */
654654
reloid = getrelid(scanrelid, estate->es_range_table);
655-
lockmode = rt_fetch(scanrelid, estate->es_range_table)->rellockmode;
656-
rel = heap_open(reloid, lockmode);
655+
rel = heap_open(reloid, NoLock);
656+
Assert(IsParallelWorker() ||
657+
CheckRelationLockedByMe(rel,
658+
rt_fetch(scanrelid, estate->es_range_table)->rellockmode,
659+
true));
657660

658661
/*
659662
* Complain if we're attempting a scan of an unscannable relation, except

0 commit comments

Comments
 (0)