mirror of
https://github.com/postgres/postgres.git
synced 2025-11-09 06:21:09 +03:00
Add an injection_points isolation test suite.
Make the isolation harness recognize injection_points wait events as a type of blocked state. Test an extant inplace-update bug. Reviewed by Robert Haas and Michael Paquier. Discussion: https://postgr.es/m/20240512232923.aa.nmisch@google.com
This commit is contained in:
@@ -63,6 +63,7 @@
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/standby.h"
|
||||
#include "utils/datum.h"
|
||||
#include "utils/injection_point.h"
|
||||
#include "utils/inval.h"
|
||||
#include "utils/relcache.h"
|
||||
#include "utils/snapmgr.h"
|
||||
@@ -6080,6 +6081,7 @@ heap_inplace_update(Relation relation, HeapTuple tuple)
|
||||
(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
|
||||
errmsg("cannot update tuples during a parallel operation")));
|
||||
|
||||
INJECTION_POINT("inplace-before-pin");
|
||||
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&(tuple->t_self)));
|
||||
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
|
||||
page = (Page) BufferGetPage(buffer);
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
|
||||
#include "catalog/pg_type.h"
|
||||
#include "storage/predicate_internals.h"
|
||||
#include "storage/proc.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/wait_event.h"
|
||||
|
||||
#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
|
||||
|
||||
|
||||
/*
|
||||
@@ -23,8 +28,9 @@
|
||||
*
|
||||
* Check if specified PID is blocked by any of the PIDs listed in the second
|
||||
* argument. Currently, this looks for blocking caused by waiting for
|
||||
* heavyweight locks or safe snapshots. We ignore blockage caused by PIDs
|
||||
* not directly under the isolationtester's control, eg autovacuum.
|
||||
* injection points, heavyweight locks, or safe snapshots. We ignore blockage
|
||||
* caused by PIDs not directly under the isolationtester's control, eg
|
||||
* autovacuum.
|
||||
*
|
||||
* This is an undocumented function intended for use by the isolation tester,
|
||||
* and may change in future releases as required for testing purposes.
|
||||
@@ -34,6 +40,8 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int blocked_pid = PG_GETARG_INT32(0);
|
||||
ArrayType *interesting_pids_a = PG_GETARG_ARRAYTYPE_P(1);
|
||||
PGPROC *proc;
|
||||
const char *wait_event_type;
|
||||
ArrayType *blocking_pids_a;
|
||||
int32 *interesting_pids;
|
||||
int32 *blocking_pids;
|
||||
@@ -43,6 +51,15 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
|
||||
int i,
|
||||
j;
|
||||
|
||||
/* Check if blocked_pid is in an injection point. */
|
||||
proc = BackendPidGetProc(blocked_pid);
|
||||
if (proc == NULL)
|
||||
PG_RETURN_BOOL(false); /* session gone: definitely unblocked */
|
||||
wait_event_type =
|
||||
pgstat_get_wait_event_type(UINT32_ACCESS_ONCE(proc->wait_event_info));
|
||||
if (wait_event_type && strcmp("InjectionPoint", wait_event_type) == 0)
|
||||
PG_RETURN_BOOL(true);
|
||||
|
||||
/* Validate the passed-in array */
|
||||
Assert(ARR_ELEMTYPE(interesting_pids_a) == INT4OID);
|
||||
if (array_contains_nulls(interesting_pids_a))
|
||||
|
||||
Reference in New Issue
Block a user