[HACKERS] [PATCH] Tap test support for backup with tablespace mapping

Started by Vaishnavi Prabakaranabout 8 years ago3 messages
#1Vaishnavi Prabakaran
vaishnaviprabakaran@gmail.com
1 attachment(s)

Hi All,

I have added support in Postgres TAP test framework to backup a data
directory with tablespace mapping. Also added support to move the backup
directory contents to standby node, because current option to init the
standby from backup does not support copying softlinks, which is needed
when tablespace mapping is involved in backup.

Added a new test to existing streaming replication tap test to demonstrate
the usage of these new APIs.

Attached the patch, Hope this enhancement is useful.

Thanks & Regards,
Vaishnavi,
Fujitsu Australia.

Attachments:

0001-Tap-test-support-for-backup-with-tablespace-mapping.patchapplication/octet-stream; name=0001-Tap-test-support-for-backup-with-tablespace-mapping.patchDownload
From 16fc7eb785ed7ef8a534ad22c3c8552cf2c55b01 Mon Sep 17 00:00:00 2001
From: Vaishnavi Prabakaran <vaishnavip@fast.au.fujitsu.com>
Date: Wed, 27 Dec 2017 12:46:25 +1100
Subject: [PATCH] Tap test support for backup with tablespace mapping

---
 src/test/perl/PostgresNode.pm         | 73 +++++++++++++++++++++++++++++++++++
 src/test/recovery/t/001_stream_rep.pl | 38 +++++++++++++++++-
 2 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/src/test/perl/PostgresNode.pm b/src/test/perl/PostgresNode.pm
index 93faadc..90db47a 100644
--- a/src/test/perl/PostgresNode.pm
+++ b/src/test/perl/PostgresNode.pm
@@ -86,6 +86,7 @@ use Config;
 use Cwd;
 use Exporter 'import';
 use File::Basename;
+use File::Copy;
 use File::Path qw(rmtree);
 use File::Spec;
 use File::Temp ();
@@ -510,6 +511,19 @@ sub backup
 	print "# Backup finished\n";
 }
 
+sub backup_withtablespace
+{
+        my ($self, $backup_name, $old_tablespacedir, $new_tablespacedir) = @_;
+        my $backup_path = $self->backup_dir . '/' . $backup_name;
+        my $port        = $self->port;
+        my $name        = $self->name;
+
+        print "# Taking pg_basebackup $backup_name from node \"$name\"\n";
+        TestLib::system_or_bail('pg_basebackup', '-D', $backup_path, '-p', $port,
+                '--no-sync','-T',"$old_tablespacedir=$new_tablespacedir");
+        print "# Backup with tablespace option finished\n";
+}
+
 =item $node->backup_fs_hot(backup_name)
 
 Create a backup with a filesystem level copy in subdirectory B<backup_name> of
@@ -646,6 +660,65 @@ port = $port
 
 =pod
 
+=item $node->convert_backup_to_standby(root_node, backup_name)
+
+Initialize a node from a backup, which may come from this node or a different
+node. root_node must be a PostgresNode reference, backup_name the string name
+of a backup previously created on that node with $node->backup.
+
+Does not start the node after initializing it.
+
+A recovery.conf is not created.
+
+Streaming replication can be enabled on this node by passing the keyword
+parameter has_streaming => 1. This is disabled by default.
+
+Restoring WAL segments from archives using restore_command can be enabled
+by passing the keyword parameter has_restoring => 1. This is disabled by
+default.
+
+The backup is moved, so backup directory no more exists. pg_hba.conf is
+unconditionally set to enable replication connections.
+
+=cut
+
+sub convert_backup_to_standby
+{
+        my ($self, $root_node, $backup_name, %params) = @_;
+        my $backup_path = $root_node->backup_dir . '/' . $backup_name;
+        my $port        = $self->port;
+        my $node_name   = $self->name;
+        my $root_name   = $root_node->name;
+
+        $params{has_streaming} = 0 unless defined $params{has_streaming};
+        $params{has_restoring} = 0 unless defined $params{has_restoring};
+
+        print
+"# Initializing node \"$node_name\" from backup \"$backup_name\" of node \"$root_name\"\n";
+        die "Backup \"$backup_name\" does not exist at $backup_path"
+          unless -d $backup_path;
+
+        mkdir $self->backup_dir;
+        mkdir $self->archive_dir;
+        my $data_path = $self->data_dir;
+
+        rmdir($data_path);
+		move("$backup_path", "$self->{_basedir}/pgdata");
+
+        chmod(0700, $data_path);
+
+        # Base configuration for this node
+         $self->append_conf(
+		'postgresql.conf',
+		qq(
+		port = $port
+		));
+	$self->enable_streaming($root_node) if $params{has_streaming};
+	$self->enable_restoring($root_node) if $params{has_restoring};
+}
+
+=pod
+
 =item $node->start()
 
 Wrapper for pg_ctl start
diff --git a/src/test/recovery/t/001_stream_rep.pl b/src/test/recovery/t/001_stream_rep.pl
index fb27925..5129b66 100644
--- a/src/test/recovery/t/001_stream_rep.pl
+++ b/src/test/recovery/t/001_stream_rep.pl
@@ -3,7 +3,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 28;
+use Test::More tests => 29;
 
 # Initialize master node
 my $node_master = get_new_node('master');
