mirror of
https://github.com/postgres/postgres.git
synced 2025-07-12 21:01:52 +03:00
Add an isolation test to exercise parallel-worker deadlock resolution.
Commita1c1af2a1
added logic in the deadlock checker to handle lock grouping, but it was very poorly tested, as evidenced by the bug fixed in3420851a2
. Add a test case that exercises that a bit better (and catches the bug --- if you revert3420851a2
, this will hang). Since it's pretty hard to get parallel workers to take exclusive regular locks that their parents don't already have, this test operates by creating a deadlock among advisory locks taken in parallel workers. To make that happen, we must override the parallel-safety labeling of the advisory-lock functions, which we do by putting them in mislabeled, non-inlinable wrapper functions. We also have to remove the redundant PreventAdvisoryLocksInParallelMode checks in lockfuncs.c. That seems fine though; if some user accidentally does what this test is intentionally doing, not much harm will ensue. (If there are any remaining bugs that are reachable that way, they're probably reachable in other ways too.) Discussion: https://postgr.es/m/3243.1564437314@sss.pgh.pa.us
This commit is contained in:
@ -655,15 +655,6 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
|
||||
#define SET_LOCKTAG_INT32(tag, key1, key2) \
|
||||
SET_LOCKTAG_ADVISORY(tag, MyDatabaseId, key1, key2, 2)
|
||||
|
||||
static void
|
||||
PreventAdvisoryLocksInParallelMode(void)
|
||||
{
|
||||
if (IsInParallelMode())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
|
||||
errmsg("cannot use advisory locks during a parallel operation")));
|
||||
}
|
||||
|
||||
/*
|
||||
* pg_advisory_lock(int8) - acquire exclusive lock on an int8 key
|
||||
*/
|
||||
@ -673,7 +664,6 @@ pg_advisory_lock_int8(PG_FUNCTION_ARGS)
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
(void) LockAcquire(&tag, ExclusiveLock, true, false);
|
||||
@ -691,7 +681,6 @@ pg_advisory_xact_lock_int8(PG_FUNCTION_ARGS)
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
(void) LockAcquire(&tag, ExclusiveLock, false, false);
|
||||
@ -708,7 +697,6 @@ pg_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
(void) LockAcquire(&tag, ShareLock, true, false);
|
||||
@ -726,7 +714,6 @@ pg_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS)
|
||||
int64 key = PG_GETARG_INT64(0);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
(void) LockAcquire(&tag, ShareLock, false, false);
|
||||
@ -746,7 +733,6 @@ pg_try_advisory_lock_int8(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockAcquire(&tag, ExclusiveLock, true, true);
|
||||
@ -767,7 +753,6 @@ pg_try_advisory_xact_lock_int8(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockAcquire(&tag, ExclusiveLock, false, true);
|
||||
@ -787,7 +772,6 @@ pg_try_advisory_lock_shared_int8(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockAcquire(&tag, ShareLock, true, true);
|
||||
@ -808,7 +792,6 @@ pg_try_advisory_xact_lock_shared_int8(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockAcquire(&tag, ShareLock, false, true);
|
||||
@ -828,7 +811,6 @@ pg_advisory_unlock_int8(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockRelease(&tag, ExclusiveLock, true);
|
||||
@ -848,7 +830,6 @@ pg_advisory_unlock_shared_int8(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT64(tag, key);
|
||||
|
||||
res = LockRelease(&tag, ShareLock, true);
|
||||
@ -866,7 +847,6 @@ pg_advisory_lock_int4(PG_FUNCTION_ARGS)
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
(void) LockAcquire(&tag, ExclusiveLock, true, false);
|
||||
@ -885,7 +865,6 @@ pg_advisory_xact_lock_int4(PG_FUNCTION_ARGS)
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
(void) LockAcquire(&tag, ExclusiveLock, false, false);
|
||||
@ -903,7 +882,6 @@ pg_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
(void) LockAcquire(&tag, ShareLock, true, false);
|
||||
@ -922,7 +900,6 @@ pg_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS)
|
||||
int32 key2 = PG_GETARG_INT32(1);
|
||||
LOCKTAG tag;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
(void) LockAcquire(&tag, ShareLock, false, false);
|
||||
@ -943,7 +920,6 @@ pg_try_advisory_lock_int4(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockAcquire(&tag, ExclusiveLock, true, true);
|
||||
@ -965,7 +941,6 @@ pg_try_advisory_xact_lock_int4(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockAcquire(&tag, ExclusiveLock, false, true);
|
||||
@ -986,7 +961,6 @@ pg_try_advisory_lock_shared_int4(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockAcquire(&tag, ShareLock, true, true);
|
||||
@ -1008,7 +982,6 @@ pg_try_advisory_xact_lock_shared_int4(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
LockAcquireResult res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockAcquire(&tag, ShareLock, false, true);
|
||||
@ -1029,7 +1002,6 @@ pg_advisory_unlock_int4(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockRelease(&tag, ExclusiveLock, true);
|
||||
@ -1050,7 +1022,6 @@ pg_advisory_unlock_shared_int4(PG_FUNCTION_ARGS)
|
||||
LOCKTAG tag;
|
||||
bool res;
|
||||
|
||||
PreventAdvisoryLocksInParallelMode();
|
||||
SET_LOCKTAG_INT32(tag, key1, key2);
|
||||
|
||||
res = LockRelease(&tag, ShareLock, true);
|
||||
|
Reference in New Issue
Block a user