PostgreSQL Source Code git master
pg_resetwal.c File Reference
#include "postgres.h"
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include "access/heaptoast.h"
#include "access/multixact.h"
#include "access/transam.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "common/controldata_utils.h"
#include "common/fe_memutils.h"
#include "common/file_perm.h"
#include "common/logging.h"
#include "common/restricted_token.h"
#include "common/string.h"
#include "fe_utils/option_utils.h"
#include "fe_utils/version.h"
#include "getopt_long.h"
#include "pg_getopt.h"
#include "storage/large_object.h"
Include dependency graph for pg_resetwal.c:

Go to the source code of this file.

Macros

#define FRONTEND   1
 
#define ARCHSTATDIR   XLOGDIR "/archive_status"
 
#define WALSUMMARYDIR   XLOGDIR "/summaries"
 
#define WALSUMMARY_NHEXCHARS   40
 

Functions

static void CheckDataVersion (void)
 
static bool read_controlfile (void)
 
static void GuessControlValues (void)
 
static void PrintControlValues (bool guessed)
 
static void PrintNewControlValues (void)
 
static void RewriteControlFile (void)
 
static void FindEndOfXLOG (void)
 
static void KillExistingXLOG (void)
 
static void KillExistingArchiveStatus (void)
 
static void KillExistingWALSummaries (void)
 
static void WriteEmptyXLOG (void)
 
static void usage (void)
 
static uint32 strtouint32_strict (const char *restrict s, char **restrict endptr, int base)
 
static uint64 strtouint64_strict (const char *restrict s, char **restrict endptr, int base)
 
int main (int argc, char *argv[])
 

Variables

static ControlFileData ControlFile
 
static XLogSegNo newXlogSegNo
 
static bool guessed = false
 
static const char * progname
 
static bool next_xid_epoch_given = false
 
static uint32 next_xid_epoch_val
 
static bool oldest_xid_given = false
 
static TransactionId oldest_xid_val
 
static bool next_xid_given = false
 
static TransactionId next_xid_val
 
static bool commit_ts_xids_given = false
 
static TransactionId oldest_commit_ts_xid_val
 
static TransactionId newest_commit_ts_xid_val
 
static bool next_oid_given = false
 
static Oid next_oid_val
 
static bool mxids_given = false
 
static MultiXactId next_mxid_val
 
static MultiXactId oldest_mxid_val = 0
 
static bool next_mxoff_given = false
 
static MultiXactOffset next_mxoff_val
 
static bool wal_segsize_given = false
 
static int wal_segsize_val
 
static bool char_signedness_given = false
 
static bool char_signedness_val
 
static TimeLineID minXlogTli = 0
 
static XLogSegNo minXlogSegNo = 0
 
static int WalSegSz
 

Macro Definition Documentation

◆ ARCHSTATDIR

#define ARCHSTATDIR   XLOGDIR "/archive_status"

◆ FRONTEND

#define FRONTEND   1

Definition at line 35 of file pg_resetwal.c.

◆ WALSUMMARY_NHEXCHARS

#define WALSUMMARY_NHEXCHARS   40

◆ WALSUMMARYDIR

#define WALSUMMARYDIR   XLOGDIR "/summaries"

Function Documentation

◆ CheckDataVersion()

static void CheckDataVersion ( void  )
static

Definition at line 572 of file pg_resetwal.c.

573{
574 char *version_str;
575 uint32 version = get_pg_version(".", &version_str);
576
577 if (GET_PG_MAJORVERSION_NUM(version) != PG_MAJORVERSION_NUM)
578 {
579 pg_log_error("data directory is of wrong version");
580 pg_log_error_detail("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
581 "PG_VERSION",
582 version_str,
583 PG_MAJORVERSION);
584 exit(1);
585 }
586}
uint32_t uint32
Definition: c.h:552
uint32 get_pg_version(const char *datadir, char **version_str)
Definition: version.c:44
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_detail(...)
Definition: logging.h:109
#define GET_PG_MAJORVERSION_NUM(v)
Definition: version.h:19

References GET_PG_MAJORVERSION_NUM, get_pg_version(), pg_log_error, and pg_log_error_detail.

Referenced by main().

◆ FindEndOfXLOG()

static void FindEndOfXLOG ( void  )
static

Definition at line 950 of file pg_resetwal.c.

