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 "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)
 
int main (int argc, char *argv[])
 

Variables

static ControlFileData ControlFile
 
static XLogSegNo newXlogSegNo
 
static bool guessed = false
 
static const char * progname
 
static uint32 set_xid_epoch = (uint32) -1
 
static TransactionId set_oldest_xid = 0
 
static TransactionId set_xid = 0
 
static TransactionId set_oldest_commit_ts_xid = 0
 
static TransactionId set_newest_commit_ts_xid = 0
 
static Oid set_oid = 0
 
static MultiXactId set_mxid = 0
 
static MultiXactOffset set_mxoff = (MultiXactOffset) -1
 
static TimeLineID minXlogTli = 0
 
static XLogSegNo minXlogSegNo = 0
 
static int WalSegSz
 
static int set_wal_segsize
 
static int set_char_signedness = -1
 

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 540 of file pg_resetwal.c.

541{
542 const char *ver_file = "PG_VERSION";
543 FILE *ver_fd;
544 char rawline[64];
545
546 if ((ver_fd = fopen(ver_file, "r")) == NULL)
547 pg_fatal("could not open file \"%s\" for reading: %m",
548 ver_file);
549
550 /* version number has to be the first line read */
551 if (!fgets(rawline, sizeof(rawline), ver_fd))
552 {
553 if (!ferror(ver_fd))
554 pg_fatal("unexpected empty file \"%s\"", ver_file);
555 else
556 pg_fatal("could not read file \"%s\": %m", ver_file);
557 }
558
559 /* strip trailing newline and carriage return */
560 (void) pg_strip_crlf(rawline);
561
562 if (strcmp(rawline, PG_MAJORVERSION) != 0)
563 {
564 pg_log_error("data directory is of wrong version");
565 pg_log_error_detail("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
566 ver_file, rawline, PG_MAJORVERSION);
567 exit(1);
568 }
569
570 fclose(ver_fd);
571}
exit(1)
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_detail(...)
Definition: logging.h:109
#define pg_fatal(...)
int pg_strip_crlf(char *str)
Definition: string.c:154

References exit(), pg_fatal, pg_log_error, pg_log_error_detail, and pg_strip_crlf().

Referenced by main().

◆ FindEndOfXLOG()

static void FindEndOfXLOG ( void  )
static

Definition at line 931 of file pg_resetwal.c.

