From a61958407770b6cb864e0b245a4341e033824f46 Mon Sep 17 00:00:00 2001 From: "Andrey M. Borodin" Date: Sun, 28 Jan 2024 23:10:55 +0500 Subject: [PATCH 3/3] Try to test multixact CV sleep --- src/backend/access/transam/multixact.c | 5 ++ .../injection_points--1.0.sql | 11 ++++ .../injection_points/injection_points.c | 26 ++++++++ .../modules/injection_points/t/001_wait.pl | 64 +++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 src/test/modules/injection_points/t/001_wait.pl diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index 03fcd25d4c..15b2a0010a 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -89,6 +89,7 @@ #include "storage/proc.h" #include "storage/procarray.h" #include "utils/builtins.h" +#include "utils/injection_point.h" #include "utils/memutils.h" #include "utils/snapmgr.h" @@ -1200,6 +1201,8 @@ GetNewMultiXactId(int nmembers, MultiXactOffset *offset) LWLockRelease(MultiXactGenLock); + INJECTION_POINT("GetNewMultiXactId-done"); + debug_elog4(DEBUG2, "GetNew: returning %u offset %u", result, *offset); return result; } @@ -1408,6 +1411,8 @@ retry: LWLockRelease(MultiXactOffsetSLRULock); CHECK_FOR_INTERRUPTS(); + INJECTION_POINT("GetMultiXactIdMembers-CV-sleep"); + ConditionVariableSleep(&MultiXactState->nextoff_cv, WAIT_EVENT_NEXT_MXMEMBERS); ConditionVariableCancelSleep(); diff --git a/src/test/modules/injection_points/injection_points--1.0.sql b/src/test/modules/injection_points/injection_points--1.0.sql index 5944c41716..d3ebda5964 100644 --- a/src/test/modules/injection_points/injection_points--1.0.sql +++ b/src/test/modules/injection_points/injection_points--1.0.sql @@ -33,3 +33,14 @@ CREATE FUNCTION injection_points_detach(IN point_name TEXT) RETURNS void AS 'MODULE_PATHNAME', 'injection_points_detach' LANGUAGE C STRICT PARALLEL UNSAFE; + + +CREATE FUNCTION create_test_multixact() +RETURNS xid +AS 'MODULE_PATHNAME', 'create_test_multixact' +LANGUAGE C STRICT PARALLEL UNSAFE; + +CREATE FUNCTION read_test_multixact(xid) +RETURNS void +AS 'MODULE_PATHNAME', 'read_test_multixact' +LANGUAGE C STRICT PARALLEL UNSAFE; \ No newline at end of file diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c index fbb30b15ad..d3d5faaa25 100644 --- a/src/test/modules/injection_points/injection_points.c +++ b/src/test/modules/injection_points/injection_points.c @@ -109,3 +109,29 @@ injection_points_detach(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + +#include "access/multixact.h" +#include "access/xact.h" + +PG_FUNCTION_INFO_V1(create_test_multixact); +Datum +create_test_multixact(PG_FUNCTION_ARGS) +{ + MultiXactId id; + MultiXactIdSetOldestMember(); + id = MultiXactIdCreate(GetCurrentTransactionId(), MultiXactStatusUpdate, + GetCurrentTransactionId(), MultiXactStatusForShare); + PG_RETURN_TRANSACTIONID(id); +} + +PG_FUNCTION_INFO_V1(read_test_multixact); +Datum +read_test_multixact(PG_FUNCTION_ARGS) +{ + MultiXactId id = PG_GETARG_TRANSACTIONID(0); + MultiXactMember *members; + INJECTION_POINT("read_test_multixact"); + if (GetMultiXactIdMembers(id,&members,false, false) == -1) + elog(ERROR, "MultiXactId not found"); + PG_RETURN_VOID(); +} \ No newline at end of file diff --git a/src/test/modules/injection_points/t/001_wait.pl b/src/test/modules/injection_points/t/001_wait.pl new file mode 100644 index 0000000000..6076ffc6ea --- /dev/null +++ b/src/test/modules/injection_points/t/001_wait.pl @@ -0,0 +1,64 @@ + +# Copyright (c) 2024, PostgreSQL Global Development Group + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; + +use Test::More; + +my ($node, $result); + +$node = PostgreSQL::Test::Cluster->new('injection_points'); +$node->init; +$node->start; +$node->safe_psql('postgres', q(CREATE EXTENSION injection_points)); + +$result = $node->psql('postgres', q(select injection_points_attach('FIRST','wait'))); +is($result, '0', 'wait injection point set'); + +my $bg = $node->background_psql('postgres'); + +$bg->query_until( + qr/start/, q( +\echo start +select injection_points_run('FIRST'); +select injection_points_attach('SECOND','wait'); +)); + +$result = $node->psql('postgres', q( +select injection_points_run('SECOND'); +select injection_points_detach('FIRST'); +)); +is($result, '0', 'wait injection point set'); + +$bg->quit; + +$node->safe_psql('postgres', q(select injection_points_attach('read_test_multixact','wait'))); +$node->safe_psql('postgres', q(select injection_points_attach('GetMultiXactIdMembers-CV-sleep','notice'))); + +my $observer = $node->background_psql('postgres'); + +$observer->query_safe( + q( +select read_test_multixact(create_test_multixact()); +)); + +$node->safe_psql('postgres', q(select injection_points_attach('GetNewMultiXactId-done','wait'))); + +my $creator = $node->background_psql('postgres'); + +$creator->query_safe( q(select create_test_multixact();)); + +$node->safe_psql('postgres', q(select injection_points_detach('read_test_multixact'))); + +$node->safe_psql('postgres', q(select injection_points_detach('GetNewMultiXactId-done'))); + +$observer->quit; + +$creator->quit; + +$node->stop; +done_testing(); -- 2.37.1 (Apple Git-137.1)