Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 36e4419

Browse files
committed
Make error messages about WAL segment size more consistent
Make the primary messages more compact and make the detail messages uniform. In initdb.c and pg_resetwal.c, use the newish option_parse_int() to simplify some of the option parsing. For the backend GUC wal_segment_size, add a GUC check hook to do the verification instead of coding it in bootstrap.c. This might be overkill, but that way the check is in the right place and it becomes more self-documenting. In passing, make pg_controldata use the logging API for warning messages. Reviewed-by: Aleksander Alekseev <aleksander@timescale.com> Discussion: https://www.postgresql.org/message-id/flat/9939aa8a-d7be-da2c-7715-0a0b5535a1f7@eisentraut.org
1 parent bb90022 commit 36e4419

File tree

12 files changed

+71
-65
lines changed

12 files changed

+71
-65
lines changed

src/backend/access/transam/xlog.c

+16-3
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,18 @@ assign_checkpoint_completion_target(double newval, void *extra)
19951995
CalculateCheckpointSegments();
19961996
}
19971997

1998+
bool
1999+
check_wal_segment_size(int *newval, void **extra, GucSource source)
2000+
{
2001+
if (!IsValidWalSegSize(*newval))
2002+
{
2003+
GUC_check_errdetail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
2004+
return false;
2005+
}
2006+
2007+
return true;
2008+
}
2009+
19982010
/*
19992011
* At a checkpoint, how many WAL segments to recycle as preallocated future
20002012
* XLOG segments? Returns the highest segment that should be preallocated.
@@ -4145,10 +4157,11 @@ ReadControlFile(void)
41454157

41464158
if (!IsValidWalSegSize(wal_segment_size))
41474159
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
4148-
errmsg_plural("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte",
4149-
"WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
4160+
errmsg_plural("invalid WAL segment size in control file (%d byte)",
4161+
"invalid WAL segment size in control file (%d bytes)",
41504162
wal_segment_size,
4151-
wal_segment_size)));
4163+
wal_segment_size),
4164+
errdetail("The WAL segment size must be a power of two between 1 MB and 1 GB.")));
41524165

41534166
snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segment_size);
41544167
SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL,

src/backend/bootstrap/bootstrap.c

+1-10
Original file line numberDiff line numberDiff line change
@@ -280,16 +280,7 @@ BootstrapModeMain(int argc, char *argv[], bool check_only)
280280
strlcpy(OutputFileName, optarg, MAXPGPATH);
281281
break;
282282
case 'X':
283-
{
284-
int WalSegSz = strtoul(optarg, NULL, 0);
285-
286-
if (!IsValidWalSegSize(WalSegSz))
287-
ereport(ERROR,
288-
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
289-
errmsg("-X requires a power of two value between 1 MB and 1 GB")));
290-
SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL,
291-
PGC_S_DYNAMIC_DEFAULT);
292-
}
283+
SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
293284
break;
294285
default:
295286
write_stderr("Try \"%s --help\" for more information.\n",

src/backend/utils/misc/guc_tables.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -3166,7 +3166,7 @@ struct config_int ConfigureNamesInt[] =
31663166
DEFAULT_XLOG_SEG_SIZE,
31673167
WalSegMinSize,
31683168
WalSegMaxSize,
3169-
NULL, NULL, NULL
3169+
check_wal_segment_size, NULL, NULL
31703170
},
31713171

31723172
{

src/bin/initdb/initdb.c

+6-19
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
#include "common/restricted_token.h"
7777
#include "common/string.h"
7878
#include "common/username.h"
79+
#include "fe_utils/option_utils.h"
7980
#include "fe_utils/string_utils.h"
8081
#include "getopt_long.h"
8182
#include "mb/pg_wchar.h"
@@ -163,8 +164,7 @@ static bool sync_only = false;
163164
static bool show_setting = false;
164165
static bool data_checksums = false;
165166
static char *xlog_dir = NULL;
166-
static char *str_wal_segment_size_mb = NULL;
167-
static int wal_segment_size_mb;
167+
static int wal_segment_size_mb = (DEFAULT_XLOG_SEG_SIZE) / (1024 * 1024);
168168

169169

170170
/* internal vars */
@@ -3258,7 +3258,8 @@ main(int argc, char *argv[])
32583258
xlog_dir = pg_strdup(optarg);
32593259
break;
32603260
case 12:
3261-
str_wal_segment_size_mb = pg_strdup(optarg);
3261+
if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segment_size_mb))
3262+
exit(1);
32623263
break;
32633264
case 13:
32643265
noinstructions = true;
@@ -3348,22 +3349,8 @@ main(int argc, char *argv[])
33483349