932{
933 DIR *xldir;
934 struct dirent *xlde;
935 uint64 xlogbytepos;
936
937 /*
938 * Initialize the max() computation using the last checkpoint address from
939 * old pg_control. Note that for the moment we are working with segment
940 * numbering according to the old xlog seg size.
941 */
944
945 /*
946 * Scan the pg_wal directory to find existing WAL segment files. We assume
947 * any present have been used; in most scenarios this should be
948 * conservative, because of xlog.c's attempts to pre-create files.
949 */
950 xldir = opendir(XLOGDIR);
951 if (xldir == NULL)
952 pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
953
954 while (errno = 0, (xlde = readdir(xldir)) != NULL)
955 {
956 if (IsXLogFileName(xlde->d_name) ||
958 {
959 TimeLineID tli;
960 XLogSegNo segno;
961
962 /* Use the segment size from the control file */
963 XLogFromFileName(xlde->d_name, &tli, &segno,
965
966 /*
967 * Note: we take the max of all files found, regardless of their
968 * timelines. Another possibility would be to ignore files of
969 * timelines other than the target TLI, but this seems safer.
970 * Better too large a result than too small...
971 */
972 if (segno > newXlogSegNo)
973 newXlogSegNo = segno;
974 }
975 }
976
977 if (errno)
978 pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
979
980 if (closedir(xldir))
981 pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
982
983 /*
984 * Finally, convert to new xlog seg size, and advance by one to ensure we
985 * are in virgin territory.
986 */
987 xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
988 newXlogSegNo = (xlogbytepos + ControlFile.xlog_seg_size - 1) / WalSegSz;
989 newXlogSegNo++;
990}
uint64_t uint64
Definition: c.h:489
int closedir(DIR *)
Definition: dirent.c:127
struct dirent * readdir(DIR *)
Definition: dirent.c:78
DIR * opendir(const char *)
Definition: dirent.c:33
static int WalSegSz
Definition: pg_resetwal.c:76
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:63
XLogRecPtr redo
Definition: pg_control.h:37
uint32 xlog_seg_size
Definition: pg_control.h:211
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:59
uint64 XLogSegNo
Definition: xlogdefs.h:48

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 655 of file pg_resetwal.c.

656{
657 uint64 sysidentifier;
658 struct timeval tv;
659
660 /*
661 * Set up a completely default set of pg_control values.
662 */
663 guessed = true;
664 memset(&ControlFile, 0, sizeof(ControlFile));
665
668
669 /*
670 * Create a new unique installation identifier, since we can no longer use
671 * any old XLOG records. See notes in xlog.c about the algorithm.
672 */
673 gettimeofday(&tv, NULL);
674 sysidentifier = ((uint64) tv.tv_sec) << 32;
675 sysidentifier |= ((uint64) tv.tv_usec) << 12;
676 sysidentifier |= getpid() & 0xFFF;
677
678 ControlFile.system_identifier = sysidentifier;
679
695
697 ControlFile.time = (pg_time_t) time(NULL);
700
701 /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
702
711
712 ControlFile.maxAlign = MAXIMUM_ALIGNOF;
714 ControlFile.blcksz = BLCKSZ;
715 ControlFile.relseg_size = RELSEG_SIZE;
716 ControlFile.xlog_blcksz = XLOG_BLCKSZ;
723
724 /*
725 * XXX eventually, should try to grovel through old XLOG to develop more
726 * accurate values for TimeLineID, nextXID, etc.
727 */
728}
#define FLOAT8PASSBYVAL
Definition: c.h:592
#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:25
#define INDEX_MAX_KEYS
#define NAMEDATALEN
#define DEFAULT_XLOG_SEG_SIZE
#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:64
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:213
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
uint32 indexMaxKeys
Definition: pg_control.h:214
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:210
uint32 loblksize
Definition: pg_control.h:217
uint32 toast_max_chunk_size
Definition: pg_control.h:216
#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:36

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, FLOAT8PASSBYVAL, 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::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 1030 of file pg_resetwal.c.

1031{
1032#define ARCHSTATDIR XLOGDIR "/archive_status"
1033
1034 DIR *xldir;
1035 struct dirent *xlde;
1036 char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1037
1038 xldir = opendir(ARCHSTATDIR);
1039 if (xldir == NULL)
1040 pg_fatal("could not open directory \"%s\": %m", ARCHSTATDIR);
1041
1042 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1043 {
1044 if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1045 (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1046 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1047 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1048 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1049 {
1050 snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1051 if (unlink(path) < 0)
1052 pg_fatal("could not delete file \"%s\": %m", path);
1053 }
1054 }
1055
1056 if (errno)
1057 pg_fatal("could not read directory \"%s\": %m", ARCHSTATDIR);
1058
1059 if (closedir(xldir))
1060 pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1061}
#define MAXPGPATH
#define ARCHSTATDIR
#define snprintf
Definition: port.h:239
#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 1067 of file pg_resetwal.c.

1068{
1069#define WALSUMMARYDIR XLOGDIR "/summaries"
1070#define WALSUMMARY_NHEXCHARS 40
1071
1072 DIR *xldir;
1073 struct dirent *xlde;
1074 char path[MAXPGPATH + sizeof(WALSUMMARYDIR)];
1075
1076 xldir = opendir(WALSUMMARYDIR);
1077 if (xldir == NULL)
1078 pg_fatal("could not open directory \"%s\": %m", WALSUMMARYDIR);
1079
1080 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1081 {
1082 if (strspn(xlde->d_name, "0123456789ABCDEF") == WALSUMMARY_NHEXCHARS &&
1083 strcmp(xlde->d_name + WALSUMMARY_NHEXCHARS, ".summary") == 0)
1084 {
1085 snprintf(path, sizeof(path), "%s/%s", WALSUMMARYDIR, xlde->d_name);
1086 if (unlink(path) < 0)
1087 pg_fatal("could not delete file \"%s\": %m", path);
1088 }
1089 }
1090
1091 if (errno)
1092 pg_fatal("could not read directory \"%s\": %m", WALSUMMARYDIR);
1093
1094 if (closedir(xldir))
1095 pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1096}
#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 997 of file pg_resetwal.c.

998{
999 DIR *xldir;
1000 struct dirent *xlde;
1001 char path[MAXPGPATH + sizeof(XLOGDIR)];
1002
1003 xldir = opendir(XLOGDIR);
1004 if (xldir == NULL)
1005 pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
1006
1007 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1008 {
1009 if (IsXLogFileName(xlde->d_name) ||
1011 {
1012 snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
1013 if (unlink(path) < 0)
1014 pg_fatal("could not delete file \"%s\": %m", path);
1015 }
1016 }
1017
1018 if (errno)
1019 pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
1020
1021 if (closedir(xldir))
1022 pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
1023}

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 95 of file pg_resetwal.c.

96{
97 static struct option long_options[] = {
98 {"commit-timestamp-ids", required_argument, NULL, 'c'},
99 {"pgdata", required_argument, NULL, 'D'},
100 {"epoch", required_argument, NULL, 'e'},
101 {"force", no_argument, NULL, 'f'},
102 {"next-wal-file", required_argument, NULL, 'l'},
103 {"multixact-ids", required_argument, NULL, 'm'},
104 {"dry-run", no_argument, NULL, 'n'},
105 {"next-oid", required_argument, NULL, 'o'},
106 {"multixact-offset", required_argument, NULL, 'O'},
107 {"oldest-transaction-id", required_argument, NULL, 'u'},
108 {"next-transaction-id", required_argument, NULL, 'x'},
109 {"wal-segsize", required_argument, NULL, 1},
110 {"char-signedness", required_argument, NULL, 2},
111 {NULL, 0, NULL, 0}
112 };
113
114 int c;
115 bool force = false;
116 bool noupdate = false;
117 MultiXactId set_oldestmxid = 0;
118 char *endptr;
119 char *endptr2;
120 char *DataDir = NULL;
121 char *log_fname = NULL;
122 int fd;
123
124 pg_logging_init(argv[0]);
125 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
126 progname = get_progname(argv[0]);
127
128 if (argc > 1)
129 {
130 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
131 {
132 usage();
133 exit(0);
134 }
135 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
136 {
137 puts("pg_resetwal (PostgreSQL) " PG_VERSION);
138 exit(0);
139 }
140 }
141
142
143 while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:u:x:", long_options, NULL)) != -1)
144 {
145 switch (c)
146 {
147 case 'D':
148 DataDir = optarg;
149 break;
150
151 case 'f':
152 force = true;
153 break;
154
155 case 'n':
156 noupdate = true;
157 break;
158
159 case 'e':
160 errno = 0;
161 set_xid_epoch = strtoul(optarg, &endptr, 0);
162 if (endptr == optarg || *endptr != '\0' || errno != 0)
163 {
164 /*------
165 translator: the second %s is a command line argument (-e, etc) */
166 pg_log_error("invalid argument for option %s", "-e");
167 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
168 exit(1);
169 }
170 if (set_xid_epoch == -1)
171 pg_fatal("transaction ID epoch (-e) must not be -1");
172 break;
173
174 case 'u':
175 errno = 0;
176 set_oldest_xid = strtoul(optarg, &endptr, 0);
177 if (endptr == optarg || *endptr != '\0' || errno != 0)
178 {
179 pg_log_error("invalid argument for option %s", "-u");
180 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
181 exit(1);
182 }
184 pg_fatal("oldest transaction ID (-u) must be greater than or equal to %u", FirstNormalTransactionId);
185 break;
186
187 case 'x':
188 errno = 0;
189 set_xid = strtoul(optarg, &endptr, 0);
190 if (endptr == optarg || *endptr != '\0' || errno != 0)
191 {
192 pg_log_error("invalid argument for option %s", "-x");
193 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
194 exit(1);
195 }
197 pg_fatal("transaction ID (-x) must be greater than or equal to %u", FirstNormalTransactionId);
198 break;
199
200 case 'c':
201 errno = 0;
202 set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
203 if (endptr == optarg || *endptr != ',' || errno != 0)
204 {
205 pg_log_error("invalid argument for option %s", "-c");
206 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
207 exit(1);
208 }
209 set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
210 if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
211 {
212 pg_log_error("invalid argument for option %s", "-c");
213 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
214 exit(1);
215 }
216
219 pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
220
223 pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
224 break;
225
226 case 'o':
227 errno = 0;
228 set_oid = strtoul(optarg, &endptr, 0);
229 if (endptr == optarg || *endptr != '\0' || errno != 0)
230 {
231 pg_log_error("invalid argument for option %s", "-o");
232 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
233 exit(1);
234 }
235 if (set_oid == 0)
236 pg_fatal("OID (-o) must not be 0");
237 break;
238
239 case 'm':
240 errno = 0;
241 set_mxid = strtoul(optarg, &endptr, 0);
242 if (endptr == optarg || *endptr != ',' || errno != 0)
243 {
244 pg_log_error("invalid argument for option %s", "-m");
245 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
246 exit(1);
247 }
248
249 set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
250 if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
251 {
252 pg_log_error("invalid argument for option %s", "-m");
253 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
254 exit(1);
255 }
256 if (set_mxid == 0)
257 pg_fatal("multitransaction ID (-m) must not be 0");
258
259 /*
260 * XXX It'd be nice to have more sanity checks here, e.g. so
261 * that oldest is not wrapped around w.r.t. nextMulti.
262 */
263 if (set_oldestmxid == 0)
264 pg_fatal("oldest multitransaction ID (-m) must not be 0");
265 break;
266
267 case 'O':
268 errno = 0;
269 set_mxoff = strtoul(optarg, &endptr, 0);
270 if (endptr == optarg || *endptr != '\0' || errno != 0)
271 {
272 pg_log_error("invalid argument for option %s", "-O");
273 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
274 exit(1);
275 }
276 if (set_mxoff == -1)
277 pg_fatal("multitransaction offset (-O) must not be -1");
278 break;
279
280 case 'l':
281 if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
282 {
283 pg_log_error("invalid argument for option %s", "-l");
284 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
285 exit(1);
286 }
287
288 /*
289 * XLogFromFileName requires wal segment size which is not yet
290 * set. Hence wal details are set later on.
291 */
292 log_fname = pg_strdup(optarg);
293 break;
294
295 case 1:
296 {
297 int wal_segsize_mb;
298
299 if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segsize_mb))
300 exit(1);
301 set_wal_segsize = wal_segsize_mb * 1024 * 1024;
303 pg_fatal("argument of %s must be a power of two between 1 and 1024", "--wal-segsize");
304 break;
305 }
306
307 case 2:
308 {
309 errno = 0;
310
311 if (pg_strcasecmp(optarg, "signed") == 0)
313 else if (pg_strcasecmp(optarg, "unsigned") == 0)
315 else
316 {
317 pg_log_error("invalid argument for option %s", "--char-signedness");
318 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
319 exit(1);
320 }
321 break;
322 }
323
324 default:
325 /* getopt_long already emitted a complaint */
326 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
327 exit(1);
328 }
329 }
330
331 if (DataDir == NULL && optind < argc)
332 DataDir = argv[optind++];
333
334 /* Complain if any arguments remain */
335 if (optind < argc)
336 {
337 pg_log_error("too many command-line arguments (first is \"%s\")",
338 argv[optind]);
339 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
340 exit(1);
341 }
342
343 if (DataDir == NULL)
344 {
345 pg_log_error("no data directory specified");
346 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
347 exit(1);
348 }
349
350 /*
351 * Don't allow pg_resetwal to be run as root, to avoid overwriting the
352 * ownership of files in the data directory. We need only check for root
353 * -- any other user won't have sufficient permissions to modify files in
354 * the data directory.
355 */
356#ifndef WIN32
357 if (geteuid() == 0)
358 {
359 pg_log_error("cannot be executed by \"root\"");
360 pg_log_error_hint("You must run %s as the PostgreSQL superuser.",
361 progname);
362 exit(1);
363 }
364#endif
365
367
368 /* Set mask based on PGDATA permissions */
370 pg_fatal("could not read permissions of directory \"%s\": %m",
371 DataDir);
372
373 umask(pg_mode_mask);
374
375 if (chdir(DataDir) < 0)
376 pg_fatal("could not change directory to \"%s\": %m",
377 DataDir);
378
379 /* Check that data directory matches our server version */
381
382 /*
383 * Check for a postmaster lock file --- if there is one, refuse to
384 * proceed, on grounds we might be interfering with a live installation.
385 */
386 if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
387 {
388 if (errno != ENOENT)
389 pg_fatal("could not open file \"%s\" for reading: %m",
390 "postmaster.pid");
391 }
392 else
393 {
394 pg_log_error("lock file \"%s\" exists", "postmaster.pid");
395 pg_log_error_hint("Is a server running? If not, delete the lock file and try again.");
396 exit(1);
397 }
398
399 /*
400 * Attempt to read the existing pg_control file
401 */
402 if (!read_controlfile())
404
405 /*
406 * If no new WAL segment size was specified, use the control file value.
407 */
408 if (set_wal_segsize != 0)
410 else
412
413 if (log_fname != NULL)
415
416 /*
417 * Also look at existing segment files to set up newXlogSegNo
418 */
420
421 /*
422 * If we're not going to proceed with the reset, print the current control
423 * file parameters.
424 */
425 if ((guessed && !force) || noupdate)
427
428 /*
429 * Adjust fields if required by switches. (Do this now so that printout,
430 * if any, includes these values.)
431 */
432 if (set_xid_epoch != -1)
436
437 if (set_oldest_xid != 0)
438 {
441 }
442
443 if (set_xid != 0)
446 set_xid);
447
452
453 if (set_oid != 0)
455
456 if (set_mxid != 0)
457 {
459
460 ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
464 }
465
466 if (set_mxoff != -1)
468
470 {
473 }
474
475 if (set_wal_segsize != 0)
477
478 if (set_char_signedness != -1)
480
483
484 if (noupdate)
485 {
487 exit(0);
488 }
489
490 /*
491 * If we had to guess anything, and -f was not given, just print the
492 * guessed values and exit.
493 */
494 if (guessed && !force)
495 {
497 pg_log_error("not proceeding because control file values were guessed");
498 pg_log_error_hint("If these values seem acceptable, use -f to force reset.");
499 exit(1);
500 }
501
502 /*
503 * Don't reset from a dirty pg_control without -f, either.
504 */
505 if (ControlFile.state != DB_SHUTDOWNED && !force)
506 {
507 pg_log_error("database server was not shut down cleanly");
508 pg_log_error_detail("Resetting the write-ahead log might cause data to be lost.");
509 pg_log_error_hint("If you want to proceed anyway, use -f to force reset.");
510 exit(1);
511 }
512
513 /*
514 * Else, do the dirty deed.
515 */
521
522 printf(_("Write-ahead log reset\n"));
523 return 0;
524}
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1171
TransactionId MultiXactId
Definition: c.h:619
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:429
#define _(x)
Definition: elog.c:90
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:70
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:931
static void RewriteControlFile(void)
Definition: pg_resetwal.c:885
static void KillExistingWALSummaries(void)
Definition: pg_resetwal.c:1067
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:997
static void CheckDataVersion(void)
Definition: pg_resetwal.c:540
static int set_char_signedness
Definition: pg_resetwal.c:78
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:75
static int set_wal_segsize
Definition: pg_resetwal.c:77
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:73
static MultiXactId set_mxid
Definition: pg_resetwal.c:72
static TimeLineID minXlogTli
Definition: pg_resetwal.c:74
static TransactionId set_oldest_xid
Definition: pg_resetwal.c:67
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:69
static TransactionId set_xid
Definition: pg_resetwal.c:68
static Oid set_oid
Definition: pg_resetwal.c:71
static void PrintNewControlValues(void)
Definition: pg_resetwal.c:813
static bool read_controlfile(void)
Definition: pg_resetwal.c:581
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1030
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1103
static const char * progname
Definition: pg_resetwal.c:65
static void usage(void)
Definition: pg_resetwal.c:1190
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:738
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:70
static uint32 set_xid_epoch
Definition: pg_resetwal.c:66
static void GuessControlValues(void)
Definition: pg_resetwal.c:655
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
const char * get_progname(const char *argv0)
Definition: path.c:652
#define printf(...)
Definition: port.h:245
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:228
#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 _, CheckDataVersion(), ControlFileData::checkPointCopy, ControlFile, DataDir, DB_SHUTDOWNED, ControlFileData::default_char_signedness, EpochFromFullTransactionId, exit(), fd(), FindEndOfXLOG(), FirstMultiXactId, FirstNormalTransactionId, FullTransactionIdFromEpochAndXid(), get_progname(), get_restricted_token(), GetDataDirectoryCreatePerm(), getopt_long(), GuessControlValues(), guessed, InvalidOid, InvalidTransactionId, IsValidWalSegSize, KillExistingArchiveStatus(), KillExistingWALSummaries(), KillExistingXLOG(), minXlogSegNo, minXlogTli, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, no_argument, 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_char_signedness, set_mxid, set_mxoff, set_newest_commit_ts_xid, set_oid, set_oldest_commit_ts_xid, set_oldest_xid, set_pglocale_pgservice(), set_wal_segsize, set_xid, set_xid_epoch, ControlFileData::state, CheckPoint::ThisTimeLineID, TransactionIdIsNormal, usage(), WalSegSz, WriteEmptyXLOG(), XidFromFullTransactionId, XLOG_FNAME_LEN, ControlFileData::xlog_seg_size, and XLogFromFileName().

◆ PrintControlValues()

static void PrintControlValues ( bool  guessed)
static

Definition at line 738 of file pg_resetwal.c.

739{
740 if (guessed)
741 printf(_("Guessed pg_control values:\n\n"));
742 else
743 printf(_("Current pg_control values:\n\n"));
744
745 printf(_("pg_control version number: %u\n"),
747 printf(_("Catalog version number: %u\n"),
749 printf(_("Database system identifier: %llu\n"),
750 (unsigned long long) ControlFile.system_identifier);
751 printf(_("Latest checkpoint's TimeLineID: %u\n"),
753 printf(_("Latest checkpoint's full_page_writes: %s\n"),
754 ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
755 printf(_("Latest checkpoint's NextXID: %u:%u\n"),
758 printf(_("Latest checkpoint's NextOID: %u\n"),
760 printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
762 printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
764 printf(_("Latest checkpoint's oldestXID: %u\n"),
766 printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
768 printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
770 printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
772 printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
774 printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
776 printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
778 printf(_("Maximum data alignment: %u\n"),
780 /* we don't print floatFormat since can't say much useful about it */
781 printf(_("Database block size: %u\n"),
783 printf(_("Blocks per segment of large relation: %u\n"),
785 printf(_("WAL block size: %u\n"),
787 printf(_("Bytes per WAL segment: %u\n"),
789 printf(_("Maximum length of identifiers: %u\n"),
791 printf(_("Maximum columns in an index: %u\n"),
793 printf(_("Maximum size of a TOAST chunk: %u\n"),
795 printf(_("Size of a large-object chunk: %u\n"),
797 /* This is no longer configurable, but users may still expect to see it: */
798 printf(_("Date/time type storage: %s\n"),
799 _("64-bit integers"));
800 printf(_("Float8 argument passing: %s\n"),
801 (ControlFile.float8ByVal ? _("by value") : _("by reference")));
802 printf(_("Data page checksum version: %u\n"),
804 printf(_("Default char data signedness: %s\n"),
805 (ControlFile.default_char_signedness ? _("signed") : _("unsigned")));
806}
uint32 data_checksum_version
Definition: pg_control.h:222

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::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 813 of file pg_resetwal.c.

814{
815 char fname[MAXFNAMELEN];
816
817 /* This will be always printed in order to keep format same. */
818 printf(_("\n\nValues to be changed:\n\n"));
819
822 printf(_("First log segment after reset: %s\n"), fname);
823
824 if (set_mxid != 0)
825 {
826 printf(_("NextMultiXactId: %u\n"),
828 printf(_("OldestMultiXid: %u\n"),
830 printf(_("OldestMulti's DB: %u\n"),
832 }
833
834 if (set_mxoff != -1)
835 {
836 printf(_("NextMultiOffset: %u\n"),
838 }
839
840 if (set_oid != 0)
841 {
842 printf(_("NextOID: %u\n"),
844 }
845
846 if (set_xid != 0)
847 {
848 printf(_("NextXID: %u\n"),
850 printf(_("OldestXID: %u\n"),
852 printf(_("OldestXID's DB: %u\n"),
854 }
855
856 if (set_xid_epoch != -1)
857 {
858 printf(_("NextXID epoch: %u\n"),
860 }
861
863 {
864 printf(_("oldestCommitTsXid: %u\n"),
866 }
868 {
869 printf(_("newestCommitTsXid: %u\n"),
871 }
872
873 if (set_wal_segsize != 0)
874 {
875 printf(_("Bytes per WAL segment: %u\n"),
877 }
878}
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References _, ControlFileData::checkPointCopy, ControlFile, EpochFromFullTransactionId, MAXFNAMELEN, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, printf, set_mxid, set_mxoff, set_newest_commit_ts_xid, set_oid, set_oldest_commit_ts_xid, set_wal_segsize, set_xid, set_xid_epoch, CheckPoint::ThisTimeLineID, WalSegSz, XidFromFullTransactionId, ControlFileData::xlog_seg_size, and XLogFileName().

Referenced by main().

◆ read_controlfile()

static bool read_controlfile ( void  )
static

Definition at line 581 of file pg_resetwal.c.

582{
583 int fd;
584 int len;
585 char *buffer;
587
588 if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
589 {
590 /*
591 * If pg_control is not there at all, or we can't read it, the odds
592 * are we've been handed a bad DataDir path, so give up. User can do
593 * "touch pg_control" to force us to proceed.
594 */
595 pg_log_error("could not open file \"%s\" for reading: %m",
597 if (errno == ENOENT)
598 pg_log_error_hint("If you are sure the data directory path is correct, execute\n"
599 " touch %s\n"
600 "and try again.",
602 exit(1);
603 }
604
605 /* Use malloc to ensure we have a maxaligned buffer */
606 buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
607
608 len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
609 if (len < 0)
610 pg_fatal("could not read file \"%s\": %m", XLOG_CONTROL_FILE);
611 close(fd);
612
613 if (len >= sizeof(ControlFileData) &&
614 ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
615 {
616 /* Check the CRC. */
619 buffer,
620 offsetof(ControlFileData, crc));
622
623 if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
624 {
625 /* We will use the data but treat it as guessed. */
626 pg_log_warning("pg_control exists but has invalid CRC; proceed with caution");
627 guessed = true;
628 }
629
630 memcpy(&ControlFile, buffer, sizeof(ControlFile));
631
632 /* return false if WAL segment size is not valid */
634 {
635 pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution",
636 "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
639 return false;
640 }
641
642 return true;
643 }
644
645 /* Looks like it's a mess. */
646 pg_log_warning("pg_control exists but is broken or wrong version; ignoring it");
647 return false;
648}
#define ngettext(s, p, n)
Definition: c.h:1138
#define PG_BINARY
Definition: c.h:1230
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:256
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:98
#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:103
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, exit(), 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 885 of file pg_resetwal.c.

886{
887 /*
888 * Adjust fields as needed to force an empty XLOG starting at
889 * newXlogSegNo.
890 */
894
902
903 /*
904 * Force the defaults for max_* settings. The values don't really matter
905 * as long as wal_level='minimal'; the postmaster will reset these fields
906 * anyway at startup.
907 */
916
917 /* The control file gets flushed here. */
918 update_controlfile(".", &ControlFile, true);
919}
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().

◆ usage()

static void usage ( void  )
static

Definition at line 1190 of file pg_resetwal.c.

1191{
1192 printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1193 printf(_("Usage:\n"));
1194 printf(_(" %s [OPTION]... DATADIR\n"), progname);
1195
1196 printf(_("\nOptions:\n"));
1197 printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
1198 printf(_(" -f, --force force update to be done even after unclean shutdown or\n"
1199 " if pg_control values had to be guessed\n"));
1200 printf(_(" -n, --dry-run no update, just show what would be done\n"));
1201 printf(_(" -V, --version output version information, then exit\n"));
1202 printf(_(" -?, --help show this help, then exit\n"));
1203
1204 printf(_("\nOptions to override control file values:\n"));
1205 printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
1206 " set oldest and newest transactions bearing\n"
1207 " commit timestamp (zero means no change)\n"));
1208 printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
1209 printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
1210 printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
1211 printf(_(" -o, --next-oid=OID set next OID\n"));
1212 printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
1213 printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n"));
1214 printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
1215 printf(_(" --char-signedness=OPTION set char signedness to \"signed\" or \"unsigned\"\n"));
1216 printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
1217
1218 printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1219 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1220}

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1103 of file pg_resetwal.c.

1104{
1105 PGAlignedXLogBlock buffer;
1106 XLogPageHeader page;
1107 XLogLongPageHeader longpage;
1108 XLogRecord *record;
1109 pg_crc32c crc;
1110 char path[MAXPGPATH];
1111 int fd;
1112 int nbytes;
1113 char *recptr;
1114
1115 memset(buffer.data, 0, XLOG_BLCKSZ);
1116
1117 /* Set up the XLOG page header */
1118 page = (XLogPageHeader) buffer.data;
1119 page->xlp_magic = XLOG_PAGE_MAGIC;
1120 page->xlp_info = XLP_LONG_HEADER;
1123 longpage = (XLogLongPageHeader) page;
1125 longpage->xlp_seg_size = WalSegSz;
1126 longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1127
1128 /* Insert the initial checkpoint record */
1129 recptr = (char *) page + SizeOfXLogLongPHD;
1130 record = (XLogRecord *) recptr;
1131 record->xl_prev = 0;
1132 record->xl_xid = InvalidTransactionId;
1135 record->xl_rmid = RM_XLOG_ID;
1136
1137 recptr += SizeOfXLogRecord;
1138 *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1139 *(recptr++) = sizeof(CheckPoint);
1140 memcpy(recptr, &ControlFile.checkPointCopy,
1141 sizeof(CheckPoint));
1142
1144 COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1145 COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1146 FIN_CRC32C(crc);
1147 record->xl_crc = crc;
1148
1149 /* Write the first page */
1152
1153 unlink(path);
1154
1155 fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1157 if (fd < 0)
1158 pg_fatal("could not open file \"%s\": %m", path);
1159
1160 errno = 0;
1161 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1162 {
1163 /* if write didn't set errno, assume problem is no disk space */
1164 if (errno == 0)
1165 errno = ENOSPC;
1166 pg_fatal("could not write file \"%s\": %m", path);
1167 }
1168
1169 /* Fill the rest of the file with zeroes */
1170 memset(buffer.data, 0, XLOG_BLCKSZ);
1171 for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1172 {
1173 errno = 0;
1174 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1175 {
1176 if (errno == 0)
1177 errno = ENOSPC;
1178 pg_fatal("could not write file \"%s\": %m", path);
1179 }
1180 }
1181
1182 if (fsync(fd) != 0)
1183 pg_fatal("fsync error: %m");
1184
1185 close(fd);
1186}
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
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
char data[XLOG_BLCKSZ]
Definition: c.h:1105
#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

◆ ControlFile

◆ guessed

bool guessed = false
static

Definition at line 64 of file pg_resetwal.c.

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

◆ minXlogSegNo

XLogSegNo minXlogSegNo = 0
static

Definition at line 75 of file pg_resetwal.c.

Referenced by main().

◆ minXlogTli

TimeLineID minXlogTli = 0
static

Definition at line 74 of file pg_resetwal.c.

Referenced by main().

◆ newXlogSegNo

XLogSegNo newXlogSegNo
static

◆ progname

const char* progname
static

Definition at line 65 of file pg_resetwal.c.

Referenced by main(), and usage().

◆ set_char_signedness

int set_char_signedness = -1
static

Definition at line 78 of file pg_resetwal.c.

Referenced by main().

◆ set_mxid

MultiXactId set_mxid = 0
static

Definition at line 72 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_mxoff

MultiXactOffset set_mxoff = (MultiXactOffset) -1
static

Definition at line 73 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_newest_commit_ts_xid

TransactionId set_newest_commit_ts_xid = 0
static

Definition at line 70 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oid

Oid set_oid = 0
static

Definition at line 71 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oldest_commit_ts_xid

TransactionId set_oldest_commit_ts_xid = 0
static

Definition at line 69 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oldest_xid

TransactionId set_oldest_xid = 0
static

Definition at line 67 of file pg_resetwal.c.

Referenced by main().

◆ set_wal_segsize

int set_wal_segsize
static

Definition at line 77 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid

TransactionId set_xid = 0
static

Definition at line 68 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid_epoch

uint32 set_xid_epoch = (uint32) -1
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ WalSegSz

int WalSegSz
static