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
 

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

519{
520 const char *ver_file = "PG_VERSION";
521 FILE *ver_fd;
522 char rawline[64];
523
524 if ((ver_fd = fopen(ver_file, "r")) == NULL)
525 pg_fatal("could not open file \"%s\" for reading: %m",
526 ver_file);
527
528 /* version number has to be the first line read */
529 if (!fgets(rawline, sizeof(rawline), ver_fd))
530 {
531 if (!ferror(ver_fd))
532 pg_fatal("unexpected empty file \"%s\"", ver_file);
533 else
534 pg_fatal("could not read file \"%s\": %m", ver_file);
535 }
536
537 /* strip trailing newline and carriage return */
538 (void) pg_strip_crlf(rawline);
539
540 if (strcmp(rawline, PG_MAJORVERSION) != 0)
541 {
542 pg_log_error("data directory is of wrong version");
543 pg_log_error_detail("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
544 ver_file, rawline, PG_MAJORVERSION);
545 exit(1);
546 }
547
548 fclose(ver_fd);
549}
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 907 of file pg_resetwal.c.

908{
909 DIR *xldir;
910 struct dirent *xlde;
911 uint64 xlogbytepos;
912
913 /*
914 * Initialize the max() computation using the last checkpoint address from
915 * old pg_control. Note that for the moment we are working with segment
916 * numbering according to the old xlog seg size.
917 */
920
921 /*
922 * Scan the pg_wal directory to find existing WAL segment files. We assume
923 * any present have been used; in most scenarios this should be
924 * conservative, because of xlog.c's attempts to pre-create files.
925 */
926 xldir = opendir(XLOGDIR);
927 if (xldir == NULL)
928 pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
929
930 while (errno = 0, (xlde = readdir(xldir)) != NULL)
931 {
932 if (IsXLogFileName(xlde->d_name) ||
934 {
935 TimeLineID tli;
936 XLogSegNo segno;
937
938 /* Use the segment size from the control file */
939 XLogFromFileName(xlde->d_name, &tli, &segno,
941
942 /*
943 * Note: we take the max of all files found, regardless of their
944 * timelines. Another possibility would be to ignore files of
945 * timelines other than the target TLI, but this seems safer.
946 * Better too large a result than too small...
947 */
948 if (segno > newXlogSegNo)
949 newXlogSegNo = segno;
950 }
951 }
952
953 if (errno)
954 pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
955
956 if (closedir(xldir))
957 pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
958
959 /*
960 * Finally, convert to new xlog seg size, and advance by one to ensure we
961 * are in virgin territory.
962 */
963 xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
964 newXlogSegNo = (xlogbytepos + ControlFile.xlog_seg_size - 1) / WalSegSz;
965 newXlogSegNo++;
966}
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 633 of file pg_resetwal.c.

634{
635 uint64 sysidentifier;
636 struct timeval tv;
637
638 /*
639 * Set up a completely default set of pg_control values.
640 */
641 guessed = true;
642 memset(&ControlFile, 0, sizeof(ControlFile));
643
646
647 /*
648 * Create a new unique installation identifier, since we can no longer use
649 * any old XLOG records. See notes in xlog.c about the algorithm.
650 */
651 gettimeofday(&tv, NULL);
652 sysidentifier = ((uint64) tv.tv_sec) << 32;
653 sysidentifier |= ((uint64) tv.tv_usec) << 12;
654 sysidentifier |= getpid() & 0xFFF;
655
656 ControlFile.system_identifier = sysidentifier;
657
673
675 ControlFile.time = (pg_time_t) time(NULL);
678
679 /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
680
689
690 ControlFile.maxAlign = MAXIMUM_ALIGNOF;
692 ControlFile.blcksz = BLCKSZ;
693 ControlFile.relseg_size = RELSEG_SIZE;
694 ControlFile.xlog_blcksz = XLOG_BLCKSZ;
701
702 /*
703 * XXX eventually, should try to grovel through old XLOG to develop more
704 * accurate values for TimeLineID, nextXID, etc.
705 */
706}
#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 1006 of file pg_resetwal.c.

1007{
1008#define ARCHSTATDIR XLOGDIR "/archive_status"
1009
1010 DIR *xldir;
1011 struct dirent *xlde;
1012 char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1013
1014 xldir = opendir(ARCHSTATDIR);
1015 if (xldir == NULL)
1016 pg_fatal("could not open directory \"%s\": %m", ARCHSTATDIR);
1017
1018 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1019 {
1020 if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1021 (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1022 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1023 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1024 strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1025 {
1026 snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1027 if (unlink(path) < 0)
1028 pg_fatal("could not delete file \"%s\": %m", path);
1029 }
1030 }
1031
1032 if (errno)
1033 pg_fatal("could not read directory \"%s\": %m", ARCHSTATDIR);
1034
1035 if (closedir(xldir))
1036 pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1037}
#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 1043 of file pg_resetwal.c.

1044{
1045#define WALSUMMARYDIR XLOGDIR "/summaries"
1046#define WALSUMMARY_NHEXCHARS 40
1047
1048 DIR *xldir;
1049 struct dirent *xlde;
1050 char path[MAXPGPATH + sizeof(WALSUMMARYDIR)];
1051
1052 xldir = opendir(WALSUMMARYDIR);
1053 if (xldir == NULL)
1054 pg_fatal("could not open directory \"%s\": %m", WALSUMMARYDIR);
1055
1056 while (errno = 0, (xlde = readdir(xldir)) != NULL)
1057 {
1058 if (strspn(xlde->d_name, "0123456789ABCDEF") == WALSUMMARY_NHEXCHARS &&
1059 strcmp(xlde->d_name + WALSUMMARY_NHEXCHARS, ".summary") == 0)
1060 {
1061 snprintf(path, sizeof(path), "%s/%s", WALSUMMARYDIR, xlde->d_name);
1062 if (unlink(path) < 0)
1063 pg_fatal("could not delete file \"%s\": %m", path);
1064 }
1065 }
1066
1067 if (errno)
1068 pg_fatal("could not read directory \"%s\": %m", WALSUMMARYDIR);
1069
1070 if (closedir(xldir))
1071 pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1072}
#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 973 of file pg_resetwal.c.

974{
975 DIR *xldir;
976 struct dirent *xlde;
977 char path[MAXPGPATH + sizeof(XLOGDIR)];
978
979 xldir = opendir(XLOGDIR);
980 if (xldir == NULL)
981 pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
982
983 while (errno = 0, (xlde = readdir(xldir)) != NULL)
984 {
985 if (IsXLogFileName(xlde->d_name) ||
987 {
988 snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
989 if (unlink(path) < 0)
990 pg_fatal("could not delete file \"%s\": %m", path);
991 }
992 }
993
994 if (errno)
995 pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
996
997 if (closedir(xldir))
998 pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
999}

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

95{
96 static struct option long_options[] = {
97 {"commit-timestamp-ids", required_argument, NULL, 'c'},
98 {"pgdata", required_argument, NULL, 'D'},
99 {"epoch", required_argument, NULL, 'e'},
100 {"force", no_argument, NULL, 'f'},
101 {"next-wal-file", required_argument, NULL, 'l'},
102 {"multixact-ids", required_argument, NULL, 'm'},
103 {"dry-run", no_argument, NULL, 'n'},
104 {"next-oid", required_argument, NULL, 'o'},
105 {"multixact-offset", required_argument, NULL, 'O'},
106 {"oldest-transaction-id", required_argument, NULL, 'u'},
107 {"next-transaction-id", required_argument, NULL, 'x'},
108 {"wal-segsize", required_argument, NULL, 1},
109 {NULL, 0, NULL, 0}
110 };
111
112 int c;
113 bool force = false;
114 bool noupdate = false;
115 MultiXactId set_oldestmxid = 0;
116 char *endptr;
117 char *endptr2;
118 char *DataDir = NULL;
119 char *log_fname = NULL;
120 int fd;
121
122 pg_logging_init(argv[0]);
123 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
124 progname = get_progname(argv[0]);
125
126 if (argc > 1)
127 {
128 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
129 {
130 usage();
131 exit(0);
132 }
133 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
134 {
135 puts("pg_resetwal (PostgreSQL) " PG_VERSION);
136 exit(0);
137 }
138 }
139
140
141 while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:u:x:", long_options, NULL)) != -1)
142 {
143 switch (c)
144 {
145 case 'D':
146 DataDir = optarg;
147 break;
148
149 case 'f':
150 force = true;
151 break;
152
153 case 'n':
154 noupdate = true;
155 break;
156
157 case 'e':
158 errno = 0;
159 set_xid_epoch = strtoul(optarg, &endptr, 0);
160 if (endptr == optarg || *endptr != '\0' || errno != 0)
161 {
162 /*------
163 translator: the second %s is a command line argument (-e, etc) */
164 pg_log_error("invalid argument for option %s", "-e");
165 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
166 exit(1);
167 }
168 if (set_xid_epoch == -1)
169 pg_fatal("transaction ID epoch (-e) must not be -1");
170 break;
171
172 case 'u':
173 errno = 0;
174 set_oldest_xid = strtoul(optarg, &endptr, 0);
175 if (endptr == optarg || *endptr != '\0' || errno != 0)
176 {
177 pg_log_error("invalid argument for option %s", "-u");
178 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
179 exit(1);
180 }
182 pg_fatal("oldest transaction ID (-u) must be greater than or equal to %u", FirstNormalTransactionId);
183 break;
184
185 case 'x':
186 errno = 0;
187 set_xid = strtoul(optarg, &endptr, 0);
188 if (endptr == optarg || *endptr != '\0' || errno != 0)
189 {
190 pg_log_error("invalid argument for option %s", "-x");
191 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
192 exit(1);
193 }
195 pg_fatal("transaction ID (-x) must be greater than or equal to %u", FirstNormalTransactionId);
196 break;
197
198 case 'c':
199 errno = 0;
200 set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
201 if (endptr == optarg || *endptr != ',' || errno != 0)
202 {
203 pg_log_error("invalid argument for option %s", "-c");
204 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
205 exit(1);
206 }
207 set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
208 if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
209 {
210 pg_log_error("invalid argument for option %s", "-c");
211 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
212 exit(1);
213 }
214
217 pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
218
221 pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
222 break;
223
224 case 'o':
225 errno = 0;
226 set_oid = strtoul(optarg, &endptr, 0);
227 if (endptr == optarg || *endptr != '\0' || errno != 0)
228 {
229 pg_log_error("invalid argument for option %s", "-o");
230 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
231 exit(1);
232 }
233 if (set_oid == 0)
234 pg_fatal("OID (-o) must not be 0");
235 break;
236
237 case 'm':
238 errno = 0;
239 set_mxid = strtoul(optarg, &endptr, 0);
240 if (endptr == optarg || *endptr != ',' || errno != 0)
241 {
242 pg_log_error("invalid argument for option %s", "-m");
243 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
244 exit(1);
245 }
246
247 set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
248 if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
249 {
250 pg_log_error("invalid argument for option %s", "-m");
251 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
252 exit(1);
253 }
254 if (set_mxid == 0)
255 pg_fatal("multitransaction ID (-m) must not be 0");
256
257 /*
258 * XXX It'd be nice to have more sanity checks here, e.g. so
259 * that oldest is not wrapped around w.r.t. nextMulti.
260 */
261 if (set_oldestmxid == 0)
262 pg_fatal("oldest multitransaction ID (-m) must not be 0");
263 break;
264
265 case 'O':
266 errno = 0;
267 set_mxoff = strtoul(optarg, &endptr, 0);
268 if (endptr == optarg || *endptr != '\0' || errno != 0)
269 {
270 pg_log_error("invalid argument for option %s", "-O");
271 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
272 exit(1);
273 }
274 if (set_mxoff == -1)
275 pg_fatal("multitransaction offset (-O) must not be -1");
276 break;
277
278 case 'l':
279 if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
280 {
281 pg_log_error("invalid argument for option %s", "-l");
282 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
283 exit(1);
284 }
285
286 /*
287 * XLogFromFileName requires wal segment size which is not yet
288 * set. Hence wal details are set later on.
289 */
290 log_fname = pg_strdup(optarg);
291 break;
292
293 case 1:
294 {
295 int wal_segsize_mb;
296
297 if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segsize_mb))
298 exit(1);
299 set_wal_segsize = wal_segsize_mb * 1024 * 1024;
301 pg_fatal("argument of %s must be a power of two between 1 and 1024", "--wal-segsize");
302 break;
303 }
304
305 default:
306 /* getopt_long already emitted a complaint */
307 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
308 exit(1);
309 }
310 }
311
312 if (DataDir == NULL && optind < argc)
313 DataDir = argv[optind++];
314
315 /* Complain if any arguments remain */
316 if (optind < argc)
317 {
318 pg_log_error("too many command-line arguments (first is \"%s\")",
319 argv[optind]);
320 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
321 exit(1);
322 }
323
324 if (DataDir == NULL)
325 {
326 pg_log_error("no data directory specified");
327 pg_log_error_hint("Try \"%s --help\" for more information.", progname);
328 exit(1);
329 }
330
331 /*
332 * Don't allow pg_resetwal to be run as root, to avoid overwriting the
333 * ownership of files in the data directory. We need only check for root
334 * -- any other user won't have sufficient permissions to modify files in
335 * the data directory.
336 */
337#ifndef WIN32
338 if (geteuid() == 0)
339 {
340 pg_log_error("cannot be executed by \"root\"");
341 pg_log_error_hint("You must run %s as the PostgreSQL superuser.",
342 progname);
343 exit(1);
344 }
345#endif
346
348
349 /* Set mask based on PGDATA permissions */
351 pg_fatal("could not read permissions of directory \"%s\": %m",
352 DataDir);
353
354 umask(pg_mode_mask);
355
356 if (chdir(DataDir) < 0)
357 pg_fatal("could not change directory to \"%s\": %m",
358 DataDir);
359
360 /* Check that data directory matches our server version */
362
363 /*
364 * Check for a postmaster lock file --- if there is one, refuse to
365 * proceed, on grounds we might be interfering with a live installation.
366 */
367 if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
368 {
369 if (errno != ENOENT)
370 pg_fatal("could not open file \"%s\" for reading: %m",
371 "postmaster.pid");
372 }
373 else
374 {
375 pg_log_error("lock file \"%s\" exists", "postmaster.pid");
376 pg_log_error_hint("Is a server running? If not, delete the lock file and try again.");
377 exit(1);
378 }
379
380 /*
381 * Attempt to read the existing pg_control file
382 */
383 if (!read_controlfile())
385
386 /*
387 * If no new WAL segment size was specified, use the control file value.
388 */
389 if (set_wal_segsize != 0)
391 else
393
394 if (log_fname != NULL)
396
397 /*
398 * Also look at existing segment files to set up newXlogSegNo
399 */
401
402 /*
403 * If we're not going to proceed with the reset, print the current control
404 * file parameters.
405 */
406 if ((guessed && !force) || noupdate)
408
409 /*
410 * Adjust fields if required by switches. (Do this now so that printout,
411 * if any, includes these values.)
412 */
413 if (set_xid_epoch != -1)
417
418 if (set_oldest_xid != 0)
419 {
422 }
423
424 if (set_xid != 0)
427 set_xid);
428
433
434 if (set_oid != 0)
436
437 if (set_mxid != 0)
438 {
440
441 ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
445 }
446
447 if (set_mxoff != -1)
449
451 {
454 }
455
456 if (set_wal_segsize != 0)
458
461
462 if (noupdate)
463 {
465 exit(0);
466 }
467
468 /*
469 * If we had to guess anything, and -f was not given, just print the
470 * guessed values and exit.
471 */
472 if (guessed && !force)
473 {
475 pg_log_error("not proceeding because control file values were guessed");
476 pg_log_error_hint("If these values seem acceptable, use -f to force reset.");
477 exit(1);
478 }
479
480 /*
481 * Don't reset from a dirty pg_control without -f, either.
482 */
483 if (ControlFile.state != DB_SHUTDOWNED && !force)
484 {
485 pg_log_error("database server was not shut down cleanly");
486 pg_log_error_detail("Resetting the write-ahead log might cause data to be lost.");
487 pg_log_error_hint("If you want to proceed anyway, use -f to force reset.");
488 exit(1);
489 }
490
491 /*
492 * Else, do the dirty deed.
493 */
499
500 printf(_("Write-ahead log reset\n"));
501 return 0;
502}
#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:907
static void RewriteControlFile(void)
Definition: pg_resetwal.c:861
static void KillExistingWALSummaries(void)
Definition: pg_resetwal.c:1043
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:973
static void CheckDataVersion(void)
Definition: pg_resetwal.c:518
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:789
static bool read_controlfile(void)
Definition: pg_resetwal.c:559
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1006
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1079
static const char * progname
Definition: pg_resetwal.c:65
static void usage(void)
Definition: pg_resetwal.c:1166
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:716
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:633
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
#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, 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_strdup(), PG_TEXTDOMAIN, CheckPoint::PrevTimeLineID, PrintControlValues(), printf, PrintNewControlValues(), progname, read_controlfile(), required_argument, RewriteControlFile(), 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 716 of file pg_resetwal.c.

717{
718 if (guessed)
719 printf(_("Guessed pg_control values:\n\n"));
720 else
721 printf(_("Current pg_control values:\n\n"));
722
723 printf(_("pg_control version number: %u\n"),
725 printf(_("Catalog version number: %u\n"),
727 printf(_("Database system identifier: %llu\n"),
728 (unsigned long long) ControlFile.system_identifier);
729 printf(_("Latest checkpoint's TimeLineID: %u\n"),
731 printf(_("Latest checkpoint's full_page_writes: %s\n"),
732 ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
733 printf(_("Latest checkpoint's NextXID: %u:%u\n"),
736 printf(_("Latest checkpoint's NextOID: %u\n"),
738 printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
740 printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
742 printf(_("Latest checkpoint's oldestXID: %u\n"),
744 printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
746 printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
748 printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
750 printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
752 printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
754 printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
756 printf(_("Maximum data alignment: %u\n"),
758 /* we don't print floatFormat since can't say much useful about it */
759 printf(_("Database block size: %u\n"),
761 printf(_("Blocks per segment of large relation: %u\n"),
763 printf(_("WAL block size: %u\n"),
765 printf(_("Bytes per WAL segment: %u\n"),
767 printf(_("Maximum length of identifiers: %u\n"),
769 printf(_("Maximum columns in an index: %u\n"),
771 printf(_("Maximum size of a TOAST chunk: %u\n"),
773 printf(_("Size of a large-object chunk: %u\n"),
775 /* This is no longer configurable, but users may still expect to see it: */
776 printf(_("Date/time type storage: %s\n"),
777 _("64-bit integers"));
778 printf(_("Float8 argument passing: %s\n"),
779 (ControlFile.float8ByVal ? _("by value") : _("by reference")));
780 printf(_("Data page checksum version: %u\n"),
782}
uint32 data_checksum_version
Definition: pg_control.h:222

References _, ControlFileData::blcksz, ControlFileData::catalog_version_no, ControlFileData::checkPointCopy, ControlFile, ControlFileData::data_checksum_version, 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 789 of file pg_resetwal.c.

790{
791 char fname[MAXFNAMELEN];
792
793 /* This will be always printed in order to keep format same. */
794 printf(_("\n\nValues to be changed:\n\n"));
795
798 printf(_("First log segment after reset: %s\n"), fname);
799
800 if (set_mxid != 0)
801 {
802 printf(_("NextMultiXactId: %u\n"),
804 printf(_("OldestMultiXid: %u\n"),
806 printf(_("OldestMulti's DB: %u\n"),
808 }
809
810 if (set_mxoff != -1)
811 {
812 printf(_("NextMultiOffset: %u\n"),
814 }
815
816 if (set_oid != 0)
817 {
818 printf(_("NextOID: %u\n"),
820 }
821
822 if (set_xid != 0)
823 {
824 printf(_("NextXID: %u\n"),
826 printf(_("OldestXID: %u\n"),
828 printf(_("OldestXID's DB: %u\n"),
830 }
831
832 if (set_xid_epoch != -1)
833 {
834 printf(_("NextXID epoch: %u\n"),
836 }
837
839 {
840 printf(_("oldestCommitTsXid: %u\n"),
842 }
844 {
845 printf(_("newestCommitTsXid: %u\n"),
847 }
848
849 if (set_wal_segsize != 0)
850 {
851 printf(_("Bytes per WAL segment: %u\n"),
853 }
854}
#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 559 of file pg_resetwal.c.

560{
561 int fd;
562 int len;
563 char *buffer;
565
566 if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
567 {
568 /*
569 * If pg_control is not there at all, or we can't read it, the odds
570 * are we've been handed a bad DataDir path, so give up. User can do
571 * "touch pg_control" to force us to proceed.
572 */
573 pg_log_error("could not open file \"%s\" for reading: %m",
575 if (errno == ENOENT)
576 pg_log_error_hint("If you are sure the data directory path is correct, execute\n"
577 " touch %s\n"
578 "and try again.",
580 exit(1);
581 }
582
583 /* Use malloc to ensure we have a maxaligned buffer */
584 buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
585
586 len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
587 if (len < 0)
588 pg_fatal("could not read file \"%s\": %m", XLOG_CONTROL_FILE);
589 close(fd);
590
591 if (len >= sizeof(ControlFileData) &&
592 ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
593 {
594 /* Check the CRC. */
597 buffer,
598 offsetof(ControlFileData, crc));
600
601 if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
602 {
603 /* We will use the data but treat it as guessed. */
604 pg_log_warning("pg_control exists but has invalid CRC; proceed with caution");
605 guessed = true;
606 }
607
608 memcpy(&ControlFile, buffer, sizeof(ControlFile));
609
610 /* return false if WAL segment size is not valid */
612 {
613 pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution",
614 "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
617 return false;
618 }
619
620 return true;
621 }
622
623 /* Looks like it's a mess. */
624 pg_log_warning("pg_control exists but is broken or wrong version; ignoring it");
625 return false;
626}
#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:250
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 861 of file pg_resetwal.c.

862{
863 /*
864 * Adjust fields as needed to force an empty XLOG starting at
865 * newXlogSegNo.
866 */
870
878
879 /*
880 * Force the defaults for max_* settings. The values don't really matter
881 * as long as wal_level='minimal'; the postmaster will reset these fields
882 * anyway at startup.
883 */
892
893 /* The control file gets flushed here. */
894 update_controlfile(".", &ControlFile, true);
895}
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 1166 of file pg_resetwal.c.

1167{
1168 printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1169 printf(_("Usage:\n"));
1170 printf(_(" %s [OPTION]... DATADIR\n"), progname);
1171
1172 printf(_("\nOptions:\n"));
1173 printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
1174 printf(_(" -f, --force force update to be done even after unclean shutdown or\n"
1175 " if pg_control values had to be guessed\n"));
1176 printf(_(" -n, --dry-run no update, just show what would be done\n"));
1177 printf(_(" -V, --version output version information, then exit\n"));
1178 printf(_(" -?, --help show this help, then exit\n"));
1179
1180 printf(_("\nOptions to override control file values:\n"));
1181 printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
1182 " set oldest and newest transactions bearing\n"
1183 " commit timestamp (zero means no change)\n"));
1184 printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
1185 printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
1186 printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
1187 printf(_(" -o, --next-oid=OID set next OID\n"));
1188 printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
1189 printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n"));
1190 printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
1191 printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
1192
1193 printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1194 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1195}

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1079 of file pg_resetwal.c.

1080{
1081 PGAlignedXLogBlock buffer;
1082 XLogPageHeader page;
1083 XLogLongPageHeader longpage;
1084 XLogRecord *record;
1085 pg_crc32c crc;
1086 char path[MAXPGPATH];
1087 int fd;
1088 int nbytes;
1089 char *recptr;
1090
1091 memset(buffer.data, 0, XLOG_BLCKSZ);
1092
1093 /* Set up the XLOG page header */
1094 page = (XLogPageHeader) buffer.data;
1095 page->xlp_magic = XLOG_PAGE_MAGIC;
1096 page->xlp_info = XLP_LONG_HEADER;
1099 longpage = (XLogLongPageHeader) page;
1101 longpage->xlp_seg_size = WalSegSz;
1102 longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1103
1104 /* Insert the initial checkpoint record */
1105 recptr = (char *) page + SizeOfXLogLongPHD;
1106 record = (XLogRecord *) recptr;
1107 record->xl_prev = 0;
1108 record->xl_xid = InvalidTransactionId;
1111 record->xl_rmid = RM_XLOG_ID;
1112
1113 recptr += SizeOfXLogRecord;
1114 *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1115 *(recptr++) = sizeof(CheckPoint);
1116 memcpy(recptr, &ControlFile.checkPointCopy,
1117 sizeof(CheckPoint));
1118
1120 COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1121 COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1122 FIN_CRC32C(crc);
1123 record->xl_crc = crc;
1124
1125 /* Write the first page */
1128
1129 unlink(path);
1130
1131 fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1133 if (fd < 0)
1134 pg_fatal("could not open file \"%s\": %m", path);
1135
1136 errno = 0;
1137 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1138 {
1139 /* if write didn't set errno, assume problem is no disk space */
1140 if (errno == 0)
1141 errno = ENOSPC;
1142 pg_fatal("could not write file \"%s\": %m", path);
1143 }
1144
1145 /* Fill the rest of the file with zeroes */
1146 memset(buffer.data, 0, XLOG_BLCKSZ);
1147 for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1148 {
1149 errno = 0;
1150 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1151 {
1152 if (errno == 0)
1153 errno = ENOSPC;
1154 pg_fatal("could not write file \"%s\": %m", path);
1155 }
1156 }
1157
1158 if (fsync(fd) != 0)
1159 pg_fatal("fsync error: %m");
1160
1161 close(fd);
1162}
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_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