Skip to content
Snippets Groups Projects
pg_upgradecluster 38.32 KiB
#!/usr/bin/perl -wT

# Upgrade a PostgreSQL cluster to a newer major version.
#
# (C) 2005-2009 Martin Pitt <mpitt@debian.org>
# (C) 2013 Peter Eisentraut <petere@debian.org>
# (C) 2013-2025 Christoph Berg <myon@debian.org>
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.

use strict;
use warnings;
use PgCommon;
use File::Temp qw(tempfile);
use Getopt::Long;
use POSIX qw(lchown);

# untaint environment
$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

# global variables
my ($version, $newversion, $cluster, $newcluster);
my (%info, %newinfo);
my ($encoding, $old_lc_ctype, $old_lc_collate); # old cluster encoding
my ($old_locale_provider, $old_icu_locale, $old_icu_rules);
my $maintenance_db = 'template1';
my $keep_on_error = 0;

# do not trip over cwd not being accessible to postgres superuser
chdir '/';

sub pre_upgrade_check($$$) {
    my ($oldversion, $newversion, $force_packages) = @_;

    return 1 if ($version == $newversion);

    my @new_packages = package_list("postgresql*-$newversion*");

    my $missing = 0;
    for my $oldpkg (package_list("postgresql*-$oldversion*")) {
        next if ($oldpkg =~ /-(dbgsym|doc)/);
        my $newpkg = $oldpkg;
        $newpkg =~ s/-$oldversion/-$newversion/;

        next if ($newpkg =~ /^postgresql-contrib-/ and $newversion >= 10); # postgresql-contrib-NN merged into postgresql-NN in 10+

        if (not grep {$_ eq $newpkg} @new_packages) {
            print "$oldpkg is installed, but $newpkg is missing\n";
            $missing++;
        }
    }

    if ($missing) {
        print "$missing package(s) from version $oldversion missing for version $newversion\n";
        if ($force_packages) {
            print "Ignoring as --force-package was used\n";
        } else {
            print "Install the missing packages and try pg_upgradecluster again. To ignore the issue, use --force-packages\n";
            return 0;
        }
    }