Skip to content

Commit a16b2b9

Browse files
committed
Fix TAP test for remove_temp_files_after_crash
The test included in cd91de0 had two simple flaws. Firstly, the number of rows was low and on some platforms (e.g. 32-bit) the sort did not require on-disk sort, so on those machines it was not testing the automatic removal. The test was however failing, because without any temporary files the base/pgsql_tmp directory was not even created. Fixed by increasing the rowcount to 5000, which should be high engough on any platform. Secondly, the test used a simple sleep to wait for the temporary file to be created. This is obviously problematic, because on slow machines (or with valgrind, CLOBBER_CACHE_ALWAYS etc.) it may take a while to create the temporary file. But we also want the tests run reasonably fast. Fixed by instead relying on a UNIQUE constraint, blocking the query that created the temporary file. Author: Euler Taveira Reviewed-by: Tomas Vondra Discussion: https://postgr.es/m/CAH503wDKdYzyq7U-QJqGn%3DGm6XmoK%2B6_6xTJ-Yn5WSvoHLY1Ww%40mail.gmail.com
1 parent 5b2266e commit a16b2b9

File tree

1 file changed

+47
-13
lines changed

1 file changed

+47
-13
lines changed

src/test/recovery/t/022_crash_temp_files.pl

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
use TestLib;
66
use Test::More;
77
use Config;
8-
use Time::HiRes qw(usleep);
98

109
plan tests => 9;
1110

@@ -33,8 +32,7 @@
3332
# create table, insert rows
3433
$node->safe_psql(
3534
'postgres',
36-
q[CREATE TABLE tab_crash (a text);
37-
INSERT INTO tab_crash (a) SELECT gen_random_uuid() FROM generate_series(1, 500);]);
35+
q[CREATE TABLE tab_crash (a integer UNIQUE);]);
3836

3937
# Run psql, keeping session alive, so we have an alive backend to kill.
4038
my ($killme_stdin, $killme_stdout, $killme_stderr) = ('', '', '');
@@ -62,29 +60,53 @@
6260
$killme_stdout = '';
6361
$killme_stderr = '';
6462

63+
# Open a 2nd session that will block the 1st one, using the UNIQUE constraint.
64+
# This will prevent removal of the temporary file created by the 1st session.
65+
my ($killme_stdin2, $killme_stdout2, $killme_stderr2) = ('', '', '');
66+
my $killme2 = IPC::Run::start(
67+
[
68+
'psql', '-X', '-qAt', '-v', 'ON_ERROR_STOP=1', '-f', '-', '-d',
69+
$node->connstr('postgres')
70+
],
71+
'<',
72+
\$killme_stdin2,
73+
'>',
74+
\$killme_stdout2,
75+
'2>',
76+
\$killme_stderr2,
77+
$psql_timeout);
78+
79+
# Insert one tuple and leave the transaction open
80+
$killme_stdin2 .= q[
81+
BEGIN;
82+
SELECT $$insert-tuple-to-lock-next-insert$$;
83+
INSERT INTO tab_crash (a) VALUES(1);
84+
];
85+
pump_until($killme2, \$killme_stdout2, qr/insert-tuple-to-lock-next-insert/m);
86+
$killme_stdout2 = '';
87+
$killme_stderr2 = '';
88+
6589
# Run the query that generates a temporary file and that will be killed before
6690
# it finishes. Since the query that generates the temporary file does not
6791
# return before the connection is killed, use a SELECT before to trigger
6892
# pump_until.
6993
$killme_stdin .= q[
7094
BEGIN;
7195
SELECT $$in-progress-before-sigkill$$;
72-
WITH foo AS (SELECT a FROM tab_crash ORDER BY a) SELECT a, pg_sleep(1) FROM foo;
96+
INSERT INTO tab_crash (a) SELECT i FROM generate_series(1, 5000) s(i);
7397
];
7498
ok(pump_until($killme, \$killme_stdout, qr/in-progress-before-sigkill/m),
75-
'select in-progress-before-sigkill');
99+
'insert in-progress-before-sigkill');
76100
$killme_stdout = '';
77101
$killme_stderr = '';
78102

79-
# Wait some time so the temporary file is generated by SELECT
80-
usleep(10_000);
81-
82103
# Kill with SIGKILL
83104
my $ret = TestLib::system_log('pg_ctl', 'kill', 'KILL', $pid);
84105
is($ret, 0, 'killed process with KILL');
85106

86107
# Close psql session
87108
$killme->finish;
109+
$killme2->finish;
88110

89111
# Wait till server restarts
90112
$node->poll_query_until('postgres', 'SELECT 1', '1');
@@ -118,29 +140,41 @@
118140
$killme_stdout = '';
119141
$killme_stderr = '';
120142

143+
# Restart the 2nd psql session
144+
($killme_stdin2, $killme_stdout2, $killme_stderr2) = ('', '', '');
145+
$killme2->run();
146+
147+
# Insert one tuple and leave the transaction open
148+
$killme_stdin2 .= q[
149+
BEGIN;
150+
SELECT $$insert-tuple-to-lock-next-insert$$;
151+
INSERT INTO tab_crash (a) VALUES(1);
152+
];
153+
pump_until($killme2, \$killme_stdout2, qr/insert-tuple-to-lock-next-insert/m);
154+
$killme_stdout2 = '';
155+
$killme_stderr2 = '';
156+
121157
# Run the query that generates a temporary file and that will be killed before
122158
# it finishes. Since the query that generates the temporary file does not
123159
# return before the connection is killed, use a SELECT before to trigger
124160
# pump_until.
125161
$killme_stdin .= q[
126162
BEGIN;
127163
SELECT $$in-progress-before-sigkill$$;
128-
WITH foo AS (SELECT a FROM tab_crash ORDER BY a) SELECT a, pg_sleep(1) FROM foo;
164+
INSERT INTO tab_crash (a) SELECT i FROM generate_series(1, 5000) s(i);
129165
];
130166
ok(pump_until($killme, \$killme_stdout, qr/in-progress-before-sigkill/m),
131-
'select in-progress-before-sigkill');
167+
'insert in-progress-before-sigkill');
132168
$killme_stdout = '';
133169
$killme_stderr = '';
134170

135-
# Wait some time so the temporary file is generated by SELECT
136-
usleep(10_000);
137-
138171
# Kill with SIGKILL
139172
$ret = TestLib::system_log('pg_ctl', 'kill', 'KILL', $pid);
140173
is($ret, 0, 'killed process with KILL');
141174

142175
# Close psql session
143176
$killme->finish;
177+
$killme2->finish;
144178

145179
# Wait till server restarts
146180
$node->poll_query_until('postgres', 'SELECT 1', '1');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy