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"
 

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

Function Documentation

◆ CheckDataVersion()

static void CheckDataVersion ( void  )
static

Definition at line 515 of file pg_resetwal.c.

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

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

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

631 {
632  uint64 sysidentifier;
633  struct timeval tv;
634 
635  /*
636  * Set up a completely default set of pg_control values.
637  */
638  guessed = true;
639  memset(&ControlFile, 0, sizeof(ControlFile));
640 
643 
644  /*
645  * Create a new unique installation identifier, since we can no longer use
646  * any old XLOG records. See notes in xlog.c about the algorithm.
647  */
648  gettimeofday(&tv, NULL);
649  sysidentifier = ((uint64) tv.tv_sec) << 32;
650  sysidentifier |= ((uint64) tv.tv_usec) << 12;
651  sysidentifier |= getpid() & 0xFFF;
652 
653  ControlFile.system_identifier = sysidentifier;
654 
668  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
670 
672  ControlFile.time = (pg_time_t) time(NULL);
675 
676  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
677 
679  ControlFile.wal_log_hints = false;
686 
687  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
689  ControlFile.blcksz = BLCKSZ;
690  ControlFile.relseg_size = RELSEG_SIZE;
691  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
698 
699  /*
700  * XXX eventually, should try to grovel through old XLOG to develop more
701  * accurate values for TimeLineID, nextXID, etc.
702  */
703 }
#define FLOAT8PASSBYVAL
Definition: c.h:624
#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:199
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
@ DB_SHUTDOWNED
Definition: pg_control.h:90
static bool guessed
Definition: pg_resetwal.c:65
int64 pg_time_t
Definition: pgtime.h:23
#define InvalidOid
Definition: postgres_ext.h:36
Oid oldestMultiDB
Definition: pg_control.h:50
MultiXactId oldestMulti
Definition: pg_control.h:49
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestXid
Definition: pg_control.h:47
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:44
TransactionId oldestActiveXid
Definition: pg_control.h:63
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:45
FullTransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
Oid oldestXidDB
Definition: pg_control.h:48
int max_worker_processes
Definition: pg_control.h:179
uint32 pg_control_version
Definition: pg_control.h:123
bool track_commit_timestamp
Definition: pg_control.h:183
int max_locks_per_xact
Definition: pg_control.h:182
uint32 nameDataLen
Definition: pg_control.h:211
XLogRecPtr unloggedLSN
Definition: pg_control.h:135
uint32 indexMaxKeys
Definition: pg_control.h:212
uint32 relseg_size
Definition: pg_control.h:206
pg_time_t time
Definition: pg_control.h:130
XLogRecPtr checkPoint
Definition: pg_control.h:131
uint64 system_identifier
Definition: pg_control.h:108
uint32 catalog_version_no
Definition: pg_control.h:124
double floatFormat
Definition: pg_control.h:198
int max_prepared_xacts
Definition: pg_control.h:181
uint32 xlog_blcksz
Definition: pg_control.h:208
uint32 loblksize
Definition: pg_control.h:215
uint32 toast_max_chunk_size
Definition: pg_control.h:214
#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:69
#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 1003 of file pg_resetwal.c.

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

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

Referenced by main().

◆ KillExistingXLOG()

static void KillExistingXLOG ( void  )
static