951{
952 DIR *xldir;
953 struct dirent *xlde;
954 uint64 xlogbytepos;
955
956 /*
957 * Initialize the max() computation using the last checkpoint address from
958 * old pg_control. Note that for the moment we are working with segment
959 * numbering according to the old xlog seg size.
960 */
963
964 /*
965 * Scan the pg_wal directory to find existing WAL segment files. We assume
966 * any present have been used; in most scenarios this should be
967 * conservative, because of xlog.c's attempts to pre-create files.
968 */
969 xldir = opendir(XLOGDIR);
970 if (xldir == NULL)
971 pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
972
973 while (errno = 0, (xlde = readdir(xldir)) != NULL)
974 {
975 if (IsXLogFileName(xlde->d_name) ||
977 {
978 TimeLineID tli;
979 XLogSegNo segno;
980
981 /* Use the segment size from the control file */
982 XLogFromFileName(xlde->d_name, &tli, &segno,
984
985 /*
986 * Note: we take the max of all files found, regardless of their
987 * timelines. Another possibility would be to ignore files of
988 * timelines other than the target TLI, but this seems safer.
989 * Better too large a result than too small...
990 */
991 if (segno > newXlogSegNo)
992 newXlogSegNo = segno;
993 }
994 }
995
996 if (errno)
997 pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
998
999 if (closedir(xldir))
1000 pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
1001
1002 /*
1003 * Finally, convert to new xlog seg size, and advance by one to ensure we
1004 * are in virgin territory.
1005 */
1006 xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
1007 newXlogSegNo = (xlogbytepos + ControlFile.xlog_seg_size - 1) / WalSegSz;
1008 newXlogSegNo++;
1009}
uint64_t uint64
Definition: c.h:553
int closedir(DIR *)
Definition: dirent.c:127
struct dirent * readdir(DIR *)
Definition: dirent.c:78
DIR * opendir(const char *)
Definition: dirent.c:33
#define pg_fatal(...)
static int WalSegSz
Definition: pg_resetwal.c:103
static ControlFileData ControlFile
Definition: pg_resetwal.c:63
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:64
XLogRecPtr redo
Definition: pg_control.h:37
uint32 xlog_seg_size
Definition: pg_control.h:213
CheckPoint checkPointCopy
Definition: pg_control.h:135
Definition: dirent.c:26
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
static bool IsXLogFileName(const char *fname)
static void XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)
#define XLOGDIR
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
static bool IsPartialXLogFileName(const char *fname)
uint32 TimeLineID
Definition: xlogdefs.h:63
uint64 XLogSegNo
Definition: xlogdefs.h:52

References ControlFileData::checkPointCopy, closedir(), ControlFile, dirent::d_name, IsPartialXLogFileName(), IsXLogFileName(), newXlogSegNo, opendir(), pg_fatal, readdir(), CheckPoint::redo, WalSegSz, XLByteToSeg, ControlFileData::xlog_seg_size, XLOGDIR, and XLogFromFileName().

Referenced by main().

◆ GuessControlValues()

static void GuessControlValues ( void  )
static

Definition at line 670 of file pg_resetwal.c.

671{
672 uint64 sysidentifier;
673 struct timeval tv;
674
675 /*
676 * Set up a completely default set of pg_control values.
677 */
678 guessed = true;
679 memset(&ControlFile, 0, sizeof(ControlFile));
680
683
684 /*
685 * Create a new unique installation identifier, since we can no longer use
686 * any old XLOG records. See notes in xlog.c about the algorithm.
687 */
688 gettimeofday(&tv, NULL);
689 sysidentifier = ((uint64) tv.tv_sec) << 32;
690 sysidentifier |= ((uint64) tv.tv_usec) << 12;
691 sysidentifier |= getpid() & 0xFFF;
692
693 ControlFile.system_identifier = sysidentifier;
694
710
712 ControlFile.time = (pg_time_t) time(NULL);
715
716 /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
717
726
727 ControlFile.maxAlign = MAXIMUM_ALIGNOF;
729 ControlFile.blcksz = BLCKSZ;
730 ControlFile.relseg_size = RELSEG_SIZE;
732 ControlFile.xlog_blcksz = XLOG_BLCKSZ;
738 ControlFile.float8ByVal = true; /* vestigial */
739
740 /*
741 * XXX eventually, should try to grovel through old XLOG to develop more
742 * accurate values for TimeLineID, nextXID, etc.
743 */
744}
#define CATALOG_VERSION_NO
Definition: catversion.h:60
#define TOAST_MAX_CHUNK_SIZE
Definition: heaptoast.h:84
#define LOBLKSIZE
Definition: large_object.h:70
#define FirstMultiXactId
Definition: multixact.h:26
#define INDEX_MAX_KEYS
#define NAMEDATALEN
#define DEFAULT_XLOG_SEG_SIZE
#define SLRU_PAGES_PER_SEGMENT
#define FLOATFORMAT_VALUE
Definition: pg_control.h:201
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
@ DB_SHUTDOWNED
Definition: pg_control.h:92
static bool guessed
Definition: pg_resetwal.c:65
int64 pg_time_t
Definition: pgtime.h:23
#define InvalidOid
Definition: postgres_ext.h:37
Oid oldestMultiDB
Definition: pg_control.h:51
MultiXactId oldestMulti
Definition: pg_control.h:50
MultiXactOffset nextMultiOffset
Definition: pg_control.h:47
TransactionId oldestXid
Definition: pg_control.h:48
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:45
TransactionId oldestActiveXid
Definition: pg_control.h:64
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:46
FullTransactionId nextXid
Definition: pg_control.h:44
pg_time_t time
Definition: pg_control.h:52
Oid oldestXidDB
Definition: pg_control.h:49
int max_worker_processes
Definition: pg_control.h:181
uint32 pg_control_version
Definition: pg_control.h:125
bool track_commit_timestamp
Definition: pg_control.h:185
int max_locks_per_xact
Definition: pg_control.h:184
uint32 nameDataLen
Definition: pg_control.h:215
uint32 slru_pages_per_segment
Definition: pg_control.h:210
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
uint32 indexMaxKeys
Definition: pg_control.h:216
uint32 relseg_size
Definition: pg_control.h:208
pg_time_t time
Definition: pg_control.h:132
XLogRecPtr checkPoint
Definition: pg_control.h:133
uint64 system_identifier
Definition: pg_control.h:110
uint32 catalog_version_no
Definition: pg_control.h:126
double floatFormat
Definition: pg_control.h:200
int max_prepared_xacts
Definition: pg_control.h:183
uint32 xlog_blcksz
Definition: pg_control.h:212
uint32 loblksize
Definition: pg_control.h:219
uint32 toast_max_chunk_size
Definition: pg_control.h:218
#define InvalidTransactionId
Definition: transam.h:31
#define FirstGenbkiObjectId
Definition: transam.h:195
#define FirstNormalTransactionId
Definition: transam.h:34
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
int gettimeofday(struct timeval *tp, void *tzp)
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:74
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:37

References ControlFileData::blcksz, CATALOG_VERSION_NO, ControlFileData::catalog_version_no, ControlFileData::checkPoint, ControlFileData::checkPointCopy, ControlFile, DB_SHUTDOWNED, DEFAULT_XLOG_SEG_SIZE, FirstGenbkiObjectId, FirstMultiXactId, FirstNormalTransactionId, FirstNormalUnloggedLSN, ControlFileData::float8ByVal, ControlFileData::floatFormat, FLOATFORMAT_VALUE, CheckPoint::fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), guessed, INDEX_MAX_KEYS, ControlFileData::indexMaxKeys, InvalidOid, InvalidTransactionId, ControlFileData::loblksize, LOBLKSIZE, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_wal_senders, ControlFileData::max_worker_processes, ControlFileData::maxAlign, ControlFileData::MaxConnections, ControlFileData::nameDataLen, NAMEDATALEN, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::oldestActiveXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, PG_CONTROL_VERSION, ControlFileData::pg_control_version, CheckPoint::PrevTimeLineID, CheckPoint::redo, ControlFileData::relseg_size, SizeOfXLogLongPHD, ControlFileData::slru_pages_per_segment, SLRU_PAGES_PER_SEGMENT, ControlFileData::state, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, CheckPoint::time, ControlFileData::time, TOAST_MAX_CHUNK_SIZE, ControlFileData::toast_max_chunk_size, ControlFileData::track_commit_timestamp, ControlFileData::unloggedLSN, ControlFileData::wal_level, WAL_LEVEL_MINIMAL, ControlFileData::wal_log_hints, ControlFileData::xlog_blcksz, and ControlFileData::xlog_seg_size.

