PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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/transam.h"
#include "access/tuptoaster.h"
#include "access/multixact.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "common/fe_memutils.h"
#include "common/restricted_token.h"
#include "storage/large_object.h"
#include "pg_getopt.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 ReadControlFile (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_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 uint32 minXlogTli = 0
 
static XLogSegNo minXlogSegNo = 0
 

Macro Definition Documentation

#define ARCHSTATDIR   XLOGDIR "/archive_status"
#define FRONTEND   1

Definition at line 36 of file pg_resetwal.c.

Function Documentation

static void CheckDataVersion ( void  )
static

Definition at line 472 of file pg_resetwal.c.

References _, NULL, progname, and strerror().

Referenced by main().

473 {
474  const char *ver_file = "PG_VERSION";
475  FILE *ver_fd;
476  char rawline[64];
477  int len;
478 
479  if ((ver_fd = fopen(ver_file, "r")) == NULL)
480  {
481  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
482  progname, ver_file, strerror(errno));
483  exit(1);
484  }
485 
486  /* version number has to be the first line read */
487  if (!fgets(rawline, sizeof(rawline), ver_fd))
488  {
489  if (!ferror(ver_fd))
490  {
491  fprintf(stderr, _("%s: unexpected empty file \"%s\"\n"),
492  progname, ver_file);
493  }
494  else
495  {
496  fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
497  progname, ver_file, strerror(errno));
498  }
499  exit(1);
500  }
501 
502  /* remove trailing newline, handling Windows newlines as well */
503  len = strlen(rawline);
504  if (len > 0 && rawline[len - 1] == '\n')
505  {
506  rawline[--len] = '\0';
507  if (len > 0 && rawline[len - 1] == '\r')
508  rawline[--len] = '\0';
509  }
510 
511  if (strcmp(rawline, PG_MAJORVERSION) != 0)
512  {
513  fprintf(stderr, _("%s: data directory is of wrong version\n"
514  "File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".\n"),
515  progname, ver_file, rawline, PG_MAJORVERSION);
516  exit(1);
517  }
518 
519  fclose(ver_fd);
520 }
static const char * progname
Definition: pg_resetwal.c:63
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
#define _(x)
Definition: elog.c:84
static void FindEndOfXLOG ( void  )
static

Definition at line 941 of file pg_resetwal.c.

References _, ControlFileData::checkPointCopy, closedir(), dirent::d_name, IsPartialXLogFileName, IsXLogFileName, newXlogSegNo, NULL, opendir(), progname, readdir(), CheckPoint::redo, strerror(), UINT64CONST, ControlFileData::xlog_seg_size, XLOGDIR, and XLogSegSize.

Referenced by main().

942 {
943  DIR *xldir;
944  struct dirent *xlde;
945  uint64 segs_per_xlogid;
946  uint64 xlogbytepos;
947 
948  /*
949  * Initialize the max() computation using the last checkpoint address from
950  * old pg_control. Note that for the moment we are working with segment
951  * numbering according to the old xlog seg size.
952  */
953  segs_per_xlogid = (UINT64CONST(0x0000000100000000) / ControlFile.xlog_seg_size);
955 
956  /*
957  * Scan the pg_wal directory to find existing WAL segment files. We assume
958  * any present have been used; in most scenarios this should be
959  * conservative, because of xlog.c's attempts to pre-create files.
960  */
961  xldir = opendir(XLOGDIR);
962  if (xldir == NULL)
963  {
964  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
965  progname, XLOGDIR, strerror(errno));
966  exit(1);
967  }
968 
969  while (errno = 0, (xlde = readdir(xldir)) != NULL)
970  {
971  if (IsXLogFileName(xlde->d_name) ||
973  {
974  unsigned int tli,
975  log,
976  seg;
977  XLogSegNo segno;
978 
979  /*
980  * Note: We don't use XLogFromFileName here, because we want to
981  * use the segment size from the control file, not the size the
982  * pg_resetwal binary was compiled with
983  */
984  sscanf(xlde->d_name, "%08X%08X%08X", &tli, &log, &seg);
985  segno = ((uint64) log) * segs_per_xlogid + seg;
986 
987  /*
988  * Note: we take the max of all files found, regardless of their
989  * timelines. Another possibility would be to ignore files of
990  * timelines other than the target TLI, but this seems safer.
991  * Better too large a result than too small...
992  */
993  if (segno > newXlogSegNo)
994  newXlogSegNo = segno;
995  }
996  }
997 
998  if (errno)
999  {
1000  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
1001  progname, XLOGDIR, strerror(errno));
1002  exit(1);
1003  }
1004 
1005  if (closedir(xldir))
1006  {
1007  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1008  progname, XLOGDIR, strerror(errno));
1009  exit(1);
1010  }
1011 
1012  /*
1013  * Finally, convert to new xlog seg size, and advance by one to ensure we
1014  * are in virgin territory.
1015  */
1016  xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
1017  newXlogSegNo = (xlogbytepos + XLogSegSize - 1) / XLogSegSize;
1018  newXlogSegNo++;
1019 }
#define XLogSegSize
Definition: xlog_internal.h:92
int closedir(DIR *)
Definition: dirent.c:111
CheckPoint checkPointCopy
Definition: pg_control.h:132
Definition: dirent.h:9
uint32 xlog_seg_size
Definition: pg_control.h:209
Definition: dirent.c:25
#define IsXLogFileName(fname)
DIR * opendir(const char *)
Definition: dirent.c:33
uint64 XLogSegNo
Definition: xlogdefs.h:34
static const char * progname
Definition: pg_resetwal.c:63
#define XLOGDIR
#define UINT64CONST(x)
Definition: c.h:311
#define NULL
Definition: c.h:229
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
struct dirent * readdir(DIR *)
Definition: dirent.c:77
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
#define IsPartialXLogFileName(fname)
const char * strerror(int errnum)
Definition: strerror.c:19
char d_name[MAX_PATH]
Definition: dirent.h:14
#define _(x)
Definition: elog.c:84
XLogRecPtr redo
Definition: pg_control.h:36
static void GuessControlValues ( void  )
static