33493350
check_need_password(authmethodlocal, authmethodhost);
33503351

3351-
/* set wal segment size */
3352-
if (str_wal_segment_size_mb == NULL)
3353-
wal_segment_size_mb = (DEFAULT_XLOG_SEG_SIZE) / (1024 * 1024);
3354-
else
3355-
{
3356-
char *endptr;
3357-
3358-
/* check that the argument is a number */
3359-
wal_segment_size_mb = strtol(str_wal_segment_size_mb, &endptr, 10);
3360-
3361-
/* verify that wal segment size is valid */
3362-
if (endptr == str_wal_segment_size_mb || *endptr != '\0')
3363-
pg_fatal("argument of --wal-segsize must be a number");
3364-
if (!IsValidWalSegSize(wal_segment_size_mb * 1024 * 1024))
3365-
pg_fatal("argument of --wal-segsize must be a power of 2 between 1 and 1024");
3366-
}
3352+
if (!IsValidWalSegSize(wal_segment_size_mb * 1024 * 1024))
3353+
pg_fatal("argument of %s must be a power of 2 between 1 and 1024", "--wal-segsize");
33673354

33683355
get_restricted_token();
33693356

src/bin/pg_basebackup/streamutil.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,11 @@ RetrieveWalSegSize(PGconn *conn)
321321

322322
if (!IsValidWalSegSize(WalSegSz))
323323
{
324-
pg_log_error(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte",
325-
"WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes",
324+
pg_log_error(ngettext("remote server reported invalid WAL segment size (%d byte)",
325+
"remote server reported invalid WAL segment size (%d bytes)",
326326
WalSegSz),
327327
WalSegSz);
328+
pg_log_error_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
328329
return false;
329330
}
330331

src/bin/pg_controldata/pg_controldata.c

+11-12
Original file line numberDiff line numberDiff line change
@@ -167,24 +167,23 @@ main(int argc, char *argv[])
167167
/* get a copy of the control file */
168168
ControlFile = get_controlfile(DataDir, &crc_ok);
169169
if (!crc_ok)
170-
printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
171-
"Either the file is corrupt, or it has a different layout than this program\n"
172-
"is expecting. The results below are untrustworthy.\n\n"));
170+
{
171+
pg_log_warning("calculated CRC checksum does not match value stored in control file");
172+
pg_log_warning_detail("Either the control file is corrupt, or it has a different layout than this program "
173+
"is expecting. The results below are untrustworthy.");
174+
}
173175

174176
/* set wal segment size */
175177
WalSegSz = ControlFile->xlog_seg_size;
176178

177179
if (!IsValidWalSegSize(WalSegSz))
178180
{
179-
printf(_("WARNING: invalid WAL segment size\n"));
180-
printf(ngettext("The WAL segment size stored in the file, %d byte, is not a power of two\n"
181-
"between 1 MB and 1 GB. The file is corrupt and the results below are\n"
182-
"untrustworthy.\n\n",
183-
"The WAL segment size stored in the file, %d bytes, is not a power of two\n"
184-
"between 1 MB and 1 GB. The file is corrupt and the results below are\n"
185-
"untrustworthy.\n\n",
186-
WalSegSz),
187-
WalSegSz);
181+
pg_log_warning(ngettext("invalid WAL segment size in control file (%d byte)",
182+
"invalid WAL segment size in control file (%d bytes)",
183+
WalSegSz),
184+
WalSegSz);
185+
pg_log_warning_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
186+
pg_log_warning_detail("The file is corrupt and the results below are untrustworthy.");
188187
}
189188

190189
/*

src/bin/pg_controldata/t/001_pg_controldata.pl

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@
3636
command_checks_all(
3737
[ 'pg_controldata', $node->data_dir ],
3838
0,
39+
[qr/./],
3940
[
40-
qr/WARNING: Calculated CRC checksum does not match value stored in file/,
41-
qr/WARNING: invalid WAL segment size/
41+
qr/warning: calculated CRC checksum does not match value stored in control file/,
42+
qr/warning: invalid WAL segment size/
4243
],
43-
[qr/^$/],
4444
'pg_controldata with corrupted pg_control');
4545

4646
done_testing();

src/bin/pg_resetwal/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ subdir = src/bin/pg_resetwal
1515
top_builddir = ../../..
1616
include $(top_builddir)/src/Makefile.global
1717

18+
LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils
19+
1820
OBJS = \
1921
$(WIN32RES) \
2022
pg_resetwal.o

src/bin/pg_resetwal/pg_resetwal.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "common/logging.h"
5656
#include "common/restricted_token.h"
5757
#include "common/string.h"
58+
#include "fe_utils/option_utils.h"
5859
#include "getopt_long.h"
5960
#include "pg_getopt.h"
6061
#include "storage/large_object.h"
@@ -290,13 +291,16 @@ main(int argc, char *argv[])
290291
break;
291292

292293
case 1:
293-
errno = 0;
294-
set_wal_segsize = strtol(optarg, &endptr, 10) * 1024 * 1024;
295-
if (endptr == optarg || *endptr != '\0' || errno != 0)
296-
pg_fatal("argument of --wal-segsize must be a number");
297-
if (!IsValidWalSegSize(set_wal_segsize))
298-
pg_fatal("argument of --wal-segsize must be a power of 2 between 1 and 1024");
299-
break;
294+
{
295+
int wal_segsize_mb;
296+
297+
if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segsize_mb))
298+
exit(1);
299+
set_wal_segsize = wal_segsize_mb * 1024 * 1024;
300+
if (!IsValidWalSegSize(set_wal_segsize))
301+
pg_fatal("argument of %s must be a power of 2 between 1 and 1024", "--wal-segsize");
302+
break;
303+
}
300304

301305
default:
302306
/* getopt_long already emitted a complaint */

src/bin/pg_rewind/pg_rewind.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -1023,10 +1023,14 @@ digestControlFile(ControlFileData *ControlFile, const char *content,
10231023
WalSegSz = ControlFile->xlog_seg_size;
10241024

10251025
if (!IsValidWalSegSize(WalSegSz))
1026-
pg_fatal(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte",
1027-
"WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
1028-
WalSegSz),
1029-
WalSegSz);
1026+
{
1027+
pg_log_error(ngettext("invalid WAL segment size in control file (%d byte)",
1028+
"invalid WAL segment size in control file (%d bytes)",
1029+
WalSegSz),
1030+
WalSegSz);
1031+
pg_log_error_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
1032+
exit(1);
1033+
}
10301034

10311035
/* Additional checks on control file */
10321036
checkControlFile(ControlFile);

src/bin/pg_waldump/pg_waldump.c

+8-4
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,14 @@ search_directory(const char *directory, const char *fname)
252252
WalSegSz = longhdr->xlp_seg_size;
253253

254254
if (!IsValidWalSegSize(WalSegSz))
255-
pg_fatal(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d byte",
256-
"WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes",
257-
WalSegSz),
258-
fname, WalSegSz);
255+
{
256+
pg_log_error(ngettext("invalid WAL segment size in WAL file \"%s\" (%d byte)",
257+
"invalid WAL segment size in WAL file \"%s\" (%d bytes)",
258+
WalSegSz),
259+
fname, WalSegSz);
260+
pg_log_error_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
261+
exit(1);
262+
}
259263
}
260264
else if (r < 0)
261265
pg_fatal("could not read file \"%s\": %m",

src/include/utils/guc_hooks.h

+1
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ extern bool check_wal_buffers(int *newval, void **extra, GucSource source);
158158
extern bool check_wal_consistency_checking(char **newval, void **extra,
159159
GucSource source);
160160
extern void assign_wal_consistency_checking(const char *newval, void *extra);
161+
extern bool check_wal_segment_size(int *newval, void **extra, GucSource source);
161162
extern void assign_xlog_sync_method(int new_sync_method, void *extra);
162163

163164
#endif /* GUC_HOOKS_H */

0 commit comments

Comments
 (0)