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 <locale.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 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 FindEndOfXLOG ( void  )
static

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

878 {
879  DIR *xldir;
880  struct dirent *xlde;
881  uint64 segs_per_xlogid;
882  uint64 xlogbytepos;
883 
884  /*
885  * Initialize the max() computation using the last checkpoint address from
886  * old pg_control. Note that for the moment we are working with segment
887  * numbering according to the old xlog seg size.
888  */
889  segs_per_xlogid = (UINT64CONST(0x0000000100000000) / ControlFile.xlog_seg_size);
891 
892  /*
893  * Scan the pg_wal directory to find existing WAL segment files. We
894  * assume any present have been used; in most scenarios this should be
895  * conservative, because of xlog.c's attempts to pre-create files.
896  */
897  xldir = opendir(XLOGDIR);
898  if (xldir == NULL)
899  {
900  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
901  progname, XLOGDIR, strerror(errno));
902  exit(1);
903  }
904 
905  while (errno = 0, (xlde = readdir(xldir)) != NULL)
906  {
907  if (IsXLogFileName(xlde->d_name) ||
909  {
910  unsigned int tli,
911  log,
912  seg;
913  XLogSegNo segno;
914 
915  /*
916  * Note: We don't use XLogFromFileName here, because we want to
917  * use the segment size from the control file, not the size the
918  * pg_resetwal binary was compiled with
919  */
920  sscanf(xlde->d_name, "%08X%08X%08X", &tli, &log, &seg);
921  segno = ((uint64) log) * segs_per_xlogid + seg;
922 
923  /*
924  * Note: we take the max of all files found, regardless of their
925  * timelines. Another possibility would be to ignore files of
926  * timelines other than the target TLI, but this seems safer.
927  * Better too large a result than too small...
928  */
929  if (segno > newXlogSegNo)
930  newXlogSegNo = segno;
931  }
932  }
933 
934  if (errno)
935  {
936  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
937  progname, XLOGDIR, strerror(errno));
938  exit(1);
939  }
940 
941  if (closedir(xldir))
942  {
943  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
944  progname, XLOGDIR, strerror(errno));
945  exit(1);
946  }
947 
948  /*
949  * Finally, convert to new xlog seg size, and advance by one to ensure we
950  * are in virgin territory.
951  */
952  xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
953  newXlogSegNo = (xlogbytepos + XLogSegSize - 1) / XLogSegSize;
954  newXlogSegNo++;
955 }
#define XLogSegSize
Definition: xlog_internal.h:92
int closedir(DIR *)
Definition: dirent.c:113
CheckPoint checkPointCopy
Definition: pg_control.h:133
Definition: dirent.h:9
uint32 xlog_seg_size
Definition: pg_control.h:210
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:64
#define XLOGDIR
#define UINT64CONST(x)
Definition: c.h:308
#define NULL
Definition: c.h:226
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
struct dirent * readdir(DIR *)
Definition: dirent.c:78
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:62
#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:33
static void GuessControlValues ( void  )
static

Definition at line 535 of file pg_resetwal.c.

References ControlFileData::blcksz, CATALOG_VERSION_NO, ControlFileData::catalog_version_no, ControlFileData::checkPoint, ControlFileData::checkPointCopy, DB_SHUTDOWNED, ControlFileData::enableIntTimes, 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().

