Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 71d1ed6

Browse files
committed
tests: Fix race condition in postmaster/002_connection_limits
The test occasionally failed due to unexpected connection limit errors being encountered after having waited for FATAL errors on another connection. These spurious failures were caused by the the backend reporting FATAL errors to the client before detaching from the PGPROC entry. Adding a sleep(1) before proc_exit() makes it easy to reproduce that problem. To fix the issue, add a helper function that waits for postmaster to notice the process having exited. For now this is implemented by waiting for the DEBUG2 message that postmaster logs in that case. That's not the prettiest fix, but simple. If we notice this problem elsewhere, it might be worthwhile to make this more general, e.g. by adding an injection point. Reported-by: Tomas Vondra <tomas@vondra.me> Diagnosed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Tested-by: Tomas Vondra <tomas@vondra.me> Discussion: https://postgr.es/m/ggflhkciwdyotpoie323chu2c2idpjk5qimrn462encwx2io7s@thmcxl7i6dpw
1 parent d3fc7a5 commit 71d1ed6

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

src/test/postmaster/t/002_connection_limits.pl

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
$node->append_conf('postgresql.conf', "reserved_connections = 2");
2121
$node->append_conf('postgresql.conf', "superuser_reserved_connections = 1");
2222
$node->append_conf('postgresql.conf', "log_connections = on");
23+
$node->append_conf('postgresql.conf', "log_min_messages=debug2");
2324
$node->start;
2425

2526
$node->safe_psql(
@@ -45,13 +46,39 @@ sub background_psql_as_user
4546
extra_params => [ '-U', $user ]);
4647
}
4748

49+
# Like connect_fails(), except that we also wait for the failed backend to
50+
# have exited.
51+
#
52+
# This tests needs to wait for client processes to exit because the error
53+
# message for a failed connection is reported before the backend has detached
54+
# from shared memory. If we didn't wait, subsequent tests might hit connection
55+
# limits spuriously.
56+
#
57+
# This can't easily be generalized, as detecting process exit requires
58+
# log_min_messages to be at least DEBUG2 and is not concurrency safe, as we
59+
# can't easily be sure the right process exited. In this test that's not a
60+
# problem though, we only have one new connection at a time.
61+
sub connect_fails_wait
62+
{
63+
local $Test::Builder::Level = $Test::Builder::Level + 1;
64+
my ($node, $connstr, $test_name, %params) = @_;
65+
66+
my $log_location = -s $node->logfile;
67+
68+
$node->connect_fails($connstr, $test_name, %params);
69+
$node->wait_for_log(qr/DEBUG: client backend.*exited with exit code 1/,
70+
$log_location);
71+
ok(1, "$test_name: client backend process exited");
72+
}
73+
4874
my @sessions = ();
4975
my @raw_connections = ();
5076

5177
push(@sessions, background_psql_as_user('regress_regular'));
5278
push(@sessions, background_psql_as_user('regress_regular'));
5379
push(@sessions, background_psql_as_user('regress_regular'));
54-
$node->connect_fails(
80+
connect_fails_wait(
81+
$node,
5582
"dbname=postgres user=regress_regular",
5683
"reserved_connections limit",
5784
expected_stderr =>
@@ -60,15 +87,17 @@ sub background_psql_as_user
6087

6188
push(@sessions, background_psql_as_user('regress_reserved'));
6289
push(@sessions, background_psql_as_user('regress_reserved'));
63-
$node->connect_fails(
90+
connect_fails_wait(
91+
$node,
6492
"dbname=postgres user=regress_regular",
6593
"reserved_connections limit",
6694
expected_stderr =>
6795
qr/FATAL: remaining connection slots are reserved for roles with the SUPERUSER attribute/
6896
);
6997

7098
push(@sessions, background_psql_as_user('regress_superuser'));
71-
$node->connect_fails(
99+
connect_fails_wait(
100+
$node,
72101
"dbname=postgres user=regress_superuser",
73102
"superuser_reserved_connections limit",
74103
expected_stderr => qr/FATAL: sorry, too many clients already/);

0 commit comments

Comments
 (0)