Definition at line 602 of file pg_resetwal.c.

References ControlFileData::blcksz, CATALOG_VERSION_NO, ControlFileData::catalog_version_no, ControlFileData::checkPoint, ControlFileData::checkPointCopy, DB_SHUTDOWNED, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, ControlFileData::float4ByVal, ControlFileData::float8ByVal, ControlFileData::floatFormat, FLOATFORMAT_VALUE, CheckPoint::fullPageWrites, gettimeofday(), guessed, INDEX_MAX_KEYS, ControlFileData::indexMaxKeys, InvalidOid, InvalidTransactionId, LOBLKSIZE, ControlFileData::loblksize, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_worker_processes, ControlFileData::maxAlign, ControlFileData::MaxConnections, NAMEDATALEN, ControlFileData::nameDataLen, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::nextXidEpoch, NULL, 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().

603 {
604  uint64 sysidentifier;
605  struct timeval tv;
606 
607  /*
608  * Set up a completely default set of pg_control values.
609  */
610  guessed = true;
611  memset(&ControlFile, 0, sizeof(ControlFile));
612 
615 
616  /*
617  * Create a new unique installation identifier, since we can no longer use
618  * any old XLOG records. See notes in xlog.c about the algorithm.
619  */
620  gettimeofday(&tv, NULL);
621  sysidentifier = ((uint64) tv.tv_sec) << 32;
622  sysidentifier |= ((uint64) tv.tv_usec) << 12;
623  sysidentifier |= getpid() & 0xFFF;
624 
625  ControlFile.system_identifier = sysidentifier;
626 
642 
644  ControlFile.time = (pg_time_t) time(NULL);
647 
648  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
649 
651  ControlFile.wal_log_hints = false;
657 
658  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
660  ControlFile.blcksz = BLCKSZ;
661  ControlFile.relseg_size = RELSEG_SIZE;
662  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
663  ControlFile.xlog_seg_size = XLOG_SEG_SIZE;
668  ControlFile.float4ByVal = FLOAT4PASSBYVAL;
669  ControlFile.float8ByVal = FLOAT8PASSBYVAL;
670 
671  /*
672  * XXX eventually, should try to grovel through old XLOG to develop more
673  * accurate values for TimeLineID, nextXID, etc.
674  */
675 }
#define LOBLKSIZE
Definition: large_object.h:72
int max_locks_per_xact
Definition: pg_control.h:182
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:181
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:128
int max_worker_processes
Definition: pg_control.h:180
TransactionId oldestActiveXid
Definition: pg_control.h:63
uint32 nameDataLen
Definition: pg_control.h:211
MultiXactId oldestMulti
Definition: pg_control.h:49
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
#define CATALOG_VERSION_NO
Definition: catversion.h:56
#define PG_CONTROL_VERSION
Definition: pg_control.h:24
uint32 pg_control_version
Definition: pg_control.h:121
CheckPoint checkPointCopy
Definition: pg_control.h:132
uint32 xlog_blcksz
Definition: pg_control.h:208
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define NAMEDATALEN
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
uint32 xlog_seg_size
Definition: pg_control.h:209
#define FirstNormalTransactionId
Definition: transam.h:34
uint64 system_identifier
Definition: pg_control.h:106
uint32 nextXidEpoch
Definition: pg_control.h:42
XLogRecPtr unloggedLSN
Definition: pg_control.h:134
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
#define FirstMultiXactId
Definition: multixact.h:24
uint32 loblksize
Definition: pg_control.h:215
uint32 indexMaxKeys
Definition: pg_control.h:212
static bool guessed
Definition: pg_resetwal.c:62
#define TOAST_MAX_CHUNK_SIZE
Definition: tuptoaster.h:91
Oid oldestMultiDB
Definition: pg_control.h:50
uint32 toast_max_chunk_size
Definition: pg_control.h:214
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:44
bool fullPageWrites
Definition: pg_control.h:41
#define NULL
Definition: c.h:229
bool track_commit_timestamp
Definition: pg_control.h:183
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
double floatFormat
Definition: pg_control.h:198
#define INDEX_MAX_KEYS
MultiXactId nextMulti
Definition: pg_control.h:45
uint32 catalog_version_no
Definition: pg_control.h:122
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
#define FLOATFORMAT_VALUE
Definition: pg_control.h:199
uint32 relseg_size
Definition: pg_control.h:206
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void KillExistingArchiveStatus ( void  )
static

Definition at line 1075 of file pg_resetwal.c.

References _, ARCHSTATDIR, closedir(), dirent::d_name, MAXPGPATH, NULL, opendir(), progname, readdir(), snprintf(), strerror(), unlink(), and XLOG_FNAME_LEN.

Referenced by main().

1076 {
1077 #define ARCHSTATDIR XLOGDIR "/archive_status"
1078 
1079  DIR *xldir;
1080  struct dirent *xlde;
1081  char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1082 
1083  xldir = opendir(ARCHSTATDIR);
1084  if (xldir == NULL)
1085  {
1086  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
1087  progname, ARCHSTATDIR, strerror(errno));
1088  exit(1);
1089  }
1090 
1091  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1092  {
1093  if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1094  (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1095  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1096  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1097  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1098  {
1099  snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1100  if (unlink(path) < 0)
1101  {
1102  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
1103  progname, path, strerror(errno));
1104  exit(1);
1105  }
1106  }
1107  }
1108 
1109  if (errno)
1110  {
1111  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
1112  progname, ARCHSTATDIR, strerror(errno));
1113  exit(1);
1114  }
1115 
1116  if (closedir(xldir))
1117  {
1118  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1119  progname, ARCHSTATDIR, strerror(errno));
1120  exit(1);
1121  }
1122 }
int closedir(DIR *)
Definition: dirent.c:111
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * opendir(const char *)
Definition: dirent.c:33
static const char * progname
Definition: pg_resetwal.c:63
int unlink(const char *filename)
#define NULL
Definition: c.h:229
struct dirent * readdir(DIR *)
Definition: dirent.c:77
#define ARCHSTATDIR
const char * strerror(int errnum)
Definition: strerror.c:19
#define XLOG_FNAME_LEN
char d_name[MAX_PATH]
Definition: dirent.h:14
#define _(x)
Definition: elog.c:84
static void KillExistingXLOG ( void  )
static