Referenced by main().

◆ KillExistingArchiveStatus()

static void KillExistingArchiveStatus ( void  )
static

Definition at line 1049 of file pg_resetwal.c.

1050{
1051#define ARCHSTATDIR XLOGDIR "/archive_status"
1052
1053 DIR *xldir;
1054 struct dirent *xlde;
1055 char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1056
1057 xldir = opendir(ARCHSTATDIR);
1058 if (xldir == NULL)
1059 pg_fatal("could not open directory \"%s\": %m", ARCHSTATDIR);
1060
1061 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1062 {
1063 if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1064 (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1065 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1066 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1067 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1068 {
1069 snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1070 if (unlink(path) < 0)
1071 pg_fatal("could not delete file \"%s\": %m", path);
1072 }
1073 }
1074
1075 if (errno)
1076 pg_fatal("could not read directory \"%s\": %m", ARCHSTATDIR);
1077
1078 if (closedir(xldir))
1079 pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1080}
#define MAXPGPATH
#define ARCHSTATDIR
#define snprintf
Definition: port.h:260
#define XLOG_FNAME_LEN

References ARCHSTATDIR, closedir(), dirent::d_name, MAXPGPATH, opendir(), pg_fatal, readdir(), snprintf, and XLOG_FNAME_LEN.

Referenced by main().

◆ KillExistingWALSummaries()

static void KillExistingWALSummaries ( void  )
static

Definition at line 1086 of file pg_resetwal.c.

1087{
1088#define WALSUMMARYDIR XLOGDIR "/summaries"
1089#define WALSUMMARY_NHEXCHARS 40
1090
1091 DIR *xldir;
1092 struct dirent *xlde;
1093 char path[MAXPGPATH + sizeof(WALSUMMARYDIR)];
1094
1095 xldir = opendir(WALSUMMARYDIR);
1096 if (xldir == NULL)
1097 pg_fatal("could not open directory \"%s\": %m", WALSUMMARYDIR);
1098
1099 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1100 {
1101 if (strspn(xlde->d_name, "0123456789ABCDEF") == WALSUMMARY_NHEXCHARS &&
1102 strcmp(xlde->d_name + WALSUMMARY_NHEXCHARS, ".summary") == 0)
1103 {
1104 snprintf(path, sizeof(path), "%s/%s", WALSUMMARYDIR, xlde->d_name);
1105 if (unlink(path) < 0)
1106 pg_fatal("could not delete file \"%s\": %m", path);
1107 }
1108 }
1109
1110 if (errno)
1111 pg_fatal("could not read directory \"%s\": %m", WALSUMMARYDIR);
1112
1113 if (closedir(xldir))
1114 pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1115}
#define WALSUMMARY_NHEXCHARS
#define WALSUMMARYDIR

References ARCHSTATDIR, closedir(), dirent::d_name, MAXPGPATH, opendir(), pg_fatal, readdir(), snprintf, WALSUMMARY_NHEXCHARS, and WALSUMMARYDIR.

Referenced by main().

◆ KillExistingXLOG()

static void KillExistingXLOG ( void  )
static

Definition at line 1016 of file pg_resetwal.c.

1017{
1018 DIR *xldir;
1019 struct dirent *xlde;
1020 char path[MAXPGPATH + sizeof(XLOGDIR)];
1021
1022 xldir = opendir(XLOGDIR);
1023 if (xldir == NULL)
1024 pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
1025
1026 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1027 {
1028 if (IsXLogFileName(xlde->d_name) ||
1030 {
1031 snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
1032 if (unlink(path) < 0)
1033 pg_fatal("could not delete file \"%s\": %m", path);
1034 }
1035 }
1036
1037 if (errno)
1038 pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
1039
1040 if (closedir(xldir))
1041 pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
1042}

References closedir(), dirent::d_name, IsPartialXLogFileName(), IsXLogFileName(), MAXPGPATH, opendir(), pg_fatal, readdir(), snprintf, and XLOGDIR.

Referenced by main().

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 122 of file pg_resetwal.c.

123{
124 static struct option long_options[] = {
125 {"commit-timestamp-ids", required_argument, NULL, 'c'},
126 {"pgdata", required_argument, NULL, 'D'},
127 {"epoch", required_argument, NULL, 'e'},
128 {"force", no_argument, NULL, 'f'},
129 {"next-wal-file", required_argument, NULL, 'l'},
130 {"multixact-ids", required_argument, NULL, 'm'},
131 {"dry-run", no_argument, NULL, 'n'},
132 {"next-oid", required_argument, NULL, 'o'},
133 {"multixact-offset", required_argument, NULL, 'O'},
134 {"oldest-transaction-id", required_argument, NULL, 'u'},
135 {"next-transaction-id", required_argument, NULL, 'x'},
136 {"wal-segsize", required_argument, NULL, 1},
137 {"char-signedness", required_argument, NULL, 2},
138 {NULL, 0, NULL, 0}
139 };
140
141 int c;
142 bool force = false;
143 bool noupdate = false;
144 char *endptr;
145 char *endptr2;
146 char *DataDir = NULL;
147 char *log_fname = NULL;
148 int fd;
149
150 pg_logging_init(argv[0]);
151 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
152 progname = get_progname(argv[0]);
153
154 if (argc > 1)
155 {
156 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
157 {
158 usage();
159 exit(0);
160 }
161 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
162 {
163 puts("pg_resetwal (PostgreSQL) " PG_VERSION);
164 exit(0);
165 }
166 }
167
168
169 while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:u:x:", long_options, NULL)) != -1)
170 {
171 switch (c)
172 {
173 case 'D':
174 DataDir = optarg;
175 break;
176
177 case 'f':
178 force = true;
179 break;
180
181 case 'n':
182 noupdate = true;
183 break;
184
185 case 'e':
186 errno = 0;
188 if (endptr == optarg || *endptr != '\0' || errno != 0)
189 {
190 /*------
191 translator: the second %s is a command line argument (-e, etc) */
192 pg_log_error("invalid argument for option %s", "-e");
193 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
194 exit(1);
195 }
197 break;
198
199 case 'u':
200 errno = 0;
202 if (endptr == optarg || *endptr != '\0' || errno != 0)
203 {
204 pg_log_error("invalid argument for option %s", "-u");
205 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
206 exit(1);
207 }
209 pg_fatal("oldest transaction ID (-u) must be greater than or equal to %u", FirstNormalTransactionId);
210 oldest_xid_given = true;
211 break;
212
213 case 'x':
214 errno = 0;
216 if (endptr == optarg || *endptr != '\0' || errno != 0)
217 {
218 pg_log_error("invalid argument for option %s", "-x");
219 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
220 exit(1);
221 }
223 pg_fatal("transaction ID (-x) must be greater than or equal to %u", FirstNormalTransactionId);
224 next_xid_given = true;
225 break;
226
227 case 'c':
228 errno = 0;
230 if (endptr == optarg || *endptr != ',' || errno != 0)
231 {
232 pg_log_error("invalid argument for option %s", "-c");
233 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
234 exit(1);
235 }
236 newest_commit_ts_xid_val = strtoul(endptr + 1, &endptr2, 0);
237 if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
238 {
239 pg_log_error("invalid argument for option %s", "-c");
240 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
241 exit(1);
242 }
243
246 pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
247
250 pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
252 break;
253
254 case 'o':
255 errno = 0;
257 if (endptr == optarg || *endptr != '\0' || errno != 0)
258 {
259 pg_log_error("invalid argument for option %s", "-o");
260 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
261 exit(1);
262 }
263 if (next_oid_val == 0)
264 pg_fatal("OID (-o) must not be 0");
265 next_oid_given = true;
266 break;
267
268 case 'm':
269 errno = 0;
271 if (endptr == optarg || *endptr != ',' || errno != 0)
272 {
273 pg_log_error("invalid argument for option %s", "-m");
274 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
275 exit(1);
276 }
277
278 oldest_mxid_val = strtouint32_strict(endptr + 1, &endptr2, 0);
279 if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
280 {
281 pg_log_error("invalid argument for option %s", "-m");
282 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
283 exit(1);
284 }
285
286 /*
287 * XXX It'd be nice to have more sanity checks here, e.g. so
288 * that oldest is not wrapped around w.r.t. nextMulti.
289 */
290 if (next_mxid_val == 0)
291 pg_fatal("next multitransaction ID (-m) must not be 0");
292 if (oldest_mxid_val == 0)
293 pg_fatal("oldest multitransaction ID (-m) must not be 0");
294 mxids_given = true;
295 break;
296
297 case 'O':
298 errno = 0;
300 if (endptr == optarg || *endptr != '\0' || errno != 0)
301 {
302 pg_log_error("invalid argument for option %s", "-O");
303 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
304 exit(1);
305 }
306 next_mxoff_given = true;
307 break;
308
309 case 'l':
310 if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
311 {
312 pg_log_error("invalid argument for option %s", "-l");
313 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
314 exit(1);
315 }
316
317 /*
318 * XLogFromFileName requires wal segment size which is not yet
319 * set. Hence wal details are set later on.
320 */
321 log_fname = pg_strdup(optarg);
322 break;
323
324 case 1:
325 {
326 int wal_segsize_mb;
327
328 if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segsize_mb))
329 exit(1);
330 wal_segsize_val = wal_segsize_mb * 1024 * 1024;
332 pg_fatal("argument of %s must be a power of two between 1 and 1024", "--wal-segsize");
333 wal_segsize_given = true;
334 break;
335 }
336
337 case 2:
338 {
339 errno = 0;
340
341 if (pg_strcasecmp(optarg, "signed") == 0)
342 char_signedness_val = true;
343 else if (pg_strcasecmp(optarg, "unsigned") == 0)
344 char_signedness_val = false;
345 else
346 {
347 pg_log_error("invalid argument for option %s", "--char-signedness");
348 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
349 exit(1);
350 }
352 break;
353 }
354
355 default:
356 /* getopt_long already emitted a complaint */
357 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
358 exit(1);
359 }
360 }
361
362 if (DataDir == NULL && optind < argc)
363 DataDir = argv[optind++];
364
365 /* Complain if any arguments remain */
366 if (optind < argc)
367 {
368 pg_log_error("too many command-line arguments (first is \"%s\")",
369 argv[optind]);
370 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
371 exit(1);
372 }
373
374 if (DataDir == NULL)
375 {
376 pg_log_error("no data directory specified");
377 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
378 exit(1);
379 }
380
381 /*
382 * Don't allow pg_resetwal to be run as root, to avoid overwriting the
383 * ownership of files in the data directory. We need only check for root
384 * -- any other user won't have sufficient permissions to modify files in
385 * the data directory.
386 */
387#ifndef WIN32
388 if (geteuid() == 0)
389 {
390 pg_log_error("cannot be executed by \"root\"");
391 pg_log_error_hint("You must run %s as the PostgreSQL superuser.",
392 progname);
393 exit(1);
394 }
395#endif
396
398
399 /* Set mask based on PGDATA permissions */
401 pg_fatal("could not read permissions of directory \"%s\": %m",
402 DataDir);
403
404 umask(pg_mode_mask);
405
406 if (chdir(DataDir) < 0)
407 pg_fatal("could not change directory to \"%s\": %m",
408 DataDir);
409
410 /* Check that data directory matches our server version */
412
413 /*
414 * Check for a postmaster lock file --- if there is one, refuse to
415 * proceed, on grounds we might be interfering with a live installation.
416 */
417 if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
418 {
419 if (errno != ENOENT)
420 pg_fatal("could not open file \"%s\" for reading: %m",
421 "postmaster.pid");
422 }
423 else
424 {
425 pg_log_error("lock file \"%s\" exists", "postmaster.pid");
426 pg_log_error_hint("Is a server running? If not, delete the lock file and try again.");
427 exit(1);
428 }
429
430 /*
431 * Attempt to read the existing pg_control file
432 */
433 if (!read_controlfile())
435
436 /*
437 * If no new WAL segment size was specified, use the control file value.
438 */
441 else
443
444 if (log_fname != NULL)
446
447 /*
448 * Also look at existing segment files to set up newXlogSegNo
449 */
451
452 /*
453 * If we're not going to proceed with the reset, print the current control
454 * file parameters.
455 */
456 if ((guessed && !force) || noupdate)
458
459 /*
460 * Adjust fields if required by switches. (Do this now so that printout,
461 * if any, includes these values.)
462 */
467
469 {
472 }
473
474 if (next_xid_given)
478
480 {
483 }
484
485 if (next_oid_given)
487
488 if (mxids_given)
489 {
491
496 }
497
500
502 {
505 }
506
509
512
515
516 if (noupdate)
517 {
519 exit(0);
520 }
521
522 /*
523 * If we had to guess anything, and -f was not given, just print the
524 * guessed values and exit.
525 */
526 if (guessed && !force)
527 {
529 pg_log_error("not proceeding because control file values were guessed");
530 pg_log_error_hint("If these values seem acceptable, use -f to force reset.");
531 exit(1);
532 }
533
534 /*
535 * Don't reset from a dirty pg_control without -f, either.
536 */
537 if (ControlFile.state != DB_SHUTDOWNED && !force)
538 {
539 pg_log_error("database server was not shut down cleanly");
540 pg_log_error_detail("Resetting the write-ahead log might cause data to be lost.");
541 pg_log_error_hint("If you want to proceed anyway, use -f to force reset.");
542 exit(1);
543 }
544
545 /*
546 * Else, do the dirty deed.
547 */
553
554 printf(_("Write-ahead log reset\n"));
555 return 0;
556}
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1212
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:430
#define _(x)
Definition: elog.c:91
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int pg_mode_mask
Definition: file_perm.c:25
bool GetDataDirectoryCreatePerm(const char *dataDir)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:60
#define no_argument
Definition: getopt_long.h:25
#define required_argument
Definition: getopt_long.h:26
char * DataDir
Definition: globals.c:71
void pg_logging_init(const char *argv0)
Definition: logging.c:83
#define pg_log_error_hint(...)
Definition: logging.h:112
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
PGDLLIMPORT int optind
Definition: getopt.c:51
PGDLLIMPORT char * optarg
Definition: getopt.c:53
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:950
static void RewriteControlFile(void)
Definition: pg_resetwal.c:904
static void KillExistingWALSummaries(void)
Definition: pg_resetwal.c:1086
static bool wal_segsize_given
Definition: pg_resetwal.c:94
static TransactionId oldest_commit_ts_xid_val
Definition: pg_resetwal.c:81
static uint32 next_xid_epoch_val
Definition: pg_resetwal.c:72
static MultiXactId oldest_mxid_val
Definition: pg_resetwal.c:89
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:1016
static void CheckDataVersion(void)
Definition: pg_resetwal.c:572
static bool char_signedness_given
Definition: pg_resetwal.c:97
static bool next_xid_epoch_given
Definition: pg_resetwal.c:71
static bool commit_ts_xids_given
Definition: pg_resetwal.c:80
static uint32 strtouint32_strict(const char *restrict s, char **restrict endptr, int base)
Definition: pg_resetwal.c:1246
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:102
static bool next_oid_given
Definition: pg_resetwal.c:84
static Oid next_oid_val
Definition: pg_resetwal.c:85
static TransactionId newest_commit_ts_xid_val
Definition: pg_resetwal.c:82
static TimeLineID minXlogTli
Definition: pg_resetwal.c:101
static bool next_xid_given
Definition: pg_resetwal.c:77
static TransactionId oldest_xid_val
Definition: pg_resetwal.c:75
static void PrintNewControlValues(void)
Definition: pg_resetwal.c:831
static uint64 strtouint64_strict(const char *restrict s, char **restrict endptr, int base)
Definition: pg_resetwal.c:1287
static bool char_signedness_val
Definition: pg_resetwal.c:98
static MultiXactOffset next_mxoff_val
Definition: pg_resetwal.c:92
static bool read_controlfile(void)
Definition: pg_resetwal.c:596
static int wal_segsize_val
Definition: pg_resetwal.c:95
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1049
static bool mxids_given
Definition: pg_resetwal.c:87
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1122
static const char * progname
Definition: pg_resetwal.c:66
static void usage(void)
Definition: pg_resetwal.c:1209
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:754
static bool oldest_xid_given
Definition: pg_resetwal.c:74
static TransactionId next_xid_val
Definition: pg_resetwal.c:78
static bool next_mxoff_given
Definition: pg_resetwal.c:91
static MultiXactId next_mxid_val
Definition: pg_resetwal.c:88
static void GuessControlValues(void)
Definition: pg_resetwal.c:670
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:32
const char * get_progname(const char *argv0)
Definition: path.c:652
#define printf(...)
Definition: port.h:266
char * c
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void get_restricted_token(void)
TransactionId newestCommitTsXid
Definition: pg_control.h:55
TransactionId oldestCommitTsXid
Definition: pg_control.h:53
bool default_char_signedness
Definition: pg_control.h:230
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
#define IsValidWalSegSize(size)
Definition: xlog_internal.h:96

