aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2024-09-27 15:28:56 -0700
committerNoah Misch <noah@leadboat.com>2024-09-27 15:28:56 -0700
commitc1ff2d8bc5be55e302731a16aaff563b7f03ed7c (patch)
tree6150e944638bb73e994f520711d05b8ae386c317
parentd8ebcac547d7c25c1378e0fc5810528f343ab8d5 (diff)
downloadpostgresql-c1ff2d8bc5be55e302731a16aaff563b7f03ed7c.tar.gz
postgresql-c1ff2d8bc5be55e302731a16aaff563b7f03ed7c.zip
Avoid 037_invalid_database.pl hang under debug_discard_caches.
Back-patch to v12 (all supported versions).
-rw-r--r--src/test/recovery/t/037_invalid_database.pl25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/test/recovery/t/037_invalid_database.pl b/src/test/recovery/t/037_invalid_database.pl
index 47f524be4cc..6d1c7117964 100644
--- a/src/test/recovery/t/037_invalid_database.pl
+++ b/src/test/recovery/t/037_invalid_database.pl
@@ -88,7 +88,10 @@ is($node->psql('postgres', 'DROP DATABASE regression_invalid'),
# Test that interruption of DROP DATABASE is handled properly. To ensure the
# interruption happens at the appropriate moment, we lock pg_tablespace. DROP
# DATABASE scans pg_tablespace once it has reached the "irreversible" part of
-# dropping the database, making it a suitable point to wait.
+# dropping the database, making it a suitable point to wait. Since relcache
+# init reads pg_tablespace, establish each connection before locking. This
+# avoids a connection-time hang with debug_discard_caches.
+my $cancel = $node->background_psql('postgres', on_error_stop => 1);
my $bgpsql = $node->background_psql('postgres', on_error_stop => 0);
my $pid = $bgpsql->query('SELECT pg_backend_pid()');
@@ -104,14 +107,19 @@ ok( $bgpsql->query_safe(
# Try to drop. This will wait due to the still held lock.
$bgpsql->query_until(qr//, "DROP DATABASE regression_invalid_interrupt;\n");
-# Ensure we're waiting for the lock
-$node->poll_query_until('postgres',
- qq(SELECT EXISTS(SELECT * FROM pg_locks WHERE NOT granted AND relation = 'pg_tablespace'::regclass AND mode = 'AccessShareLock');)
-);
-# and finally interrupt the DROP DATABASE
-ok($node->safe_psql('postgres', "SELECT pg_cancel_backend($pid)"),
+# Once the DROP DATABASE is waiting for the lock, interrupt it.
+ok( $cancel->query_safe(
+ qq(
+ DO \$\$
+ BEGIN
+ WHILE NOT EXISTS(SELECT * FROM pg_locks WHERE NOT granted AND relation = 'pg_tablespace'::regclass AND mode = 'AccessShareLock') LOOP
+ PERFORM pg_sleep(.1);
+ END LOOP;
+ END\$\$;
+ SELECT pg_cancel_backend($pid);)),
"canceling DROP DATABASE");
+$cancel->quit();
# wait for cancellation to be processed
ok( pump_until(
@@ -120,7 +128,8 @@ ok( pump_until(
"cancel processed");
$bgpsql->{stderr} = '';
-# verify that connection to the database aren't allowed
+# Verify that connections to the database aren't allowed. The backend checks
+# this before relcache init, so the lock won't interfere.
is($node->psql('regression_invalid_interrupt', ''),
2, "can't connect to invalid_interrupt database");