Skip to content

Commit c1ff2d8

Browse files
committed
Avoid 037_invalid_database.pl hang under debug_discard_caches.
Back-patch to v12 (all supported versions).
1 parent d8ebcac commit c1ff2d8

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

src/test/recovery/t/037_invalid_database.pl

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@
8888
# Test that interruption of DROP DATABASE is handled properly. To ensure the
8989
# interruption happens at the appropriate moment, we lock pg_tablespace. DROP
9090
# DATABASE scans pg_tablespace once it has reached the "irreversible" part of
91-
# dropping the database, making it a suitable point to wait.
91+
# dropping the database, making it a suitable point to wait. Since relcache
92+
# init reads pg_tablespace, establish each connection before locking. This
93+
# avoids a connection-time hang with debug_discard_caches.
94+
my $cancel = $node->background_psql('postgres', on_error_stop => 1);
9295
my $bgpsql = $node->background_psql('postgres', on_error_stop => 0);
9396
my $pid = $bgpsql->query('SELECT pg_backend_pid()');
9497

@@ -104,14 +107,19 @@
104107
# Try to drop. This will wait due to the still held lock.
105108
$bgpsql->query_until(qr//, "DROP DATABASE regression_invalid_interrupt;\n");
106109

107-
# Ensure we're waiting for the lock
108-
$node->poll_query_until('postgres',
109-
qq(SELECT EXISTS(SELECT * FROM pg_locks WHERE NOT granted AND relation = 'pg_tablespace'::regclass AND mode = 'AccessShareLock');)
110-
);
111110

112-
# and finally interrupt the DROP DATABASE
113-
ok($node->safe_psql('postgres', "SELECT pg_cancel_backend($pid)"),
111+
# Once the DROP DATABASE is waiting for the lock, interrupt it.
112+
ok( $cancel->query_safe(
113+
qq(
114+
DO \$\$
115+
BEGIN
116+
WHILE NOT EXISTS(SELECT * FROM pg_locks WHERE NOT granted AND relation = 'pg_tablespace'::regclass AND mode = 'AccessShareLock') LOOP
117+
PERFORM pg_sleep(.1);
118+
END LOOP;
119+
END\$\$;
120+
SELECT pg_cancel_backend($pid);)),
114121
"canceling DROP DATABASE");
122+
$cancel->quit();
115123

116124
# wait for cancellation to be processed
117125
ok( pump_until(
@@ -120,7 +128,8 @@
120128
"cancel processed");
121129
$bgpsql->{stderr} = '';
122130

123-
# verify that connection to the database aren't allowed
131+
# Verify that connections to the database aren't allowed. The backend checks
132+
# this before relcache init, so the lock won't interfere.
124133
is($node->psql('regression_invalid_interrupt', ''),
125134
2, "can't connect to invalid_interrupt database");
126135

0 commit comments

Comments
 (0)