References _, char_signedness_given, char_signedness_val, CheckDataVersion(), ControlFileData::checkPointCopy, commit_ts_xids_given, ControlFile, DataDir, DB_SHUTDOWNED, ControlFileData::default_char_signedness, EpochFromFullTransactionId, fd(), FindEndOfXLOG(), FirstMultiXactId, FirstNormalTransactionId, FullTransactionIdFromEpochAndXid(), get_progname(), get_restricted_token(), GetDataDirectoryCreatePerm(), getopt_long(), GuessControlValues(), guessed, InvalidOid, InvalidTransactionId, IsValidWalSegSize, KillExistingArchiveStatus(), KillExistingWALSummaries(), KillExistingXLOG(), minXlogSegNo, minXlogTli, mxids_given, newest_commit_ts_xid_val, CheckPoint::newestCommitTsXid, newXlogSegNo, next_mxid_val, next_mxoff_given, next_mxoff_val, next_oid_given, next_oid_val, next_xid_epoch_given, next_xid_epoch_val, next_xid_given, next_xid_val, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, no_argument, oldest_commit_ts_xid_val, oldest_mxid_val, oldest_xid_given, oldest_xid_val, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, optarg, optind, option_parse_int(), pg_fatal, pg_log_error, pg_log_error_detail, pg_log_error_hint, pg_logging_init(), pg_mode_mask, pg_strcasecmp(), pg_strdup(), PG_TEXTDOMAIN, CheckPoint::PrevTimeLineID, PrintControlValues(), printf, PrintNewControlValues(), progname, read_controlfile(), required_argument, RewriteControlFile(), set_pglocale_pgservice(), ControlFileData::state, strtouint32_strict(), strtouint64_strict(), CheckPoint::ThisTimeLineID, TransactionIdIsNormal, usage(), wal_segsize_given, wal_segsize_val, WalSegSz, WriteEmptyXLOG(), XidFromFullTransactionId, XLOG_FNAME_LEN, ControlFileData::xlog_seg_size, and XLogFromFileName().

