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

Commit fbcf4b9

Browse files
committed
Fix possible "tuple concurrently updated" error in ALTER TABLE.
When adding an inheritance parent to a table, an AccessShareLock on the parent isn't strong enough to prevent trouble, so take ShareUpdateExclusiveLock instead. Since this is a behavior change, albeit a fairly unobtrusive one, and since we have only one report from the field, no back-patch. Report by Jon Nelson, analysis by Alvaro Herrera, fix by me.
1 parent 7275899 commit fbcf4b9

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

src/backend/commands/tablecmds.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,7 +1345,14 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
13451345
AttrNumber *newattno;
13461346
AttrNumber parent_attno;
13471347

1348-
relation = heap_openrv(parent, AccessShareLock);
1348+
/*
1349+
* A self-exclusive lock is needed here. If two backends attempt to
1350+
* add children to the same parent simultaneously, and that parent has
1351+
* no pre-existing children, then both will attempt to update the
1352+
* parent's relhassubclass field, leading to a "tuple concurrently
1353+
* updated" error.
1354+
*/
1355+
relation = heap_openrv(parent, ShareUpdateExclusiveLock);
13491356

13501357
if (relation->rd_rel->relkind != RELKIND_RELATION)
13511358
ereport(ERROR,
@@ -7942,10 +7949,10 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
79427949
List *children;
79437950

79447951
/*
7945-
* AccessShareLock on the parent is what's obtained during normal CREATE
7946-
* TABLE ... INHERITS ..., so should be enough here.
7952+
* A self-exclusive lock is needed here. See the similar case in
7953+
* MergeAttributes() for a full explanation.
79477954
*/
7948-
parent_rel = heap_openrv(parent, AccessShareLock);
7955+
parent_rel = heap_openrv(parent, ShareUpdateExclusiveLock);
79497956

79507957
/*
79517958
* Must be owner of both parent and child -- child was checked by

0 commit comments

Comments
 (0)