# Copyright (c) 2021-2025, PostgreSQL Global Development Group
# Test postmaster start and stop state machine.
use strict;
use warnings FATAL => 'all';
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;
use Test::More;
# # Test that dead-end backends don't prevent the server from shutting # down. # # Dead-end backends can linger until they reach # authentication_timeout. We use a long authentication_timeout and a # much shorter timeout for the "pg_ctl stop" operation, to test that # if dead-end backends are killed at fast shut down. If they're not, # "pg_ctl stop" will error out before the authentication timeout kicks # in and cleans up the dead-end backends.
my $authentication_timeout = $PostgreSQL::Test::Utils::timeout_default;
# Don't fail due to hitting the max value allowed for authentication_timeout.
$authentication_timeout = 600 unless $authentication_timeout < 600;
my $stop_timeout = $authentication_timeout / 2;
# Initialize the server with low connection limits, to test dead-end backends
my $node = PostgreSQL::Test::Cluster->new('main');
$node->init;
$node->append_conf('postgresql.conf', "max_connections = 5");
$node->append_conf('postgresql.conf', "max_wal_senders = 0");
$node->append_conf('postgresql.conf', "autovacuum_max_workers = 1");
$node->append_conf('postgresql.conf', "max_worker_processes = 1");
$node->append_conf('postgresql.conf', "log_connections = 'receipt,authentication,authorization'");
$node->append_conf('postgresql.conf', "log_min_messages = debug2");
$node->append_conf('postgresql.conf', "authentication_timeout = '$authentication_timeout s'");
$node->append_conf('postgresql.conf', 'trace_connection_negotiation=on');
$node->start;
if (!$node->raw_connect_works())
{
plan skip_all => "this test requires working raw_connect()";
}
# Restart the server to ensure that the backend launched for # raw_connect_works() is gone. Otherwise, it might free up the # connection slot later, when we expect all the slots to be in use.
$node->restart;
my @raw_connections = ();
# Open a lot of TCP (or Unix domain socket) connections to use up all # the connection slots. Beyond a certain number (roughly 2x # max_connections), they will be "dead-end backends". for (my $i = 0; $i <= 20; $i++)
{
my $sock = $node->raw_connect();
# On a busy system, the server might reject connections if # postmaster cannot accept() them fast enough. The exact limit # and behavior depends on the platform. To make this reliable, # we attempt SSL negotiation on each connection before opening # next one. The server will reject the SSL negotiations, but # when it does so, we know that the backend has been launched # and we should be able to open another connection.
# SSLRequest packet consists of packet length followed by # NEGOTIATE_SSL_CODE.
my $negotiate_ssl_code = pack("Nnn", 8, 1234, 5679);
my $sent = $sock->send($negotiate_ssl_code);
# Read reply. We expect the server to reject it with 'N'
my $reply = "";
$sock->recv($reply, 1);
is($reply, "N", "dead-end connection $i");
push(@raw_connections, $sock);
}
# When all the connection slots are in use, new connections will fail # before even looking up the user. Hence you now get "sorry, too many # clients already" instead of "role does not exist" error. Test that # to ensure that we have used up all the slots.
$node->connect_fails("dbname=postgres user=invalid_user", "connection is rejected when all slots are in use",
expected_stderr => qr/FATAL: sorry, too many clients already/);
# Open one more connection, to really ensure that we have at least one # dead-end backend.
my $sock = $node->raw_connect();
# Test that the dead-end backends don't prevent the server from stopping.
$node->stop('fast', timeout => $stop_timeout);
$node->start();
$node->connect_ok("dbname=postgres", "works after restart");
# Clean up foreach my $socket (@raw_connections)
{
$socket->close();
}
done_testing();
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-08-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.