◆ PrintControlValues()

static void PrintControlValues ( bool  guessed)
static

Definition at line 754 of file pg_resetwal.c.

755{
756 if (guessed)
757 printf(_("Guessed pg_control values:\n\n"));
758 else
759 printf(_("Current pg_control values:\n\n"));
760
761 printf(_("pg_control version number: %u\n"),
763 printf(_("Catalog version number: %u\n"),
765 printf(_("Database system identifier: %" PRIu64 "\n"),
767 printf(_("Latest checkpoint's TimeLineID: %u\n"),
769 printf(_("Latest checkpoint's full_page_writes: %s\n"),
770 ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
771 printf(_("Latest checkpoint's NextXID: %u:%u\n"),
774 printf(_("Latest checkpoint's NextOID: %u\n"),
776 printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
778 printf(_("Latest checkpoint's NextMultiOffset: %" PRIu64 "\n"),
780 printf(_("Latest checkpoint's oldestXID: %u\n"),
782 printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
784 printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
786 printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
788 printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
790 printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
792 printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
794 printf(_("Maximum data alignment: %u\n"),
796 /* we don't print floatFormat since can't say much useful about it */
797 printf(_("Database block size: %u\n"),
799 printf(_("Blocks per segment of large relation: %u\n"),
801 printf(_("Pages per SLRU segment: %u\n"),
803 printf(_("WAL block size: %u\n"),
805 printf(_("Bytes per WAL segment: %u\n"),
807 printf(_("Maximum length of identifiers: %u\n"),
809 printf(_("Maximum columns in an index: %u\n"),
811 printf(_("Maximum size of a TOAST chunk: %u\n"),
813 printf(_("Size of a large-object chunk: %u\n"),
815 /* This is no longer configurable, but users may still expect to see it: */
816 printf(_("Date/time type storage: %s\n"),
817 _("64-bit integers"));
818 printf(_("Float8 argument passing: %s\n"),
819 (ControlFile.float8ByVal ? _("by value") : _("by reference")));
820 printf(_("Data page checksum version: %u\n"),
822 printf(_("Default char data signedness: %s\n"),
823 (ControlFile.default_char_signedness ? _("signed") : _("unsigned")));
824}
uint32 data_checksum_version
Definition: pg_control.h:224

References _, ControlFileData::blcksz, ControlFileData::catalog_version_no, ControlFileData::checkPointCopy, ControlFile, ControlFileData::data_checksum_version, ControlFileData::default_char_signedness, EpochFromFullTransactionId, ControlFileData::float8ByVal, CheckPoint::fullPageWrites, guessed, ControlFileData::indexMaxKeys, ControlFileData::loblksize, ControlFileData::maxAlign, ControlFileData::nameDataLen, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, ControlFileData::pg_control_version, printf, ControlFileData::relseg_size, ControlFileData::slru_pages_per_segment, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, ControlFileData::toast_max_chunk_size, XidFromFullTransactionId, ControlFileData::xlog_blcksz, and ControlFileData::xlog_seg_size.

Referenced by main().

◆ PrintNewControlValues()

static void PrintNewControlValues ( void  )
static

Definition at line 831 of file pg_resetwal.c.

832{
833 char fname[MAXFNAMELEN];
834
835 /* This will be always printed in order to keep format same. */
836 printf(_("\n\nValues to be changed:\n\n"));
837
840 printf(_("First log segment after reset: %s\n"), fname);
841
842 if (mxids_given)
843 {
844 printf(_("NextMultiXactId: %u\n"),
846 printf(_("OldestMultiXid: %u\n"),
848 printf(_("OldestMulti's DB: %u\n"),
850 }
851
853 {
854 printf(_("NextMultiOffset: %" PRIu64 "\n"),
856 }
857
858 if (next_oid_given)
859 {
860 printf(_("NextOID: %u\n"),
862 }
863
864 if (next_xid_given)
865 {
866 printf(_("NextXID: %u\n"),
868 }
869
871 {
872 printf(_("OldestXID: %u\n"),
874 printf(_("OldestXID's DB: %u\n"),
876 }
877
879 {
880 printf(_("NextXID epoch: %u\n"),
882 }
883
885 {
886 printf(_("oldestCommitTsXid: %u\n"),
888 printf(_("newestCommitTsXid: %u\n"),
890 }
891
893 {
894 printf(_("Bytes per WAL segment: %u\n"),
896 }
897}
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References _, ControlFileData::checkPointCopy, commit_ts_xids_given, ControlFile, EpochFromFullTransactionId, MAXFNAMELEN, mxids_given, CheckPoint::newestCommitTsXid, newXlogSegNo, next_mxoff_given, next_oid_given, next_xid_epoch_given, next_xid_given, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, oldest_xid_given, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, printf, CheckPoint::ThisTimeLineID, wal_segsize_given, WalSegSz, XidFromFullTransactionId, ControlFileData::xlog_seg_size, and XLogFileName().

Referenced by main().

◆ read_controlfile()

static bool read_controlfile ( void  )
static

Definition at line 596 of file pg_resetwal.c.

597{
598 int fd;
599 int len;
600 char *buffer;
602
603 if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
604 {
605 /*
606 * If pg_control is not there at all, or we can't read it, the odds
607 * are we've been handed a bad DataDir path, so give up. User can do
608 * "touch pg_control" to force us to proceed.
609 */
610 pg_log_error("could not open file \"%s\" for reading: %m",
612 if (errno == ENOENT)
613 pg_log_error_hint("If you are sure the data directory path is correct, execute\n"
614 " touch %s\n"
615 "and try again.",
617 exit(1);
618 }
619
620 /* Use malloc to ensure we have a maxaligned buffer */
621 buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
622
623 len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
624 if (len < 0)
625 pg_fatal("could not read file \"%s\": %m", XLOG_CONTROL_FILE);
626 close(fd);
627
628 if (len >= sizeof(ControlFileData) &&
629 ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
630 {
631 /* Check the CRC. */
634 buffer,
635 offsetof(ControlFileData, crc));
637
638 if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
639 {
640 /* We will use the data but treat it as guessed. */
641 pg_log_warning("pg_control exists but has invalid CRC; proceed with caution");
642 guessed = true;
643 }
644
645 memcpy(&ControlFile, buffer, sizeof(ControlFile));
646
647 /* return false if WAL segment size is not valid */
649 {
650 pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution",
651 "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
654 return false;
655 }
656
657 return true;
658 }
659
660 /* Looks like it's a mess. */
661 pg_log_warning("pg_control exists but is broken or wrong version; ignoring it");
662 return false;
663}
#define ngettext(s, p, n)
Definition: c.h:1179
#define PG_BINARY
Definition: c.h:1271
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:258
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:153
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:158
const void size_t len
return crc
#define pg_log_warning(...)
Definition: pgfnames.c:24
#define XLOG_CONTROL_FILE

References close, COMP_CRC32C, ControlFile, crc, EQ_CRC32C, fd(), FIN_CRC32C, guessed, INIT_CRC32C, IsValidWalSegSize, len, ngettext, PG_BINARY, PG_CONTROL_FILE_SIZE, PG_CONTROL_VERSION, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_warning, pg_malloc(), read, XLOG_CONTROL_FILE, and ControlFileData::xlog_seg_size.

Referenced by main().

◆ RewriteControlFile()

static void RewriteControlFile ( void  )
static

Definition at line 904 of file pg_resetwal.c.

905{
906 /*
907 * Adjust fields as needed to force an empty XLOG starting at
908 * newXlogSegNo.
909 */
913
921
922 /*
923 * Force the defaults for max_* settings. The values don't really matter
924 * as long as wal_level='minimal'; the postmaster will reset these fields
925 * anyway at startup.
926 */
935
936 /* The control file gets flushed here. */
937 update_controlfile(".", &ControlFile, true);
938}
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
XLogRecPtr backupStartPoint
Definition: pg_control.h:170
bool backupEndRequired
Definition: pg_control.h:172
XLogRecPtr backupEndPoint
Definition: pg_control.h:171
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest)

References ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, ControlFileData::checkPoint, ControlFileData::checkPointCopy, ControlFile, DB_SHUTDOWNED, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_wal_senders, ControlFileData::max_worker_processes, ControlFileData::MaxConnections, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, newXlogSegNo, CheckPoint::redo, SizeOfXLogLongPHD, ControlFileData::state, CheckPoint::time, ControlFileData::track_commit_timestamp, update_controlfile(), ControlFileData::wal_level, WAL_LEVEL_MINIMAL, ControlFileData::wal_log_hints, WalSegSz, and XLogSegNoOffsetToRecPtr.

Referenced by main().

◆ strtouint32_strict()

static uint32 strtouint32_strict ( const char *restrict  s,
char **restrict  endptr,
int  base 
)
static

Definition at line 1246 of file pg_resetwal.c.

1247{
1248 unsigned long val;
1249 bool is_neg;
1250
1251 /* skip leading whitespace */
1252 while (isspace((unsigned char) *s))
1253 s++;
1254
1255 /*
1256 * Is it negative? We still call strtoul() if it was, to set 'endptr'.
1257 * (The current callers don't care though.)
1258 */
1259 is_neg = (*s == '-');
1260
1261 val = strtoul(s, endptr, base);
1262
1263 /* reject if it was negative */
1264 if (errno == 0 && is_neg)
1265 {
1266 errno = ERANGE;
1267 val = 0;
1268 }
1269
1270 /*
1271 * reject values larger than UINT32_MAX on platforms where long is 64 bits
1272 * wide.
1273 */
1274 if (errno == 0 && val != (uint32) val)
1275 {
1276 errno = ERANGE;
1277 val = UINT32_MAX;
1278 }
1279
1280 return (uint32) val;
1281}
long val
Definition: informix.c:689

References val.

Referenced by main().

◆ strtouint64_strict()

static uint64 strtouint64_strict ( const char *restrict  s,
char **restrict  endptr,
int  base 
)
static

Definition at line 1287 of file pg_resetwal.c.

1288{
1289 uint64 val;
1290 bool is_neg;
1291
1292 /* skip leading whitespace */
1293 while (isspace((unsigned char) *s))
1294 s++;
1295
1296 /*
1297 * Is it negative? We still call strtou64() if it was, to set 'endptr'.
1298 * (The current callers don't care though.)
1299 */
1300 is_neg = (*s == '-');
1301
1302 val = strtou64(s, endptr, base);
1303
1304 /* reject if it was negative */
1305 if (errno == 0 && is_neg)
1306 {
1307 errno = ERANGE;
1308 val = 0;
1309 }
1310
1311 return val;
1312}

References val.

Referenced by main().

◆ usage()

static void usage ( void  )
static

Definition at line 1209 of file pg_resetwal.c.

1210{
1211 printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1212 printf(_("Usage:\n"));
1213 printf(_(" %s [OPTION]... DATADIR\n"), progname);
1214
1215 printf(_("\nOptions:\n"));
1216 printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
1217 printf(_(" -f, --force force update to be done even after unclean shutdown or\n"
1218 " if pg_control values had to be guessed\n"));
1219 printf(_(" -n, --dry-run no update, just show what would be done\n"));
1220 printf(_(" -V, --version output version information, then exit\n"));
1221 printf(_(" -?, --help show this help, then exit\n"));
1222
1223 printf(_("\nOptions to override control file values:\n"));
1224 printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
1225 " set oldest and newest transactions bearing\n"
1226 " commit timestamp (zero means no change)\n"));
1227 printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
1228 printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
1229 printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
1230 printf(_(" -o, --next-oid=OID set next OID\n"));
1231 printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
1232 printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n"));
1233 printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
1234 printf(_(" --char-signedness=OPTION set char signedness to \"signed\" or \"unsigned\"\n"));
1235 printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
1236
1237 printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1238 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1239}

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1122 of file pg_resetwal.c.

1123{
1124 PGAlignedXLogBlock buffer;
1125 XLogPageHeader page;
1126 XLogLongPageHeader longpage;
1127 XLogRecord *record;
1128 pg_crc32c crc;
1129 char path[MAXPGPATH];
1130 int fd;
1131 int nbytes;
1132 char *recptr;
1133
1134 memset(buffer.data, 0, XLOG_BLCKSZ);
1135
1136 /* Set up the XLOG page header */
1137 page = (XLogPageHeader) buffer.data;
1138 page->xlp_magic = XLOG_PAGE_MAGIC;
1139 page->xlp_info = XLP_LONG_HEADER;
1142 longpage = (XLogLongPageHeader) page;
1144 longpage->xlp_seg_size = WalSegSz;
1145 longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1146
1147 /* Insert the initial checkpoint record */
1148 recptr = (char *) page + SizeOfXLogLongPHD;
1149 record = (XLogRecord *) recptr;
1150 record->xl_prev = 0;
1151 record->xl_xid = InvalidTransactionId;
1154 record->xl_rmid = RM_XLOG_ID;
1155
1156 recptr += SizeOfXLogRecord;
1157 *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1158 *(recptr++) = sizeof(CheckPoint);
1159 memcpy(recptr, &ControlFile.checkPointCopy,
1160 sizeof(CheckPoint));
1161
1163 COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1164 COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1165 FIN_CRC32C(crc);
1166 record->xl_crc = crc;
1167
1168 /* Write the first page */
1171
1172 unlink(path);
1173
1174 fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1176 if (fd < 0)
1177 pg_fatal("could not open file \"%s\": %m", path);
1178
1179 errno = 0;
1180 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1181 {
1182 /* if write didn't set errno, assume problem is no disk space */
1183 if (errno == 0)
1184 errno = ENOSPC;
1185 pg_fatal("could not write file \"%s\": %m", path);
1186 }
1187
1188 /* Fill the rest of the file with zeroes */
1189 memset(buffer.data, 0, XLOG_BLCKSZ);
1190 for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1191 {
1192 errno = 0;
1193 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1194 {
1195 if (errno == 0)
1196 errno = ENOSPC;
1197 pg_fatal("could not write file \"%s\": %m", path);
1198 }
1199 }
1200
1201 if (fsync(fd) != 0)
1202 pg_fatal("fsync error: %m");
1203
1204 close(fd);
1205}
int pg_file_create_mode
Definition: file_perm.c:19
#define write(a, b, c)
Definition: win32.h:14
struct CheckPoint CheckPoint
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:68
char data[XLOG_BLCKSZ]
Definition: c.h:1148
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
uint8 xl_info
Definition: xlogrecord.h:46
uint32 xl_tot_len
Definition: xlogrecord.h:43
TransactionId xl_xid
Definition: xlogrecord.h:44
RmgrId xl_rmid
Definition: xlogrecord.h:47
#define fsync(fd)
Definition: win32_port.h:83
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
static void XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:217
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:241
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

References ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFile, crc, PGAlignedXLogBlock::data, fd(), FIN_CRC32C, fsync, INIT_CRC32C, InvalidTransactionId, MAXPGPATH, newXlogSegNo, PG_BINARY, pg_fatal, pg_file_create_mode, CheckPoint::redo, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, WalSegSz, write, XLogRecord::xl_crc, XLogRecord::xl_info, XLogRecord::xl_prev, XLogRecord::xl_rmid, XLogRecord::xl_tot_len, XLogRecord::xl_xid, XLOG_CHECKPOINT_SHUTDOWN, XLOG_PAGE_MAGIC, XLogFilePath(), XLogPageHeaderData::xlp_info, XLP_LONG_HEADER, XLogPageHeaderData::xlp_magic, XLogPageHeaderData::xlp_pageaddr, XLogLongPageHeaderData::xlp_seg_size, XLogLongPageHeaderData::xlp_sysid, XLogPageHeaderData::xlp_tli, XLogLongPageHeaderData::xlp_xlog_blcksz, and XLR_BLOCK_ID_DATA_SHORT.

Referenced by main().

Variable Documentation

◆ char_signedness_given

bool char_signedness_given = false
static

Definition at line 97 of file pg_resetwal.c.

Referenced by main().

◆ char_signedness_val

bool char_signedness_val
static

Definition at line 98 of file pg_resetwal.c.

Referenced by main().

◆ commit_ts_xids_given

bool commit_ts_xids_given = false
static

Definition at line 80 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ ControlFile

◆ guessed

bool guessed = false
static

Definition at line 65 of file pg_resetwal.c.

Referenced by GuessControlValues(), main(), PrintControlValues(), and read_controlfile().

◆ minXlogSegNo

XLogSegNo minXlogSegNo = 0
static

Definition at line 102 of file pg_resetwal.c.

Referenced by main().

◆ minXlogTli

TimeLineID minXlogTli = 0
static

Definition at line 101 of file pg_resetwal.c.

Referenced by main().

◆ mxids_given

bool mxids_given = false
static

Definition at line 87 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ newest_commit_ts_xid_val

TransactionId newest_commit_ts_xid_val
static

Definition at line 82 of file pg_resetwal.c.

Referenced by main().

◆ newXlogSegNo

XLogSegNo newXlogSegNo
static

◆ next_mxid_val

MultiXactId next_mxid_val
static

Definition at line 88 of file pg_resetwal.c.

Referenced by main().

◆ next_mxoff_given

bool next_mxoff_given = false
static

Definition at line 91 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ next_mxoff_val

MultiXactOffset next_mxoff_val
static

Definition at line 92 of file pg_resetwal.c.

Referenced by main().

◆ next_oid_given

bool next_oid_given = false
static

Definition at line 84 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ next_oid_val

Oid next_oid_val
static

Definition at line 85 of file pg_resetwal.c.

Referenced by main().

◆ next_xid_epoch_given

bool next_xid_epoch_given = false
static

Definition at line 71 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ next_xid_epoch_val

uint32 next_xid_epoch_val
static

Definition at line 72 of file pg_resetwal.c.

Referenced by main().

◆ next_xid_given

bool next_xid_given = false
static

Definition at line 77 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ next_xid_val

TransactionId next_xid_val
static

Definition at line 78 of file pg_resetwal.c.

Referenced by main().

◆ oldest_commit_ts_xid_val

TransactionId oldest_commit_ts_xid_val
static

Definition at line 81 of file pg_resetwal.c.

Referenced by main().

◆ oldest_mxid_val

MultiXactId oldest_mxid_val = 0
static

Definition at line 89 of file pg_resetwal.c.

Referenced by main().

◆ oldest_xid_given

bool oldest_xid_given = false
static

Definition at line 74 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ oldest_xid_val

TransactionId oldest_xid_val
static

Definition at line 75 of file pg_resetwal.c.

Referenced by main().

◆ progname

const char* progname
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and usage().

◆ wal_segsize_given

bool wal_segsize_given = false
static

Definition at line 94 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ wal_segsize_val

int wal_segsize_val
static

Definition at line 95 of file pg_resetwal.c.

Referenced by main().

◆ WalSegSz

int WalSegSz
static