Move routines to manipulate WAL into PostgreSQL::Test::Cluster
[pgsql.git] / src / bin / pg_resetwal / t / 001_basic.pl
blobd0bd1f7ace8dfc591e602113b4b119e5b3729928
2 # Copyright (c) 2021-2025, PostgreSQL Global Development Group
4 use strict;
5 use warnings FATAL => 'all';
7 use PostgreSQL::Test::Cluster;
8 use PostgreSQL::Test::Utils;
9 use Test::More;
11 program_help_ok('pg_resetwal');
12 program_version_ok('pg_resetwal');
13 program_options_handling_ok('pg_resetwal');
15 my $node = PostgreSQL::Test::Cluster->new('main');
16 $node->init;
17 $node->append_conf('postgresql.conf', 'track_commit_timestamp = on');
19 command_like([ 'pg_resetwal', '-n', $node->data_dir ],
20 qr/checkpoint/, 'pg_resetwal -n produces output');
23 # Permissions on PGDATA should be default
24 SKIP:
26 skip "unix-style permissions not supported on Windows", 1
27 if ($windows_os);
29 ok(check_mode_recursive($node->data_dir, 0700, 0600),
30 'check PGDATA permissions');
33 command_ok([ 'pg_resetwal', '-D', $node->data_dir ], 'pg_resetwal runs');
34 $node->start;
35 is($node->safe_psql("postgres", "SELECT 1;"),
36 1, 'server running and working after reset');
38 command_fails_like(
39 [ 'pg_resetwal', $node->data_dir ],
40 qr/lock file .* exists/,
41 'fails if server running');
43 $node->stop('immediate');
44 command_fails_like(
45 [ 'pg_resetwal', $node->data_dir ],
46 qr/database server was not shut down cleanly/,
47 'does not run after immediate shutdown');
48 command_ok(
49 [ 'pg_resetwal', '-f', $node->data_dir ],
50 'runs after immediate shutdown with force');
51 $node->start;
52 is($node->safe_psql("postgres", "SELECT 1;"),
53 1, 'server running and working after forced reset');
55 $node->stop;
57 # check various command-line handling
59 # Note: This test intends to check that a nonexistent data directory
60 # gives a reasonable error message. Because of the way the code is
61 # currently structured, you get an error about readings permissions,
62 # which is perhaps suboptimal, so feel free to update this test if
63 # this gets improved.
64 command_fails_like(
65 [ 'pg_resetwal', 'foo' ],
66 qr/error: could not read permissions of directory/,
67 'fails with nonexistent data directory');
69 command_fails_like(
70 [ 'pg_resetwal', 'foo', 'bar' ],
71 qr/too many command-line arguments/,
72 'fails with too many command-line arguments');
74 $ENV{PGDATA} = $node->data_dir; # not used
75 command_fails_like(
76 ['pg_resetwal'],
77 qr/no data directory specified/,
78 'fails with too few command-line arguments');
80 # error cases
81 # -c
82 command_fails_like(
83 [ 'pg_resetwal', '-c', 'foo', $node->data_dir ],
84 qr/error: invalid argument for option -c/,
85 'fails with incorrect -c option');
86 command_fails_like(
87 [ 'pg_resetwal', '-c', '10,bar', $node->data_dir ],
88 qr/error: invalid argument for option -c/,
89 'fails with incorrect -c option part 2');
90 command_fails_like(
91 [ 'pg_resetwal', '-c', '1,10', $node->data_dir ],
92 qr/greater than/,
93 'fails with -c value 1 part 1');
94 command_fails_like(
95 [ 'pg_resetwal', '-c', '10,1', $node->data_dir ],
96 qr/greater than/,
97 'fails with -c value 1 part 2');
98 # -e
99 command_fails_like(
100 [ 'pg_resetwal', '-e', 'foo', $node->data_dir ],
101 qr/error: invalid argument for option -e/,
102 'fails with incorrect -e option');
103 command_fails_like(
104 [ 'pg_resetwal', '-e', '-1', $node->data_dir ],
105 qr/must not be -1/,
106 'fails with -e value -1');
107 # -l
108 command_fails_like(
109 [ 'pg_resetwal', '-l', 'foo', $node->data_dir ],
110 qr/error: invalid argument for option -l/,
111 'fails with incorrect -l option');
112 # -m
113 command_fails_like(
114 [ 'pg_resetwal', '-m', 'foo', $node->data_dir ],
115 qr/error: invalid argument for option -m/,
116 'fails with incorrect -m option');
117 command_fails_like(
118 [ 'pg_resetwal', '-m', '10,bar', $node->data_dir ],
119 qr/error: invalid argument for option -m/,
120 'fails with incorrect -m option part 2');
121 command_fails_like(
122 [ 'pg_resetwal', '-m', '0,10', $node->data_dir ],
123 qr/must not be 0/,
124 'fails with -m value 0 part 1');
125 command_fails_like(
126 [ 'pg_resetwal', '-m', '10,0', $node->data_dir ],
127 qr/must not be 0/,
128 'fails with -m value 0 part 2');
129 # -o
130 command_fails_like(
131 [ 'pg_resetwal', '-o', 'foo', $node->data_dir ],
132 qr/error: invalid argument for option -o/,
133 'fails with incorrect -o option');
134 command_fails_like(
135 [ 'pg_resetwal', '-o', '0', $node->data_dir ],
136 qr/must not be 0/,
137 'fails with -o value 0');
138 # -O
139 command_fails_like(
140 [ 'pg_resetwal', '-O', 'foo', $node->data_dir ],
141 qr/error: invalid argument for option -O/,
142 'fails with incorrect -O option');
143 command_fails_like(
144 [ 'pg_resetwal', '-O', '-1', $node->data_dir ],
145 qr/must not be -1/,
146 'fails with -O value -1');
147 # --wal-segsize
148 command_fails_like(
149 [ 'pg_resetwal', '--wal-segsize', 'foo', $node->data_dir ],
150 qr/error: invalid value/,
151 'fails with incorrect --wal-segsize option');
152 command_fails_like(
153 [ 'pg_resetwal', '--wal-segsize', '13', $node->data_dir ],
154 qr/must be a power/,
155 'fails with invalid --wal-segsize value');
156 # -u
157 command_fails_like(
158 [ 'pg_resetwal', '-u', 'foo', $node->data_dir ],
159 qr/error: invalid argument for option -u/,
160 'fails with incorrect -u option');
161 command_fails_like(
162 [ 'pg_resetwal', '-u', '1', $node->data_dir ],
163 qr/must be greater than/,
164 'fails with -u value too small');
165 # -x
166 command_fails_like(
167 [ 'pg_resetwal', '-x', 'foo', $node->data_dir ],
168 qr/error: invalid argument for option -x/,
169 'fails with incorrect -x option');
170 command_fails_like(
171 [ 'pg_resetwal', '-x', '1', $node->data_dir ],
172 qr/must be greater than/,
173 'fails with -x value too small');
175 # run with control override options
177 my $out = (run_command([ 'pg_resetwal', '-n', $node->data_dir ]))[0];
178 $out =~ /^Database block size: *(\d+)$/m or die;
179 my $blcksz = $1;
181 my @cmd = ('pg_resetwal', '-D', $node->data_dir);
183 # some not-so-critical hardcoded values
184 push @cmd, '-e', 1;
185 push @cmd, '-l', '00000001000000320000004B';
186 push @cmd, '-o', 100_000;
187 push @cmd, '--wal-segsize', 1;
189 # these use the guidance from the documentation
191 sub get_slru_files
193 opendir(my $dh, $node->data_dir . '/' . $_[0]) or die $!;
194 my @files = sort grep { /[0-9A-F]+/ } readdir $dh;
195 closedir $dh;
196 return @files;
199 my (@files, $mult);
201 @files = get_slru_files('pg_commit_ts');
202 # XXX: Should there be a multiplier, similar to the other options?
203 # -c argument is "old,new"
204 push @cmd,
205 '-c',
206 sprintf("%d,%d", hex($files[0]) == 0 ? 3 : hex($files[0]), hex($files[-1]));
208 @files = get_slru_files('pg_multixact/offsets');
209 $mult = 32 * $blcksz / 4;
210 # -m argument is "new,old"
211 push @cmd, '-m',
212 sprintf("%d,%d",
213 (hex($files[-1]) + 1) * $mult,
214 hex($files[0]) == 0 ? 1 : hex($files[0] * $mult));
216 @files = get_slru_files('pg_multixact/members');
217 $mult = 32 * int($blcksz / 20) * 4;
218 push @cmd, '-O', (hex($files[-1]) + 1) * $mult;
220 @files = get_slru_files('pg_xact');
221 $mult = 32 * $blcksz * 4;
222 push @cmd,
223 '-u', (hex($files[0]) == 0 ? 3 : hex($files[0]) * $mult),
224 '-x', ((hex($files[-1]) + 1) * $mult);
226 command_ok([ @cmd, '-n' ], 'runs with control override options, dry run');
227 command_ok(\@cmd, 'runs with control override options');
228 command_like(
229 [ 'pg_resetwal', '-n', $node->data_dir ],
230 qr/^Latest checkpoint's NextOID: *100000$/m,
231 'spot check that control changes were applied');
233 $node->start;
234 ok(1, 'server started after reset');
236 done_testing();