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

Go to the source code of this file.

Macros

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

Functions

static void CheckDataVersion (void)
 
static bool read_controlfile (void)
 
static void GuessControlValues (void)
 
static void PrintControlValues (bool guessed)
 
static void PrintNewControlValues (void)
 
static void RewriteControlFile (void)
 
static void FindEndOfXLOG (void)
 
static void KillExistingXLOG (void)
 
static void KillExistingArchiveStatus (void)
 
static void KillExistingWALSummaries (void)
 
static void WriteEmptyXLOG (void)
 
static void usage (void)
 
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 bool mxid_given = false
 
static MultiXactId set_mxid = 0
 
static bool mxoff_given = false
 
static MultiXactOffset set_mxoff = 0
 
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 546 of file pg_resetwal.c.

547{
548 char *version_str;
549 uint32 version = get_pg_version(".", &version_str);
550
551 if (GET_PG_MAJORVERSION_NUM(version) != PG_MAJORVERSION_NUM)
552 {
553 pg_log_error("data directory is of wrong version");
554 pg_log_error_detail("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
555 "PG_VERSION",
556 version_str,
557 PG_MAJORVERSION);
558 exit(1);
559 }
560}
uint32_t uint32
Definition: c.h:541
uint32 get_pg_version(const char *datadir, char **version_str)
Definition: version.c:44
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_detail(...)
Definition: logging.h:109
#define GET_PG_MAJORVERSION_NUM(v)
Definition: version.h:19

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

Referenced by main().

◆ FindEndOfXLOG()

static void FindEndOfXLOG ( void  )
static

Definition at line 927 of file pg_resetwal.c.

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

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

Referenced by main().

◆ GuessControlValues()

static void GuessControlValues ( void  )
static

Definition at line 644 of file pg_resetwal.c.

645{
646 uint64 sysidentifier;
647 struct timeval tv;
648
649 /*
650 * Set up a completely default set of pg_control values.
651 */
652 guessed = true;
653 memset(&ControlFile, 0, sizeof(ControlFile));
654
657
658 /*
659 * Create a new unique installation identifier, since we can no longer use
660 * any old XLOG records. See notes in xlog.c about the algorithm.
661 */
662 gettimeofday(&tv, NULL);
663 sysidentifier = ((uint64) tv.tv_sec) << 32;
664 sysidentifier |= ((uint64) tv.tv_usec) << 12;
665 sysidentifier |= getpid() & 0xFFF;
666
667 ControlFile.system_identifier = sysidentifier;
668
684
686 ControlFile.time = (pg_time_t) time(NULL);
689
690 /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
691
700
701 ControlFile.maxAlign = MAXIMUM_ALIGNOF;
703 ControlFile.blcksz = BLCKSZ;
704 ControlFile.relseg_size = RELSEG_SIZE;
706 ControlFile.xlog_blcksz = XLOG_BLCKSZ;
712 ControlFile.float8ByVal = true; /* vestigial */
713
714 /*
715 * XXX eventually, should try to grovel through old XLOG to develop more
716 * accurate values for TimeLineID, nextXID, etc.
717 */
718}
#define CATALOG_VERSION_NO
Definition: catversion.h:60
#define TOAST_MAX_CHUNK_SIZE
Definition: heaptoast.h:84
#define LOBLKSIZE
Definition: large_object.h:70
#define FirstMultiXactId
Definition: multixact.h:26
#define INDEX_MAX_KEYS
#define NAMEDATALEN
#define DEFAULT_XLOG_SEG_SIZE
#define SLRU_PAGES_PER_SEGMENT
#define FLOATFORMAT_VALUE
Definition: pg_control.h:201
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
@ DB_SHUTDOWNED
Definition: pg_control.h:92
static bool guessed
Definition: pg_resetwal.c:65
int64 pg_time_t
Definition: pgtime.h:23
#define InvalidOid
Definition: postgres_ext.h:37
Oid oldestMultiDB
Definition: pg_control.h:51
MultiXactId oldestMulti
Definition: pg_control.h:50
MultiXactOffset nextMultiOffset
Definition: pg_control.h:47
TransactionId oldestXid
Definition: pg_control.h:48
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:45
TransactionId oldestActiveXid
Definition: pg_control.h:64
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:46
FullTransactionId nextXid
Definition: pg_control.h:44
pg_time_t time
Definition: pg_control.h:52
Oid oldestXidDB
Definition: pg_control.h:49
int max_worker_processes
Definition: pg_control.h:181
uint32 pg_control_version
Definition: pg_control.h:125
bool track_commit_timestamp
Definition: pg_control.h:185
int max_locks_per_xact
Definition: pg_control.h:184
uint32 nameDataLen
Definition: pg_control.h:215
uint32 slru_pages_per_segment
Definition: pg_control.h:210
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
uint32 indexMaxKeys
Definition: pg_control.h:216
uint32 relseg_size
Definition: pg_control.h:208
pg_time_t time
Definition: pg_control.h:132
XLogRecPtr checkPoint
Definition: pg_control.h:133
uint64 system_identifier
Definition: pg_control.h:110
uint32 catalog_version_no
Definition: pg_control.h:126
double floatFormat
Definition: pg_control.h:200
int max_prepared_xacts
Definition: pg_control.h:183
uint32 xlog_blcksz
Definition: pg_control.h:212
uint32 loblksize
Definition: pg_control.h:219
uint32 toast_max_chunk_size
Definition: pg_control.h:218
#define InvalidTransactionId
Definition: transam.h:31
#define FirstGenbkiObjectId
Definition: transam.h:195
#define FirstNormalTransactionId
Definition: transam.h:34
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
int gettimeofday(struct timeval *tp, void *tzp)
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:74
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:37

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