Definition at line 1026 of file pg_resetwal.c.

References _, closedir(), dirent::d_name, IsPartialXLogFileName, IsXLogFileName, MAXPGPATH, NULL, opendir(), progname, readdir(), snprintf(), strerror(), unlink(), and XLOGDIR.

Referenced by main().

1027 {
1028  DIR *xldir;
1029  struct dirent *xlde;
1030  char path[MAXPGPATH + sizeof(XLOGDIR)];
1031 
1032  xldir = opendir(XLOGDIR);
1033  if (xldir == NULL)
1034  {
1035  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
1036  progname, XLOGDIR, strerror(errno));
1037  exit(1);
1038  }
1039 
1040  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1041  {
1042  if (IsXLogFileName(xlde->d_name) ||
1044  {
1045  snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
1046  if (unlink(path) < 0)
1047  {
1048  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
1049  progname, path, strerror(errno));
1050  exit(1);
1051  }
1052  }
1053  }
1054 
1055  if (errno)
1056  {
1057  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
1058  progname, XLOGDIR, strerror(errno));
1059  exit(1);
1060  }
1061 
1062  if (closedir(xldir))
1063  {
1064  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1065  progname, XLOGDIR, strerror(errno));
1066  exit(1);
1067  }
1068 }
int closedir(DIR *)
Definition: dirent.c:111
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
Definition: dirent.h:9
Definition: dirent.c:25
#define IsXLogFileName(fname)
#define MAXPGPATH
DIR * opendir(const char *)
Definition: dirent.c:33
static const char * progname
Definition: pg_resetwal.c:63
int unlink(const char *filename)
#define XLOGDIR
#define NULL
Definition: c.h:229
struct dirent * readdir(DIR *)
Definition: dirent.c:77
#define IsPartialXLogFileName(fname)
const char * strerror(int errnum)
Definition: strerror.c:19
char d_name[MAX_PATH]
Definition: dirent.h:14
#define _(x)
Definition: elog.c:84
int main ( int  argc,
char *  argv[] 
)

Definition at line 88 of file pg_resetwal.c.

References _, CheckDataVersion(), ControlFileData::checkPointCopy, DataDir, DB_SHUTDOWNED, fd(), FindEndOfXLOG(), FirstMultiXactId, FirstNormalTransactionId, get_progname(), get_restricted_token(), getopt(), GuessControlValues(), guessed, InvalidOid, KillExistingArchiveStatus(), KillExistingXLOG(), minXlogSegNo, minXlogTli, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::nextXidEpoch, NULL, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, optarg, optind, PG_TEXTDOMAIN, CheckPoint::PrevTimeLineID, PrintControlValues(), PrintNewControlValues(), progname, ReadControlFile(), RewriteControlFile(), set_mxid, set_mxoff, set_newest_commit_ts_xid, set_oid, set_oldest_commit_ts_xid, set_pglocale_pgservice(), set_xid, set_xid_epoch, ControlFileData::state, strerror(), CheckPoint::ThisTimeLineID, usage(), WriteEmptyXLOG(), XLOG_FNAME_LEN, and XLogFromFileName.

