sub setup_cluster
{
-
# Initialize master, data checksums are mandatory
$node_master = get_new_node('master');
- $node_master->init;
-
- # Custom parameters for master's postgresql.conf
- $node_master->append_conf(
- "postgresql.conf", qq(
-wal_level = hot_standby
-max_wal_senders = 2
-wal_keep_segments = 20
-max_wal_size = 200MB
-shared_buffers = 1MB
-wal_log_hints = on
-hot_standby = on
-autovacuum = off
-max_connections = 10
-));
+ $node_master->init(allows_streaming => 1);
}
sub start_master
# Now promote slave and insert some new data on master, this will put
# the master out-of-sync with the standby. Wait until the standby is
# out of recovery mode, and is ready to accept read-write connections.
- system_or_bail('pg_ctl', '-w', '-D', $node_standby->data_dir, 'promote');
+ $node_standby->promote;
$node_standby->poll_query_until('postgres',
"SELECT NOT pg_is_in_recovery()")
or die "Timed out while waiting for promotion of standby";
The set of nodes managed by a given test is also managed by this module.
In addition to node management, PostgresNode instances have some wrappers
-around Test::More functions to run commands with an envronment set up to
+around Test::More functions to run commands with an environment set up to
point to the instance.
The IPC::Run module is required.
use File::Spec;
use File::Temp ();
use IPC::Run;
-use PostgresNode;
use RecursiveCopy;
use Test::More;
use TestLib ();
pg_hba.conf is configured to allow replication connections. Pass the keyword
parameter hba_permit_replication => 0 to disable this.
+postgresql.conf can be set up for replication by passing the keyword
+parameter allows_streaming => 1. This is disabled by default.
+
The new node is set up in a fast but unsafe configuration where fsync is
disabled.
my $host = $self->host;
$params{hba_permit_replication} = 1
- if (!defined($params{hba_permit_replication}));
+ unless defined $params{hba_permit_replication};
+ $params{allows_streaming} = 0 unless defined $params{allows_streaming};
mkdir $self->backup_dir;
mkdir $self->archive_dir;
print $conf "fsync = off\n";
print $conf "log_statement = all\n";
print $conf "port = $port\n";
+
+ if ($params{allows_streaming})
+ {
+ print $conf "wal_level = hot_standby\n";
+ print $conf "max_wal_senders = 5\n";
+ print $conf "wal_keep_segments = 20\n";
+ print $conf "max_wal_size = 128MB\n";
+ print $conf "shared_buffers = 1MB\n";
+ print $conf "wal_log_hints = on\n";
+ print $conf "hot_standby = on\n";
+ print $conf "max_connections = 10\n";
+ }
+
if ($TestLib::windows_os)
{
print $conf "listen_addresses = '$host'\n";
}
close $conf;
- $self->set_replication_conf if ($params{hba_permit_replication});
+ $self->set_replication_conf if $params{hba_permit_replication};
}
=pod
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.
+
The backup is copied, leaving the original unmodified. pg_hba.conf is
unconditionally set to enable replication connections.
sub init_from_backup
{
- my ($self, $root_node, $backup_name) = @_;
+ 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};
print
"# Initializing node \"$node_name\" from backup \"$backup_name\" of node \"$root_name\"\n";
die "Backup \"$backup_name\" does not exist at $backup_path"
port = $port
));
$self->set_replication_conf;
+ $self->enable_streaming($root_node) if $params{has_streaming};
}
=pod
my $port = $self->port;
my $pgdata = $self->data_dir;
my $name = $self->name;
- $mode = 'fast' if (!defined($mode));
+ $mode = 'fast' unless defined $mode;
print "### Stopping node \"$name\" using mode $mode\n";
TestLib::system_log('pg_ctl', '-D', $pgdata, '-m', $mode, 'stop');
$self->{_pid} = undef;
=item $node->restart()
-wrapper for pg_ctl -w restart
+Wrapper for pg_ctl -w restart
=cut
$self->_update_pid;
}
+=pod
+
+=item $node->promote()
+
+Wrapper for pg_ctl promote
+
+=cut
+
+sub promote
+{
+ my ($self) = @_;
+ my $port = $self->port;
+ my $pgdata = $self->data_dir;
+ my $logfile = $self->logfile;
+ my $name = $self->name;
+ print "### Promoting node \"$name\"\n";
+ TestLib::system_log('pg_ctl', '-D', $pgdata, '-l', $logfile,
+ 'promote');
+}
+
+# Internal routine to enable streaming replication on a standby node.
+sub enable_streaming
+{
+ my ($self, $root_node) = @_;
+ my $root_connstr = $root_node->connstr;
+ my $name = $self->name;
+
+ print "### Enabling streaming replication for node \"$name\"\n";
+ $self->append_conf('recovery.conf', qq(
+primary_conninfo='$root_connstr application_name=$name'
+standby_mode=on
+));
+}
# Internal method
sub _update_pid
{
my $self = shift;
my $name = $self->name;
- return if not defined $self->{_pid};
+ return unless defined $self->{_pid};
print "### Signalling QUIT to $self->{_pid} for node \"$name\"\n";
TestLib::system_log('pg_ctl', 'kill', 'QUIT', $self->{_pid});
}
server log file.
Reads the whole log file so be careful when working with large log outputs.
+The log file is truncated prior to running the command, however.
=cut