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 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 872 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().

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

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

535 {
536  uint64 sysidentifier;
537  struct timeval tv;
538 
539  /*
540  * Set up a completely default set of pg_control values.
541  */
542  guessed = true;
543  memset(&ControlFile, 0, sizeof(ControlFile));
544 
547 
548  /*
549  * Create a new unique installation identifier, since we can no longer use
550  * any old XLOG records. See notes in xlog.c about the algorithm.
551  */
552  gettimeofday(&tv, NULL);
553  sysidentifier = ((uint64) tv.tv_sec) << 32;
554  sysidentifier |= ((uint64) tv.tv_usec) << 12;
555  sysidentifier |= getpid() & 0xFFF;
556 
557  ControlFile.system_identifier = sysidentifier;
558 
574 
576  ControlFile.time = (pg_time_t) time(NULL);
579 
580  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
581 
583  ControlFile.wal_log_hints = false;
589 
590  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
592  ControlFile.blcksz = BLCKSZ;
593  ControlFile.relseg_size = RELSEG_SIZE;
594  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
595  ControlFile.xlog_seg_size = XLOG_SEG_SIZE;
600  ControlFile.float4ByVal = FLOAT4PASSBYVAL;
601  ControlFile.float8ByVal = FLOAT8PASSBYVAL;
602 
603  /*
604  * XXX eventually, should try to grovel through old XLOG to develop more
605  * accurate values for TimeLineID, nextXID, etc.
606  */
607 }
#define LOBLKSIZE
Definition: large_object.h:72
int max_locks_per_xact
Definition: pg_control.h:185
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:184
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:131
int max_worker_processes
Definition: pg_control.h:183
TransactionId oldestActiveXid
Definition: pg_control.h:62
uint32 nameDataLen
Definition: pg_control.h:214
MultiXactId oldestMulti
Definition: pg_control.h:48
TimeLineID PrevTimeLineID
Definition: pg_control.h:38
#define CATALOG_VERSION_NO
Definition: catversion.h:56
#define PG_CONTROL_VERSION
Definition: pg_control.h:26
uint32 pg_control_version
Definition: pg_control.h:124
CheckPoint checkPointCopy
Definition: pg_control.h:135
uint32 xlog_blcksz
Definition: pg_control.h:211
TransactionId oldestXid
Definition: pg_control.h:46
TransactionId nextXid
Definition: pg_control.h:42
pg_time_t time
Definition: pg_control.h:50
#define NAMEDATALEN
MultiXactOffset nextMultiOffset
Definition: pg_control.h:45
uint32 xlog_seg_size
Definition: pg_control.h:212
#define FirstNormalTransactionId
Definition: transam.h:34
uint64 system_identifier
Definition: pg_control.h:109
uint32 nextXidEpoch
Definition: pg_control.h:41
XLogRecPtr unloggedLSN
Definition: pg_control.h:137
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
#define FirstMultiXactId
Definition: multixact.h:24
uint32 loblksize
Definition: pg_control.h:218
uint32 indexMaxKeys
Definition: pg_control.h:215
static bool guessed
Definition: pg_resetwal.c:62
#define TOAST_MAX_CHUNK_SIZE
Definition: tuptoaster.h:91
Oid oldestMultiDB
Definition: pg_control.h:49
uint32 toast_max_chunk_size
Definition: pg_control.h:217
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:43
bool fullPageWrites
Definition: pg_control.h:40
#define NULL
Definition: c.h:229
bool track_commit_timestamp
Definition: pg_control.h:186
Oid oldestXidDB
Definition: pg_control.h:47
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
double floatFormat
Definition: pg_control.h:201
#define INDEX_MAX_KEYS
MultiXactId nextMulti
Definition: pg_control.h:44
uint32 catalog_version_no
Definition: pg_control.h:125
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
#define FLOATFORMAT_VALUE
Definition: pg_control.h:202
uint32 relseg_size
Definition: pg_control.h:209
XLogRecPtr checkPoint
Definition: pg_control.h:132
XLogRecPtr redo
Definition: pg_control.h:35
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void KillExistingArchiveStatus ( void  )
static

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

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