Definition at line 970 of file pg_resetwal.c.

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

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 
215  if (set_oldest_commit_ts_xid < 2 &&
217  pg_fatal("transaction ID (-c) must be either 0 or greater than or equal to 2");
218 
219  if (set_newest_commit_ts_xid < 2 &&
221  pg_fatal("transaction ID (-c) must be either 0 or greater than or equal to 2");
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  */
400  FindEndOfXLOG();
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 
429  if (set_oldest_commit_ts_xid != 0)
431  if (set_newest_commit_ts_xid != 0)
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  /*
463  * If we had to guess anything, and -f was not given, just print the
464  * guessed values and exit. Also print if -n is given.
465  */
466  if ((guessed && !force) || noupdate)
467  {
469  if (!noupdate)
470  {
471  printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
472  exit(1);
473  }
474  else
475  exit(0);
476  }
477 
478  /*
479  * Don't reset from a dirty pg_control without -f, either.
480  */
481  if (ControlFile.state != DB_SHUTDOWNED && !force)
482  {
483  printf(_("The database server was not shut down cleanly.\n"
484  "Resetting the write-ahead log might cause data to be lost.\n"
485  "If you want to proceed anyway, use -f to force reset.\n"));
486  exit(1);
487  }
488 
489  /*
490  * Else, do the dirty deed.
491  */
495  WriteEmptyXLOG();
496 
497  printf(_("Write-ahead log reset\n"));
498  return 0;
499 }
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1227
TransactionId MultiXactId
Definition: c.h:651
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:436
#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:24
#define required_argument
Definition: getopt_long.h:25
char * DataDir
Definition: globals.c:66
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:50
PGDLLIMPORT char * optarg
Definition: getopt.c:52
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:904
static void RewriteControlFile(void)
Definition: pg_resetwal.c:858
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:970
static void CheckDataVersion(void)
Definition: pg_resetwal.c:515
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:76
static int set_wal_segsize
Definition: pg_resetwal.c:78
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:74
static MultiXactId set_mxid
Definition: pg_resetwal.c:73
static TimeLineID minXlogTli
Definition: pg_resetwal.c:75
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:786
static bool read_controlfile(void)
Definition: pg_resetwal.c:556
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1003
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1042
static const char * progname
Definition: pg_resetwal.c:66
static void usage(void)
Definition: pg_resetwal.c:1129
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:713
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:630
const char * get_progname(const char *argv0)
Definition: path.c:574
#define printf(...)
Definition: port.h:244
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:54
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
#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, IsValidWalSegSize, KillExistingArchiveStatus(), 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_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 713 of file pg_resetwal.c.

714 {
715  if (guessed)
716  printf(_("Guessed pg_control values:\n\n"));
717  else
718  printf(_("Current pg_control values:\n\n"));
719 
720  printf(_("pg_control version number: %u\n"),
722  printf(_("Catalog version number: %u\n"),
724  printf(_("Database system identifier: %llu\n"),
725  (unsigned long long) ControlFile.system_identifier);
726  printf(_("Latest checkpoint's TimeLineID: %u\n"),
728  printf(_("Latest checkpoint's full_page_writes: %s\n"),
729  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
730  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
733  printf(_("Latest checkpoint's NextOID: %u\n"),
735  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
737  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
739  printf(_("Latest checkpoint's oldestXID: %u\n"),
741  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
743  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
745  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
747  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
749  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
751  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
753  printf(_("Maximum data alignment: %u\n"),
755  /* we don't print floatFormat since can't say much useful about it */
756  printf(_("Database block size: %u\n"),
758  printf(_("Blocks per segment of large relation: %u\n"),
760  printf(_("WAL block size: %u\n"),
762  printf(_("Bytes per WAL segment: %u\n"),
764  printf(_("Maximum length of identifiers: %u\n"),
766  printf(_("Maximum columns in an index: %u\n"),
768  printf(_("Maximum size of a TOAST chunk: %u\n"),
770  printf(_("Size of a large-object chunk: %u\n"),
772  /* This is no longer configurable, but users may still expect to see it: */
773  printf(_("Date/time type storage: %s\n"),
774  _("64-bit integers"));
775  printf(_("Float8 argument passing: %s\n"),
776  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
777  printf(_("Data page checksum version: %u\n"),
779 }
uint32 data_checksum_version
Definition: pg_control.h:220

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

787 {
788  char fname[MAXFNAMELEN];
789 
790  /* This will be always printed in order to keep format same. */
791  printf(_("\n\nValues to be changed:\n\n"));
792 
795  printf(_("First log segment after reset: %s\n"), fname);
796 
797  if (set_mxid != 0)
798  {
799  printf(_("NextMultiXactId: %u\n"),
801  printf(_("OldestMultiXid: %u\n"),
803  printf(_("OldestMulti's DB: %u\n"),
805  }
806 
807  if (set_mxoff != -1)
808  {
809  printf(_("NextMultiOffset: %u\n"),
811  }
812 
813  if (set_oid != 0)
814  {
815  printf(_("NextOID: %u\n"),
817  }
818 
819  if (set_xid != 0)
820  {
821  printf(_("NextXID: %u\n"),
823  printf(_("OldestXID: %u\n"),
825  printf(_("OldestXID's DB: %u\n"),
827  }
828 
829  if (set_xid_epoch != -1)
830  {
831  printf(_("NextXID epoch: %u\n"),
833  }
834 
835  if (set_oldest_commit_ts_xid != 0)
836  {
837  printf(_("oldestCommitTsXid: %u\n"),
839  }
840  if (set_newest_commit_ts_xid != 0)
841  {
842  printf(_("newestCommitTsXid: %u\n"),
844  }
845 
846  if (set_wal_segsize != 0)
847  {
848  printf(_("Bytes per WAL segment: %u\n"),
850  }
851 }
#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 556 of file pg_resetwal.c.

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

859 {
860  /*
861  * Adjust fields as needed to force an empty XLOG starting at
862  * newXlogSegNo.
863  */
866  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
867 
875 
876  /*
877  * Force the defaults for max_* settings. The values don't really matter
878  * as long as wal_level='minimal'; the postmaster will reset these fields
879  * anyway at startup.
880  */
882  ControlFile.wal_log_hints = false;
889 
890  /* The control file gets flushed here. */
891  update_controlfile(".", &ControlFile, true);
892 }
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
bool backupEndRequired
Definition: pg_control.h:170
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:167
#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 1129 of file pg_resetwal.c.

1130 {
1131  printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1132  printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
1133  printf(_("Options:\n"));
1134  printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
1135  " set oldest and newest transactions bearing\n"
1136  " commit timestamp (zero means no change)\n"));
1137  printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
1138  printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
1139  printf(_(" -f, --force force update to be done\n"));
1140  printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
1141  printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
1142  printf(_(" -n, --dry-run no update, just show what would be done\n"));
1143  printf(_(" -o, --next-oid=OID set next OID\n"));
1144  printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
1145  printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n"));
1146  printf(_(" -V, --version output version information, then exit\n"));
1147  printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
1148  printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
1149  printf(_(" -?, --help show this help, then exit\n"));
1150  printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1151  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1152 }

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1042 of file pg_resetwal.c.

1043 {
1044  PGAlignedXLogBlock buffer;
1045  XLogPageHeader page;
1046  XLogLongPageHeader longpage;
1047  XLogRecord *record;
1048  pg_crc32c crc;
1049  char path[MAXPGPATH];
1050  int fd;
1051  int nbytes;
1052  char *recptr;
1053 
1054  memset(buffer.data, 0, XLOG_BLCKSZ);
1055 
1056  /* Set up the XLOG page header */
1057  page = (XLogPageHeader) buffer.data;
1058  page->xlp_magic = XLOG_PAGE_MAGIC;
1059  page->xlp_info = XLP_LONG_HEADER;
1062  longpage = (XLogLongPageHeader) page;
1064  longpage->xlp_seg_size = WalSegSz;
1065  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1066 
1067  /* Insert the initial checkpoint record */
1068  recptr = (char *) page + SizeOfXLogLongPHD;
1069  record = (XLogRecord *) recptr;
1070  record->xl_prev = 0;
1071  record->xl_xid = InvalidTransactionId;
1074  record->xl_rmid = RM_XLOG_ID;
1075 
1076  recptr += SizeOfXLogRecord;
1077  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1078  *(recptr++) = sizeof(CheckPoint);
1079  memcpy(recptr, &ControlFile.checkPointCopy,
1080  sizeof(CheckPoint));
1081 
1082  INIT_CRC32C(crc);
1083  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1084  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1085  FIN_CRC32C(crc);
1086  record->xl_crc = crc;
1087 
1088  /* Write the first page */
1091 
1092  unlink(path);
1093 
1094  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1096  if (fd < 0)
1097  pg_fatal("could not open file \"%s\": %m", path);
1098 
1099  errno = 0;
1100  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1101  {
1102  /* if write didn't set errno, assume problem is no disk space */
1103  if (errno == 0)
1104  errno = ENOSPC;
1105  pg_fatal("could not write file \"%s\": %m", path);
1106  }
1107 
1108  /* Fill the rest of the file with zeroes */
1109  memset(buffer.data, 0, XLOG_BLCKSZ);
1110  for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1111  {
1112  errno = 0;
1113  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1114  {
1115  if (errno == 0)
1116  errno = ENOSPC;
1117  pg_fatal("could not write file \"%s\": %m", path);
1118  }
1119  }
1120 
1121  if (fsync(fd) != 0)
1122  pg_fatal("fsync error: %m");
1123 
1124  close(fd);
1125 }
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:67
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:1161
#define fsync(fd)
Definition: win32_port.h:85
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 76 of file pg_resetwal.c.

Referenced by main().

◆ minXlogTli

TimeLineID minXlogTli = 0
static

Definition at line 75 of file pg_resetwal.c.

Referenced by main().

◆ newXlogSegNo

XLogSegNo newXlogSegNo
static

◆ progname

const char* progname
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and usage().

◆ set_mxid

MultiXactId set_mxid = 0
static

Definition at line 73 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_mxoff

MultiXactOffset set_mxoff = (MultiXactOffset) -1
static

Definition at line 74 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 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().

◆ set_wal_segsize

int set_wal_segsize
static

Definition at line 78 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