# Copyright (c) 2021-2025, PostgreSQL Global Development Group
# Test for recovery targets: name, timestamp, XID
use strict;
use warnings FATAL => 'all';
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
use Time::HiRes qw(usleep);
# Create and test a standby from given backup, with a certain recovery target. # Choose $until_lsn later than the transaction commit that causes the row # count to reach $num_rows, yet not later than the recovery target.
sub test_recovery_standby
{
local $Test::Builder::Level = $Test::Builder::Level + 1;
my $test_name = shift;
my $node_name = shift;
my $node_primary = shift;
my $recovery_params = shift;
my $num_rows = shift;
my $until_lsn = shift;
my $node_standby = PostgreSQL::Test::Cluster->new($node_name);
$node_standby->init_from_backup($node_primary, 'my_backup',
has_restoring => 1);
foreach my $param_item (@$recovery_params)
{
$node_standby->append_conf('postgresql.conf', qq($param_item));
}
$node_standby->start;
# Wait until standby has replayed enough data
my $caughtup_query = "SELECT '$until_lsn'::pg_lsn <= pg_last_wal_replay_lsn()";
$node_standby->poll_query_until('postgres', $caughtup_query)
or die "Timed out while waiting for standby to catch up";
# Create some content on primary and check its presence in standby
my $result =
$node_standby->safe_psql('postgres', "SELECT count(*) FROM tab_int");
is($result, qq($num_rows), "check standby content for $test_name");
# Bump the transaction ID epoch. This is useful to stress the portability # of recovery_target_xid parsing.
system_or_bail('pg_resetwal', '--epoch' => '1', $node_primary->data_dir);
# Start it
$node_primary->start;
# Create data before taking the backup, aimed at testing # recovery_target = 'immediate'
$node_primary->safe_psql('postgres', "CREATE TABLE tab_int AS SELECT generate_series(1,1000) AS a");
my $lsn1 =
$node_primary->safe_psql('postgres', "SELECT pg_current_wal_lsn();");
# Take backup from which all operations will be run
$node_primary->backup('my_backup');
# Insert some data with used as a replay reference, with a recovery # target TXID.
$node_primary->safe_psql('postgres', "INSERT INTO tab_int VALUES (generate_series(1001,2000))");
my $ret = $node_primary->safe_psql('postgres', "SELECT pg_current_wal_lsn(), pg_current_xact_id();");
my ($lsn2, $recovery_txid) = split /\|/, $ret;
# More data, with recovery target timestamp
$node_primary->safe_psql('postgres', "INSERT INTO tab_int VALUES (generate_series(2001,3000))");
my $lsn3 =
$node_primary->safe_psql('postgres', "SELECT pg_current_wal_lsn();");
my $recovery_time = $node_primary->safe_psql('postgres', "SELECT now()");
# Even more data, this time with a recovery target name
$node_primary->safe_psql('postgres', "INSERT INTO tab_int VALUES (generate_series(3001,4000))");
my $recovery_name = "my_target";
my $lsn4 =
$node_primary->safe_psql('postgres', "SELECT pg_current_wal_lsn();");
$node_primary->safe_psql('postgres', "SELECT pg_create_restore_point('$recovery_name');");
# And now for a recovery target LSN
$node_primary->safe_psql('postgres', "INSERT INTO tab_int VALUES (generate_series(4001,5000))");
my $lsn5 = my $recovery_lsn =
$node_primary->safe_psql('postgres', "SELECT pg_current_wal_lsn()");
$node_primary->safe_psql('postgres', "INSERT INTO tab_int VALUES (generate_series(5001,6000))");
# Force archiving of WAL file
$node_primary->safe_psql('postgres', "SELECT pg_switch_wal()");
# Multiple targets # # Multiple conflicting settings are not allowed, but setting the same # parameter multiple times or unsetting a parameter and setting a # different one is allowed.
# wait for postgres to terminate foreach my $i (0 .. 10 * $PostgreSQL::Test::Utils::timeout_default)
{
last if !-f $node_standby->data_dir . '/postmaster.pid';
usleep(100_000);
}
$logfile = slurp_file($node_standby->logfile());
ok( $logfile =~
qr/FATAL: .* recovery ended before configured recovery target was reached/, 'recovery end before target reached is a fatal error');
done_testing();
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-08-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.