958 {
959  DIR *xldir;
960  struct dirent *xlde;
961  char path[MAXPGPATH];
962 
963  xldir = opendir(XLOGDIR);
964  if (xldir == NULL)
965  {
966  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
967  progname, XLOGDIR, strerror(errno));
968  exit(1);
969  }
970 
971  while (errno = 0, (xlde = readdir(xldir)) != NULL)
972  {
973  if (IsXLogFileName(xlde->d_name) ||
975  {
976  snprintf(path, MAXPGPATH, "%s/%s", XLOGDIR, xlde->d_name);
977  if (unlink(path) < 0)
978  {
979  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
980  progname, path, strerror(errno));
981  exit(1);
982  }
983  }
984  }
985 
986  if (errno)
987  {
988  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
989  progname, XLOGDIR, strerror(errno));
990  exit(1);
991  }
992 
993  if (closedir(xldir))
994  {
995  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
996  progname, XLOGDIR, strerror(errno));
997  exit(1);
998  }
999 }
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:63
int unlink(const char *filename)
#define XLOGDIR
#define NULL
Definition: c.h:229
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 87 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.

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

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

618 {
619  char sysident_str[32];
620 
621  if (guessed)
622  printf(_("Guessed pg_control values:\n\n"));
623  else
624  printf(_("Current pg_control values:\n\n"));
625 
626  /*
627  * Format system_identifier separately to keep platform-dependent format
628  * code out of the translatable message string.
629  */
630  snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
632 
633  printf(_("pg_control version number: %u\n"),
635  printf(_("Catalog version number: %u\n"),
637  printf(_("Database system identifier: %s\n"),
638  sysident_str);
639  printf(_("Latest checkpoint's TimeLineID: %u\n"),
641  printf(_("Latest checkpoint's full_page_writes: %s\n"),
642  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
643  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
646  printf(_("Latest checkpoint's NextOID: %u\n"),
648  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
650  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
652  printf(_("Latest checkpoint's oldestXID: %u\n"),
654  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
656  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
658  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
660  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
662  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
664  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
666  printf(_("Maximum data alignment: %u\n"),
668  /* we don't print floatFormat since can't say much useful about it */
669  printf(_("Database block size: %u\n"),
671  printf(_("Blocks per segment of large relation: %u\n"),
673  printf(_("WAL block size: %u\n"),
675  printf(_("Bytes per WAL segment: %u\n"),
677  printf(_("Maximum length of identifiers: %u\n"),
679  printf(_("Maximum columns in an index: %u\n"),
681  printf(_("Maximum size of a TOAST chunk: %u\n"),
683  printf(_("Size of a large-object chunk: %u\n"),
685  /* This is no longer configurable, but users may still expect to see it: */
686  printf(_("Date/time type storage: %s\n"),
687  _("64-bit integers"));
688  printf(_("Float4 argument passing: %s\n"),
689  (ControlFile.float4ByVal ? _("by value") : _("by reference")));
690  printf(_("Float8 argument passing: %s\n"),
691  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
692  printf(_("Data page checksum version: %u\n"),
694 }
TransactionId oldestActiveXid
Definition: pg_control.h:62
uint32 nameDataLen
Definition: pg_control.h:214
MultiXactId oldestMulti
Definition: pg_control.h:48
uint32 pg_control_version
Definition: pg_control.h:124
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
CheckPoint checkPointCopy
Definition: pg_control.h:135
uint32 xlog_blcksz
Definition: pg_control.h:211
TransactionId oldestXid
Definition: pg_control.h:46
TransactionId nextXid
Definition: pg_control.h:42
MultiXactOffset nextMultiOffset
Definition: pg_control.h:45
TransactionId oldestCommitTsXid
Definition: pg_control.h:51
uint32 xlog_seg_size
Definition: pg_control.h:212
uint64 system_identifier
Definition: pg_control.h:109
uint32 nextXidEpoch
Definition: pg_control.h:41
uint32 data_checksum_version
Definition: pg_control.h:225
uint32 loblksize
Definition: pg_control.h:218
uint32 indexMaxKeys
Definition: pg_control.h:215
static bool guessed
Definition: pg_resetwal.c:62
TransactionId newestCommitTsXid
Definition: pg_control.h:53
Oid oldestMultiDB
Definition: pg_control.h:49
uint32 toast_max_chunk_size
Definition: pg_control.h:217
Oid nextOid
Definition: pg_control.h:43
bool fullPageWrites
Definition: pg_control.h:40
Oid oldestXidDB
Definition: pg_control.h:47
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
MultiXactId nextMulti
Definition: pg_control.h:44
uint32 catalog_version_no
Definition: pg_control.h:125
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
#define _(x)
Definition: elog.c:84
#define UINT64_FORMAT
Definition: c.h:316
uint32 relseg_size
Definition: pg_control.h:209
static void PrintNewControlValues ( void  )
static

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

702 {
703  char fname[MAXFNAMELEN];
704 
705  /* This will be always printed in order to keep format same. */
706  printf(_("\n\nValues to be changed:\n\n"));
707 
709  printf(_("First log segment after reset: %s\n"), fname);
710 
711  if (set_mxid != 0)
712  {
713  printf(_("NextMultiXactId: %u\n"),
715  printf(_("OldestMultiXid: %u\n"),
717  printf(_("OldestMulti's DB: %u\n"),
719  }
720 
721  if (set_mxoff != -1)
722  {
723  printf(_("NextMultiOffset: %u\n"),
725  }
726 
727  if (set_oid != 0)
728  {
729  printf(_("NextOID: %u\n"),
731  }
732 
733  if (set_xid != 0)
734  {
735  printf(_("NextXID: %u\n"),
737  printf(_("OldestXID: %u\n"),
739  printf(_("OldestXID's DB: %u\n"),
741  }
742 
743  if (set_xid_epoch != -1)
744  {
745  printf(_("NextXID epoch: %u\n"),
747  }
748 
749  if (set_oldest_commit_ts_xid != 0)
750  {
751  printf(_("oldestCommitTsXid: %u\n"),
753  }
754  if (set_newest_commit_ts_xid != 0)
755  {
756  printf(_("newestCommitTsXid: %u\n"),
758  }
759 }
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:48
static Oid set_oid
Definition: pg_resetwal.c:68
CheckPoint checkPointCopy
Definition: pg_control.h:135
TransactionId oldestXid
Definition: pg_control.h:46
TransactionId nextXid
Definition: pg_control.h:42
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:67
MultiXactOffset nextMultiOffset
Definition: pg_control.h:45
TransactionId oldestCommitTsXid
Definition: pg_control.h:51
uint32 nextXidEpoch
Definition: pg_control.h:41
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:66
#define MAXFNAMELEN
TransactionId newestCommitTsXid
Definition: pg_control.h:53
Oid oldestMultiDB
Definition: pg_control.h:49
Oid nextOid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:47
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
MultiXactId nextMulti
Definition: pg_control.h:44
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:70
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
#define _(x)
Definition: elog.c:84
static uint32 set_xid_epoch
Definition: pg_resetwal.c:64
static bool ReadControlFile ( void  )
static

Definition at line 462 of file pg_resetwal.c.

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

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

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

767 {
768  int fd;
769  char buffer[PG_CONTROL_SIZE]; /* need not be aligned */
770 
771  /*
772  * Adjust fields as needed to force an empty XLOG starting at
773  * newXlogSegNo.
774  */
778 
780  ControlFile.time = (pg_time_t) time(NULL);
788 
789  /*
790  * Force the defaults for max_* settings. The values don't really matter
791  * as long as wal_level='minimal'; the postmaster will reset these fields
792  * anyway at startup.
793  */
795  ControlFile.wal_log_hints = false;
801 
802  /* Now we can force the recorded xlog seg size to the right thing. */
804 
805  /* Contents are protected with a CRC */
808  (char *) &ControlFile,
809  offsetof(ControlFileData, crc));
811 
812  /*
813  * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
814  * excess over sizeof(ControlFileData). This reduces the odds of
815  * premature-EOF errors when reading pg_control. We'll still fail when we
816  * check the contents of the file, but hopefully with a more specific
817  * error than "couldn't read pg_control".
818  */
819  if (sizeof(ControlFileData) > PG_CONTROL_SIZE)
820  {
821  fprintf(stderr,
822  _("%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n"),
823  progname);
824  exit(1);
825  }
826 
827  memset(buffer, 0, PG_CONTROL_SIZE);
828  memcpy(buffer, &ControlFile, sizeof(ControlFileData));
829 
831 
832  fd = open(XLOG_CONTROL_FILE,
833  O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
834  S_IRUSR | S_IWUSR);
835  if (fd < 0)
836  {
837  fprintf(stderr, _("%s: could not create pg_control file: %s\n"),
838  progname, strerror(errno));
839  exit(1);
840  }
841 
842  errno = 0;
843  if (write(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE)
844  {
845  /* if write didn't set errno, assume problem is no disk space */
846  if (errno == 0)
847  errno = ENOSPC;
848  fprintf(stderr, _("%s: could not write pg_control file: %s\n"),
849  progname, strerror(errno));
850  exit(1);
851  }
852 
853  if (fsync(fd) != 0)
854  {
855  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
856  exit(1);
857  }
858 
859  close(fd);
860 }
#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:185
int max_prepared_xacts
Definition: pg_control.h:184
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:131
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:171
#define write(a, b, c)
Definition: win32.h:19
int max_worker_processes
Definition: pg_control.h:183
#define PG_CONTROL_SIZE
Definition: pg_control.h:245
CheckPoint checkPointCopy
Definition: pg_control.h:135
pg_time_t time
Definition: pg_control.h:50
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1038
#define XLogSegNoOffsetToRecPtr(segno, offset, dest)
Definition: xlog_internal.h:95
bool backupEndRequired
Definition: pg_control.h:174
uint32 xlog_seg_size
Definition: pg_control.h:212
pg_crc32c crc
Definition: pg_control.h:235
static const char * progname
Definition: pg_resetwal.c:63
int unlink(const char *filename)
#define fsync(fd)
Definition: win32.h:70
XLogRecPtr prevCheckPoint
Definition: pg_control.h:133
#define XLOG_CONTROL_FILE
XLogRecPtr backupEndPoint
Definition: pg_control.h:173
#define NULL
Definition: c.h:229
bool track_commit_timestamp
Definition: pg_control.h:186
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
static XLogSegNo newXlogSegNo
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
XLogRecPtr backupStartPoint
Definition: pg_control.h:172
XLogRecPtr checkPoint
Definition: pg_control.h:132
XLogRecPtr redo
Definition: pg_control.h:35
#define offsetof(type, field)
Definition: c.h:555
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:170
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void usage ( void  )
static

Definition at line 1160 of file pg_resetwal.c.

References _, and progname.

Referenced by main().

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

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

1062 {
1063  char *buffer;
1064  XLogPageHeader page;
1065  XLogLongPageHeader longpage;
1066  XLogRecord *record;
1067  pg_crc32c crc;
1068  char path[MAXPGPATH];
1069  int fd;
1070  int nbytes;
1071  char *recptr;
1072 
1073  /* Use malloc() to ensure buffer is MAXALIGNED */
1074  buffer = (char *) pg_malloc(XLOG_BLCKSZ);
1075  page = (XLogPageHeader) buffer;
1076  memset(buffer, 0, XLOG_BLCKSZ);
1077 
1078  /* Set up the XLOG page header */
1079  page->xlp_magic = XLOG_PAGE_MAGIC;
1080  page->xlp_info = XLP_LONG_HEADER;
1083  longpage = (XLogLongPageHeader) page;
1085  longpage->xlp_seg_size = XLogSegSize;
1086  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1087 
1088  /* Insert the initial checkpoint record */
1089  recptr = (char *) page + SizeOfXLogLongPHD;
1090  record = (XLogRecord *) recptr;
1091  record->xl_prev = 0;
1092  record->xl_xid = InvalidTransactionId;
1095  record->xl_rmid = RM_XLOG_ID;
1096 
1097  recptr += SizeOfXLogRecord;
1098  *(recptr++) = XLR_BLOCK_ID_DATA_SHORT;
1099  *(recptr++) = sizeof(CheckPoint);
1100  memcpy(recptr, &ControlFile.checkPointCopy,
1101  sizeof(CheckPoint));
1102 
1103  INIT_CRC32C(crc);
1104  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1105  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1106  FIN_CRC32C(crc);
1107  record->xl_crc = crc;
1108 
1109  /* Write the first page */
1111 
1112  unlink(path);
1113 
1114  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1115  S_IRUSR | S_IWUSR);
1116  if (fd < 0)
1117  {
1118  fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
1119  progname, path, strerror(errno));
1120  exit(1);
1121  }
1122 
1123  errno = 0;
1124  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1125  {
1126  /* if write didn't set errno, assume problem is no disk space */
1127  if (errno == 0)
1128  errno = ENOSPC;
1129  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1130  progname, path, strerror(errno));
1131  exit(1);
1132  }
1133 
1134  /* Fill the rest of the file with zeroes */
1135  memset(buffer, 0, XLOG_BLCKSZ);
1136  for (nbytes = XLOG_BLCKSZ; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ)
1137  {
1138  errno = 0;
1139  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1140  {
1141  if (errno == 0)
1142  errno = ENOSPC;
1143  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1144  progname, path, strerror(errno));
1145  exit(1);
1146  }
1147  }
1148 
1149  if (fsync(fd) != 0)
1150  {
1151  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
1152  exit(1);
1153  }
1154 
1155  close(fd);
1156 }
#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:135
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1038
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
uint64 system_identifier
Definition: pg_control.h:109
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define MAXPGPATH
#define XLogFilePath(path, tli, logSegNo)
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:66
#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: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
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:207
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:223
TransactionId xl_xid
Definition: xlogrecord.h:44
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
TimeLineID ThisTimeLineID
Definition: pg_control.h:37
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:35
#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().