89 {
90  int c;
91  bool force = false;
92  bool noupdate = false;
93  MultiXactId set_oldestmxid = 0;
94  char *endptr;
95  char *endptr2;
96  char *DataDir = NULL;
97  int fd;
98 
99  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
100 
101  progname = get_progname(argv[0]);
102 
103  if (argc > 1)
104  {
105  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
106  {
107  usage();
108  exit(0);
109  }
110  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
111  {
112  puts("pg_resetwal (PostgreSQL) " PG_VERSION);
113  exit(0);
114  }
115  }
116 
117 
118  while ((c = getopt(argc, argv, "c:D:e:fl:m:no:O:x:")) != -1)
119  {
120  switch (c)
121  {
122  case 'D':
123  DataDir = optarg;
124  break;
125 
126  case 'f':
127  force = true;
128  break;
129 
130  case 'n':
131  noupdate = true;
132  break;
133 
134  case 'e':
135  set_xid_epoch = strtoul(optarg, &endptr, 0);
136  if (endptr == optarg || *endptr != '\0')
137  {
138  /*------
139  translator: the second %s is a command line argument (-e, etc) */
140  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-e");
141  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
142  exit(1);
143  }
144  if (set_xid_epoch == -1)
145  {
146  fprintf(stderr, _("%s: transaction ID epoch (-e) must not be -1\n"), progname);
147  exit(1);
148  }
149  break;
150 
151  case 'x':
152  set_xid = strtoul(optarg, &endptr, 0);
153  if (endptr == optarg || *endptr != '\0')
154  {
155  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-x");
156  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
157  exit(1);
158  }
159  if (set_xid == 0)
160  {
161  fprintf(stderr, _("%s: transaction ID (-x) must not be 0\n"), progname);
162  exit(1);
163  }
164  break;
165 
166  case 'c':
167  set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
168  if (endptr == optarg || *endptr != ',')
169  {
170  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c");
171  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
172  exit(1);
173  }
174  set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
175  if (endptr2 == endptr + 1 || *endptr2 != '\0')
176  {
177  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-c");
178  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
179  exit(1);
180  }
181 
182  if (set_oldest_commit_ts_xid < 2 &&
184  {
185  fprintf(stderr, _("%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n"), progname);
186  exit(1);
187  }
188 
189  if (set_newest_commit_ts_xid < 2 &&
191  {
192  fprintf(stderr, _("%s: transaction ID (-c) must be either 0 or greater than or equal to 2\n"), progname);
193  exit(1);
194  }
195  break;
196 
197  case 'o':
198  set_oid = strtoul(optarg, &endptr, 0);
199  if (endptr == optarg || *endptr != '\0')
200  {
201  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-o");
202  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
203  exit(1);
204  }
205  if (set_oid == 0)
206  {
207  fprintf(stderr, _("%s: OID (-o) must not be 0\n"), progname);
208  exit(1);
209  }
210  break;
211 
212  case 'm':
213  set_mxid = strtoul(optarg, &endptr, 0);
214  if (endptr == optarg || *endptr != ',')
215  {
216  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m");
217  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
218  exit(1);
219  }
220 
221  set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
222  if (endptr2 == endptr + 1 || *endptr2 != '\0')
223  {
224  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-m");
225  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
226  exit(1);
227  }
228  if (set_mxid == 0)
229  {
230  fprintf(stderr, _("%s: multitransaction ID (-m) must not be 0\n"), progname);
231  exit(1);
232  }
233 
234  /*
235  * XXX It'd be nice to have more sanity checks here, e.g. so
236  * that oldest is not wrapped around w.r.t. nextMulti.
237  */
238  if (set_oldestmxid == 0)
239  {
240  fprintf(stderr, _("%s: oldest multitransaction ID (-m) must not be 0\n"),
241  progname);
242  exit(1);
243  }
244  break;
245 
246  case 'O':
247  set_mxoff = strtoul(optarg, &endptr, 0);
248  if (endptr == optarg || *endptr != '\0')
249  {
250  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-O");
251  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
252  exit(1);
253  }
254  if (set_mxoff == -1)
255  {
256  fprintf(stderr, _("%s: multitransaction offset (-O) must not be -1\n"), progname);
257  exit(1);
258  }
259  break;
260 
261  case 'l':
262  if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
263  {
264  fprintf(stderr, _("%s: invalid argument for option %s\n"), progname, "-l");
265  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
266  exit(1);
267  }
269  break;
270 
271  default:
272  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
273  exit(1);
274  }
275  }
276 
277  if (DataDir == NULL && optind < argc)
278  DataDir = argv[optind++];
279 
280  /* Complain if any arguments remain */
281  if (optind < argc)
282  {
283  fprintf(stderr, _("%s: too many command-line arguments (first is \"%s\")\n"),
284  progname, argv[optind]);
285  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
286  progname);
287  exit(1);
288  }
289 
290  if (DataDir == NULL)
291  {
292  fprintf(stderr, _("%s: no data directory specified\n"), progname);
293  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
294  exit(1);
295  }
296 
297  /*
298  * Don't allow pg_resetwal to be run as root, to avoid overwriting the
299  * ownership of files in the data directory. We need only check for root
300  * -- any other user won't have sufficient permissions to modify files in
301  * the data directory.
302  */
303 #ifndef WIN32
304  if (geteuid() == 0)
305  {
306  fprintf(stderr, _("%s: cannot be executed by \"root\"\n"),
307  progname);
308  fprintf(stderr, _("You must run %s as the PostgreSQL superuser.\n"),
309  progname);
310  exit(1);
311  }
312 #endif
313 
315 
316  if (chdir(DataDir) < 0)
317  {
318  fprintf(stderr, _("%s: could not change directory to \"%s\": %s\n"),
319  progname, DataDir, strerror(errno));
320  exit(1);
321  }
322 
323  /* Check that data directory matches our server version */
325 
326  /*
327  * Check for a postmaster lock file --- if there is one, refuse to
328  * proceed, on grounds we might be interfering with a live installation.
329  */
330  if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
331  {
332  if (errno != ENOENT)
333  {
334  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
335  progname, "postmaster.pid", strerror(errno));
336  exit(1);
337  }
338  }
339  else
340  {
341  fprintf(stderr, _("%s: lock file \"%s\" exists\n"
342  "Is a server running? If not, delete the lock file and try again.\n"),
343  progname, "postmaster.pid");
344  exit(1);
345  }
346 
347  /*
348  * Attempt to read the existing pg_control file
349  */
350  if (!ReadControlFile())
352 
353  /*
354  * Also look at existing segment files to set up newXlogSegNo
355  */
356  FindEndOfXLOG();
357 
358  /*
359  * If we're not going to proceed with the reset, print the current control
360  * file parameters.
361  */
362  if ((guessed && !force) || noupdate)
364 
365  /*
366  * Adjust fields if required by switches. (Do this now so that printout,
367  * if any, includes these values.)
368  */
369  if (set_xid_epoch != -1)
371 
372  if (set_xid != 0)
373  {
375 
376  /*
377  * For the moment, just set oldestXid to a value that will force
378  * immediate autovacuum-for-wraparound. It's not clear whether adding
379  * user control of this is useful, so let's just do something that's
380  * reasonably safe. The magic constant here corresponds to the
381  * maximum allowed value of autovacuum_freeze_max_age.
382  */
387  }
388 
389  if (set_oldest_commit_ts_xid != 0)
391  if (set_newest_commit_ts_xid != 0)
393 
394  if (set_oid != 0)
396 
397  if (set_mxid != 0)
398  {
400 
401  ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
405  }
406 
407  if (set_mxoff != -1)
409 
411  {
414  }
415 
418 
419  /*
420  * If we had to guess anything, and -f was not given, just print the
421  * guessed values and exit. Also print if -n is given.
422  */
423  if ((guessed && !force) || noupdate)
424  {
426  if (!noupdate)
427  {
428  printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
429  exit(1);
430  }
431  else
432  exit(0);
433  }
434 
435  /*
436  * Don't reset from a dirty pg_control without -f, either.
437  */
438  if (ControlFile.state != DB_SHUTDOWNED && !force)
439  {
440  printf(_("The database server was not shut down cleanly.\n"
441  "Resetting the write-ahead log might cause data to be lost.\n"
442  "If you want to proceed anyway, use -f to force reset.\n"));
443  exit(1);
444  }
445 
446  /*
447  * Else, do the dirty deed.
448  */
452  WriteEmptyXLOG();
453 
454  printf(_("Write-ahead log reset\n"));
455  return 0;
456 }
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:685
static MultiXactId set_mxid
Definition: pg_resetwal.c:69
static void usage(void)
Definition: pg_resetwal.c:1229
static TransactionId set_xid
Definition: pg_resetwal.c:65
const char * get_progname(const char *argv0)
Definition: path.c:453
static void PrintNewControlValues(void)
Definition: pg_resetwal.c:769
MultiXactId oldestMulti
Definition: pg_control.h:49
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:941
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1130
static Oid set_oid
Definition: pg_resetwal.c:68
CheckPoint checkPointCopy
Definition: pg_control.h:132
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
static void CheckDataVersion(void)
Definition: pg_resetwal.c:472
static int fd(const char *x, int i)
Definition: preproc-init.c:105
int getopt(int nargc, char *const *nargv, const char *ostr)
Definition: getopt.c:72
static bool ReadControlFile(void)
Definition: pg_resetwal.c:530
void get_restricted_token(const char *progname)
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:67
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:1026
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
int optind
Definition: getopt.c:51
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1075
#define FirstNormalTransactionId
Definition: transam.h:34
uint32 nextXidEpoch
Definition: pg_control.h:42
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:66
char * c
#define FirstMultiXactId
Definition: multixact.h:24
static const char * progname
Definition: pg_resetwal.c:63
static bool guessed
Definition: pg_resetwal.c:62
TransactionId newestCommitTsXid
Definition: pg_control.h:54
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1013
Oid oldestMultiDB
Definition: pg_control.h:50
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:44
TransactionId MultiXactId
Definition: c.h:407
#define NULL
Definition: c.h:229
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
MultiXactId nextMulti
Definition: pg_control.h:45
static void RewriteControlFile(void)
Definition: pg_resetwal.c:834
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:70
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
static void GuessControlValues(void)
Definition: pg_resetwal.c:602
static uint32 minXlogTli
Definition: pg_resetwal.c:71
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:550
char * optarg
Definition: getopt.c:53
const char * strerror(int errnum)
Definition: strerror.c:19
char * DataDir
Definition: globals.c:60
#define XLOG_FNAME_LEN
#define XLogFromFileName(fname, tli, logSegNo)
#define _(x)
Definition: elog.c:84
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:72
static uint32 set_xid_epoch
Definition: pg_resetwal.c:64
static void PrintControlValues ( bool  guessed)
static