@@ -303,3 +303,39 @@ $node_standby_2->start;
   get_slot_xmins($node_standby_1, $slotname_2, "xmin IS NULL");
 is($xmin, '',
 	'xmin of cascaded slot reset after startup with hs feedback reset');
+
+# Convert backup taken with tablespace mapping to standby
+my $master_tablespacedir = "$TestLib::tmp_check/master_securetblspcdir";
+mkdir $master_tablespacedir;
+my $standby_tablespacedir = "$TestLib::tmp_check/standby_securetblspcdir";
+mkdir $standby_tablespacedir;
+my $backup_with_tablespace='backup_with_tablespace';
+
+#Create tablespace with contents
+
+$node_master->safe_psql('postgres',
+        "CREATE TABLESPACE testtblspc location '$master_tablespacedir';");
+$node_master->safe_psql('postgres',
+        "CREATE TABLE test_table(id integer,name varchar(20)) TABLESPACE testtblspc;");
+$node_master->safe_psql('postgres',
+		"INSERT INTO test_table VALUES(generate_series(1,10),'some_name');");
+
+# Backup master with tablespace option
+$node_master->backup_withtablespace($backup_with_tablespace,$master_tablespacedir,$standby_tablespacedir);
+
+# Create streaming standby linking to master
+my $node_standby_3 = get_new_node('standby_3');
+
+$node_standby_3->convert_backup_to_standby($node_master, $backup_name,
+	has_streaming => 1);
+print "standby 3 setup success\n";
+# Start the standby
+$node_standby_3->start;
+
+print "standby 3 start success\n";
+
+# Test inserted values in standby.
+$result =
+  $node_standby_3->safe_psql('postgres', "SELECT count(*) FROM test_table");
+print "standby 3: $result\n";
+is($result, qq(10), 'check streamed content on standby 3');
-- 
2.7.4.windows.1

#2Michael Paquier
michael.paquier@gmail.com
In reply to: Vaishnavi Prabakaran (#1)
Re: [HACKERS] [PATCH] Tap test support for backup with tablespace mapping

On Wed, Dec 27, 2017 at 12:58:28PM +1100, Vaishnavi Prabakaran wrote:

I have added support in Postgres TAP test framework to backup a data
directory with tablespace mapping. Also added support to move the backup
directory contents to standby node, because current option to init the
standby from backup does not support copying softlinks, which is needed
when tablespace mapping is involved in backup.

Added a new test to existing streaming replication tap test to demonstrate
the usage of these new APIs.

Attached the patch, Hope this enhancement is useful.

+sub backup_withtablespace
+{
+        my ($self, $backup_name, $old_tablespacedir, $new_tablespacedir) = @_;
+        my $backup_path = $self->backup_dir . '/' . $backup_name;
+        my $port        = $self->port;
+        my $name        = $self->name;
+
+        print "# Taking pg_basebackup $backup_name from node \"$name\"\n";
+        TestLib::system_or_bail('pg_basebackup', '-D', $backup_path, '-p', $port,
+                '--no-sync','-T',"$old_tablespacedir=$new_tablespacedir");
+        print "# Backup with tablespace option finished\n";
+}
Let's not reinvent the wheel and instead let's extend the existing
PostgresNode::backup with a new option set. Please be careful that this
new option needs to be able to handle multiple sets of old/new
directories as pg_basebackup is able to handle that as well.

+=cut
+
+sub convert_backup_to_standby
+{
This is a copy/paste of the existing PostgresNode::init_from_backup,
except that you remove forcibly a backup. I don't understand what you
can actually win from that. A new routine which *removes* a past backup
could have some value, still those are automatically wiped out at the
end of the tests if the person who designed the test is smart enough to
use the default paths.

+$node_master->safe_psql('postgres',
+        "CREATE TABLESPACE testtblspc location '$master_tablespacedir';");
+$node_master->safe_psql('postgres',
+        "CREATE TABLE test_table(id integer,name varchar(20)) TABLESPACE testtblspc;");
Those tests overlap with the existing 010_pg_basebackup.pl.
--
Michael
#3Tels
nospam-pg-abuse@bloodgate.com
In reply to: Vaishnavi Prabakaran (#1)
Re: [HACKERS] [PATCH] Tap test support for backup with tablespace mapping

Dear Vaishnavi,

On Tue, December 26, 2017 8:58 pm, Vaishnavi Prabakaran wrote:

Hi All,

I have added support in Postgres TAP test framework to backup a data
directory with tablespace mapping. Also added support to move the backup
directory contents to standby node, because current option to init the
standby from backup does not support copying softlinks, which is needed
when tablespace mapping is involved in backup.

Added a new test to existing streaming replication tap test to demonstrate
the usage of these new APIs.

Attached the patch, Hope this enhancement is useful.

Thanks & Regards,
Vaishnavi,
Fujitsu Australia.

Thank you for the path, I saw these things:

* backup_withtablespace() does not have any documentation?

* The mkdir calls do not set a mask for the created dir, defaulting to
0777 - is this what is wanted here?

* none of the mkdir, chdir etc. calls check any error code, e.g. what
happens if one of them fails?

* different indentation between rmdir and move (tab vs. spaces):

+        rmdir($data_path);
+		move("$backup_path", "$self->{_basedir}/pgdata")

Best regards,

Tels