536 {
537  uint64 sysidentifier;
538  struct timeval tv;
539 
540  /*
541  * Set up a completely default set of pg_control values.
542  */
543  guessed = true;
544  memset(&ControlFile, 0, sizeof(ControlFile));
545 
548 
549  /*
550  * Create a new unique installation identifier, since we can no longer use
551  * any old XLOG records. See notes in xlog.c about the algorithm.
552  */
553  gettimeofday(&tv, NULL);
554  sysidentifier = ((uint64) tv.tv_sec) << 32;
555  sysidentifier |= ((uint64) tv.tv_usec) << 12;
556  sysidentifier |= getpid() & 0xFFF;
557 
558  ControlFile.system_identifier = sysidentifier;
559 
575 
577  ControlFile.time = (pg_time_t) time(NULL);
580 
581  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
582 
584  ControlFile.wal_log_hints = false;
590 
591  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
593  ControlFile.blcksz = BLCKSZ;
594  ControlFile.relseg_size = RELSEG_SIZE;
595  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
596  ControlFile.xlog_seg_size = XLOG_SEG_SIZE;
601 #ifdef HAVE_INT64_TIMESTAMP
603 #else
604  ControlFile.enableIntTimes = false;
605 #endif
606  ControlFile.float4ByVal = FLOAT4PASSBYVAL;
607  ControlFile.float8ByVal = FLOAT8PASSBYVAL;
608 
609  /*
610  * XXX eventually, should try to grovel through old XLOG to develop more
611  * accurate values for TimeLineID, nextXID, etc.
612  */
613 }
#define LOBLKSIZE
Definition: large_object.h:72
int max_locks_per_xact
Definition: pg_control.h:183
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:182
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:129
int max_worker_processes
Definition: pg_control.h:181
TransactionId oldestActiveXid
Definition: pg_control.h:60
uint32 nameDataLen
Definition: pg_control.h:212
MultiXactId oldestMulti
Definition: pg_control.h:46
TimeLineID PrevTimeLineID
Definition: pg_control.h:36
#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:122
CheckPoint checkPointCopy
Definition: pg_control.h:133
uint32 xlog_blcksz
Definition: pg_control.h:209
TransactionId oldestXid
Definition: pg_control.h:44
TransactionId nextXid
Definition: pg_control.h:40
pg_time_t time
Definition: pg_control.h:48
#define NAMEDATALEN
MultiXactOffset nextMultiOffset
Definition: pg_control.h:43
uint32 xlog_seg_size
Definition: pg_control.h:210
#define FirstNormalTransactionId
Definition: transam.h:34
uint64 system_identifier
Definition: pg_control.h:107
uint32 nextXidEpoch
Definition: pg_control.h:39
XLogRecPtr unloggedLSN
Definition: pg_control.h:135
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
#define FirstMultiXactId
Definition: multixact.h:24
uint32 loblksize
Definition: pg_control.h:216
uint32 indexMaxKeys
Definition: pg_control.h:213
static bool guessed
Definition: pg_resetwal.c:63
#define TOAST_MAX_CHUNK_SIZE
Definition: tuptoaster.h:91
Oid oldestMultiDB
Definition: pg_control.h:47
uint32 toast_max_chunk_size
Definition: pg_control.h:215
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:41
bool fullPageWrites
Definition: pg_control.h:38
#define NULL
Definition: c.h:226
bool track_commit_timestamp
Definition: pg_control.h:184
Oid oldestXidDB
Definition: pg_control.h:45
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
double floatFormat
Definition: pg_control.h:199
#define INDEX_MAX_KEYS
MultiXactId nextMulti
Definition: pg_control.h:42
uint32 catalog_version_no
Definition: pg_control.h:123
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
#define FLOATFORMAT_VALUE
Definition: pg_control.h:200
uint32 relseg_size
Definition: pg_control.h:207
XLogRecPtr checkPoint
Definition: pg_control.h:130
XLogRecPtr redo
Definition: pg_control.h:33
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void KillExistingArchiveStatus ( void  )
static

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

1012 {
1013  DIR *xldir;
1014  struct dirent *xlde;
1015  char path[MAXPGPATH];
1016 
1017 #define ARCHSTATDIR XLOGDIR "/archive_status"
1018 
1019  xldir = opendir(ARCHSTATDIR);
1020  if (xldir == NULL)
1021  {
1022  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
1023  progname, ARCHSTATDIR, strerror(errno));
1024  exit(1);
1025  }
1026 
1027  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1028  {
1029  if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1030  (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1031  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1032  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1033  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1034  {
1035  snprintf(path, MAXPGPATH, "%s/%s", ARCHSTATDIR, xlde->d_name);
1036  if (unlink(path) < 0)
1037  {
1038  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
1039  progname, path, strerror(errno));
1040  exit(1);
1041  }
1042  }
1043  }
1044 
1045  if (errno)
1046  {
1047  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
1048  progname, ARCHSTATDIR, strerror(errno));
1049  exit(1);
1050  }
1051 
1052  if (closedir(xldir))
1053  {
1054  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1055  progname, ARCHSTATDIR, strerror(errno));
1056  exit(1);
1057  }
1058 }
int closedir(DIR *)
Definition: dirent.c:113
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:64
int unlink(const char *filename)
#define NULL
Definition: c.h:226
struct dirent * readdir(DIR *)
Definition: dirent.c:78
#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 962 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().