Referenced by main().

◆ KillExistingArchiveStatus()

static void KillExistingArchiveStatus ( void  )
static

Definition at line 1026 of file pg_resetwal.c.

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

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

Referenced by main().

◆ KillExistingWALSummaries()

static void KillExistingWALSummaries ( void  )
static

Definition at line 1063 of file pg_resetwal.c.

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

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

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

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

References _, CheckDataVersion(), ControlFileData::checkPointCopy, ControlFile, DataDir, DB_SHUTDOWNED, ControlFileData::default_char_signedness, EpochFromFullTransactionId, fd(), FindEndOfXLOG(), FirstMultiXactId, FirstNormalTransactionId, FullTransactionIdFromEpochAndXid(), get_progname(), get_restricted_token(), GetDataDirectoryCreatePerm(), getopt_long(), GuessControlValues(), guessed, InvalidOid, InvalidTransactionId, IsValidWalSegSize, KillExistingArchiveStatus(), KillExistingWALSummaries(), KillExistingXLOG(), MaxMultiXactOffset, minXlogSegNo, minXlogTli, mxid_given, mxoff_given, 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 728 of file pg_resetwal.c.

729{
730 if (guessed)
731 printf(_("Guessed pg_control values:\n\n"));
732 else
733 printf(_("Current pg_control values:\n\n"));
734
735 printf(_("pg_control version number: %u\n"),
737 printf(_("Catalog version number: %u\n"),
739 printf(_("Database system identifier: %" PRIu64 "\n"),
741 printf(_("Latest checkpoint's TimeLineID: %u\n"),
743 printf(_("Latest checkpoint's full_page_writes: %s\n"),
744 ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
745 printf(_("Latest checkpoint's NextXID: %u:%u\n"),
748 printf(_("Latest checkpoint's NextOID: %u\n"),
750 printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
752 printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
754 printf(_("Latest checkpoint's oldestXID: %u\n"),
756 printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
758 printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
760 printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
762 printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
764 printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
766 printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
768 printf(_("Maximum data alignment: %u\n"),
770 /* we don't print floatFormat since can't say much useful about it */
771 printf(_("Database block size: %u\n"),
773 printf(_("Blocks per segment of large relation: %u\n"),
775 printf(_("Pages per SLRU segment: %u\n"),
777 printf(_("WAL block size: %u\n"),
779 printf(_("Bytes per WAL segment: %u\n"),
781 printf(_("Maximum length of identifiers: %u\n"),
783 printf(_("Maximum columns in an index: %u\n"),
785 printf(_("Maximum size of a TOAST chunk: %u\n"),
787 printf(_("Size of a large-object chunk: %u\n"),
789 /* This is no longer configurable, but users may still expect to see it: */
790 printf(_("Date/time type storage: %s\n"),
791 _("64-bit integers"));
792 printf(_("Float8 argument passing: %s\n"),
793 (ControlFile.float8ByVal ? _("by value") : _("by reference")));
794 printf(_("Data page checksum version: %u\n"),
796 printf(_("Default char data signedness: %s\n"),
797 (ControlFile.default_char_signedness ? _("signed") : _("unsigned")));
798}
uint32 data_checksum_version
Definition: pg_control.h:224

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

Referenced by main().

◆ PrintNewControlValues()

static void PrintNewControlValues ( void  )
static

Definition at line 805 of file pg_resetwal.c.

806{
807 char fname[MAXFNAMELEN];
808
809 /* This will be always printed in order to keep format same. */
810 printf(_("\n\nValues to be changed:\n\n"));
811
814 printf(_("First log segment after reset: %s\n"), fname);
815
816 if (mxid_given)
817 {
818 printf(_("NextMultiXactId: %u\n"),
820 printf(_("OldestMultiXid: %u\n"),
822 printf(_("OldestMulti's DB: %u\n"),
824 }
825
826 if (mxoff_given)
827 {
828 printf(_("NextMultiOffset: %u\n"),
830 }
831
832 if (set_oid != 0)
833 {
834 printf(_("NextOID: %u\n"),
836 }
837
838 if (set_xid != 0)
839 {
840 printf(_("NextXID: %u\n"),
842 }
843
844 if (set_oldest_xid != 0)
845 {
846 printf(_("OldestXID: %u\n"),
848 printf(_("OldestXID's DB: %u\n"),
850 }
851
852 if (set_xid_epoch != -1)
853 {
854 printf(_("NextXID epoch: %u\n"),
856 }
857
859 {
860 printf(_("oldestCommitTsXid: %u\n"),
862 }
864 {
865 printf(_("newestCommitTsXid: %u\n"),
867 }
868
869 if (set_wal_segsize != 0)
870 {
871 printf(_("Bytes per WAL segment: %u\n"),
873 }
874}
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References _, ControlFileData::checkPointCopy, ControlFile, EpochFromFullTransactionId, MAXFNAMELEN, mxid_given, mxoff_given, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, printf, set_newest_commit_ts_xid, set_oid, set_oldest_commit_ts_xid, set_oldest_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 570 of file pg_resetwal.c.

571{
572 int fd;
573 int len;
574 char *buffer;
576
577 if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
578 {
579 /*
580 * If pg_control is not there at all, or we can't read it, the odds
581 * are we've been handed a bad DataDir path, so give up. User can do
582 * "touch pg_control" to force us to proceed.
583 */
584 pg_log_error("could not open file \"%s\" for reading: %m",
586 if (errno == ENOENT)
587 pg_log_error_hint("If you are sure the data directory path is correct, execute\n"
588 " touch %s\n"
589 "and try again.",
591 exit(1);
592 }
593
594 /* Use malloc to ensure we have a maxaligned buffer */
595 buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
596
597 len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
598 if (len < 0)
599 pg_fatal("could not read file \"%s\": %m", XLOG_CONTROL_FILE);
600 close(fd);
601
602 if (len >= sizeof(ControlFileData) &&
603 ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
604 {
605 /* Check the CRC. */
608 buffer,
609 offsetof(ControlFileData, crc));
611
612 if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
613 {
614 /* We will use the data but treat it as guessed. */
615 pg_log_warning("pg_control exists but has invalid CRC; proceed with caution");
616 guessed = true;
617 }
618
619 memcpy(&ControlFile, buffer, sizeof(ControlFile));
620
621 /* return false if WAL segment size is not valid */
623 {
624 pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution",
625 "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
628 return false;
629 }
630
631 return true;
632 }
633
634 /* Looks like it's a mess. */
635 pg_log_warning("pg_control exists but is broken or wrong version; ignoring it");
636 return false;
637}
#define ngettext(s, p, n)
Definition: c.h:1169
#define PG_BINARY
Definition: c.h:1261
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:258
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:153
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:158
const void size_t len
return crc
#define pg_log_warning(...)
Definition: pgfnames.c:24
#define XLOG_CONTROL_FILE

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

Referenced by main().

◆ RewriteControlFile()

static void RewriteControlFile ( void  )
static

Definition at line 881 of file pg_resetwal.c.

882{
883 /*
884 * Adjust fields as needed to force an empty XLOG starting at
885 * newXlogSegNo.
886 */
890
898
899 /*
900 * Force the defaults for max_* settings. The values don't really matter
901 * as long as wal_level='minimal'; the postmaster will reset these fields
902 * anyway at startup.
903 */
912
913 /* The control file gets flushed here. */
914 update_controlfile(".", &ControlFile, true);
915}
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 1186 of file pg_resetwal.c.

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

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1099 of file pg_resetwal.c.

1100{
1101 PGAlignedXLogBlock buffer;
1102 XLogPageHeader page;
1103 XLogLongPageHeader longpage;
1104 XLogRecord *record;
1105 pg_crc32c crc;
1106 char path[MAXPGPATH];
1107 int fd;
1108 int nbytes;
1109 char *recptr;
1110
1111 memset(buffer.data, 0, XLOG_BLCKSZ);
1112
1113 /* Set up the XLOG page header */
1114 page = (XLogPageHeader) buffer.data;
1115 page->xlp_magic = XLOG_PAGE_MAGIC;
1116 page->xlp_info = XLP_LONG_HEADER;
1119 longpage = (XLogLongPageHeader) page;
1121 longpage->xlp_seg_size = WalSegSz;
1122 longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1123
1124 /* Insert the initial checkpoint record */
1125 recptr = (char *) page + SizeOfXLogLongPHD;
1126 record = (XLogRecord *) recptr;
1127 record->xl_prev = 0;
1128 record->xl_xid = InvalidTransactionId;
1131 record->xl_rmid = RM_XLOG_ID;
1132
1133 recptr += SizeOfXLogRecord;
1134 *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1135 *(recptr++) = sizeof(CheckPoint);
1136 memcpy(recptr, &ControlFile.checkPointCopy,
1137 sizeof(CheckPoint));
1138
1140 COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1141 COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1142 FIN_CRC32C(crc);
1143 record->xl_crc = crc;
1144
1145 /* Write the first page */
1148
1149 unlink(path);
1150
1151 fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1153 if (fd < 0)
1154 pg_fatal("could not open file \"%s\": %m", path);
1155
1156 errno = 0;
1157 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1158 {
1159 /* if write didn't set errno, assume problem is no disk space */
1160 if (errno == 0)
1161 errno = ENOSPC;
1162 pg_fatal("could not write file \"%s\": %m", path);
1163 }
1164
1165 /* Fill the rest of the file with zeroes */
1166 memset(buffer.data, 0, XLOG_BLCKSZ);
1167 for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1168 {
1169 errno = 0;
1170 if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1171 {
1172 if (errno == 0)
1173 errno = ENOSPC;
1174 pg_fatal("could not write file \"%s\": %m", path);
1175 }
1176 }
1177
1178 if (fsync(fd) != 0)
1179 pg_fatal("fsync error: %m");
1180
1181 close(fd);
1182}
int pg_file_create_mode
Definition: file_perm.c:19
#define write(a, b, c)
Definition: win32.h:14
struct CheckPoint CheckPoint
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:68
char data[XLOG_BLCKSZ]
Definition: c.h:1138
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
uint8 xl_info
Definition: xlogrecord.h:46
uint32 xl_tot_len
Definition: xlogrecord.h:43
TransactionId xl_xid
Definition: xlogrecord.h:44
RmgrId xl_rmid
Definition: xlogrecord.h:47
#define fsync(fd)
Definition: win32_port.h:83
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
static void XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:217
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:241
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

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

Referenced by main().

Variable Documentation

◆ ControlFile

◆ guessed

bool guessed = false
static

Definition at line 65 of file pg_resetwal.c.

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

◆ minXlogSegNo

XLogSegNo minXlogSegNo = 0
static

Definition at line 78 of file pg_resetwal.c.

Referenced by main().

◆ minXlogTli

TimeLineID minXlogTli = 0
static

Definition at line 77 of file pg_resetwal.c.

Referenced by main().

◆ mxid_given

bool mxid_given = false
static

Definition at line 73 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ mxoff_given

bool mxoff_given = false
static

Definition at line 75 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ newXlogSegNo

XLogSegNo newXlogSegNo
static

◆ progname

const char* progname
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and usage().

◆ set_char_signedness

int set_char_signedness = -1
static

Definition at line 81 of file pg_resetwal.c.

Referenced by main().

◆ set_mxid

MultiXactId set_mxid = 0
static

Definition at line 74 of file pg_resetwal.c.

Referenced by main().

◆ set_mxoff

MultiXactOffset set_mxoff = 0
static

Definition at line 76 of file pg_resetwal.c.

Referenced by main().

◆ set_newest_commit_ts_xid

TransactionId set_newest_commit_ts_xid = 0
static

Definition at line 71 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oid

Oid set_oid = 0
static

Definition at line 72 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 70 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oldest_xid

TransactionId set_oldest_xid = 0
static

Definition at line 68 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_wal_segsize

int set_wal_segsize
static

Definition at line 80 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid

TransactionId set_xid = 0
static

Definition at line 69 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid_epoch

uint32 set_xid_epoch = (uint32) -1
static

Definition at line 67 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ WalSegSz

int WalSegSz
static