mirror of
https://github.com/postgres/postgres.git
synced 2025-12-26 00:14:48 -05:00
Presently, pg_upgrade assumes that all non-default tablespaces don't move to different directories during upgrade. Unfortunately, this isn't true for in-place tablespaces, which move to the new cluster's pg_tblspc directory. This commit teaches pg_upgrade to handle in-place tablespaces by retrieving the tablespace directories for both the old and new clusters. In turn, we can relax the prohibition on non-default tablespaces for same-version upgrades, i.e., if all non-default tablespaces are in-place, pg_upgrade may proceed. This change is primarily intended to enable additional pg_upgrade testing with non-default tablespaces, as is done in 006_transfer_modes.pl. Reviewed-by: Corey Huinker <corey.huinker@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/aA_uBLYMUs5D66Nb%40nathan
154 lines
4.7 KiB
Perl
154 lines
4.7 KiB
Perl
# Copyright (c) 2025, PostgreSQL Global Development Group
|
|
|
|
# Tests for file transfer modes
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
|
|
use PostgreSQL::Test::Cluster;
|
|
use PostgreSQL::Test::Utils;
|
|
use Test::More;
|
|
|
|
sub test_mode
|
|
{
|
|
my ($mode) = @_;
|
|
|
|
my $old =
|
|
PostgreSQL::Test::Cluster->new('old', install_path => $ENV{oldinstall});
|
|
my $new = PostgreSQL::Test::Cluster->new('new');
|
|
|
|
# --swap can't be used to upgrade from versions older than 10, so just skip
|
|
# the test if the old cluster version is too old.
|
|
if ($old->pg_version < 10 && $mode eq "--swap")
|
|
{
|
|
$old->clean_node();
|
|
$new->clean_node();
|
|
return;
|
|
}
|
|
|
|
if (defined($ENV{oldinstall}))
|
|
{
|
|
# Checksums are now enabled by default, but weren't before 18, so pass
|
|
# '-k' to initdb on older versions so that upgrades work.
|
|
$old->init(extra => ['-k']);
|
|
}
|
|
else
|
|
{
|
|
$old->init();
|
|
}
|
|
$new->init();
|
|
|
|
# allow_in_place_tablespaces is available as far back as v10.
|
|
if ($old->pg_version >= 10)
|
|
{
|
|
$new->append_conf('postgresql.conf', "allow_in_place_tablespaces = true");
|
|
$old->append_conf('postgresql.conf', "allow_in_place_tablespaces = true");
|
|
}
|
|
|
|
# Create a small variety of simple test objects on the old cluster. We'll
|
|
# check that these reach the new version after upgrading.
|
|
$old->start;
|
|
$old->safe_psql('postgres',
|
|
"CREATE TABLE test1 AS SELECT generate_series(1, 100)");
|
|
$old->safe_psql('postgres', "CREATE DATABASE testdb1");
|
|
$old->safe_psql('testdb1',
|
|
"CREATE TABLE test2 AS SELECT generate_series(200, 300)");
|
|
$old->safe_psql('testdb1', "VACUUM FULL test2");
|
|
$old->safe_psql('testdb1', "CREATE SEQUENCE testseq START 5432");
|
|
|
|
# If an old installation is provided, we can test non-in-place tablespaces.
|
|
if (defined($ENV{oldinstall}))
|
|
{
|
|
my $tblspc = PostgreSQL::Test::Utils::tempdir_short();
|
|
$old->safe_psql('postgres',
|
|
"CREATE TABLESPACE test_tblspc LOCATION '$tblspc'");
|
|
$old->safe_psql('postgres',
|
|
"CREATE DATABASE testdb2 TABLESPACE test_tblspc");
|
|
$old->safe_psql('postgres',
|
|
"CREATE TABLE test3 TABLESPACE test_tblspc AS SELECT generate_series(300, 401)"
|
|
);
|
|
$old->safe_psql('testdb2',
|
|
"CREATE TABLE test4 AS SELECT generate_series(400, 502)");
|
|
}
|
|
|
|
# If the old cluster is >= v10, we can test in-place tablespaces.
|
|
if ($old->pg_version >= 10)
|
|
{
|
|
$old->safe_psql('postgres',
|
|
"CREATE TABLESPACE inplc_tblspc LOCATION ''");
|
|
$old->safe_psql('postgres',
|
|
"CREATE DATABASE testdb3 TABLESPACE inplc_tblspc");
|
|
$old->safe_psql('postgres',
|
|
"CREATE TABLE test5 TABLESPACE inplc_tblspc AS SELECT generate_series(503, 606)");
|
|
$old->safe_psql('testdb3',
|
|
"CREATE TABLE test6 AS SELECT generate_series(607, 711)");
|
|
}
|
|
$old->stop;
|
|
|
|
my $result = command_ok_or_fails_like(
|
|
[
|
|
'pg_upgrade', '--no-sync',
|
|
'--old-datadir' => $old->data_dir,
|
|
'--new-datadir' => $new->data_dir,
|
|
'--old-bindir' => $old->config_data('--bindir'),
|
|
'--new-bindir' => $new->config_data('--bindir'),
|
|
'--socketdir' => $new->host,
|
|
'--old-port' => $old->port,
|
|
'--new-port' => $new->port,
|
|
$mode
|
|
],
|
|
qr/.* not supported on this platform|could not .* between old and new data directories: .*/,
|
|
qr/^$/,
|
|
"pg_upgrade with transfer mode $mode");
|
|
|
|
# If pg_upgrade was successful, check that all of our test objects reached
|
|
# the new version.
|
|
if ($result)
|
|
{
|
|
$new->start;
|
|
$result = $new->safe_psql('postgres', "SELECT COUNT(*) FROM test1");
|
|
is($result, '100', "test1 data after pg_upgrade $mode");
|
|
$result = $new->safe_psql('testdb1', "SELECT COUNT(*) FROM test2");
|
|
is($result, '101', "test2 data after pg_upgrade $mode");
|
|
$result = $new->safe_psql('testdb1', "SELECT nextval('testseq')");
|
|
is($result, '5432', "sequence data after pg_upgrade $mode");
|
|
|
|
# Tests for non-in-place tablespaces.
|
|
if (defined($ENV{oldinstall}))
|
|
{
|
|
$result =
|
|
$new->safe_psql('postgres', "SELECT COUNT(*) FROM test3");
|
|
is($result, '102', "test3 data after pg_upgrade $mode");
|
|
$result =
|
|
$new->safe_psql('testdb2', "SELECT COUNT(*) FROM test4");
|
|
is($result, '103', "test4 data after pg_upgrade $mode");
|
|
}
|
|
|
|
# Tests for in-place tablespaces.
|
|
if ($old->pg_version >= 10)
|
|
{
|
|
$result = $new->safe_psql('postgres', "SELECT COUNT(*) FROM test5");
|
|
is($result, '104', "test5 data after pg_upgrade $mode");
|
|
$result = $new->safe_psql('testdb3', "SELECT COUNT(*) FROM test6");
|
|
is($result, '105', "test6 data after pg_upgrade $mode");
|
|
}
|
|
$new->stop;
|
|
}
|
|
|
|
$old->clean_node();
|
|
$new->clean_node();
|
|
}
|
|
|
|
# Run pg_upgrade in tmp_check to avoid leaving files like
|
|
# delete_old_cluster.{sh,bat} in the source directory for VPATH and meson
|
|
# builds.
|
|
chdir ${PostgreSQL::Test::Utils::tmp_check};
|
|
|
|
test_mode('--clone');
|
|
test_mode('--copy');
|
|
test_mode('--copy-file-range');
|
|
test_mode('--link');
|
|
test_mode('--swap');
|
|
|
|
done_testing();
|