963 {
964  DIR *xldir;
965  struct dirent *xlde;
966  char path[MAXPGPATH];
967 
968  xldir = opendir(XLOGDIR);
969  if (xldir == NULL)
970  {
971  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
972  progname, XLOGDIR, strerror(errno));
973  exit(1);
974  }
975 
976  while (errno = 0, (xlde = readdir(xldir)) != NULL)
977  {
978  if (IsXLogFileName(xlde->d_name) ||
980  {
981  snprintf(path, MAXPGPATH, "%s/%s", XLOGDIR, xlde->d_name);
982  if (unlink(path) < 0)
983  {
984  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
985  progname, path, strerror(errno));
986  exit(1);
987  }
988  }
989  }
990 
991  if (errno)
992  {
993  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
994  progname, XLOGDIR, strerror(errno));
995  exit(1);
996  }
997 
998  if (closedir(xldir))
999  {
1000  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1001  progname, XLOGDIR, strerror(errno));
1002  exit(1);
1003  }
1004 }
int closedir(DIR *)
Definition: dirent.c:113
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:64
int unlink(const char *filename)
#define XLOGDIR
#define NULL
Definition: c.h:226
struct dirent * readdir(DIR *)
Definition: dirent.c:78
#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 _, 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  /*
324  * Check for a postmaster lock file --- if there is one, refuse to
325  * proceed, on grounds we might be interfering with a live installation.
326  */
327  if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
328  {
329  if (errno != ENOENT)
330  {
331  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
332  progname, "postmaster.pid", strerror(errno));
333  exit(1);
334  }
335  }
336  else
337  {
338  fprintf(stderr, _("%s: lock file \"%s\" exists\n"
339  "Is a server running? If not, delete the lock file and try again.\n"),
340  progname, "postmaster.pid");
341  exit(1);
342  }
343 
344  /*
345  * Attempt to read the existing pg_control file
346  */
347  if (!ReadControlFile())
349 
350  /*
351  * Also look at existing segment files to set up newXlogSegNo
352  */
353  FindEndOfXLOG();
354 
355  /*
356  * If we're not going to proceed with the reset, print the current control
357  * file parameters.
358  */
359  if ((guessed && !force) || noupdate)
361 
362  /*
363  * Adjust fields if required by switches. (Do this now so that printout,
364  * if any, includes these values.)
365  */
366  if (set_xid_epoch != -1)
368 
369  if (set_xid != 0)
370  {
372 
373  /*
374  * For the moment, just set oldestXid to a value that will force
375  * immediate autovacuum-for-wraparound. It's not clear whether adding
376  * user control of this is useful, so let's just do something that's
377  * reasonably safe. The magic constant here corresponds to the
378  * maximum allowed value of autovacuum_freeze_max_age.
379  */
384  }
385 
386  if (set_oldest_commit_ts_xid != 0)
388  if (set_newest_commit_ts_xid != 0)
390 
391  if (set_oid != 0)
393 
394  if (set_mxid != 0)
395  {
397 
398  ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
402  }
403 
404  if (set_mxoff != -1)
406 
408  {
411  }
412 
415 
416  /*
417  * If we had to guess anything, and -f was not given, just print the
418  * guessed values and exit. Also print if -n is given.
419  */
420  if ((guessed && !force) || noupdate)
421  {
423  if (!noupdate)
424  {
425  printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
426  exit(1);
427  }
428  else
429  exit(0);
430  }
431 
432  /*
433  * Don't reset from a dirty pg_control without -f, either.
434  */
435  if (ControlFile.state != DB_SHUTDOWNED && !force)
436  {
437  printf(_("The database server was not shut down cleanly.\n"
438  "Resetting the transaction log might cause data to be lost.\n"
439  "If you want to proceed anyway, use -f to force reset.\n"));
440  exit(1);
441  }
442 
443  /*
444  * Else, do the dirty deed.
445  */
449  WriteEmptyXLOG();
450 
451  printf(_("Transaction log reset\n"));
452  return 0;
453 }
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:623
static MultiXactId set_mxid
Definition: pg_resetwal.c:70
static void usage(void)
Definition: pg_resetwal.c:1165
static TransactionId set_xid
Definition: pg_resetwal.c:66
const char * get_progname(const char *argv0)
Definition: path.c:453
static void PrintNewControlValues(void)
Definition: pg_resetwal.c:706
MultiXactId oldestMulti
Definition: pg_control.h:46
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:877
TimeLineID PrevTimeLineID
Definition: pg_control.h:36
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1066
static Oid set_oid
Definition: pg_resetwal.c:69
CheckPoint checkPointCopy
Definition: pg_control.h:133
TransactionId oldestXid
Definition: pg_control.h:44
TransactionId nextXid
Definition: pg_control.h:40
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:463
void get_restricted_token(const char *progname)
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:68
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:962
MultiXactOffset nextMultiOffset
Definition: pg_control.h:43
TransactionId oldestCommitTsXid
Definition: pg_control.h:49
int optind
Definition: getopt.c:51
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1011
#define FirstNormalTransactionId
Definition: transam.h:34
uint32 nextXidEpoch
Definition: pg_control.h:39
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:67
char * c
#define FirstMultiXactId
Definition: multixact.h:24
static const char * progname
Definition: pg_resetwal.c:64
static bool guessed
Definition: pg_resetwal.c:63
TransactionId newestCommitTsXid
Definition: pg_control.h:51
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1011
Oid oldestMultiDB
Definition: pg_control.h:47
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:41
TransactionId MultiXactId
Definition: c.h:403
#define NULL
Definition: c.h:226
Oid oldestXidDB
Definition: pg_control.h:45
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
MultiXactId nextMulti
Definition: pg_control.h:42
static void RewriteControlFile(void)
Definition: pg_resetwal.c:771
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:71
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:62
static void GuessControlValues(void)
Definition: pg_resetwal.c:535
static uint32 minXlogTli
Definition: pg_resetwal.c:72
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
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:59
#define XLOG_FNAME_LEN
#define XLogFromFileName(fname, tli, logSegNo)
#define _(x)
Definition: elog.c:84
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:73
static uint32 set_xid_epoch
Definition: pg_resetwal.c:65
static void PrintControlValues ( bool  guessed)
static

