From 6613850df90f60a6e9daa0677bd81c64d5eb3107 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Tue, 8 Sep 2020 20:49:37 -0700 Subject: [PATCH v1 2/3] WIP: Treat BufferPin as a waiting condition in isolationtest. --- src/include/storage/procarray.h | 1 + src/backend/storage/ipc/procarray.c | 24 ++++++++++++++++++++++++ src/backend/utils/adt/lockfuncs.c | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h index ea8a876ca45..62ee6833787 100644 --- a/src/include/storage/procarray.h +++ b/src/include/storage/procarray.h @@ -66,6 +66,7 @@ extern PGPROC *BackendPidGetProc(int pid); extern PGPROC *BackendPidGetProcWithLock(int pid); extern int BackendXidGetPid(TransactionId xid); extern bool IsBackendPid(int pid); +extern uint32 BackendPidGetWaitEvent(int pid); extern VirtualTransactionId *GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, bool allDbs, int excludeVacuum, diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 1c0cd6b2487..5fb67e0e217 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -3023,6 +3023,30 @@ BackendPidGetProcWithLock(int pid) return result; } +/* + * BackendPidGetWaitEvent -- return wait event of a backend + * + * This return 0 both if there is no backend with the passed PID and if the + * backend exists but is not currently waiting. + */ +uint32 +BackendPidGetWaitEvent(int pid) +{ + PGPROC *proc; + uint32 raw_wait_event = 0; + + LWLockAcquire(ProcArrayLock, LW_SHARED); + + proc = BackendPidGetProcWithLock(pid); + + if (proc) + raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info); + + LWLockRelease(ProcArrayLock); + + return raw_wait_event; +} + /* * BackendXidGetPid -- get a backend's pid given its XID * diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c index f592292d067..1f41a85d496 100644 --- a/src/backend/utils/adt/lockfuncs.c +++ b/src/backend/utils/adt/lockfuncs.c @@ -17,7 +17,9 @@ #include "catalog/pg_type.h" #include "funcapi.h" #include "miscadmin.h" +#include "pgstat.h" #include "storage/predicate_internals.h" +#include "storage/procarray.h" #include "utils/array.h" #include "utils/builtins.h" @@ -601,6 +603,7 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS) int num_interesting_pids; int num_blocking_pids; int dummy; + uint32 raw_wait_event; int i, j; @@ -653,6 +656,28 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS) if (GetSafeSnapshotBlockingPids(blocked_pid, &dummy, 1) > 0) PG_RETURN_BOOL(true); + raw_wait_event = BackendPidGetWaitEvent(blocked_pid); + + if (raw_wait_event != 0) + { + const char* wait_event_type; + const char* wait_event; + + /* + * FIXME: probably better to match on the integer value itself. But + * currently the class / event mask is not exposed outside pgstat.c... + */ + wait_event_type = pgstat_get_wait_event_type(raw_wait_event); + wait_event = pgstat_get_wait_event(raw_wait_event); + + if (wait_event_type != NULL && wait_event_type != NULL && + strcmp(wait_event_type, "BufferPin") == 0 && + strcmp(wait_event, "BufferPin") == 0) + { + PG_RETURN_BOOL(true); + } + } + PG_RETURN_BOOL(false); } -- 2.25.0.114.g5b0ca878e0