From ee832b9bc7b240b279f0228e624356ca3fd63a27 Mon Sep 17 00:00:00 2001 From: Craig Ringer Date: Tue, 1 Mar 2016 21:21:25 +0800 Subject: [PATCH 4/7] TAP: Add support for taking filesystem level backups --- src/test/perl/PostgresNode.pm | 83 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 12 deletions(-) diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm index c18c94a..099bb89 100644 --- a/src/test/perl/PostgresNode.pm +++ b/src/test/perl/PostgresNode.pm @@ -463,11 +463,81 @@ sub backup my $port = $self->port; my $name = $self->name; - print "# Taking backup $backup_name from node \"$name\"\n"; + print "# Taking pg_basebackup $backup_name from node \"$name\"\n"; TestLib::system_or_bail("pg_basebackup -D $backup_path -p $port -x"); print "# Backup finished\n"; } +=item $node->backup_fs_hot(backup_name) + +Create a backup with a filesystem level copy in $node->backup_dir, +including transaction logs. Archiving must be enabled as pg_start_backup +and pg_stop_backup are used. This is not checked or enforced. + +The backup name is passed as the backup label to pg_start_backup. + +=cut + +sub backup_fs_hot +{ + my ($self, $backup_name) = @_; + $self->_backup_fs($backup_name, 1); +} + +=item $node->backup_fs_cold(backup_name) + +Create a backup with a filesystem level copy in $node->backup dir, +including transaction logs. The server must be stopped as no +attempt to handle concurrent writes is made. + +Use backup or backup_fs_hot if you want to back up a running +server. + +=cut + +sub backup_fs_cold +{ + my ($self, $backup_name) = @_; + $self->_backup_fs($backup_name, 0); +} + + +# Common sub of backup_fs_hot and backup_fs_cold +sub _backup_fs +{ + my ($self, $backup_name, $hot) = @_; + my $backup_path = $self->backup_dir . '/' . $backup_name; + my $port = $self->port; + my $name = $self->name; + + print "# Taking filesystem level backup $backup_name from node \"$name\"\n"; + + if ($hot) { + my $stdout = $self->psql_check('postgres', "SELECT * FROM pg_start_backup('$backup_name');"); + print "# pg_start_backup: $stdout\n"; + } + + RecursiveCopy::copypath($self->data_dir, $backup_path, + filterfn => sub { + my $src = shift; + return $src !~ /\/pg_log\// && $src !~ /\/postmaster.pid$/; + } + ); + + if ($hot) + { + # We ignore pg_stop_backup's return value. We also assume archiving + # is enabled; otherwise the caller will have to copy the remaining + # segments. + my $stdout = $self->psql_check('postgres', 'SELECT * FROM pg_stop_backup();'); + print "# pg_stop_backup: $stdout\n"; + } + + print "# Backup finished\n"; +} + + + =pod =item $node->init_from_backup(root_node, backup_name) @@ -917,17 +987,6 @@ Pass additional parameters to psql. Must be an arrayref. e.g. - my ($stdout, $stderr, $timed_out); - my $cmdret = $psql_expert('postgres', 'SELECT pg_sleep(60)', - stdout => \$stdout, stderr => \$stderr, - timeout => 30, timed_out => \$timed_out, - extra_params => ['--single-transaction']) - -will set $cmdret to undef and $timed_out to a true value. - - $psql_expert('postgres', $sql, on_error_die => 1); - -dies with an informative message if $sql fails. =cut -- 2.1.0