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

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

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

627 {
628  uint64 sysidentifier;
629  struct timeval tv;
630 
631  /*
632  * Set up a completely default set of pg_control values.
633  */
634  guessed = true;
635  memset(&ControlFile, 0, sizeof(ControlFile));
636 
639 
640  /*
641  * Create a new unique installation identifier, since we can no longer use
642  * any old XLOG records. See notes in xlog.c about the algorithm.
643  */
644  gettimeofday(&tv, NULL);
645  sysidentifier = ((uint64) tv.tv_sec) << 32;
646  sysidentifier |= ((uint64) tv.tv_usec) << 12;
647  sysidentifier |= getpid() & 0xFFF;
648 
649  ControlFile.system_identifier = sysidentifier;
650 
664  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
666 
668  ControlFile.time = (pg_time_t) time(NULL);
671 
672  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
673 
675  ControlFile.wal_log_hints = false;
682 
683  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
685  ControlFile.blcksz = BLCKSZ;
686  ControlFile.relseg_size = RELSEG_SIZE;
687  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
694 
695  /*
696  * XXX eventually, should try to grovel through old XLOG to develop more
697  * accurate values for TimeLineID, nextXID, etc.
698  */
699 }
#define FLOAT8PASSBYVAL
Definition: c.h:571
#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:64
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 999 of file pg_resetwal.c.

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

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

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

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

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

783 {
784  char fname[MAXFNAMELEN];
785 
786  /* This will be always printed in order to keep format same. */
787  printf(_("\n\nValues to be changed:\n\n"));
788 
791  printf(_("First log segment after reset: %s\n"), fname);
792 
793  if (set_mxid != 0)
794  {
795  printf(_("NextMultiXactId: %u\n"),
797  printf(_("OldestMultiXid: %u\n"),
799  printf(_("OldestMulti's DB: %u\n"),
801  }
802 
803  if (set_mxoff != -1)
804  {
805  printf(_("NextMultiOffset: %u\n"),
807  }
808 
809  if (set_oid != 0)
810  {
811  printf(_("NextOID: %u\n"),
813  }
814 
815  if (set_xid != 0)
816  {
817  printf(_("NextXID: %u\n"),
819  printf(_("OldestXID: %u\n"),
821  printf(_("OldestXID's DB: %u\n"),
823  }
824 
825  if (set_xid_epoch != -1)
826  {
827  printf(_("NextXID epoch: %u\n"),
829  }
830 
831  if (set_oldest_commit_ts_xid != 0)
832  {
833  printf(_("oldestCommitTsXid: %u\n"),
835  }
836  if (set_newest_commit_ts_xid != 0)
837  {
838  printf(_("newestCommitTsXid: %u\n"),
840  }
841 
842  if (set_wal_segsize != 0)
843  {
844  printf(_("Bytes per WAL segment: %u\n"),
846  }
847 }
#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 552 of file pg_resetwal.c.

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

855 {
856  /*
857  * Adjust fields as needed to force an empty XLOG starting at
858  * newXlogSegNo.
859  */
862  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
863 
871 
872  /*
873  * Force the defaults for max_* settings. The values don't really matter
874  * as long as wal_level='minimal'; the postmaster will reset these fields
875  * anyway at startup.
876  */
878  ControlFile.wal_log_hints = false;
885 
886  /* The control file gets flushed here. */
887  update_controlfile(".", &ControlFile, true);
888 }
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 1125 of file pg_resetwal.c.

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

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1038 of file pg_resetwal.c.

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

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

Referenced by main().

Variable Documentation

◆ ControlFile

◆ guessed

bool guessed = false
static

Definition at line 64 of file pg_resetwal.c.

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

◆ minXlogSegNo

XLogSegNo minXlogSegNo = 0
static

Definition at line 75 of file pg_resetwal.c.

Referenced by main().

◆ minXlogTli

TimeLineID minXlogTli = 0
static

Definition at line 74 of file pg_resetwal.c.

Referenced by main().

◆ newXlogSegNo

XLogSegNo newXlogSegNo
static

◆ progname

const char* progname
static

Definition at line 65 of file pg_resetwal.c.

Referenced by main(), and usage().

◆ set_mxid

MultiXactId set_mxid = 0
static

Definition at line 72 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_mxoff

MultiXactOffset set_mxoff = (MultiXactOffset) -1
static

Definition at line 73 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_newest_commit_ts_xid

TransactionId set_newest_commit_ts_xid = 0
static

Definition at line 70 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oid

Oid set_oid = 0
static

Definition at line 71 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oldest_commit_ts_xid

TransactionId set_oldest_commit_ts_xid = 0
static

Definition at line 69 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oldest_xid

TransactionId set_oldest_xid = 0
static

Definition at line 67 of file pg_resetwal.c.

Referenced by main().

◆ set_wal_segsize

int set_wal_segsize
static

Definition at line 77 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid

TransactionId set_xid = 0
static

Definition at line 68 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid_epoch

uint32 set_xid_epoch = (uint32) -1
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ WalSegSz

int WalSegSz
static