Server IP : 85.214.239.14 / Your IP : 18.223.170.253 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /bin/ |
Upload File : |
#!/usr/bin/perl -wT # Completely delete a PostgreSQL cluster. Fails if there is still a server # process attached. # # (C) 2005-2009 Martin Pitt <mpitt@debian.org> # (C) 2015-2021 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 Getopt::Long; use PgCommon; # untaint environment $ENV{'PATH'} = '/bin:/usr/bin'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; my $stopserver = 0; exit 1 unless GetOptions ('stop-server' => \$stopserver, 'stop' => \$stopserver); # command line options if ($#ARGV != 1) { print "Usage: $0 [--stop] <version> <cluster>\n"; exit 1; } my ($version) = $ARGV[0] =~ /^(\d+\.?\d+)$/; my ($cluster) = $ARGV[1] =~ /^([-.\w]+)$/; error 'invalid version' unless defined $version; error 'invalid cluster name' unless defined $cluster; my %info; my $c; # configuration directory my $startconf; if (cluster_exists $version, $cluster) { %info = cluster_info ($version, $cluster); validate_cluster_owner \%info if ($info{pgdata} && -d $info{pgdata}); # ignore missing data directory if ($info{'running'}) { if ($stopserver) { if ($info{'pgdata'} && -d $info{'pgdata'}) { if (system ('pg_ctlcluster', $version, $cluster, 'stop')) { error 'could not stop server, aborting'; } } else { print STDERR "Warning: corrupted cluster: data directory does not exist any more, but server is still running; you have to manually kill the postgres process\n"; } } else { error 'This cluster is still running. Stop it or supply the --stop option'; } } $c = $info{'configdir'}; $startconf = $info{'start'}; } else { $c = "/etc/postgresql/$version/$cluster"; # check if we have a broken cluster, clean up if necessary -d $c or error 'specified cluster does not exist'; } # disable systemd-enabled clusters if (not exists $ENV{'PG_CLUSTER_CONF_ROOT'} and -d '/run/systemd/system') { if ($> == 0) { system "systemctl", "disable", "postgresql\@$version-$cluster"; system "systemctl", "disable", "--now", "pg_receivewal\@$version-$cluster"; system "systemctl", "disable", "--now", "pg_basebackup\@$version-$cluster.timer"; system "systemctl", "disable", "--now", "pg_dump\@$version-$cluster.timer"; } } if ($info{'pgdata'} && -d $info{'pgdata'}) { # remove custom wal directory if ($info{waldir} and -d $info{waldir}) { my $walowner = (stat($info{waldir}))[4]; if (defined $walowner and $walowner == $info{owneruid}) { my $result = system 'rm', '-r', '--', $info{waldir}; if ($result) { print STDERR "Warning: could not remove wal directory $info{waldir}"; } } else { print STDERR "Warning: wal directory $info{waldir} is not owned by uid $info{owneruid}, not removing\n"; } } # remove tablespace subdirectories that belong to our version for my $link (glob "$info{pgdata}/pg_tblspc/*") { next unless (-l $link); my $tblspc = readlink $link; my $tblspcowner = (stat($tblspc))[4]; if (defined $tblspcowner and $tblspcowner == $info{owneruid}) { if ($version >= 9.0) { for my $dir (glob "$tblspc/PG_${version}_*") { my $dirowner = (stat($dir))[4]; if (defined $dirowner and $dirowner == $info{owneruid}) { my $result = system 'rm', '-r', '--', ($dir =~ /(.*)/); # untaint if ($result) { print STDERR "Warning: could not remove tablespace directory $dir"; } } else { print STDERR "Warning: tablespace subdirectory $dir (in tablespace linked from $link) is not owned by uid $info{owneruid}, not removing\n"; } } } else { # before 9.0 if (open my $fh, '<', "$tblspc/PG_VERSION") { my $v = <$fh>; chomp $v; close $fh; if ($v eq $version) { $tblspc =~ /(.*)/; # untaint my $result = system "rm -r -- $1/*"; } else { print STDERR "Warning: tablespace directory $tblspc (linked from $link) is from PostgreSQL version $v, not removing\n"; } } else { print STDERR "Warning: tablespace directory $tblspc (linked from $link) is not a PostgreSQL directory, not removing\n"; } } } else { print STDERR "Warning: tablespace directory $tblspc (linked from $link) is not owned by uid $info{owneruid}, not considering\n"; } } # remove pgdata my $result = system 'rm', '-r', $info{'pgdata'}; if ($result) { if (! -w ($info{'pgdata'} . '/..')) { error 'you might need to run this program with root privileges'; } exit $result; } } else { print STDERR "Warning: corrupted cluster: data directory does not exist\n"; } # remove config unlink $c.'/pg_hba.conf', $c.'/pg_ident.conf', $c.'/postgresql.conf', $c.'/start.conf', $c.'/log', $c.'/autovacuum_log', $c.'/pgdata', $c.'/environment', $c.'/pg_ctl.conf'; rmdir $_ foreach (map { /(.*)/ && $1 } glob "$c/*"); # remove empty conf.d directories unlink $info{'logfile'} if defined ($info{'logfile'}); if ($info{'socketdir'} and $info{'socketdir'} !~ /^(\/tmp|\/var\/run\/postgresql)\/?$/) { rmdir $info{'socketdir'}; } rmdir $c; rmdir "/etc/postgresql/$version"; rmdir "/var/lib/postgresql/$version/$cluster"; rmdir "/var/lib/postgresql/$version"; unlink "/var/log/postgresql/postgresql-$version-$cluster.log"; # remove logrotated files foreach my $f (</var/log/postgresql/postgresql-$version-$cluster.log.[1-9]*>) { unlink ($f =~ /(.*)/); # untaint } # remove stats_temp_directory my $statstempdir = $info{config}->{stats_temp_directory}; if ($statstempdir) { my $statsowner = (stat($statstempdir))[4]; if (defined $statsowner and defined $info{owneruid} and $statsowner == $info{owneruid}) { foreach my $f (<$statstempdir/*.stat>) { unlink ($f =~ /(.*)/); # untaint } rmdir $statstempdir; } } # notify systemd when an autostarted cluster went away if (not exists $ENV{'PG_CLUSTER_CONF_ROOT'} and $startconf and $startconf eq 'auto' and -d '/run/systemd/system') { if ($> == 0) { system 'systemctl daemon-reload'; } elsif (-t 1) { print "Warning: systemd was not informed about the removed cluster yet. Operations like \"service postgresql start\" might fail. To fix, run:\n"; print " sudo systemctl daemon-reload\n"; } } # notify apt about the new cluster if (not exists $ENV{'PG_CLUSTER_CONF_ROOT'} and $> == 0) { system "/usr/share/postgresql-common/pg_updateaptconfig"; } exit 0; __END__ =head1 NAME pg_dropcluster - completely delete a PostgreSQL cluster =head1 SYNOPSIS B<pg_dropcluster> [B<--stop>] I<cluster-version> I<cluster-name> =head1 DESCRIPTION This program removes all files that belong to a given PostgreSQL cluster; that includes the data, wal, and tablespace directories, the log file, and all configuration files that were created by L<pg_createcluster(1)>. If the configuration directory (C</etc/postgresql/>I<version>C</>I<cluster>) is empty after this, it is removed as well. An empty socket directory other than B</var/run/postgresql> or B</tmp> is also removed. Usually a cluster which still has a running server attached will not be deleted. To override this, the B<--stop> option forces a server shutdown before the files are removed. =head1 SEE ALSO L<pg_createcluster(1)>, L<pg_ctlcluster(1)> =head1 AUTHOR Martin Pitt L<E<lt>mpitt@debian.orgE<gt>>