Commit 98a9b37b authored by Amit Kapila's avatar Amit Kapila

Revert commits 290acac9 and 8a7e9e9d.

This commit revert the commits to add a test case that tests the 'force'
option when there is an active backend connected to the database being
dropped.

This feature internally sends SIGTERM to all the backends connected to the
database being dropped and then the same is reported to the client.  We
found that on Windows, the client end of the socket is not able to read
the data once we close the socket in the server which leads to loss of
error message which is not what we expect.  We also observed  similar
behavior in other cases like pg_terminate_backend(),
pg_ctl kill TERM <pid>.  There are probably a few others like that.  The
fix for this requires further study.

Discussion: https://postgr.es/m/E1iaD8h-0004us-K9@gemulon.postgresql.org
parent e6c2d17c
......@@ -3,7 +3,7 @@ use warnings;
use PostgresNode;
use TestLib;
use Test::More tests => 11;
use Test::More tests => 13;
program_help_ok('dropdb');
program_version_ok('dropdb');
......@@ -19,5 +19,11 @@ $node->issues_sql_like(
qr/statement: DROP DATABASE foobar1/,
'SQL DROP DATABASE run');
$node->safe_psql('postgres', 'CREATE DATABASE foobar2');
$node->issues_sql_like(
[ 'dropdb', '--force', 'foobar2' ],
qr/statement: DROP DATABASE foobar2 WITH \(FORCE\);/,
'SQL DROP DATABASE (FORCE) run');
$node->command_fails([ 'dropdb', 'nonexistent' ],
'fails with nonexistent database');
#
# Tests the force option of drop database command.
#
use strict;
use warnings;
use PostgresNode;
use TestLib;
use Test::More tests => 9;
# To avoid hanging while expecting some specific input from a psql
# instance being driven by us, add a timeout high enough that it
# should never trigger even on very slow machines, unless something
# is really wrong.
my $psql_timeout = IPC::Run::timer(60);
my $node = get_new_node('master');
$node->init;
$node->start;
# Create a database that will be dropped. This will test that the force
# option works when no other backend is connected to the database being
# dropped.
$node->safe_psql('postgres', 'CREATE DATABASE foobar');
$node->issues_sql_like(
[ 'dropdb', '--force', 'foobar' ],
qr/statement: DROP DATABASE foobar WITH \(FORCE\);/,
'SQL DROP DATABASE (FORCE) run');
# database foobar must not exist.
is( $node->safe_psql(
'postgres',
qq[SELECT EXISTS(SELECT * FROM pg_database WHERE datname='foobar');]
),
'f',
'database foobar was removed');
# Create a database that will be dropped. This will test that the force
# option works when one other backend is connected to the database being
# dropped.
$node->safe_psql('postgres', 'CREATE DATABASE foobar1');
# Run psql, keeping session alive, so we have an alive backend to kill.
my ($killme_stdin, $killme_stdout, $killme_stderr) = ('', '', '');
my $killme = IPC::Run::start(
[
'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d',
$node->connstr('foobar1')
],
'<',
\$killme_stdin,
'>',
\$killme_stdout,
'2>',
\$killme_stderr,
$psql_timeout);
# Ensure killme process is active.
$killme_stdin .= q[
SELECT pg_backend_pid();
];
ok( TestLib::pump_until(
$killme, $psql_timeout, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m),
'acquired pid for SIGTERM');
my $pid = $killme_stdout;
chomp($pid);
$killme_stdout = '';
$killme_stderr = '';
# Check the connections on foobar1 database.
is( $node->safe_psql(
'postgres',
qq[SELECT pid FROM pg_stat_activity WHERE datname='foobar1' AND pid = $pid;]
),
$pid,
'database foobar1 is used');
# Now drop database with dropdb --force command.
$node->issues_sql_like(
[ 'dropdb', '--force', 'foobar1' ],
qr/statement: DROP DATABASE foobar1 WITH \(FORCE\);/,
'SQL DROP DATABASE (FORCE) run');
# Check that psql sees the killed backend as having been terminated.
$killme_stdin .= q[
SELECT 1;
];
ok( TestLib::pump_until(
$killme, $psql_timeout, \$killme_stderr,
qr/FATAL: terminating connection due to administrator command/m),
"psql query died successfully after SIGTERM");
$killme_stderr = '';
$killme_stdout = '';
$killme->finish;
# database foobar1 must not exist.
is( $node->safe_psql(
'postgres',
qq[SELECT EXISTS(SELECT * FROM pg_database WHERE datname='foobar1');]
),
'f',
'database foobar1 was removed');
$node->stop();
......@@ -860,43 +860,6 @@ sub command_checks_all
=pod
=item pump_until(proc, timeout, stream, untl)
# Pump until string is matched, or timeout occurs
=cut
sub pump_until
{
my ($proc, $timeout, $stream, $untl) = @_;
$proc->pump_nb();
while (1)
{
last if $$stream =~ /$untl/;
if ($timeout->is_expired)
{
diag("aborting wait: program timed out");
diag("stream contents: >>", $$stream, "<<");
diag("pattern searched for: ", $untl);
return 0;
}
if (not $proc->pumpable())
{
diag("aborting wait: program died");
diag("stream contents: >>", $$stream, "<<");
diag("pattern searched for: ", $untl);
return 0;
}
$proc->pump();
}
return 1;
}
=pod
=back
=cut
......
......@@ -72,9 +72,7 @@ CREATE TABLE alive(status text);
INSERT INTO alive VALUES($$committed-before-sigquit$$);
SELECT pg_backend_pid();
];
ok(TestLib::pump_until(
$killme, $psql_timeout, \$killme_stdout,
qr/[[:digit:]]+[\r\n]$/m),
ok(pump_until($killme, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m),
'acquired pid for SIGQUIT');
my $pid = $killme_stdout;
chomp($pid);
......@@ -86,9 +84,7 @@ $killme_stdin .= q[
BEGIN;
INSERT INTO alive VALUES($$in-progress-before-sigquit$$) RETURNING status;
];
ok(TestLib::pump_until(
$killme, $psql_timeout, \$killme_stdout,
qr/in-progress-before-sigquit/m),
ok(pump_until($killme, \$killme_stdout, qr/in-progress-before-sigquit/m),
'inserted in-progress-before-sigquit');
$killme_stdout = '';
$killme_stderr = '';
......@@ -101,8 +97,7 @@ $monitor_stdin .= q[
SELECT $$psql-connected$$;
SELECT pg_sleep(3600);
];
ok(TestLib::pump_until(
$monitor, $psql_timeout, \$monitor_stdout, qr/psql-connected/m),
ok(pump_until($monitor, \$monitor_stdout, qr/psql-connected/m),
'monitor connected');
$monitor_stdout = '';
$monitor_stderr = '';
......@@ -117,9 +112,8 @@ is($ret, 0, "killed process with SIGQUIT");
$killme_stdin .= q[
SELECT 1;
];
ok( TestLib::pump_until(
ok( pump_until(
$killme,
$psql_timeout,
\$killme_stderr,
qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly|connection to server was lost/m
),
......@@ -131,9 +125,8 @@ $killme->finish;
# Wait till server restarts - we should get the WARNING here, but
# sometimes the server is unable to send that, if interrupted while
# sending.
ok( TestLib::pump_until(
ok( pump_until(
$monitor,
$psql_timeout,
\$monitor_stderr,
qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly|connection to server was lost/m
),
......@@ -160,8 +153,7 @@ $monitor->run();
$killme_stdin .= q[
SELECT pg_backend_pid();
];
ok(TestLib::pump_until(
$killme, $psql_timeout, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m),
ok(pump_until($killme, \$killme_stdout, qr/[[:digit:]]+[\r\n]$/m),
"acquired pid for SIGKILL");
$pid = $killme_stdout;
chomp($pid);
......@@ -174,9 +166,7 @@ INSERT INTO alive VALUES($$committed-before-sigkill$$) RETURNING status;
BEGIN;
INSERT INTO alive VALUES($$in-progress-before-sigkill$$) RETURNING status;
];
ok(TestLib::pump_until(
$killme, $psql_timeout, \$killme_stdout,
qr/in-progress-before-sigkill/m),
ok(pump_until($killme, \$killme_stdout, qr/in-progress-before-sigkill/m),
'inserted in-progress-before-sigkill');
$killme_stdout = '';
$killme_stderr = '';
......@@ -188,8 +178,7 @@ $monitor_stdin .= q[
SELECT $$psql-connected$$;
SELECT pg_sleep(3600);
];
ok(TestLib::pump_until(
$monitor, $psql_timeout, \$monitor_stdout, qr/psql-connected/m),
ok(pump_until($monitor, \$monitor_stdout, qr/psql-connected/m),
'monitor connected');
$monitor_stdout = '';
$monitor_stderr = '';
......@@ -205,9 +194,8 @@ is($ret, 0, "killed process with KILL");
$killme_stdin .= q[
SELECT 1;
];
ok( TestLib::pump_until(
ok( pump_until(
$killme,
$psql_timeout,
\$killme_stderr,
qr/server closed the connection unexpectedly|connection to server was lost/m
),
......@@ -217,9 +205,8 @@ $killme->finish;
# Wait till server restarts - we should get the WARNING here, but
# sometimes the server is unable to send that, if interrupted while
# sending.
ok( TestLib::pump_until(
ok( pump_until(
$monitor,
$psql_timeout,
\$monitor_stderr,
qr/WARNING: terminating connection because of crash of another server process|server closed the connection unexpectedly|connection to server was lost/m
),
......@@ -257,3 +244,33 @@ is( $node->safe_psql(
'can still write after orderly restart');
$node->stop();
# Pump until string is matched, or timeout occurs
sub pump_until
{
my ($proc, $stream, $untl) = @_;
$proc->pump_nb();
while (1)
{
last if $$stream =~ /$untl/;
if ($psql_timeout->is_expired)
{
diag("aborting wait: program timed out");
diag("stream contents: >>", $$stream, "<<");
diag("pattern searched for: ", $untl);
return 0;
}
if (not $proc->pumpable())
{
diag("aborting wait: program died");
diag("stream contents: >>", $$stream, "<<");
diag("pattern searched for: ", $untl);
return 0;
}
$proc->pump();
}
return 1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment