From 4c65f8e58b0f0eae4a9ea6aba8838273c1bc8c62 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Tue, 9 Jan 2024 13:30:56 +0900 Subject: [PATCH v9 3/4] Add regression test to show snapbuild consistency Reverting 409f9ca44713 causes the test to fail. The test added here relies on the existing callbacks in injection_points. --- src/backend/replication/logical/snapbuild.c | 3 ++ src/test/recovery/Makefile | 7 ++- src/test/recovery/meson.build | 4 ++ src/test/recovery/t/040_snapshot_status.pl | 51 +++++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/test/recovery/t/040_snapshot_status.pl diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index a0b7947d2f..93048afc2f 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -141,6 +141,7 @@ #include "storage/procarray.h" #include "storage/standby.h" #include "utils/builtins.h" +#include "utils/injection_point.h" #include "utils/memutils.h" #include "utils/snapmgr.h" #include "utils/snapshot.h" @@ -654,6 +655,8 @@ SnapBuildInitialSnapshot(SnapBuild *builder) snap->xcnt = newxcnt; snap->xip = newxip; + INJECTION_POINT("SnapBuildInitialSnapshot"); + return snap; } diff --git a/src/test/recovery/Makefile b/src/test/recovery/Makefile index 17ee353735..f57baba5e8 100644 --- a/src/test/recovery/Makefile +++ b/src/test/recovery/Makefile @@ -9,12 +9,17 @@ # #------------------------------------------------------------------------- -EXTRA_INSTALL=contrib/pg_prewarm contrib/pg_stat_statements contrib/test_decoding +EXTRA_INSTALL=contrib/pg_prewarm \ + contrib/pg_stat_statements \ + contrib/test_decoding \ + src/test/modules/injection_points subdir = src/test/recovery top_builddir = ../../.. include $(top_builddir)/src/Makefile.global +export enable_injection_points enable_injection_points + # required for 017_shm.pl and 027_stream_regress.pl REGRESS_SHLIB=$(abs_top_builddir)/src/test/regress/regress$(DLSUFFIX) export REGRESS_SHLIB diff --git a/src/test/recovery/meson.build b/src/test/recovery/meson.build index 88fb0306f5..43d7411a79 100644 --- a/src/test/recovery/meson.build +++ b/src/test/recovery/meson.build @@ -6,6 +6,9 @@ tests += { 'bd': meson.current_build_dir(), 'tap': { 'test_kwargs': {'priority': 40}, # recovery tests are slow, start early + 'env': { + 'enable_injection_points': get_option('injection_points') ? 'yes' : 'no', + }, 'tests': [ 't/001_stream_rep.pl', 't/002_archiving.pl', @@ -45,6 +48,7 @@ tests += { 't/037_invalid_database.pl', 't/038_save_logical_slots_shutdown.pl', 't/039_end_of_wal.pl', + 't/040_snapshot_status.pl', ], }, } diff --git a/src/test/recovery/t/040_snapshot_status.pl b/src/test/recovery/t/040_snapshot_status.pl new file mode 100644 index 0000000000..e77b138144 --- /dev/null +++ b/src/test/recovery/t/040_snapshot_status.pl @@ -0,0 +1,51 @@ +# Test consistent of initial snapshot data. + +# This requires a node with wal_level=logical combined with an injection +# point that forces a failure when a snapshot is initially built with a +# logical slot created. +# +# See bug https://postgr.es/m/CAFiTN-s0zA1Kj0ozGHwkYkHwa5U0zUE94RSc_g81WrpcETB5=w@mail.gmail.com. + +use strict; +use warnings; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +if ($ENV{enable_injection_points} ne 'yes') +{ + plan skip_all => 'Injection points not supported by this build'; +} + +my $node = PostgreSQL::Test::Cluster->new('node'); +$node->init(allows_streaming => 'logical'); +$node->start; + +$node->safe_psql('postgres', 'CREATE EXTENSION injection_points;'); +$node->safe_psql('postgres', + "SELECT injection_points_attach('SnapBuildInitialSnapshot', 'error');"); + +my $node_host = $node->host; +my $node_port = $node->port; +my $connstr_common = "host=$node_host port=$node_port"; +my $connstr_db = "$connstr_common replication=database dbname=postgres"; + +# This requires a single session, with two commands. +my $psql_session = + $node->background_psql('postgres', on_error_stop => 0, + extra_params => [ '-d', $connstr_db ]); +my ($output, $ret) = $psql_session->query( + 'CREATE_REPLICATION_SLOT "slot" LOGICAL "pgoutput";'); +ok($ret != 0, "First CREATE_REPLICATION_SLOT fails on injected error"); + +# Now remove the injected error and check that the second command works. +$node->safe_psql('postgres', + "SELECT injection_points_detach('SnapBuildInitialSnapshot');"); + +($output, $ret) = $psql_session->query( + 'CREATE_REPLICATION_SLOT "slot" LOGICAL "pgoutput";'); +ok(substr($output, 0, 4) eq 'slot', + "Second CREATE_REPLICATION_SLOT passes"); + +done_testing(); -- 2.43.0