From 062bf8a06f68b7d543288260dd0cdf50bb5e9a72 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Thu, 14 Jul 2022 16:56:17 +0900 Subject: [PATCH] Add TAP test for BASE_BACKUP cancellation with pg_stop_backup() --- src/test/recovery/t/033_basebackup_cancel.pl | 60 ++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/test/recovery/t/033_basebackup_cancel.pl diff --git a/src/test/recovery/t/033_basebackup_cancel.pl b/src/test/recovery/t/033_basebackup_cancel.pl new file mode 100644 index 0000000000..56cbaf83d0 --- /dev/null +++ b/src/test/recovery/t/033_basebackup_cancel.pl @@ -0,0 +1,60 @@ +# Copyright (c) 2021-2022, PostgreSQL Global Development Group + +# BASE_BACKUP cancellation with replication database connection. +use strict; +use warnings; +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; +use Test::More; + +# Initialize primary node +my $node = PostgreSQL::Test::Cluster->new('node'); +$node->init(allows_streaming => 1); +$node->append_conf('postgresql.conf', 'log_replication_commands = on'); +$node->start; + +note "testing BASE_BACKUP cancellation"; + +my $sigchld_bb_timeout = + IPC::Run::timer($PostgreSQL::Test::Utils::timeout_default); + +# This test requires a replication connection with a database, as it mixes +# a replication command and a SQL command. The first BASE_BACKUP is throttled +# to give enough room for the cancellation running below. The second command +# for pg_backup_stop() should fail. +my $connstr = + $node->connstr('postgres') . " replication=database dbname=postgres"; +my ($sigchld_bb_stdin, $sigchld_bb_stdout, $sigchld_bb_stderr) = ('', '', ''); +my $sigchld_bb = IPC::Run::start( + [ + 'psql', '-X', '-c', "BASE_BACKUP (CHECKPOINT 'fast', MAX_RATE 32);", + '-c', 'SELECT pg_backup_stop()', + '-d', $connstr + ], + '<', + \$sigchld_bb_stdin, + '>', + \$sigchld_bb_stdout, + '2>', + \$sigchld_bb_stderr, + $sigchld_bb_timeout); + +# Waiting on the wait event BaseBackupThrottle ensures that the checkpoint +# issued at backup start completes, making the cancellation happen in the +# middle of the base backup sent. +is( $node->poll_query_until( + 'postgres', + "SELECT pg_cancel_backend(pid) FROM pg_stat_activity WHERE " + . "wait_event = 'BaseBackupThrottle' " + . "AND backend_type = 'walsender' AND query ~ 'BASE_BACKUP'"), + "1", + "WAL sender sending base backup killed"); + +# The psql command should fail on pg_stop_backup(). +ok( pump_until( + $sigchld_bb, $sigchld_bb_timeout, + \$sigchld_bb_stderr, qr/backup is not in progress/), + 'base backup cleanly cancelled'); +$sigchld_bb->finish(); + +done_testing(); -- 2.36.1