Skip to content

Commit 3420851

Browse files
committed
Fix busted logic for parallel lock grouping in TopoSort().
A "break" statement erroneously left behind by commit a1c1af2 caused TopoSort to do the wrong thing if a lock's wait list contained multiple members of the same locking group. Because parallel workers don't normally need any locks not already taken by their leader, this is very hard --- maybe impossible --- to hit in production. Still, if it did happen, the queries involved in an otherwise-resolvable deadlock would block until canceled. In addition to removing the bogus "break", add an Assert showing that the conflicting uses of the beforeConstraints[] array (for both counts and flags) don't overlap, and add some commentary explaining why not; because it's not obvious without explanation, IMHO. Original report and patch from Rui Hai Jiang; additional assert and commentary by me. Back-patch to 9.6 where the bug came in. Discussion: https://postgr.es/m/CAEri+mLd3bpHLyW+a9pSe1y=aEkeuJpwBSwvo-+m4n7-ceRmXw@mail.gmail.com
1 parent 1e2fddf commit 3420851

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

src/backend/storage/lmgr/deadlock.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,12 @@ TopoSort(LOCK *lock,
922922
* in the same lock group on the queue, set their number of
923923
* beforeConstraints to -1 to indicate that they should be emitted
924924
* with their groupmates rather than considered separately.
925+
*
926+
* In this loop and the similar one just below, it's critical that we
927+
* consistently select the same representative member of any one lock
928+
* group, so that all the constraints are associated with the same
929+
* proc, and the -1's are only associated with not-representative
930+
* members. We select the last one in the topoProcs array.
925931
*/
926932
proc = constraints[i].waiter;
927933
Assert(proc != NULL);
@@ -940,7 +946,6 @@ TopoSort(LOCK *lock,
940946
Assert(beforeConstraints[j] <= 0);
941947
beforeConstraints[j] = -1;
942948
}
943-
break;
944949
}
945950
}
946951

@@ -977,6 +982,7 @@ TopoSort(LOCK *lock,
977982
if (kk < 0)
978983
continue;
979984

985+
Assert(beforeConstraints[jj] >= 0);
980986
beforeConstraints[jj]++; /* waiter must come before */
981987
/* add this constraint to list of after-constraints for blocker */
982988
constraints[i].pred = jj;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy