CalculateCheckpointSegments();
}
+bool
+check_wal_segment_size(int *newval, void **extra, GucSource source)
+{
+ if (!IsValidWalSegSize(*newval))
+ {
+ GUC_check_errdetail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
+ return false;
+ }
+
+ return true;
+}
+
/*
* At a checkpoint, how many WAL segments to recycle as preallocated future
* XLOG segments? Returns the highest segment that should be preallocated.
if (!IsValidWalSegSize(wal_segment_size))
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg_plural("WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d byte",
- "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
+ errmsg_plural("invalid WAL segment size in control file (%d byte)",
+ "invalid WAL segment size in control file (%d bytes)",
wal_segment_size,
- wal_segment_size)));
+ wal_segment_size),
+ errdetail("The WAL segment size must be a power of two between 1 MB and 1 GB.")));
snprintf(wal_segsz_str, sizeof(wal_segsz_str), "%d", wal_segment_size);
SetConfigOption("wal_segment_size", wal_segsz_str, PGC_INTERNAL,
strlcpy(OutputFileName, optarg, MAXPGPATH);
break;
case 'X':
- {
- int WalSegSz = strtoul(optarg, NULL, 0);
-
- if (!IsValidWalSegSize(WalSegSz))
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("-X requires a power of two value between 1 MB and 1 GB")));
- SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL,
- PGC_S_DYNAMIC_DEFAULT);
- }
+ SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT);
break;
default:
write_stderr("Try \"%s --help\" for more information.\n",
DEFAULT_XLOG_SEG_SIZE,
WalSegMinSize,
WalSegMaxSize,
- NULL, NULL, NULL
+ check_wal_segment_size, NULL, NULL
},
{
#include "common/restricted_token.h"
#include "common/string.h"
#include "common/username.h"
+#include "fe_utils/option_utils.h"
#include "fe_utils/string_utils.h"
#include "getopt_long.h"
#include "mb/pg_wchar.h"
static bool show_setting = false;
static bool data_checksums = false;
static char *xlog_dir = NULL;
-static char *str_wal_segment_size_mb = NULL;
-static int wal_segment_size_mb;
+static int wal_segment_size_mb = (DEFAULT_XLOG_SEG_SIZE) / (1024 * 1024);
/* internal vars */
xlog_dir = pg_strdup(optarg);
break;
case 12:
- str_wal_segment_size_mb = pg_strdup(optarg);
+ if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segment_size_mb))
+ exit(1);
break;
case 13:
noinstructions = true;
check_need_password(authmethodlocal, authmethodhost);
- /* set wal segment size */
- if (str_wal_segment_size_mb == NULL)
- wal_segment_size_mb = (DEFAULT_XLOG_SEG_SIZE) / (1024 * 1024);
- else
- {
- char *endptr;
-
- /* check that the argument is a number */
- wal_segment_size_mb = strtol(str_wal_segment_size_mb, &endptr, 10);
-
- /* verify that wal segment size is valid */
- if (endptr == str_wal_segment_size_mb || *endptr != '\0')
- pg_fatal("argument of --wal-segsize must be a number");
- if (!IsValidWalSegSize(wal_segment_size_mb * 1024 * 1024))
- pg_fatal("argument of --wal-segsize must be a power of 2 between 1 and 1024");
- }
+ if (!IsValidWalSegSize(wal_segment_size_mb * 1024 * 1024))
+ pg_fatal("argument of %s must be a power of 2 between 1 and 1024", "--wal-segsize");
get_restricted_token();
if (!IsValidWalSegSize(WalSegSz))
{
- 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",
- "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",
+ pg_log_error(ngettext("remote server reported invalid WAL segment size (%d byte)",
+ "remote server reported invalid WAL segment size (%d bytes)",
WalSegSz),
WalSegSz);
+ pg_log_error_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
return false;
}
/* get a copy of the control file */
ControlFile = get_controlfile(DataDir, &crc_ok);
if (!crc_ok)
- printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
- "Either the file is corrupt, or it has a different layout than this program\n"
- "is expecting. The results below are untrustworthy.\n\n"));
+ {
+ pg_log_warning("calculated CRC checksum does not match value stored in control file");
+ pg_log_warning_detail("Either the control file is corrupt, or it has a different layout than this program "
+ "is expecting. The results below are untrustworthy.");
+ }
/* set wal segment size */
WalSegSz = ControlFile->xlog_seg_size;
if (!IsValidWalSegSize(WalSegSz))
{
- printf(_("WARNING: invalid WAL segment size\n"));
- printf(ngettext("The WAL segment size stored in the file, %d byte, is not a power of two\n"
- "between 1 MB and 1 GB. The file is corrupt and the results below are\n"
- "untrustworthy.\n\n",
- "The WAL segment size stored in the file, %d bytes, is not a power of two\n"
- "between 1 MB and 1 GB. The file is corrupt and the results below are\n"
- "untrustworthy.\n\n",
- WalSegSz),
- WalSegSz);
+ pg_log_warning(ngettext("invalid WAL segment size in control file (%d byte)",
+ "invalid WAL segment size in control file (%d bytes)",
+ WalSegSz),
+ WalSegSz);
+ pg_log_warning_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
+ pg_log_warning_detail("The file is corrupt and the results below are untrustworthy.");
}
/*
command_checks_all(
[ 'pg_controldata', $node->data_dir ],
0,
+ [qr/./],
[
- qr/WARNING: Calculated CRC checksum does not match value stored in file/,
- qr/WARNING: invalid WAL segment size/
+ qr/warning: calculated CRC checksum does not match value stored in control file/,
+ qr/warning: invalid WAL segment size/
],
- [qr/^$/],
'pg_controldata with corrupted pg_control');
done_testing();
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
+LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils
+
OBJS = \
$(WIN32RES) \
pg_resetwal.o
#include "common/logging.h"
#include "common/restricted_token.h"
#include "common/string.h"
+#include "fe_utils/option_utils.h"
#include "getopt_long.h"
#include "pg_getopt.h"
#include "storage/large_object.h"
break;
case 1:
- errno = 0;
- set_wal_segsize = strtol(optarg, &endptr, 10) * 1024 * 1024;
- if (endptr == optarg || *endptr != '\0' || errno != 0)
- pg_fatal("argument of --wal-segsize must be a number");
- if (!IsValidWalSegSize(set_wal_segsize))
- pg_fatal("argument of --wal-segsize must be a power of 2 between 1 and 1024");
- break;
+ {
+ int wal_segsize_mb;
+
+ if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segsize_mb))
+ exit(1);
+ set_wal_segsize = wal_segsize_mb * 1024 * 1024;
+ if (!IsValidWalSegSize(set_wal_segsize))
+ pg_fatal("argument of %s must be a power of 2 between 1 and 1024", "--wal-segsize");
+ break;
+ }
default:
/* getopt_long already emitted a complaint */
WalSegSz = ControlFile->xlog_seg_size;
if (!IsValidWalSegSize(WalSegSz))
- 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",
- "WAL segment size must be a power of two between 1 MB and 1 GB, but the control file specifies %d bytes",
- WalSegSz),
- WalSegSz);
+ {
+ pg_log_error(ngettext("invalid WAL segment size in control file (%d byte)",
+ "invalid WAL segment size in control file (%d bytes)",
+ WalSegSz),
+ WalSegSz);
+ pg_log_error_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
+ exit(1);
+ }
/* Additional checks on control file */
checkControlFile(ControlFile);
WalSegSz = longhdr->xlp_seg_size;
if (!IsValidWalSegSize(WalSegSz))
- 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",
- "WAL segment size must be a power of two between 1 MB and 1 GB, but the WAL file \"%s\" header specifies %d bytes",
- WalSegSz),
- fname, WalSegSz);
+ {
+ pg_log_error(ngettext("invalid WAL segment size in WAL file \"%s\" (%d byte)",
+ "invalid WAL segment size in WAL file \"%s\" (%d bytes)",
+ WalSegSz),
+ fname, WalSegSz);
+ pg_log_error_detail("The WAL segment size must be a power of two between 1 MB and 1 GB.");
+ exit(1);
+ }
}
else if (r < 0)
pg_fatal("could not read file \"%s\": %m",
extern bool check_wal_consistency_checking(char **newval, void **extra,
GucSource source);
extern void assign_wal_consistency_checking(const char *newval, void *extra);
+extern bool check_wal_segment_size(int *newval, void **extra, GucSource source);
extern void assign_xlog_sync_method(int new_sync_method, void *extra);
#endif /* GUC_HOOKS_H */