pax_global_header00006660000000000000000000000064123217440140014510gustar00rootroot0000000000000052 comment=f667d0483c9f024127da0692c96bf452c45d8cc9 pgespresso-1.0/000077500000000000000000000000001232174401400135425ustar00rootroot00000000000000pgespresso-1.0/.gitignore000066400000000000000000000000201232174401400155220ustar00rootroot00000000000000*.so *.o .deps/ pgespresso-1.0/COPYING000066400000000000000000000017411232174401400146000ustar00rootroot00000000000000pgespresso - PostgreSQL extension for Barman (www.pgbarman.org) Copyright (c) 2014, 2ndQuadrant Ltd. Permission to use, copy, modify, and distribute this software and its documentation for any purpose, without fee, and without a written agreement is hereby granted, provided that the above copyright notice and this paragraph and the following two paragraphs appear in all copies. IN NO EVENT SHALL 2NDQUADRANT BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 2NDQUADRANT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2NDQUADRANT SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 2NDQUADRANT HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. pgespresso-1.0/ChangeLog000066400000000000000000000027701232174401400153220ustar00rootroot000000000000002014-04-11 Marco Nenciarini Update the ChangeLog file Add release.sh script 2014-04-08 Gabriele Bartolini Added RPM spec file 2014-04-02 Giulio Calacoci Modified META.json. Added requirements in description and abstract 2014-03-27 Giulio Calacoci correction of json syntax added META.json file for pgxn changed version from 0.1 to 1.0 2014-03-27 Marco Nenciarini Fix COPYING file 2014-02-13 Marco Nenciarini Added basic testing script 2014-02-13 Gabriele Bartolini Cosmetic changes on comments 2014-02-13 Marco Nenciarini Add pgespresso_abort_backup function pgespresso_abort_backup allows the user to terminate a backup without any knowledge about the backup label content. This function is intended to be called by an error handler. Support PostgreSQL 9.2 2014-02-12 Marco Nenciarini Write correct file name in "START WAL LOCATION" backup_label's field ThisTimeLineID is always 0 in a normal backend during recovery. We get latest redo apply position timeline and we update it globally to make do_pg_start_backup using the correct value when generate the backup label text 2014-02-10 Gabriele Bartolini Initial commit pgespresso-1.0/META.json000066400000000000000000000033431232174401400151660ustar00rootroot00000000000000{ "name": "pgespresso", "abstract": "Optional Extension for Barman, Backup and Recovery Manager for PostgreSQL. Requires at least Barman 1.3.1 and PostgreSQL 9.2", "description": "pgespresso is an extension that adds functions and views to be used by Barman, the disaster recovery tool written by 2ndQuadrant and released as open source (http://www.pgbarman.org/). Requires at least Barman 1.3.1 and PostgreSQL 9.2 ", "version": "1.0.0", "maintainer": [ "Gabriele Bartolini ", "Giulio Calacoci ", "Marco Nenciarini " ], "license": { "PostgreSQL": "http://www.postgresql.org/about/licence" }, "prereqs":{ "runtime":{ "requires":{ "PostgreSQL": "9.2.0" } } }, "provides": { "pgespresso": { "file": "pgespresso--1.0.sql", "docfile": "README.asciidoc", "version": "1.0.0", "abstract": "Optional Extension for Barman, Backup and Recovery Manager for PostgreSQL" } }, "resources": { "homepage": "https://github.com/2ndquadrant-it/pgespresso", "bugtracker": { "web": "https://github.com/2ndquadrant-it/pgespresso/issues" }, "repository": { "url": "https://github.com/2ndquadrant-it/pgespresso.git", "web": "https://github.com/2ndquadrant-it/pgespresso", "type": "git" } }, "generated_by": "Giulio Calacoci", "release_status": "stable", "meta-spec": { "version": "1.0.0", "url": "http://pgxn.org/meta/spec.txt" }, "tags": [ "Barman", "concurrent backup", "backup", "backup from standby", "pgespresso" ] }pgespresso-1.0/Makefile000066400000000000000000000002471232174401400152050ustar00rootroot00000000000000MODULES = pgespresso OBJS = pgespresso.o EXTENSION = pgespresso DATA = pgespresso--1.0.sql PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) pgespresso-1.0/README.asciidoc000066400000000000000000000035251232174401400162040ustar00rootroot00000000000000= pgespresso Optional Extension for Barman, Backup and Recovery Manager for PostgreSQL * Version: 1.0 * Based on an idea by Simon Riggs * Authors: Gabriele Bartolini, Marco Nenciarini and Simon Riggs == Introduction *pgespresso* is an extension that adds functions and views to be used by Barman, the disaster recovery tool written by 2ndQuadrant and released as open source (http://www.pgbarman.org/). == Supported PostgreSQL and Barman versions This extension requires at least PostgreSQL 9.2 and Barman 1.3.1. == Installation To install +pgespresso+ from sources, type: ---- make make install ---- +pgespresso+ can be installed in a specific database using the following command: ---- CREATE EXTENSION pgespresso; ---- == Available functions `pgespresso_start_backup (label, fast)`:: `pgespresso_start_backup` is used to start taking a concurrent backup. It returns a backup label file that the user is responsible for placing in the $PGDATA of the backup AFTER the backup has been taken. The label file must not be written to the data directory of the server from which the backup is taken because this type of backup presumes and allows that more than one backup may be in progress at any one time. The label file contains the user-supplied label string (typically this would be used to tell where the backup dump will be stored) and the starting time and starting WAL location for the dump. `pgespresso_stop_backup (label_content)`:: `pgespresso_stop_backup` is used to stop a concurrent backup. It returns the XLOG filename containing end of backup location, combining both the TLI and the end location.footnote:[The user is responsible for ensuring that the last file is correctly archived.] `pgespresso_abort_backup ()`:: `pgespresso_abort_backup` aborts a running concurrent backup. == License pgespresso is free software. See COPYING for details. pgespresso-1.0/pgespresso--1.0.sql000066400000000000000000000010321232174401400170220ustar00rootroot00000000000000-- pgespresso - PostgreSQL extension for Barman (www.pgbarman.org) -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION pgespresso" to load this file. \quit CREATE FUNCTION pgespresso_start_backup(label TEXT, fast BOOL) RETURNS TEXT AS 'MODULE_PATHNAME' LANGUAGE C STRICT; CREATE FUNCTION pgespresso_stop_backup(label_content TEXT) RETURNS TEXT AS 'MODULE_PATHNAME' LANGUAGE C STRICT; CREATE FUNCTION pgespresso_abort_backup() RETURNS VOID AS 'MODULE_PATHNAME' LANGUAGE C STRICT; pgespresso-1.0/pgespresso.c000066400000000000000000000120161232174401400161000ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * pgespresso.c * * * Copyright (c) 2014, 2ndQuadrant Limited * * Authors: Simon Riggs * Marco Nenciarini * Gabriele Bartolini * * See COPYING for licensing information * * IDENTIFICATION * pgespresso/pgespresso.c * *------------------------------------------------------------------------- */ #include "postgres.h" #include "access/xlog.h" #include "access/xlog_internal.h" #include "access/xlogdefs.h" #include "utils/builtins.h" #include "miscadmin.h" PG_MODULE_MAGIC; Datum pgespresso_start_backup(PG_FUNCTION_ARGS); Datum pgespresso_stop_backup(PG_FUNCTION_ARGS); Datum pgespresso_abort_backup(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(pgespresso_start_backup); PG_FUNCTION_INFO_V1(pgespresso_stop_backup); PG_FUNCTION_INFO_V1(pgespresso_abort_backup); /* * pgespresso_start_backup: set up for taking an on-line backup dump * * Essentially what this does is to return a backup label file that the * user is responsible for placing in the $PGDATA of the backup AFTER * the backup has been taken. The label file must not be written to the * data directory of the server from which the backup is taken because * this type of backup presumes and allows that more than one backup * may be in progress at any one time. The label file * contains the user-supplied label string (typically this would be used * to tell where the backup dump will be stored) and the starting time and * starting WAL location for the dump. */ Datum pgespresso_start_backup(PG_FUNCTION_ARGS) { text *backupid = PG_GETARG_TEXT_P(0); bool fast = PG_GETARG_BOOL(1); char *backupidstr; char *labelfile; backupidstr = text_to_cstring(backupid); if (!superuser() && !has_rolreplication(GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser or replication role to run a backup"))); /* * ThisTimeLineID is always 0 in a normal backend during recovery. * We get latest redo apply position timeline and we update it globally * to make do_pg_start_backup use the correct value when generating * the backup label text */ if (RecoveryInProgress()) { TimeLineID replayTLI; GetXLogReplayRecPtr(&replayTLI); ThisTimeLineID = replayTLI; elog(DEBUG1, "updated ThisTimeLineID = %u", ThisTimeLineID); } /* * Starting from 9.3 the do_pg_start_backup returns the timeline ID * in *starttli_p additional argument */ #if PG_VERSION_NUM >= 90300 do_pg_start_backup(backupidstr, fast, NULL, &labelfile); #else do_pg_start_backup(backupidstr, fast, &labelfile); #endif PG_RETURN_TEXT_P(cstring_to_text(labelfile)); } /* * pgespresso_stop_backup: finish taking an on-line backup dump * * Only parameter is the labelfile returned from pg_start_concurrent_backup * * Return is the XLOG filename containing end of backup location, combining * both the TLI and the end location. NOTE: the user is responsible for * ensuring that the last file is correctly archived. */ Datum pgespresso_stop_backup(PG_FUNCTION_ARGS) { XLogRecPtr stoppoint; text *labelfile = PG_GETARG_TEXT_P(0); char *backupidstr; char xlogfilename[MAXFNAMELEN]; backupidstr = text_to_cstring(labelfile); if (!superuser() && !has_rolreplication(GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser or replication role to run a backup")))); #if PG_VERSION_NUM >= 90300 { XLogSegNo xlogsegno; TimeLineID endtli; stoppoint = do_pg_stop_backup(backupidstr, false, /* don't wait for archive */ &endtli); XLByteToPrevSeg(stoppoint, xlogsegno); XLogFileName(xlogfilename, endtli, xlogsegno); } #else { uint32 xlogid; uint32 xlogseg; stoppoint = do_pg_stop_backup(backupidstr, false); /* don't wait for archive */ /* * In 9.2 the do_pg_stop_backup doesn't return the timeline ID and * ThisTimeLineID is always 0 in a normal backend during recovery. * We get latest redo apply position timeline and we update it globally */ if (RecoveryInProgress()) { TimeLineID replayTLI; GetXLogReplayRecPtr(&replayTLI); ThisTimeLineID = replayTLI; elog(DEBUG1, "updated ThisTimeLineID = %u", ThisTimeLineID); } XLByteToPrevSeg(stoppoint, xlogid, xlogseg); XLogFileName(xlogfilename, ThisTimeLineID, xlogid, xlogseg); } #endif PG_RETURN_TEXT_P(cstring_to_text(xlogfilename)); } /* * pgespresso_abort_backup: abort a running backup * * This does just the most basic steps of pgespresso_stop_backup(), by taking * the system out of backup mode, thus making it a lot more safe to call from * an error handler. */ Datum pgespresso_abort_backup(PG_FUNCTION_ARGS) { if (!superuser() && !has_rolreplication(GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser or replication role to run a backup")))); do_pg_abort_backup(); PG_RETURN_VOID(); } pgespresso-1.0/pgespresso.control000066400000000000000000000001631232174401400173360ustar00rootroot00000000000000comment = 'pgespresso extension for Barman backups' default_version = '1.0' module_pathname = '$libdir/pgespresso' pgespresso-1.0/rpm/000077500000000000000000000000001232174401400143405ustar00rootroot00000000000000pgespresso-1.0/rpm/pgespresso.spec000066400000000000000000000025451232174401400174140ustar00rootroot00000000000000%global pgmajorversion 93 %global pginstdir /usr/pgsql-9.3 %global sname pgespresso Summary: Optional Extension for Barman, Backup and Recovery Manager for PostgreSQL Name: %{sname}%{pgmajorversion} Version: 1.0 Release: 1%{?dist} License: BSD Group: Applications/Databases Source0: %{sname}-%{version}.tar.gz URL: https://github.com/2ndquadrant-it/%{sname} BuildRequires: postgresql%{pgmajorversion}-devel Requires: postgresql%{pgmajorversion}-server BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Vendor: 2ndQuadrant Italia (Devise.IT S.r.l.) %description pgespresso is an extension that adds functions and views to be used by Barman, the disaster recovery tool written by 2ndQuadrant and released as open source. %prep %setup -q -n %{sname}-%{version} %build make PG_CONFIG=%{pginstdir}/bin/pg_config %{?_smp_mflags} %install rm -rf %{buildroot} make PG_CONFIG=%{pginstdir}/bin/pg_config %{?_smp_mflags} install DESTDIR=%{buildroot} %clean rm -rf %{buildroot} %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %defattr(644,root,root,755) %doc COPYING README.asciidoc %{pginstdir}/lib/%{sname}.so %{pginstdir}/share/extension/%{sname}*.sql %{pginstdir}/share/extension/%{sname}.control %changelog * Mon Apr 7 2013 - Marco Nenciarini 1.0-1 - Initial packaging. pgespresso-1.0/scripts/000077500000000000000000000000001232174401400152315ustar00rootroot00000000000000pgespresso-1.0/scripts/.gitignore000066400000000000000000000000061232174401400172150ustar00rootroot00000000000000test/ pgespresso-1.0/scripts/gitlog-to-changelog000077500000000000000000000112431232174401400210120ustar00rootroot00000000000000#!/usr/bin/perl # Convert git log output to ChangeLog format. my $VERSION = '2010-10-28 09:48'; # UTC # The definition above must lie within the first 8 lines in order # for the Emacs time-stamp write hook (at end) to update it. # If you change this file with Emacs, please let the write hook # do its job. Otherwise, update this string manually. # Copyright (C) 2008 Free Software Foundation, Inc. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Written by Jim Meyering use strict; use warnings; use Getopt::Long; use POSIX qw(strftime); (my $ME = $0) =~ s|.*/||; # use File::Coda; # http://meyering.net/code/Coda/ END { defined fileno STDOUT or return; close STDOUT and return; warn "$ME: failed to close standard output: $!\n"; $? ||= 1; } sub usage ($) { my ($exit_code) = @_; my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); if ($exit_code != 0) { print $STREAM "Try `$ME --help' for more information.\n"; } else { print $STREAM < ChangeLog EOF } exit $exit_code; } # If the string $S is a well-behaved file name, simply return it. # If it contains white space, quotes, etc., quote it, and return the new tring. sub shell_quote($) { my ($s) = @_; if ($s =~ m![^\w+/.,-]!) { # Convert each single quote to '\'' $s =~ s/\'/\'\\\'\'/g; # Then single quote the string. $s = "'$s'"; } return $s; } sub quoted_cmd(@) { return join (' ', map {shell_quote $_} @_); } { my $since_date = '1970-01-01 UTC'; GetOptions ( help => sub { usage 0 }, version => sub { print "$ME version $VERSION\n"; exit }, 'since=s' => \$since_date, ) or usage 1; @ARGV and (warn "$ME: too many arguments\n"), usage 1; my @cmd = (qw (git log --log-size), "--since=$since_date", '--pretty=format:%at %an <%ae>%n%n%s%n%b%n'); open PIPE, '-|', @cmd or die "$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n"; my $prev_date_line = ''; while (1) { defined (my $in = ) or last; $in =~ /^log size (\d+)$/ or die "$ME:$.: Invalid line (expected log size):\n$in"; my $log_nbytes = $1; my $log; my $n_read = read PIPE, $log, $log_nbytes; $n_read == $log_nbytes or die "$ME:$.: unexpected EOF\n"; my @line = split "\n", $log; my $author_line = shift @line; defined $author_line or die "$ME:$.: unexpected EOF\n"; $author_line =~ /^(\d+) (.*>)$/ or die "$ME:$.: Invalid line " . "(expected date/author/email):\n$author_line\n"; my $date_line = sprintf "%s $2\n", strftime ("%F", localtime ($1)); # If this line would be the same as the previous date/name/email # line, then arrange not to print it. if ($date_line ne $prev_date_line) { $prev_date_line eq '' or print "\n"; print $date_line; } $prev_date_line = $date_line; # Omit "Signed-off-by..." lines. @line = grep !/^Signed-off-by: .*>$/, @line; # Remove leading and trailing blank lines. while ($line[0] =~ /^\s*$/) { shift @line; } while ($line[$#line] =~ /^\s*$/) { pop @line; } # Prefix each non-empty line with a TAB. @line = map { length $_ ? "\t$_" : '' } @line; print "\n", join ("\n", @line), "\n"; defined ($in = ) or last; $in ne "\n" and die "$ME:$.: unexpected line:\n$in"; } close PIPE or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n"; # FIXME-someday: include $PROCESS_STATUS in the diagnostic } # Local Variables: # indent-tabs-mode: nil # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "my $VERSION = '" # time-stamp-format: "%:y-%02m-%02d %02H:%02M" # time-stamp-time-zone: "UTC" # time-stamp-end: "'; # UTC" # End: pgespresso-1.0/scripts/release.sh000077500000000000000000000011731232174401400172120ustar00rootroot00000000000000#!/bin/sh # Copyright (C) 2011-2014 2ndQuadrant Italia (Devise.IT S.r.L.) # # This file is part of pgespresso. # # See COPYING for licensing information set -e BASE="$(dirname $(cd $(dirname "$0"); pwd))" cd "$BASE" VERSION="$(awk -F "[[:space:]=']+" '/default_version/{print $2}' pgespresso.control)" scripts/gitlog-to-changelog > ChangeLog git add ChangeLog git commit -m "Update the ChangeLog file" scripts/gitlog-to-changelog > ChangeLog git add ChangeLog git commit -m "Update the ChangeLog file" --amend if ! git tag -s -m "Release ${VERSION}" ${VERSION} then echo "Cannot tag the release as the private key is missing" fi pgespresso-1.0/scripts/test-pgespresso.sh000077500000000000000000000143451232174401400207460ustar00rootroot00000000000000#!/bin/bash # Basic test script for concurrent backup from a standby # using pgespresso and rsync. By default, it creates a # test directory (within the current directory) containing # the required Postgres clusters. # # Requirements: PostgreSQL 9.2 or 9.3 # Recommended: pgbench # # Usage: ./test-pgespresso.sh # Cleanup: ./test-pgespresso.sh destroy # # Copyright (c) 2014, 2ndQuadrant Limited # # Author: Marco Nenciarini # # See COPYING for licensing information # set -e # in case of error print a red error message trap "echo -e '\033[1;31mERROR!\033[0m'" ERR destdir=$(mkdir -p test && cd test && pwd) waldir="$destdir/archive" masterdir="$destdir/master" masterlog="/tmp/master.log" masterport="6432" standbydir="$destdir/standby" standbylog="/tmp/standby.log" standbyport="6433" backupdir="$destdir/backup" backuplog="/tmp/backup.log" backupport="6434" # reset the postgres environment unset PGDATA PGHOST PGPORT PGPASSWORD export PGUSER=postgres export PGHOST=/tmp # print a green progress message progress() { echo -e "\033[1;32m$*\033[0m" } # if the first argument is "destroy" dispose the test environment if [ "$1" = "destroy" ] then progress "Destroying the test environment" pg_ctl -D "$masterdir" -w stop || : pg_ctl -D "$standbydir" -w stop || : pg_ctl -D "$backupdir" -w stop || : rm -fr "$destdir" echo progress "Done. Test environment destroyed." echo exit 0 fi # initialize the wal archive mkdir -p "$waldir" # initdb the master if not exists if [ ! -e "$masterdir/PG_VERSION" ] then progress "Creating the master instance" mkdir -p "$masterdir" # if postgres 9.3 or greater enable checksum version=($(initdb --version | sed -e 's/.* //; s/\./ /g')) if [ "${version[0]}" -gt "9" ] || ([ "${version[0]}" = "9" ] && [ "${version[1]}" -ge "3" ]) then initdb -k -D "$masterdir" -U "$PGUSER" else initdb -D "$masterdir" -U "$PGUSER" fi cat >> "$masterdir/postgresql.conf" <> "$masterdir/pg_hba.conf" < "$masterlog" echo fi # start the master if not nunning if [ ! -e "$masterdir/postmaster.pid" ] then progress "Starting the master instance" pg_ctl -D "$masterdir" -w -l "$masterlog" start echo fi # clone the standby using pg_basebackup if not exists if [ ! -e "$standbydir/PG_VERSION" ] then progress "Creating the standby instance" mkdir -p "$standbydir" pg_basebackup -p "$masterport" -X stream -D "$standbydir" chmod 700 "$standbydir" cat >> "$standbydir/postgresql.conf" < "$standbydir/recovery.conf" < "$standbylog" echo fi # start the standby if not running if [ ! -e "$standbydir/postmaster.pid" ] then progress "Starting the standby instance" pg_ctl -D "$standbydir" -w -l "$standbylog" start echo fi # stop the backup instance if running if [ -e "$backupdir/postmaster.pid" ] then progress "Stopping esisting backup instance" pg_ctl -D "$backupdir" -w stop echo fi ###################################################### ### test the backup using the pgespresso extension ### ###################################################### if [ -n "$(which pgbench)" ] then progress "Starting pgbench to generate some traffic" pgbench -i -p "$masterport" &> /dev/null pgbench -p "$masterport" -T 60 &> /dev/null & pgbenchpid=$! # on exit kill background pgbench trap '([ -n "$pgbenchpid" ] && kill "$pgbenchpid" && wait "$pgbenchpid") &> /dev/null || :' EXIT echo else pgbenchpid= fi progress "Create the pgespresso extension (if not exists)" psql -p "$masterport" -tAc "CREATE EXTENSION IF NOT EXISTS pgespresso;" echo # from now on we access only the standby export PGPORT=$standbyport # wait the pgespresso extension to be available on standby while ! psql -tAc "\dx" | grep -q pgespresso do sleep 1 done progress "Starting pgespresso backup" LABEL=$(psql -tAc "SELECT pgespresso_start_backup('test backup', true);") echo progress "Copy data" rsync -a --delete-excluded \ --exclude="postmaster.*" \ --exclude="recovery.*" \ --exclude="pg_xlog/*" \ "$standbydir/" "$backupdir" \ || [ $? -eq 24 ] # avoid failing if rsync reports vanished files # always sync controldata as last file rsync -a "$standbydir/global/pg_control" "$backupdir/global/pg_control" echo progress "Stop backup" stop_segment=$(psql -tAc "SELECT pgespresso_stop_backup('$LABEL ');") echo progress "Generating the backup label" cat > "$backupdir/backup_label" < /dev/null || : pgbenchpid= echo fi # change the port and enable full debug logging on the backup cat >> "$backupdir/postgresql.conf" < "$backupdir/recovery.conf" <