Definition at line 685 of file pg_resetwal.c.

References _, ControlFileData::blcksz, ControlFileData::catalog_version_no, ControlFileData::checkPointCopy, ControlFileData::data_checksum_version, ControlFileData::float4ByVal, ControlFileData::float8ByVal, CheckPoint::fullPageWrites, ControlFileData::indexMaxKeys, ControlFileData::loblksize, ControlFileData::maxAlign, ControlFileData::nameDataLen, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::nextXidEpoch, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, ControlFileData::pg_control_version, ControlFileData::relseg_size, snprintf(), ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, ControlFileData::toast_max_chunk_size, UINT64_FORMAT, ControlFileData::xlog_blcksz, and ControlFileData::xlog_seg_size.

Referenced by main().

686 {
687  char sysident_str[32];
688 
689  if (guessed)
690  printf(_("Guessed pg_control values:\n\n"));
691  else
692  printf(_("Current pg_control values:\n\n"));
693 
694  /*
695  * Format system_identifier separately to keep platform-dependent format
696  * code out of the translatable message string.
697  */
698  snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
700 
701  printf(_("pg_control version number: %u\n"),
703  printf(_("Catalog version number: %u\n"),
705  printf(_("Database system identifier: %s\n"),
706  sysident_str);
707  printf(_("Latest checkpoint's TimeLineID: %u\n"),
709  printf(_("Latest checkpoint's full_page_writes: %s\n"),
710  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
711  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
714  printf(_("Latest checkpoint's NextOID: %u\n"),
716  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
718  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
720  printf(_("Latest checkpoint's oldestXID: %u\n"),
722  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
724  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
726  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
728  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
730  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
732  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
734  printf(_("Maximum data alignment: %u\n"),
736  /* we don't print floatFormat since can't say much useful about it */
737  printf(_("Database block size: %u\n"),
739  printf(_("Blocks per segment of large relation: %u\n"),
741  printf(_("WAL block size: %u\n"),
743  printf(_("Bytes per WAL segment: %u\n"),
745  printf(_("Maximum length of identifiers: %u\n"),
747  printf(_("Maximum columns in an index: %u\n"),
749  printf(_("Maximum size of a TOAST chunk: %u\n"),
751  printf(_("Size of a large-object chunk: %u\n"),
753  /* This is no longer configurable, but users may still expect to see it: */
754  printf(_("Date/time type storage: %s\n"),
755  _("64-bit integers"));
756  printf(_("Float4 argument passing: %s\n"),
757  (ControlFile.float4ByVal ? _("by value") : _("by reference")));
758  printf(_("Float8 argument passing: %s\n"),
759  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
760  printf(_("Data page checksum version: %u\n"),
762 }
TransactionId oldestActiveXid
Definition: pg_control.h:63
uint32 nameDataLen
Definition: pg_control.h:211
MultiXactId oldestMulti
Definition: pg_control.h:49
uint32 pg_control_version
Definition: pg_control.h:121
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
CheckPoint checkPointCopy
Definition: pg_control.h:132
uint32 xlog_blcksz
Definition: pg_control.h:208
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
uint32 xlog_seg_size
Definition: pg_control.h:209
uint64 system_identifier
Definition: pg_control.h:106
uint32 nextXidEpoch
Definition: pg_control.h:42
uint32 data_checksum_version
Definition: pg_control.h:222
uint32 loblksize
Definition: pg_control.h:215
uint32 indexMaxKeys
Definition: pg_control.h:212
static bool guessed
Definition: pg_resetwal.c:62
TransactionId newestCommitTsXid
Definition: pg_control.h:54
Oid oldestMultiDB
Definition: pg_control.h:50
uint32 toast_max_chunk_size
Definition: pg_control.h:214
Oid nextOid
Definition: pg_control.h:44
bool fullPageWrites
Definition: pg_control.h:41
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
MultiXactId nextMulti
Definition: pg_control.h:45
uint32 catalog_version_no
Definition: pg_control.h:122
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
#define _(x)
Definition: elog.c:84
#define UINT64_FORMAT
Definition: c.h:316
uint32 relseg_size
Definition: pg_control.h:206
static void PrintNewControlValues ( void  )
static

Definition at line 769 of file pg_resetwal.c.

References _, ControlFileData::checkPointCopy, MAXFNAMELEN, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::nextXidEpoch, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, set_mxid, set_mxoff, set_newest_commit_ts_xid, set_oid, set_oldest_commit_ts_xid, set_xid, set_xid_epoch, CheckPoint::ThisTimeLineID, and XLogFileName.

Referenced by main().

770 {
771  char fname[MAXFNAMELEN];
772 
773  /* This will be always printed in order to keep format same. */
774  printf(_("\n\nValues to be changed:\n\n"));
775 
777  printf(_("First log segment after reset: %s\n"), fname);
778 
779  if (set_mxid != 0)
780  {
781  printf(_("NextMultiXactId: %u\n"),
783  printf(_("OldestMultiXid: %u\n"),
785  printf(_("OldestMulti's DB: %u\n"),
787  }
788 
789  if (set_mxoff != -1)
790  {
791  printf(_("NextMultiOffset: %u\n"),
793  }
794 
795  if (set_oid != 0)
796  {
797  printf(_("NextOID: %u\n"),
799  }
800 
801  if (set_xid != 0)
802  {
803  printf(_("NextXID: %u\n"),
805  printf(_("OldestXID: %u\n"),
807  printf(_("OldestXID's DB: %u\n"),
809  }
810 
811  if (set_xid_epoch != -1)
812  {
813  printf(_("NextXID epoch: %u\n"),
815  }
816 
817  if (set_oldest_commit_ts_xid != 0)
818  {
819  printf(_("oldestCommitTsXid: %u\n"),
821  }
822  if (set_newest_commit_ts_xid != 0)
823  {
824  printf(_("newestCommitTsXid: %u\n"),
826  }
827 }
static MultiXactId set_mxid
Definition: pg_resetwal.c:69
static TransactionId set_xid
Definition: pg_resetwal.c:65
#define XLogFileName(fname, tli, logSegNo)
MultiXactId oldestMulti
Definition: pg_control.h:49
static Oid set_oid
Definition: pg_resetwal.c:68
CheckPoint checkPointCopy
Definition: pg_control.h:132
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:67
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
uint32 nextXidEpoch
Definition: pg_control.h:42
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:66
#define MAXFNAMELEN
TransactionId newestCommitTsXid
Definition: pg_control.h:54
Oid oldestMultiDB
Definition: pg_control.h:50
Oid nextOid
Definition: pg_control.h:44
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
MultiXactId nextMulti
Definition: pg_control.h:45
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:70
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
#define _(x)
Definition: elog.c:84
static uint32 set_xid_epoch
Definition: pg_resetwal.c:64
static bool ReadControlFile ( void  )
static

Definition at line 530 of file pg_resetwal.c.

References _, buffer, close, COMP_CRC32C, EQ_CRC32C, fd(), FIN_CRC32C, guessed, INIT_CRC32C, offsetof, PG_BINARY, PG_CONTROL_FILE_SIZE, PG_CONTROL_VERSION, pg_malloc(), progname, read, strerror(), and XLOG_CONTROL_FILE.

Referenced by main().

531 {
532  int fd;
533  int len;
534  char *buffer;
535  pg_crc32c crc;
536 
537  if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
538  {
539  /*
540  * If pg_control is not there at all, or we can't read it, the odds
541  * are we've been handed a bad DataDir path, so give up. User can do
542  * "touch pg_control" to force us to proceed.
543  */
544  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
546  if (errno == ENOENT)
547  fprintf(stderr, _("If you are sure the data directory path is correct, execute\n"
548  " touch %s\n"
549  "and try again.\n"),
551  exit(1);
552  }
553 
554  /* Use malloc to ensure we have a maxaligned buffer */
555  buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
556 
557  len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
558  if (len < 0)
559  {
560  fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
562  exit(1);
563  }
564  close(fd);
565 
566  if (len >= sizeof(ControlFileData) &&
567  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
568  {
569  /* Check the CRC. */
570  INIT_CRC32C(crc);
571  COMP_CRC32C(crc,
572  buffer,
573  offsetof(ControlFileData, crc));
574  FIN_CRC32C(crc);
575 
576  if (EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
577  {
578  /* Valid data... */
579  memcpy(&ControlFile, buffer, sizeof(ControlFile));
580  return true;
581  }
582 
583  fprintf(stderr, _("%s: pg_control exists but has invalid CRC; proceed with caution\n"),
584  progname);
585  /* We will use the data anyway, but treat it as guessed. */
586  memcpy(&ControlFile, buffer, sizeof(ControlFile));
587  guessed = true;
588  return true;
589  }
590 
591  /* Looks like it's a mess. */
592  fprintf(stderr, _("%s: pg_control exists but is broken or wrong version; ignoring it\n"),
593  progname);
594  return false;
595 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define PG_CONTROL_VERSION
Definition: pg_control.h:24
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1039
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
static const char * progname
Definition: pg_resetwal.c:63
static bool guessed
Definition: pg_resetwal.c:62
#define XLOG_CONTROL_FILE
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:250
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
#define read(a, b, c)
Definition: win32.h:13
#define offsetof(type, field)
Definition: c.h:555
static void RewriteControlFile ( void  )
static

Definition at line 834 of file pg_resetwal.c.

References _, ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, buffer, ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFileData::crc, DB_SHUTDOWNED, fd(), FIN_CRC32C, fsync, INIT_CRC32C, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_worker_processes, ControlFileData::MaxConnections, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, newXlogSegNo, NULL, offsetof, PG_BINARY, PG_CONTROL_FILE_SIZE, PG_CONTROL_MAX_SAFE_SIZE, ControlFileData::prevCheckPoint, progname, CheckPoint::redo, SizeOfXLogLongPHD, ControlFileData::state, StaticAssertStmt, strerror(), CheckPoint::time, ControlFileData::time, ControlFileData::track_commit_timestamp, unlink(), ControlFileData::wal_level, WAL_LEVEL_MINIMAL, ControlFileData::wal_log_hints, write, XLOG_CONTROL_FILE, ControlFileData::xlog_seg_size, XLogSegNoOffsetToRecPtr, and XLogSegSize.

Referenced by main().

835 {
836  int fd;
837  char buffer[PG_CONTROL_FILE_SIZE]; /* need not be aligned */
838 
839  /*
840  * For good luck, apply the same static assertions as in backend's
841  * WriteControlFile().
842  */
844  "pg_control is too large for atomic disk writes");
846  "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE");
847 
848  /*
849  * Adjust fields as needed to force an empty XLOG starting at
850  * newXlogSegNo.
851  */
855 
857  ControlFile.time = (pg_time_t) time(NULL);
865 
866  /*
867  * Force the defaults for max_* settings. The values don't really matter
868  * as long as wal_level='minimal'; the postmaster will reset these fields
869  * anyway at startup.
870  */
872  ControlFile.wal_log_hints = false;
878 
879  /* Now we can force the recorded xlog seg size to the right thing. */
881 
882  /* Contents are protected with a CRC */
885  (char *) &ControlFile,
886  offsetof(ControlFileData, crc));
888 
889  /*
890  * We write out PG_CONTROL_FILE_SIZE bytes into pg_control, zero-padding
891  * the excess over sizeof(ControlFileData). This reduces the odds of
892  * premature-EOF errors when reading pg_control. We'll still fail when we
893  * check the contents of the file, but hopefully with a more specific
894  * error than "couldn't read pg_control".
895  */
896  memset(buffer, 0, PG_CONTROL_FILE_SIZE);
897  memcpy(buffer, &ControlFile, sizeof(ControlFileData));
898 
900 
901  fd = open(XLOG_CONTROL_FILE,
902  O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
903  S_IRUSR | S_IWUSR);
904  if (fd < 0)
905  {
906  fprintf(stderr, _("%s: could not create pg_control file: %s\n"),
907  progname, strerror(errno));
908  exit(1);
909  }
910 
911  errno = 0;
912  if (write(fd, buffer, PG_CONTROL_FILE_SIZE) != PG_CONTROL_FILE_SIZE)
913  {
914  /* if write didn't set errno, assume problem is no disk space */
915  if (errno == 0)
916  errno = ENOSPC;
917  fprintf(stderr, _("%s: could not write pg_control file: %s\n"),
918  progname, strerror(errno));
919  exit(1);
920  }
921 
922  if (fsync(fd) != 0)
923  {
924  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
925  exit(1);
926  }
927 
928  close(fd);
929 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define XLogSegSize
Definition: xlog_internal.h:92
int max_locks_per_xact
Definition: pg_control.h:182
int max_prepared_xacts
Definition: pg_control.h:181
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:168
#define write(a, b, c)
Definition: win32.h:14
int max_worker_processes
Definition: pg_control.h:180
CheckPoint checkPointCopy
Definition: pg_control.h:132
#define PG_CONTROL_MAX_SAFE_SIZE
Definition: pg_control.h:241
pg_time_t time
Definition: pg_control.h:51
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1039
#define XLogSegNoOffsetToRecPtr(segno, offset, dest)
Definition: xlog_internal.h:95
bool backupEndRequired
Definition: pg_control.h:171
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:758
uint32 xlog_seg_size
Definition: pg_control.h:209
pg_crc32c crc
Definition: pg_control.h:232
static const char * progname
Definition: pg_resetwal.c:63
int unlink(const char *filename)
#define fsync(fd)
Definition: win32.h:62
XLogRecPtr prevCheckPoint
Definition: pg_control.h:130
#define XLOG_CONTROL_FILE
XLogRecPtr backupEndPoint
Definition: pg_control.h:170
#define NULL
Definition: c.h:229
bool track_commit_timestamp
Definition: pg_control.h:183
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:250
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
XLogRecPtr backupStartPoint
Definition: pg_control.h:169
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:555
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:167
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void usage ( void  )
static

Definition at line 1229 of file pg_resetwal.c.

References _, and progname.

Referenced by main().

1230 {
1231  printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1232  printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
1233  printf(_("Options:\n"));
1234  printf(_(" -c XID,XID set oldest and newest transactions bearing commit timestamp\n"));
1235  printf(_(" (zero in either value means no change)\n"));
1236  printf(_(" [-D] DATADIR data directory\n"));
1237  printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
1238  printf(_(" -f force update to be done\n"));
1239  printf(_(" -l WALFILE force minimum WAL starting location for new write-ahead log\n"));
1240  printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
1241  printf(_(" -n no update, just show what would be done (for testing)\n"));
1242  printf(_(" -o OID set next OID\n"));
1243  printf(_(" -O OFFSET set next multitransaction offset\n"));
1244  printf(_(" -V, --version output version information, then exit\n"));
1245  printf(_(" -x XID set next transaction ID\n"));
1246  printf(_(" -?, --help show this help, then exit\n"));
1247  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1248 }
static const char * progname
Definition: pg_resetwal.c:63
#define _(x)
Definition: elog.c:84
static void WriteEmptyXLOG ( void  )
static

Definition at line 1130 of file pg_resetwal.c.

References _, buffer, ControlFileData::checkPointCopy, close, COMP_CRC32C, fd(), FIN_CRC32C, fsync, INIT_CRC32C, InvalidTransactionId, MAXPGPATH, newXlogSegNo, offsetof, PG_BINARY, pg_malloc(), progname, CheckPoint::redo, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, strerror(), ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, unlink(), 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, XLogSegSize, 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().

1131 {
1132  char *buffer;
1133  XLogPageHeader page;
1134  XLogLongPageHeader longpage;
1135  XLogRecord *record;
1136  pg_crc32c crc;
1137  char path[MAXPGPATH];
1138  int fd;
1139  int nbytes;
1140  char *recptr;
1141 
1142  /* Use malloc() to ensure buffer is MAXALIGNED */
1143  buffer = (char *) pg_malloc(XLOG_BLCKSZ);
1144  page = (XLogPageHeader) buffer;
1145  memset(buffer, 0, XLOG_BLCKSZ);
1146 
1147  /* Set up the XLOG page header */
1148  page->xlp_magic = XLOG_PAGE_MAGIC;
1149  page->xlp_info = XLP_LONG_HEADER;
1152  longpage = (XLogLongPageHeader) page;
1154  longpage->xlp_seg_size = XLogSegSize;
1155  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1156 
1157  /* Insert the initial checkpoint record */
1158  recptr = (char *) page + SizeOfXLogLongPHD;
1159  record = (XLogRecord *) recptr;
1160  record->xl_prev = 0;
1161  record->xl_xid = InvalidTransactionId;
1164  record->xl_rmid = RM_XLOG_ID;
1165 
1166  recptr += SizeOfXLogRecord;
1167  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1168  *(recptr++) = sizeof(CheckPoint);
1169  memcpy(recptr, &ControlFile.checkPointCopy,
1170  sizeof(CheckPoint));
1171 
1172  INIT_CRC32C(crc);
1173  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1174  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1175  FIN_CRC32C(crc);
1176  record->xl_crc = crc;
1177 
1178  /* Write the first page */
1180 
1181  unlink(path);
1182 
1183  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1184  S_IRUSR | S_IWUSR);
1185  if (fd < 0)
1186  {
1187  fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
1188  progname, path, strerror(errno));
1189  exit(1);
1190  }
1191 
1192  errno = 0;
1193  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1194  {
1195  /* if write didn't set errno, assume problem is no disk space */
1196  if (errno == 0)
1197  errno = ENOSPC;
1198  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1199  progname, path, strerror(errno));
1200  exit(1);
1201  }
1202 
1203  /* Fill the rest of the file with zeroes */
1204  memset(buffer, 0, XLOG_BLCKSZ);
1205  for (nbytes = XLOG_BLCKSZ; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
1206  {
1207  errno = 0;
1208  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1209  {
1210  if (errno == 0)
1211  errno = ENOSPC;
1212  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1213  progname, path, strerror(errno));
1214  exit(1);
1215  }
1216  }
1217 
1218  if (fsync(fd) != 0)
1219  {
1220  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
1221  exit(1);
1222  }
1223 
1224  close(fd);
1225 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define XLogSegSize
Definition: xlog_internal.h:92
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:201
uint32 pg_crc32c
Definition: pg_crc32c.h:38
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:132
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1039
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
uint64 system_identifier
Definition: pg_control.h:106
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define MAXPGPATH
#define XLogFilePath(path, tli, logSegNo)
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
#define InvalidTransactionId
Definition: transam.h:31
static const char * progname
Definition: pg_resetwal.c:63
int unlink(const char *filename)
#define fsync(fd)
Definition: win32.h:62
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
#define SizeOfXLogRecord
Definition: xlogrecord.h:55
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
uint8 xl_info
Definition: xlogrecord.h:46
pg_crc32c xl_crc
Definition: xlogrecord.h:49
struct CheckPoint CheckPoint
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:224
TransactionId xl_xid
Definition: xlogrecord.h:44
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:555
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72

Variable Documentation

ControlFileData ControlFile
static

Definition at line 60 of file pg_resetwal.c.

bool guessed = false
static

Definition at line 62 of file pg_resetwal.c.

Referenced by GuessControlValues(), main(), and ReadControlFile().

XLogSegNo minXlogSegNo = 0
static

Definition at line 72 of file pg_resetwal.c.

Referenced by main().

uint32 minXlogTli = 0
static

Definition at line 71 of file pg_resetwal.c.

Referenced by main().

XLogSegNo newXlogSegNo
static
MultiXactId set_mxid = 0
static

Definition at line 69 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

MultiXactOffset set_mxoff = (MultiXactOffset) -1
static

Definition at line 70 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

TransactionId set_newest_commit_ts_xid = 0
static

Definition at line 67 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

Oid set_oid = 0
static

Definition at line 68 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

TransactionId set_oldest_commit_ts_xid = 0
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

TransactionId set_xid = 0
static

Definition at line 65 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

uint32 set_xid_epoch = (uint32) -1
static

Definition at line 64 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().