Definition at line 623 of file pg_resetwal.c.

References _, ControlFileData::blcksz, ControlFileData::catalog_version_no, ControlFileData::checkPointCopy, ControlFileData::data_checksum_version, ControlFileData::enableIntTimes, 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().

624 {
625  char sysident_str[32];
626 
627  if (guessed)
628  printf(_("Guessed pg_control values:\n\n"));
629  else
630  printf(_("Current pg_control values:\n\n"));
631 
632  /*
633  * Format system_identifier separately to keep platform-dependent format
634  * code out of the translatable message string.
635  */
636  snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
638 
639  printf(_("pg_control version number: %u\n"),
641  printf(_("Catalog version number: %u\n"),
643  printf(_("Database system identifier: %s\n"),
644  sysident_str);
645  printf(_("Latest checkpoint's TimeLineID: %u\n"),
647  printf(_("Latest checkpoint's full_page_writes: %s\n"),
648  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
649  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
652  printf(_("Latest checkpoint's NextOID: %u\n"),
654  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
656  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
658  printf(_("Latest checkpoint's oldestXID: %u\n"),
660  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
662  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
664  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
666  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
668  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
670  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
672  printf(_("Maximum data alignment: %u\n"),
674  /* we don't print floatFormat since can't say much useful about it */
675  printf(_("Database block size: %u\n"),
677  printf(_("Blocks per segment of large relation: %u\n"),
679  printf(_("WAL block size: %u\n"),
681  printf(_("Bytes per WAL segment: %u\n"),
683  printf(_("Maximum length of identifiers: %u\n"),
685  printf(_("Maximum columns in an index: %u\n"),
687  printf(_("Maximum size of a TOAST chunk: %u\n"),
689  printf(_("Size of a large-object chunk: %u\n"),
691  printf(_("Date/time type storage: %s\n"),
692  (ControlFile.enableIntTimes ? _("64-bit integers") : _("floating-point numbers")));
693  printf(_("Float4 argument passing: %s\n"),
694  (ControlFile.float4ByVal ? _("by value") : _("by reference")));
695  printf(_("Float8 argument passing: %s\n"),
696  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
697  printf(_("Data page checksum version: %u\n"),
699 }
TransactionId oldestActiveXid
Definition: pg_control.h:60
uint32 nameDataLen
Definition: pg_control.h:212
MultiXactId oldestMulti
Definition: pg_control.h:46
uint32 pg_control_version
Definition: pg_control.h:122
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
CheckPoint checkPointCopy
Definition: pg_control.h:133
uint32 xlog_blcksz
Definition: pg_control.h:209
TransactionId oldestXid
Definition: pg_control.h:44
TransactionId nextXid
Definition: pg_control.h:40
MultiXactOffset nextMultiOffset
Definition: pg_control.h:43
TransactionId oldestCommitTsXid
Definition: pg_control.h:49
uint32 xlog_seg_size
Definition: pg_control.h:210
uint64 system_identifier
Definition: pg_control.h:107
uint32 nextXidEpoch
Definition: pg_control.h:39
uint32 data_checksum_version
Definition: pg_control.h:226
uint32 loblksize
Definition: pg_control.h:216
uint32 indexMaxKeys
Definition: pg_control.h:213
static bool guessed
Definition: pg_resetwal.c:63
TransactionId newestCommitTsXid
Definition: pg_control.h:51
Oid oldestMultiDB
Definition: pg_control.h:47
uint32 toast_max_chunk_size
Definition: pg_control.h:215
Oid nextOid
Definition: pg_control.h:41
bool fullPageWrites
Definition: pg_control.h:38
Oid oldestXidDB
Definition: pg_control.h:45
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
MultiXactId nextMulti
Definition: pg_control.h:42
uint32 catalog_version_no
Definition: pg_control.h:123
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
#define _(x)
Definition: elog.c:84
#define UINT64_FORMAT
Definition: c.h:313
uint32 relseg_size
Definition: pg_control.h:207
static void PrintNewControlValues ( void  )
static

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

707 {
708  char fname[MAXFNAMELEN];
709 
710  /* This will be always printed in order to keep format same. */
711  printf(_("\n\nValues to be changed:\n\n"));
712 
714  printf(_("First log segment after reset: %s\n"), fname);
715 
716  if (set_mxid != 0)
717  {
718  printf(_("NextMultiXactId: %u\n"),
720  printf(_("OldestMultiXid: %u\n"),
722  printf(_("OldestMulti's DB: %u\n"),
724  }
725 
726  if (set_mxoff != -1)
727  {
728  printf(_("NextMultiOffset: %u\n"),
730  }
731 
732  if (set_oid != 0)
733  {
734  printf(_("NextOID: %u\n"),
736  }
737 
738  if (set_xid != 0)
739  {
740  printf(_("NextXID: %u\n"),
742  printf(_("OldestXID: %u\n"),
744  printf(_("OldestXID's DB: %u\n"),
746  }
747 
748  if (set_xid_epoch != -1)
749  {
750  printf(_("NextXID epoch: %u\n"),
752  }
753 
754  if (set_oldest_commit_ts_xid != 0)
755  {
756  printf(_("oldestCommitTsXid: %u\n"),
758  }
759  if (set_newest_commit_ts_xid != 0)
760  {
761  printf(_("newestCommitTsXid: %u\n"),
763  }
764 }
static MultiXactId set_mxid
Definition: pg_resetwal.c:70
static TransactionId set_xid
Definition: pg_resetwal.c:66
#define XLogFileName(fname, tli, logSegNo)
MultiXactId oldestMulti
Definition: pg_control.h:46
static Oid set_oid
Definition: pg_resetwal.c:69
CheckPoint checkPointCopy
Definition: pg_control.h:133
TransactionId oldestXid
Definition: pg_control.h:44
TransactionId nextXid
Definition: pg_control.h:40
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:68
MultiXactOffset nextMultiOffset
Definition: pg_control.h:43
TransactionId oldestCommitTsXid
Definition: pg_control.h:49
uint32 nextXidEpoch
Definition: pg_control.h:39
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:67
#define MAXFNAMELEN
TransactionId newestCommitTsXid
Definition: pg_control.h:51
Oid oldestMultiDB
Definition: pg_control.h:47
Oid nextOid
Definition: pg_control.h:41
Oid oldestXidDB
Definition: pg_control.h:45
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
MultiXactId nextMulti
Definition: pg_control.h:42
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:71
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:62
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
#define _(x)
Definition: elog.c:84
static uint32 set_xid_epoch
Definition: pg_resetwal.c:65
static bool ReadControlFile ( void  )
static

Definition at line 463 of file pg_resetwal.c.

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

Referenced by main().

464 {
465  int fd;
466  int len;
467  char *buffer;
468  pg_crc32c crc;
469 
470  if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
471  {
472  /*
473  * If pg_control is not there at all, or we can't read it, the odds
474  * are we've been handed a bad DataDir path, so give up. User can do
475  * "touch pg_control" to force us to proceed.
476  */
477  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
479  if (errno == ENOENT)
480  fprintf(stderr, _("If you are sure the data directory path is correct, execute\n"
481  " touch %s\n"
482  "and try again.\n"),
484  exit(1);
485  }
486 
487  /* Use malloc to ensure we have a maxaligned buffer */
488  buffer = (char *) pg_malloc(PG_CONTROL_SIZE);
489 
490  len = read(fd, buffer, PG_CONTROL_SIZE);
491  if (len < 0)
492  {
493  fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
495  exit(1);
496  }
497  close(fd);
498 
499  if (len >= sizeof(ControlFileData) &&
500  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
501  {
502  /* Check the CRC. */
503  INIT_CRC32C(crc);
504  COMP_CRC32C(crc,
505  buffer,
506  offsetof(ControlFileData, crc));
507  FIN_CRC32C(crc);
508 
509  if (EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
510  {
511  /* Valid data... */
512  memcpy(&ControlFile, buffer, sizeof(ControlFile));
513  return true;
514  }
515 
516  fprintf(stderr, _("%s: pg_control exists but has invalid CRC; proceed with caution\n"),
517  progname);
518  /* We will use the data anyway, but treat it as guessed. */
519  memcpy(&ControlFile, buffer, sizeof(ControlFile));
520  guessed = true;
521  return true;
522  }
523 
524  /* Looks like it's a mess. */
525  fprintf(stderr, _("%s: pg_control exists but is broken or unknown version; ignoring it\n"),
526  progname);
527  return false;
528 }
#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
#define PG_CONTROL_SIZE
Definition: pg_control.h:239
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1037
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
static const char * progname
Definition: pg_resetwal.c:64
static bool guessed
Definition: pg_resetwal.c:63
#define XLOG_CONTROL_FILE
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:17
#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:18
#define offsetof(type, field)
Definition: c.h:550
static void RewriteControlFile ( void  )
static

Definition at line 771 of file pg_resetwal.c.

References _, ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, 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_SIZE, ControlFileData::prevCheckPoint, progname, CheckPoint::redo, SizeOfXLogLongPHD, ControlFileData::state, 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().

772 {
773  int fd;
774  char buffer[PG_CONTROL_SIZE]; /* need not be aligned */
775 
776  /*
777  * Adjust fields as needed to force an empty XLOG starting at
778  * newXlogSegNo.
779  */
783 
785  ControlFile.time = (pg_time_t) time(NULL);
793 
794  /*
795  * Force the defaults for max_* settings. The values don't really matter
796  * as long as wal_level='minimal'; the postmaster will reset these fields
797  * anyway at startup.
798  */
800  ControlFile.wal_log_hints = false;
806 
807  /* Now we can force the recorded xlog seg size to the right thing. */
809 
810  /* Contents are protected with a CRC */
813  (char *) &ControlFile,
814  offsetof(ControlFileData, crc));
816 
817  /*
818  * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
819  * excess over sizeof(ControlFileData). This reduces the odds of
820  * premature-EOF errors when reading pg_control. We'll still fail when we
821  * check the contents of the file, but hopefully with a more specific
822  * error than "couldn't read pg_control".
823  */
824  if (sizeof(ControlFileData) > PG_CONTROL_SIZE)
825  {
826  fprintf(stderr,
827  _("%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n"),
828  progname);
829  exit(1);
830  }
831 
832  memset(buffer, 0, PG_CONTROL_SIZE);
833  memcpy(buffer, &ControlFile, sizeof(ControlFileData));
834 
836 
837  fd = open(XLOG_CONTROL_FILE,
838  O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
839  S_IRUSR | S_IWUSR);
840  if (fd < 0)
841  {
842  fprintf(stderr, _("%s: could not create pg_control file: %s\n"),
843  progname, strerror(errno));
844  exit(1);
845  }
846 
847  errno = 0;
848  if (write(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE)
849  {
850  /* if write didn't set errno, assume problem is no disk space */
851  if (errno == 0)
852  errno = ENOSPC;
853  fprintf(stderr, _("%s: could not write pg_control file: %s\n"),
854  progname, strerror(errno));
855  exit(1);
856  }
857 
858  if (fsync(fd) != 0)
859  {
860  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
861  exit(1);
862  }
863 
864  close(fd);
865 }
#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:183
int max_prepared_xacts
Definition: pg_control.h:182
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:129
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
#define write(a, b, c)
Definition: win32.h:19
int max_worker_processes
Definition: pg_control.h:181
#define PG_CONTROL_SIZE
Definition: pg_control.h:239
CheckPoint checkPointCopy
Definition: pg_control.h:133
pg_time_t time
Definition: pg_control.h:48
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1037
#define XLogSegNoOffsetToRecPtr(segno, offset, dest)
Definition: xlog_internal.h:95
bool backupEndRequired
Definition: pg_control.h:172
uint32 xlog_seg_size
Definition: pg_control.h:210
pg_crc32c crc
Definition: pg_control.h:229
static const char * progname
Definition: pg_resetwal.c:64
int unlink(const char *filename)
#define fsync(fd)
Definition: win32.h:70
XLogRecPtr prevCheckPoint
Definition: pg_control.h:131
#define XLOG_CONTROL_FILE
XLogRecPtr backupEndPoint
Definition: pg_control.h:171
#define NULL
Definition: c.h:226
bool track_commit_timestamp
Definition: pg_control.h:184
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:62
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:17
#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:170
XLogRecPtr checkPoint
Definition: pg_control.h:130
XLogRecPtr redo
Definition: pg_control.h:33
#define offsetof(type, field)
Definition: c.h:550
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void usage ( void  )
static

Definition at line 1165 of file pg_resetwal.c.

References _, and progname.

Referenced by main().

1166 {
1167  printf(_("%s resets the PostgreSQL transaction log.\n\n"), progname);
1168  printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
1169  printf(_("Options:\n"));
1170  printf(_(" -c XID,XID set oldest and newest transactions bearing commit timestamp\n"));
1171  printf(_(" (zero in either value means no change)\n"));
1172  printf(_(" [-D] DATADIR data directory\n"));
1173  printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
1174  printf(_(" -f force update to be done\n"));
1175  printf(_(" -l XLOGFILE force minimum WAL starting location for new transaction log\n"));
1176  printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
1177  printf(_(" -n no update, just show what would be done (for testing)\n"));
1178  printf(_(" -o OID set next OID\n"));
1179  printf(_(" -O OFFSET set next multitransaction offset\n"));
1180  printf(_(" -V, --version output version information, then exit\n"));
1181  printf(_(" -x XID set next transaction ID\n"));
1182  printf(_(" -?, --help show this help, then exit\n"));
1183  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1184 }
static const char * progname
Definition: pg_resetwal.c:64
#define _(x)
Definition: elog.c:84
static void WriteEmptyXLOG ( void  )
static

Definition at line 1066 of file pg_resetwal.c.

References _, 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().

1067 {
1068  char *buffer;
1069  XLogPageHeader page;
1070  XLogLongPageHeader longpage;
1071  XLogRecord *record;
1072  pg_crc32c crc;
1073  char path[MAXPGPATH];
1074  int fd;
1075  int nbytes;
1076  char *recptr;
1077 
1078  /* Use malloc() to ensure buffer is MAXALIGNED */
1079  buffer = (char *) pg_malloc(XLOG_BLCKSZ);
1080  page = (XLogPageHeader) buffer;
1081  memset(buffer, 0, XLOG_BLCKSZ);
1082 
1083  /* Set up the XLOG page header */
1084  page->xlp_magic = XLOG_PAGE_MAGIC;
1085  page->xlp_info = XLP_LONG_HEADER;
1088  longpage = (XLogLongPageHeader) page;
1090  longpage->xlp_seg_size = XLogSegSize;
1091  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1092 
1093  /* Insert the initial checkpoint record */
1094  recptr = (char *) page + SizeOfXLogLongPHD;
1095  record = (XLogRecord *) recptr;
1096  record->xl_prev = 0;
1097  record->xl_xid = InvalidTransactionId;
1100  record->xl_rmid = RM_XLOG_ID;
1101 
1102  recptr += SizeOfXLogRecord;
1103  *(recptr++) = XLR_BLOCK_ID_DATA_SHORT;
1104  *(recptr++) = sizeof(CheckPoint);
1105  memcpy(recptr, &ControlFile.checkPointCopy,
1106  sizeof(CheckPoint));
1107 
1108  INIT_CRC32C(crc);
1109  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1110  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1111  FIN_CRC32C(crc);
1112  record->xl_crc = crc;
1113 
1114  /* Write the first page */
1116 
1117  unlink(path);
1118 
1119  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1120  S_IRUSR | S_IWUSR);
1121  if (fd < 0)
1122  {
1123  fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
1124  progname, path, strerror(errno));
1125  exit(1);
1126  }
1127 
1128  errno = 0;
1129  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1130  {
1131  /* if write didn't set errno, assume problem is no disk space */
1132  if (errno == 0)
1133  errno = ENOSPC;
1134  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1135  progname, path, strerror(errno));
1136  exit(1);
1137  }
1138 
1139  /* Fill the rest of the file with zeroes */
1140  memset(buffer, 0, XLOG_BLCKSZ);
1141  for (nbytes = XLOG_BLCKSZ; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
1142  {
1143  errno = 0;
1144  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1145  {
1146  if (errno == 0)
1147  errno = ENOSPC;
1148  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1149  progname, path, strerror(errno));
1150  exit(1);
1151  }
1152  }
1153 
1154  if (fsync(fd) != 0)
1155  {
1156  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
1157  exit(1);
1158  }
1159 
1160  close(fd);
1161 }
#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:19
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:200
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:133
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1037
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
uint64 system_identifier
Definition: pg_control.h:107
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:64
#define InvalidTransactionId
Definition: transam.h:31
static const char * progname
Definition: pg_resetwal.c:64
int unlink(const char *filename)
#define fsync(fd)
Definition: win32.h:70
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
static ControlFileData ControlFile
Definition: pg_resetwal.c:61
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:223
TransactionId xl_xid
Definition: xlogrecord.h:44
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:62
TimeLineID ThisTimeLineID
Definition: pg_control.h:35
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:17
#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:33
#define offsetof(type, field)
Definition: c.h:550
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72

Variable Documentation

ControlFileData ControlFile
static

Definition at line 61 of file pg_resetwal.c.

bool guessed = false
static

Definition at line 63 of file pg_resetwal.c.

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

XLogSegNo minXlogSegNo = 0
static

Definition at line 73 of file pg_resetwal.c.

Referenced by main().

uint32 minXlogTli = 0
static

Definition at line 72 of file pg_resetwal.c.

Referenced by main().

XLogSegNo newXlogSegNo
static
MultiXactId set_mxid = 0
static

Definition at line 70 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

MultiXactOffset set_mxoff = (MultiXactOffset) -1
static

Definition at line 71 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

TransactionId set_newest_commit_ts_xid = 0
static

Definition at line 68 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

Oid set_oid = 0
static

Definition at line 69 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

TransactionId set_oldest_commit_ts_xid = 0
static

Definition at line 67 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

TransactionId set_xid = 0
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

uint32 set_xid_epoch = (uint32) -1
static

Definition at line 65 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().