PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_resetwal.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_resetwal.c
4  * A utility to "zero out" the xlog when it's corrupt beyond recovery.
5  * Can also rebuild pg_control if needed.
6  *
7  * The theory of operation is fairly simple:
8  * 1. Read the existing pg_control (which will include the last
9  * checkpoint record). If it is an old format then update to
10  * current format.
11  * 2. If pg_control is corrupt, attempt to intuit reasonable values,
12  * by scanning the old xlog if necessary.
13  * 3. Modify pg_control to reflect a "shutdown" state with a checkpoint
14  * record at the start of xlog.
15  * 4. Flush the existing xlog files and write a new segment with
16  * just a checkpoint record in it. The new segment is positioned
17  * just past the end of the old xlog, so that existing LSNs in
18  * data pages will appear to be "in the past".
19  * This is all pretty straightforward except for the intuition part of
20  * step 2 ...
21  *
22  *
23  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
24  * Portions Copyright (c) 1994, Regents of the University of California
25  *
26  * src/bin/pg_resetwal/pg_resetwal.c
27  *
28  *-------------------------------------------------------------------------
29  */
30 
31 /*
32  * We have to use postgres.h not postgres_fe.h here, because there's so much
33  * backend-only stuff in the XLOG include files we need. But we need a
34  * frontend-ish environment otherwise. Hence this ugly hack.
35  */
36 #define FRONTEND 1
37 
38 #include "postgres.h"
39 
40 #include <dirent.h>
41 #include <fcntl.h>
42 #include <sys/stat.h>
43 #include <sys/time.h>
44 #include <time.h>
45 #include <unistd.h>
46 
47 #include "access/transam.h"
48 #include "access/tuptoaster.h"
49 #include "access/multixact.h"
50 #include "access/xlog.h"
51 #include "access/xlog_internal.h"
52 #include "catalog/catversion.h"
53 #include "catalog/pg_control.h"
54 #include "common/fe_memutils.h"
56 #include "storage/large_object.h"
57 #include "pg_getopt.h"
58 
59 
60 static ControlFileData ControlFile; /* pg_control values */
61 static XLogSegNo newXlogSegNo; /* new XLOG segment # */
62 static bool guessed = false; /* T if we had to guess at any values */
63 static const char *progname;
64 static uint32 set_xid_epoch = (uint32) -1;
68 static Oid set_oid = 0;
69 static MultiXactId set_mxid = 0;
71 static uint32 minXlogTli = 0;
73 
74 static bool ReadControlFile(void);
75 static void GuessControlValues(void);
76 static void PrintControlValues(bool guessed);
77 static void PrintNewControlValues(void);
78 static void RewriteControlFile(void);
79 static void FindEndOfXLOG(void);
80 static void KillExistingXLOG(void);
81 static void KillExistingArchiveStatus(void);
82 static void WriteEmptyXLOG(void);
83 static void usage(void);
84 
85 
86 int
87 main(int argc, char *argv[])
88 {
89  int c;
90  bool force = false;
91  bool noupdate = false;
92  MultiXactId set_oldestmxid = 0;
93  char *endptr;
94  char *endptr2;
95  char *DataDir = NULL;
96  int fd;
97 
98  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
99 
100  progname = get_progname(argv[0]);
101 
102  if (argc > 1)
103  {
104  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
105  {
106  usage();
107  exit(0);
108  }
109  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
110  {
111  puts("pg_resetwal (PostgreSQL) " PG_VERSION);
112  exit(0);
113  }
114  }
115 
116 
117  while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:x:")) != -1)
118  {
119  switch (c)
120  {
121  case 'D':
122  DataDir = optarg;
123  break;
124 
125  case 'f':
126  force = true;
127  break;
128 
129  case 'n':
130  noupdate = true;
131  break;
132 
133  case 'e':
134  set_xid_epoch = strtoul(optarg, &endptr, 0);
135  if (endptr == optarg || *endptr != '\0')
136  {
137  /*------
138  translator: the second %s is a command line argument (-e, etc) */
139  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-e");
140  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
141  exit(1);
142  }
143  if (set_xid_epoch == -1)
144  {
145  fprintf(stderr, _("%s: transaction ID epoch (-e) must not be -1\n"), progname);
146  exit(1);
147  }
148  break;
149 
150  case 'x':
151  set_xid = strtoul(optarg, &endptr, 0);
152  if (endptr == optarg || *endptr != '\0')
153  {
154  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-x");
155  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
156  exit(1);
157  }
158  if (set_xid == 0)
159  {
160  fprintf(stderr, _("%s: transaction ID (-x) must not be 0\n"), progname);
161  exit(1);
162  }
163  break;
164 
165  case 'c':
166  set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
167  if (endptr == optarg || *endptr != ',')
168  {
169  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c");
170  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
171  exit(1);
172  }
173  set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
174  if (endptr2 == endptr + 1 || *endptr2 != '\0')
175  {
176  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c");
177  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
178  exit(1);
179  }
180 
181  if (set_oldest_commit_ts_xid < 2 &&
183  {
184  fprintf(stderr, _("%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n"), progname);
185  exit(1);
186  }
187 
188  if (set_newest_commit_ts_xid < 2 &&
190  {
191  fprintf(stderr, _("%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n"), progname);
192  exit(1);
193  }
194  break;
195 
196  case 'o':
197  set_oid = strtoul(optarg, &endptr, 0);
198  if (endptr == optarg || *endptr != '\0')
199  {
200  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-o");
201  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
202  exit(1);
203  }
204  if (set_oid == 0)
205  {
206  fprintf(stderr, _("%s: OID (-o) must not be 0\n"), progname);
207  exit(1);
208  }
209  break;
210 
211  case 'm':
212  set_mxid = strtoul(optarg, &endptr, 0);
213  if (endptr == optarg || *endptr != ',')
214  {
215  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m");
216  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
217  exit(1);
218  }
219 
220  set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
221  if (endptr2 == endptr + 1 || *endptr2 != '\0')
222  {
223  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m");
224  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
225  exit(1);
226  }
227  if (set_mxid == 0)
228  {
229  fprintf(stderr, _("%s: multitransaction ID (-m) must not be 0\n"), progname);
230  exit(1);
231  }
232 
233  /*
234  * XXX It'd be nice to have more sanity checks here, e.g. so
235  * that oldest is not wrapped around w.r.t. nextMulti.
236  */
237  if (set_oldestmxid == 0)
238  {
239  fprintf(stderr, _("%s: oldest multitransaction ID (-m) must not be 0\n"),
240  progname);
241  exit(1);
242  }
243  break;
244 
245  case 'O':
246  set_mxoff = strtoul(optarg, &endptr, 0);
247  if (endptr == optarg || *endptr != '\0')
248  {
249  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-O");
250  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
251  exit(1);
252  }
253  if (set_mxoff == -1)
254  {
255  fprintf(stderr, _("%s: multitransaction offset (-O) must not be -1\n"), progname);
256  exit(1);
257  }
258  break;
259 
260  case 'l':
261  if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
262  {
263  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-l");
264  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
265  exit(1);
266  }
268  break;
269 
270  default:
271  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
272  exit(1);
273  }
274  }
275 
276  if (DataDir == NULL && optind < argc)
277  DataDir = argv[optind++];
278 
279  /* Complain if any arguments remain */
280  if (optind < argc)
281  {
282  fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
283  progname, argv[optind]);
284  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
285  progname);
286  exit(1);
287  }
288 
289  if (DataDir == NULL)
290  {
291  fprintf(stderr, _("%s: no data directory specified\n"), progname);
292  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
293  exit(1);
294  }
295 
296  /*
297  * Don't allow pg_resetwal to be run as root, to avoid overwriting the
298  * ownership of files in the data directory. We need only check for root
299  * -- any other user won't have sufficient permissions to modify files in
300  * the data directory.
301  */
302 #ifndef WIN32
303  if (geteuid() == 0)
304  {
305  fprintf(stderr, _("%s: cannot be executed by \"root\"\n"),
306  progname);
307  fprintf(stderr, _("You must run %s as the PostgreSQL superuser.\n"),
308  progname);
309  exit(1);
310  }
311 #endif
312 
314 
315  if (chdir(DataDir) < 0)
316  {
317  fprintf(stderr, _("%s: could not change directory to \"%s\": %s\n"),
318  progname, DataDir, strerror(errno));
319  exit(1);
320  }
321 
322  /*
323  * Check for a postmaster lock file --- if there is one, refuse to
324  * proceed, on grounds we might be interfering with a live installation.
325  */
326  if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
327  {
328  if (errno != ENOENT)
329  {
330  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
331  progname, "postmaster.pid", strerror(errno));
332  exit(1);
333  }
334  }
335  else
336  {
337  fprintf(stderr, _("%s: lock file \"%s\" exists\n"
338  "Is a server running? If not, delete the lock file and try again.\n"),
339  progname, "postmaster.pid");
340  exit(1);
341  }
342 
343  /*
344  * Attempt to read the existing pg_control file
345  */
346  if (!ReadControlFile())
348 
349  /*
350  * Also look at existing segment files to set up newXlogSegNo
351  */
352  FindEndOfXLOG();
353 
354  /*
355  * If we're not going to proceed with the reset, print the current control
356  * file parameters.
357  */
358  if ((guessed && !force) || noupdate)
360 
361  /*
362  * Adjust fields if required by switches. (Do this now so that printout,
363  * if any, includes these values.)
364  */
365  if (set_xid_epoch != -1)
367 
368  if (set_xid != 0)
369  {
370  ControlFile.checkPointCopy.nextXid = set_xid;
371 
372  /*
373  * For the moment, just set oldestXid to a value that will force
374  * immediate autovacuum-for-wraparound. It's not clear whether adding
375  * user control of this is useful, so let's just do something that's
376  * reasonably safe. The magic constant here corresponds to the
377  * maximum allowed value of autovacuum_freeze_max_age.
378  */
379  ControlFile.checkPointCopy.oldestXid = set_xid - 2000000000;
382  ControlFile.checkPointCopy.oldestXidDB = InvalidOid;
383  }
384 
385  if (set_oldest_commit_ts_xid != 0)
387  if (set_newest_commit_ts_xid != 0)
389 
390  if (set_oid != 0)
391  ControlFile.checkPointCopy.nextOid = set_oid;
392 
393  if (set_mxid != 0)
394  {
395  ControlFile.checkPointCopy.nextMulti = set_mxid;
396 
397  ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
398  if (ControlFile.checkPointCopy.oldestMulti < FirstMultiXactId)
401  }
402 
403  if (set_mxoff != -1)
405 
406  if (minXlogTli > ControlFile.checkPointCopy.ThisTimeLineID)
407  {
410  }
411 
414 
415  /*
416  * If we had to guess anything, and -f was not given, just print the
417  * guessed values and exit. Also print if -n is given.
418  */
419  if ((guessed && !force) || noupdate)
420  {
422  if (!noupdate)
423  {
424  printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
425  exit(1);
426  }
427  else
428  exit(0);
429  }
430 
431  /*
432  * Don't reset from a dirty pg_control without -f, either.
433  */
434  if (ControlFile.state != DB_SHUTDOWNED && !force)
435  {
436  printf(_("The database server was not shut down cleanly.\n"
437  "Resetting the write-ahead log might cause data to be lost.\n"
438  "If you want to proceed anyway, use -f to force reset.\n"));
439  exit(1);
440  }
441 
442  /*
443  * Else, do the dirty deed.
444  */
448  WriteEmptyXLOG();
449 
450  printf(_("Write-ahead log reset\n"));
451  return 0;
452 }
453 
454 
455 /*
456  * Try to read the existing pg_control file.
457  *
458  * This routine is also responsible for updating old pg_control versions
459  * to the current format. (Currently we don't do anything of the sort.)
460  */
461 static bool
463 {
464  int fd;
465  int len;
466  char *buffer;
467  pg_crc32c crc;
468 
469  if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
470  {
471  /*
472  * If pg_control is not there at all, or we can't read it, the odds
473  * are we've been handed a bad DataDir path, so give up. User can do
474  * "touch pg_control" to force us to proceed.
475  */
476  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
478  if (errno == ENOENT)
479  fprintf(stderr, _("If you are sure the data directory path is correct, execute\n"
480  " touch %s\n"
481  "and try again.\n"),
483  exit(1);
484  }
485 
486  /* Use malloc to ensure we have a maxaligned buffer */
487  buffer = (char *) pg_malloc(PG_CONTROL_SIZE);
488 
489  len = read(fd, buffer, PG_CONTROL_SIZE);
490  if (len < 0)
491  {
492  fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
494  exit(1);
495  }
496  close(fd);
497 
498  if (len >= sizeof(ControlFileData) &&
499  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
500  {
501  /* Check the CRC. */
502  INIT_CRC32C(crc);
503  COMP_CRC32C(crc,
504  buffer,
505  offsetof(ControlFileData, crc));
506  FIN_CRC32C(crc);
507 
508  if (EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
509  {
510  /* Valid data... */
511  memcpy(&ControlFile, buffer, sizeof(ControlFile));
512  return true;
513  }
514 
515  fprintf(stderr, _("%s: pg_control exists but has invalid CRC; proceed with caution\n"),
516  progname);
517  /* We will use the data anyway, but treat it as guessed. */
518  memcpy(&ControlFile, buffer, sizeof(ControlFile));
519  guessed = true;
520  return true;
521  }
522 
523  /* Looks like it's a mess. */
524  fprintf(stderr, _("%s: pg_control exists but is broken or unknown version; ignoring it\n"),
525  progname);
526  return false;
527 }
528 
529 
530 /*
531  * Guess at pg_control values when we can't read the old ones.
532  */
533 static void
535 {
536  uint64 sysidentifier;
537  struct timeval tv;
538 
539  /*
540  * Set up a completely default set of pg_control values.
541  */
542  guessed = true;
543  memset(&ControlFile, 0, sizeof(ControlFile));
544 
547 
548  /*
549  * Create a new unique installation identifier, since we can no longer use
550  * any old XLOG records. See notes in xlog.c about the algorithm.
551  */
552  gettimeofday(&tv, NULL);
553  sysidentifier = ((uint64) tv.tv_sec) << 32;
554  sysidentifier |= ((uint64) tv.tv_usec) << 12;
555  sysidentifier |= getpid() & 0xFFF;
556 
557  ControlFile.system_identifier = sysidentifier;
558 
559  ControlFile.checkPointCopy.redo = SizeOfXLogLongPHD;
560  ControlFile.checkPointCopy.ThisTimeLineID = 1;
561  ControlFile.checkPointCopy.PrevTimeLineID = 1;
562  ControlFile.checkPointCopy.fullPageWrites = false;
563  ControlFile.checkPointCopy.nextXidEpoch = 0;
567  ControlFile.checkPointCopy.nextMultiOffset = 0;
569  ControlFile.checkPointCopy.oldestXidDB = InvalidOid;
572  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
574 
575  ControlFile.state = DB_SHUTDOWNED;
576  ControlFile.time = (pg_time_t) time(NULL);
577  ControlFile.checkPoint = ControlFile.checkPointCopy.redo;
578  ControlFile.unloggedLSN = 1;
579 
580  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
581 
582  ControlFile.wal_level = WAL_LEVEL_MINIMAL;
583  ControlFile.wal_log_hints = false;
584  ControlFile.track_commit_timestamp = false;
585  ControlFile.MaxConnections = 100;
586  ControlFile.max_worker_processes = 8;
587  ControlFile.max_prepared_xacts = 0;
588  ControlFile.max_locks_per_xact = 64;
589 
590  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
591  ControlFile.floatFormat = FLOATFORMAT_VALUE;
592  ControlFile.blcksz = BLCKSZ;
593  ControlFile.relseg_size = RELSEG_SIZE;
594  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
595  ControlFile.xlog_seg_size = XLOG_SEG_SIZE;
596  ControlFile.nameDataLen = NAMEDATALEN;
597  ControlFile.indexMaxKeys = INDEX_MAX_KEYS;
599  ControlFile.loblksize = LOBLKSIZE;
600  ControlFile.float4ByVal = FLOAT4PASSBYVAL;
601  ControlFile.float8ByVal = FLOAT8PASSBYVAL;
602 
603  /*
604  * XXX eventually, should try to grovel through old XLOG to develop more
605  * accurate values for TimeLineID, nextXID, etc.
606  */
607 }
608 
609 
610 /*
611  * Print the guessed pg_control values when we had to guess.
612  *
613  * NB: this display should be just those fields that will not be
614  * reset by RewriteControlFile().
615  */
616 static void
618 {
619  char sysident_str[32];
620 
621  if (guessed)
622  printf(_("Guessed pg_control values:\n\n"));
623  else
624  printf(_("Current pg_control values:\n\n"));
625 
626  /*
627  * Format system_identifier separately to keep platform-dependent format
628  * code out of the translatable message string.
629  */
630  snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
631  ControlFile.system_identifier);
632 
633  printf(_("pg_control version number: %u\n"),
634  ControlFile.pg_control_version);
635  printf(_("Catalog version number: %u\n"),
636  ControlFile.catalog_version_no);
637  printf(_("Database system identifier: %s\n"),
638  sysident_str);
639  printf(_("Latest checkpoint's TimeLineID: %u\n"),
640  ControlFile.checkPointCopy.ThisTimeLineID);
641  printf(_("Latest checkpoint's full_page_writes: %s\n"),
642  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
643  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
644  ControlFile.checkPointCopy.nextXidEpoch,
645  ControlFile.checkPointCopy.nextXid);
646  printf(_("Latest checkpoint's NextOID: %u\n"),
647  ControlFile.checkPointCopy.nextOid);
648  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
649  ControlFile.checkPointCopy.nextMulti);
650  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
651  ControlFile.checkPointCopy.nextMultiOffset);
652  printf(_("Latest checkpoint's oldestXID: %u\n"),
653  ControlFile.checkPointCopy.oldestXid);
654  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
655  ControlFile.checkPointCopy.oldestXidDB);
656  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
657  ControlFile.checkPointCopy.oldestActiveXid);
658  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
659  ControlFile.checkPointCopy.oldestMulti);
660  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
661  ControlFile.checkPointCopy.oldestMultiDB);
662  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
663  ControlFile.checkPointCopy.oldestCommitTsXid);
664  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
665  ControlFile.checkPointCopy.newestCommitTsXid);
666  printf(_("Maximum data alignment: %u\n"),
667  ControlFile.maxAlign);
668  /* we don't print floatFormat since can't say much useful about it */
669  printf(_("Database block size: %u\n"),
670  ControlFile.blcksz);
671  printf(_("Blocks per segment of large relation: %u\n"),
672  ControlFile.relseg_size);
673  printf(_("WAL block size: %u\n"),
674  ControlFile.xlog_blcksz);
675  printf(_("Bytes per WAL segment: %u\n"),
676  ControlFile.xlog_seg_size);
677  printf(_("Maximum length of identifiers: %u\n"),
678  ControlFile.nameDataLen);
679  printf(_("Maximum columns in an index: %u\n"),
680  ControlFile.indexMaxKeys);
681  printf(_("Maximum size of a TOAST chunk: %u\n"),
682  ControlFile.toast_max_chunk_size);
683  printf(_("Size of a large-object chunk: %u\n"),
684  ControlFile.loblksize);
685  /* This is no longer configurable, but users may still expect to see it: */
686  printf(_("Date/time type storage: %s\n"),
687  _("64-bit integers"));
688  printf(_("Float4 argument passing: %s\n"),
689  (ControlFile.float4ByVal ? _("by value") : _("by reference")));
690  printf(_("Float8 argument passing: %s\n"),
691  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
692  printf(_("Data page checksum version: %u\n"),
693  ControlFile.data_checksum_version);
694 }
695 
696 
697 /*
698  * Print the values to be changed.
699  */
700 static void
702 {
703  char fname[MAXFNAMELEN];
704 
705  /* This will be always printed in order to keep format same. */
706  printf(_("\n\nValues to be changed:\n\n"));
707 
709  printf(_("First log segment after reset: %s\n"), fname);
710 
711  if (set_mxid != 0)
712  {
713  printf(_("NextMultiXactId: %u\n"),
714  ControlFile.checkPointCopy.nextMulti);
715  printf(_("OldestMultiXid: %u\n"),
716  ControlFile.checkPointCopy.oldestMulti);
717  printf(_("OldestMulti's DB: %u\n"),
718  ControlFile.checkPointCopy.oldestMultiDB);
719  }
720 
721  if (set_mxoff != -1)
722  {
723  printf(_("NextMultiOffset: %u\n"),
724  ControlFile.checkPointCopy.nextMultiOffset);
725  }
726 
727  if (set_oid != 0)
728  {
729  printf(_("NextOID: %u\n"),
730  ControlFile.checkPointCopy.nextOid);
731  }
732 
733  if (set_xid != 0)
734  {
735  printf(_("NextXID: %u\n"),
736  ControlFile.checkPointCopy.nextXid);
737  printf(_("OldestXID: %u\n"),
738  ControlFile.checkPointCopy.oldestXid);
739  printf(_("OldestXID's DB: %u\n"),
740  ControlFile.checkPointCopy.oldestXidDB);
741  }
742 
743  if (set_xid_epoch != -1)
744  {
745  printf(_("NextXID epoch: %u\n"),
746  ControlFile.checkPointCopy.nextXidEpoch);
747  }
748 
749  if (set_oldest_commit_ts_xid != 0)
750  {
751  printf(_("oldestCommitTsXid: %u\n"),
752  ControlFile.checkPointCopy.oldestCommitTsXid);
753  }
754  if (set_newest_commit_ts_xid != 0)
755  {
756  printf(_("newestCommitTsXid: %u\n"),
757  ControlFile.checkPointCopy.newestCommitTsXid);
758  }
759 }
760 
761 
762 /*
763  * Write out the new pg_control file.
764  */
765 static void
767 {
768  int fd;
769  char buffer[PG_CONTROL_SIZE]; /* need not be aligned */
770 
771  /*
772  * Adjust fields as needed to force an empty XLOG starting at
773  * newXlogSegNo.
774  */
776  ControlFile.checkPointCopy.redo);
777  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
778 
779  ControlFile.state = DB_SHUTDOWNED;
780  ControlFile.time = (pg_time_t) time(NULL);
781  ControlFile.checkPoint = ControlFile.checkPointCopy.redo;
782  ControlFile.prevCheckPoint = 0;
783  ControlFile.minRecoveryPoint = 0;
784  ControlFile.minRecoveryPointTLI = 0;
785  ControlFile.backupStartPoint = 0;
786  ControlFile.backupEndPoint = 0;
787  ControlFile.backupEndRequired = false;
788 
789  /*
790  * Force the defaults for max_* settings. The values don't really matter
791  * as long as wal_level='minimal'; the postmaster will reset these fields
792  * anyway at startup.
793  */
794  ControlFile.wal_level = WAL_LEVEL_MINIMAL;
795  ControlFile.wal_log_hints = false;
796  ControlFile.track_commit_timestamp = false;
797  ControlFile.MaxConnections = 100;
798  ControlFile.max_worker_processes = 8;
799  ControlFile.max_prepared_xacts = 0;
800  ControlFile.max_locks_per_xact = 64;
801 
802  /* Now we can force the recorded xlog seg size to the right thing. */
803  ControlFile.xlog_seg_size = XLogSegSize;
804 
805  /* Contents are protected with a CRC */
806  INIT_CRC32C(ControlFile.crc);
807  COMP_CRC32C(ControlFile.crc,
808  (char *) &ControlFile,
809  offsetof(ControlFileData, crc));
810  FIN_CRC32C(ControlFile.crc);
811 
812  /*
813  * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
814  * excess over sizeof(ControlFileData). This reduces the odds of
815  * premature-EOF errors when reading pg_control. We'll still fail when we
816  * check the contents of the file, but hopefully with a more specific
817  * error than "couldn't read pg_control".
818  */
819  if (sizeof(ControlFileData) > PG_CONTROL_SIZE)
820  {
821  fprintf(stderr,
822  _("%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n"),
823  progname);
824  exit(1);
825  }
826 
827  memset(buffer, 0, PG_CONTROL_SIZE);
828  memcpy(buffer, &ControlFile, sizeof(ControlFileData));
829 
831 
832  fd = open(XLOG_CONTROL_FILE,
833  O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
834  S_IRUSR | S_IWUSR);
835  if (fd < 0)
836  {
837  fprintf(stderr, _("%s: could not create pg_control file: %s\n"),
838  progname, strerror(errno));
839  exit(1);
840  }
841 
842  errno = 0;
843  if (write(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE)
844  {
845  /* if write didn't set errno, assume problem is no disk space */
846  if (errno == 0)
847  errno = ENOSPC;
848  fprintf(stderr, _("%s: could not write pg_control file: %s\n"),
849  progname, strerror(errno));
850  exit(1);
851  }
852 
853  if (fsync(fd) != 0)
854  {
855  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
856  exit(1);
857  }
858 
859  close(fd);
860 }
861 
862 
863 /*
864  * Scan existing XLOG files and determine the highest existing WAL address
865  *
866  * On entry, ControlFile.checkPointCopy.redo and ControlFile.xlog_seg_size
867  * are assumed valid (note that we allow the old xlog seg size to differ
868  * from what we're using). On exit, newXlogId and newXlogSeg are set to
869  * suitable values for the beginning of replacement WAL (in our seg size).
870  */
871 static void
873 {
874  DIR *xldir;
875  struct dirent *xlde;
876  uint64 segs_per_xlogid;
877  uint64 xlogbytepos;
878 
879  /*
880  * Initialize the max() computation using the last checkpoint address from
881  * old pg_control. Note that for the moment we are working with segment
882  * numbering according to the old xlog seg size.
883  */
884  segs_per_xlogid = (UINT64CONST(0x0000000100000000) / ControlFile.xlog_seg_size);
885  newXlogSegNo = ControlFile.checkPointCopy.redo / ControlFile.xlog_seg_size;
886 
887  /*
888  * Scan the pg_wal directory to find existing WAL segment files. We assume
889  * any present have been used; in most scenarios this should be
890  * conservative, because of xlog.c's attempts to pre-create files.
891  */
892  xldir = opendir(XLOGDIR);
893  if (xldir == NULL)
894  {
895  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
896  progname, XLOGDIR, strerror(errno));
897  exit(1);
898  }
899 
900  while (errno = 0, (xlde = readdir(xldir)) != NULL)
901  {
902  if (IsXLogFileName(xlde->d_name) ||
904  {
905  unsigned int tli,
906  log,
907  seg;
908  XLogSegNo segno;
909 
910  /*
911  * Note: We don't use XLogFromFileName here, because we want to
912  * use the segment size from the control file, not the size the
913  * pg_resetwal binary was compiled with
914  */
915  sscanf(xlde->d_name, "%08X%08X%08X", &tli, &log, &seg);
916  segno = ((uint64) log) * segs_per_xlogid + seg;
917 
918  /*
919  * Note: we take the max of all files found, regardless of their
920  * timelines. Another possibility would be to ignore files of
921  * timelines other than the target TLI, but this seems safer.
922  * Better too large a result than too small...
923  */
924  if (segno > newXlogSegNo)
925  newXlogSegNo = segno;
926  }
927  }
928 
929  if (errno)
930  {
931  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
932  progname, XLOGDIR, strerror(errno));
933  exit(1);
934  }
935 
936  if (closedir(xldir))
937  {
938  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
939  progname, XLOGDIR, strerror(errno));
940  exit(1);
941  }
942 
943  /*
944  * Finally, convert to new xlog seg size, and advance by one to ensure we
945  * are in virgin territory.
946  */
947  xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
948  newXlogSegNo = (xlogbytepos + XLogSegSize - 1) / XLogSegSize;
949  newXlogSegNo++;
950 }
951 
952 
953 /*
954  * Remove existing XLOG files
955  */
956 static void
958 {
959  DIR *xldir;
960  struct dirent *xlde;
961  char path[MAXPGPATH + sizeof(XLOGDIR)];
962 
963  xldir = opendir(XLOGDIR);
964  if (xldir == NULL)
965  {
966  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
967  progname, XLOGDIR, strerror(errno));
968  exit(1);
969  }
970 
971  while (errno = 0, (xlde = readdir(xldir)) != NULL)
972  {
973  if (IsXLogFileName(xlde->d_name) ||
975  {
976  snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
977  if (unlink(path) < 0)
978  {
979  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
980  progname, path, strerror(errno));
981  exit(1);
982  }
983  }
984  }
985 
986  if (errno)
987  {
988  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
989  progname, XLOGDIR, strerror(errno));
990  exit(1);
991  }
992 
993  if (closedir(xldir))
994  {
995  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
996  progname, XLOGDIR, strerror(errno));
997  exit(1);
998  }
999 }
1000 
1001 
1002 /*
1003  * Remove existing archive status files
1004  */
1005 static void
1007 {
1008 #define ARCHSTATDIR XLOGDIR "/archive_status"
1009 
1010  DIR *xldir;
1011  struct dirent *xlde;
1012  char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1013 
1014  xldir = opendir(ARCHSTATDIR);
1015  if (xldir == NULL)
1016  {
1017  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
1018  progname, ARCHSTATDIR, strerror(errno));
1019  exit(1);
1020  }
1021 
1022  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1023  {
1024  if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1025  (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1026  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1027  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1028  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1029  {
1030  snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1031  if (unlink(path) < 0)
1032  {
1033  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
1034  progname, path, strerror(errno));
1035  exit(1);
1036  }
1037  }
1038  }
1039 
1040  if (errno)
1041  {
1042  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
1043  progname, ARCHSTATDIR, strerror(errno));
1044  exit(1);
1045  }
1046 
1047  if (closedir(xldir))
1048  {
1049  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1050  progname, ARCHSTATDIR, strerror(errno));
1051  exit(1);
1052  }
1053 }
1054 
1055 
1056 /*
1057  * Write an empty XLOG file, containing only the checkpoint record
1058  * already set up in ControlFile.
1059  */
1060 static void
1062 {
1063  char *buffer;
1064  XLogPageHeader page;
1065  XLogLongPageHeader longpage;
1066  XLogRecord *record;
1067  pg_crc32c crc;
1068  char path[MAXPGPATH];
1069  int fd;
1070  int nbytes;
1071  char *recptr;
1072 
1073  /* Use malloc() to ensure buffer is MAXALIGNED */
1074  buffer = (char *) pg_malloc(XLOG_BLCKSZ);
1075  page = (XLogPageHeader) buffer;
1076  memset(buffer, 0, XLOG_BLCKSZ);
1077 
1078  /* Set up the XLOG page header */
1079  page->xlp_magic = XLOG_PAGE_MAGIC;
1080  page->xlp_info = XLP_LONG_HEADER;
1081  page->xlp_tli = ControlFile.checkPointCopy.ThisTimeLineID;
1082  page->xlp_pageaddr = ControlFile.checkPointCopy.redo - SizeOfXLogLongPHD;
1083  longpage = (XLogLongPageHeader) page;
1084  longpage->xlp_sysid = ControlFile.system_identifier;
1085  longpage->xlp_seg_size = XLogSegSize;
1086  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1087 
1088  /* Insert the initial checkpoint record */
1089  recptr = (char *) page + SizeOfXLogLongPHD;
1090  record = (XLogRecord *) recptr;
1091  record->xl_prev = 0;
1092  record->xl_xid = InvalidTransactionId;
1095  record->xl_rmid = RM_XLOG_ID;
1096 
1097  recptr += SizeOfXLogRecord;
1098  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1099  *(recptr++) = sizeof(CheckPoint);
1100  memcpy(recptr, &ControlFile.checkPointCopy,
1101  sizeof(CheckPoint));
1102 
1103  INIT_CRC32C(crc);
1104  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1105  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1106  FIN_CRC32C(crc);
1107  record->xl_crc = crc;
1108 
1109  /* Write the first page */
1111 
1112  unlink(path);
1113 
1114  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1115  S_IRUSR | S_IWUSR);
1116  if (fd < 0)
1117  {
1118  fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
1119  progname, path, strerror(errno));
1120  exit(1);
1121  }
1122 
1123  errno = 0;
1124  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1125  {
1126  /* if write didn't set errno, assume problem is no disk space */
1127  if (errno == 0)
1128  errno = ENOSPC;
1129  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1130  progname, path, strerror(errno));
1131  exit(1);
1132  }
1133 
1134  /* Fill the rest of the file with zeroes */
1135  memset(buffer, 0, XLOG_BLCKSZ);
1136  for (nbytes = XLOG_BLCKSZ; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
1137  {
1138  errno = 0;
1139  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1140  {
1141  if (errno == 0)
1142  errno = ENOSPC;
1143  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1144  progname, path, strerror(errno));
1145  exit(1);
1146  }
1147  }
1148 
1149  if (fsync(fd) != 0)
1150  {
1151  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
1152  exit(1);
1153  }
1154 
1155  close(fd);
1156 }
1157 
1158 
1159 static void
1160 usage(void)
1161 {
1162  printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1163  printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
1164  printf(_("Options:\n"));
1165  printf(_(" -c XID,XID set oldest and newest transactions bearing commit timestamp\n"));
1166  printf(_(" (zero in either value means no change)\n"));
1167  printf(_(" [-D] DATADIR data directory\n"));
1168  printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
1169  printf(_(" -f force update to be done\n"));
1170  printf(_(" -l WALFILE force minimum WAL starting location for new write-ahead log\n"));
1171  printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
1172  printf(_(" -n no update, just show what would be done (for testing)\n"));
1173  printf(_(" -o OID set next OID\n"));
1174  printf(_(" -O OFFSET set next multitransaction offset\n"));
1175  printf(_(" -V, --version output version information, then exit\n"));
1176  printf(_(" -x XID set next transaction ID\n"));
1177  printf(_(" -?, --help show this help, then exit\n"));
1178  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1179 }
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:617
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define XLogSegSize
Definition: xlog_internal.h:92
#define LOBLKSIZE
Definition: large_object.h:72
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int max_locks_per_xact
Definition: pg_control.h:185
static MultiXactId set_mxid
Definition: pg_resetwal.c:69
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:184
int64 pg_time_t
Definition: pgtime.h:23
uint32 MultiXactOffset
Definition: c.h:409
static void usage(void)
Definition: pg_resetwal.c:1160
static TransactionId set_xid
Definition: pg_resetwal.c:65
pg_time_t time
Definition: pg_control.h:131
uint32 TransactionId
Definition: c.h:397
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
#define write(a, b, c)
Definition: win32.h:14
const char * get_progname(const char *argv0)
Definition: path.c:453
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:200
int max_worker_processes
Definition: pg_control.h:183
uint32 pg_crc32c
Definition: pg_crc32c.h:38
TransactionId oldestActiveXid
Definition: pg_control.h:62
static void PrintNewControlValues(void)
Definition: pg_resetwal.c:701
uint32 nameDataLen
Definition: pg_control.h:214
#define XLogFileName(fname, tli, logSegNo)
MultiXactId oldestMulti
Definition: pg_control.h:48
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:872
TimeLineID PrevTimeLineID
Definition: pg_control.h:38
int closedir(DIR *)
Definition: dirent.c:113
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1061
#define CATALOG_VERSION_NO
Definition: catversion.h:56
#define PG_CONTROL_VERSION
Definition: pg_control.h:26
static Oid set_oid
Definition: pg_resetwal.c:68
RmgrId xl_rmid
Definition: xlogrecord.h:47
#define PG_CONTROL_SIZE
Definition: pg_control.h:245
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
uint32 pg_control_version
Definition: pg_control.h:124
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
CheckPoint checkPointCopy
Definition: pg_control.h:135
uint32 xlog_blcksz
Definition: pg_control.h:211
TransactionId oldestXid
Definition: pg_control.h:46
unsigned int Oid
Definition: postgres_ext.h:31
TransactionId nextXid
Definition: pg_control.h:42
Definition: dirent.h:9
pg_time_t time
Definition: pg_control.h:50
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1038
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:72
#define XLogSegNoOffsetToRecPtr(segno, offset, dest)
Definition: xlog_internal.h:95
static bool ReadControlFile(void)
Definition: pg_resetwal.c:462
void get_restricted_token(const char *progname)
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:67
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:957
#define NAMEDATALEN
bool backupEndRequired
Definition: pg_control.h:174
MultiXactOffset nextMultiOffset
Definition: pg_control.h:45
TransactionId oldestCommitTsXid
Definition: pg_control.h:51
uint32 xlog_seg_size
Definition: pg_control.h:212
int optind
Definition: getopt.c:51
Definition: dirent.c:25
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1006
#define FirstNormalTransactionId
Definition: transam.h:34
#define IsXLogFileName(fname)
uint64 system_identifier
Definition: pg_control.h:109
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define MAXPGPATH
uint32 nextXidEpoch
Definition: pg_control.h:41
DIR * opendir(const char *)
Definition: dirent.c:33
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:66
#define XLogFilePath(path, tli, logSegNo)
uint32 data_checksum_version
Definition: pg_control.h:225
char * c
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:66
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
uint64 XLogSegNo
Definition: xlogdefs.h:34
#define InvalidTransactionId
Definition: transam.h:31
unsigned int uint32
Definition: c.h:268
pg_crc32c crc
Definition: pg_control.h:235
#define FirstBootstrapObjectId
Definition: transam.h:93
#define FirstMultiXactId
Definition: multixact.h:24
uint32 loblksize
Definition: pg_control.h:218
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
static const char * progname
Definition: pg_resetwal.c:63
int unlink(const char *filename)
#define fsync(fd)
Definition: win32.h:62
uint32 indexMaxKeys
Definition: pg_control.h:215
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
static bool guessed
Definition: pg_resetwal.c:62
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define MAXFNAMELEN
#define TOAST_MAX_CHUNK_SIZE
Definition: tuptoaster.h:91
TransactionId newestCommitTsXid
Definition: pg_control.h:53
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1012
#define XLOGDIR
#define UINT64CONST(x)
Definition: c.h:311
Oid oldestMultiDB
Definition: pg_control.h:49
XLogRecPtr prevCheckPoint
Definition: pg_control.h:133
uint32 toast_max_chunk_size
Definition: pg_control.h:217
#define XLOG_CONTROL_FILE
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:43
XLogRecPtr backupEndPoint
Definition: pg_control.h:173
bool fullPageWrites
Definition: pg_control.h:40
TransactionId MultiXactId
Definition: c.h:407
#define NULL
Definition: c.h:229
bool track_commit_timestamp
Definition: pg_control.h:186
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
Oid oldestXidDB
Definition: pg_control.h:47
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
int main(int argc, char *argv[])
Definition: pg_resetwal.c:87
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
double floatFormat
Definition: pg_control.h:201
#define INDEX_MAX_KEYS
uint8 xl_info
Definition: xlogrecord.h:46
MultiXactId nextMulti
Definition: pg_control.h:44
static void RewriteControlFile(void)
Definition: pg_resetwal.c:766
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:70
uint32 catalog_version_no
Definition: pg_control.h:125
struct dirent * readdir(DIR *)
Definition: dirent.c:78
pg_crc32c xl_crc
Definition: xlogrecord.h:49
struct CheckPoint CheckPoint
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
TransactionId xl_xid
Definition: xlogrecord.h:44
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
static void GuessControlValues(void)
Definition: pg_resetwal.c:534
static uint32 minXlogTli
Definition: pg_resetwal.c:71
#define IsPartialXLogFileName(fname)
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:550
#define ARCHSTATDIR
char * optarg
Definition: getopt.c:53
const char * strerror(int errnum)
Definition: strerror.c:19
char * DataDir
Definition: globals.c:59
#define XLOG_FNAME_LEN
char d_name[MAX_PATH]
Definition: dirent.h:14
#define close(a)
Definition: win32.h:12
#define FLOATFORMAT_VALUE
Definition: pg_control.h:202
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define XLogFromFileName(fname, tli, logSegNo)
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
#define UINT64_FORMAT
Definition: c.h:316
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:72
XLogRecPtr backupStartPoint
Definition: pg_control.h:172
uint32 relseg_size
Definition: pg_control.h:209
XLogRecPtr checkPoint
Definition: pg_control.h:132
XLogRecPtr redo
Definition: pg_control.h:35
#define read(a, b, c)
Definition: win32.h:13
#define offsetof(type, field)
Definition: c.h:555
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
static uint32 set_xid_epoch
Definition: pg_resetwal.c:64
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72