PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_resetwal.c File Reference
#include "postgres.h"
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include "access/transam.h"
#include "access/tuptoaster.h"
#include "access/multixact.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "catalog/catversion.h"
#include "catalog/pg_control.h"
#include "common/fe_memutils.h"
#include "common/restricted_token.h"
#include "storage/large_object.h"
#include "pg_getopt.h"
Include dependency graph for pg_resetwal.c:

Go to the source code of this file.

Macros

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

Functions

static void CheckDataVersion (void)
 
static bool ReadControlFile (void)
 
static void GuessControlValues (void)
 
static void PrintControlValues (bool guessed)
 
static void PrintNewControlValues (void)
 
static void RewriteControlFile (void)
 
static void FindEndOfXLOG (void)
 
static void KillExistingXLOG (void)
 
static void KillExistingArchiveStatus (void)
 
static void WriteEmptyXLOG (void)
 
static void usage (void)
 
int main (int argc, char *argv[])
 

Variables

static ControlFileData ControlFile
 
static XLogSegNo newXlogSegNo
 
static bool guessed = false
 
static const char * progname
 
static uint32 set_xid_epoch = (uint32) -1
 
static TransactionId set_xid = 0
 
static TransactionId set_oldest_commit_ts_xid = 0
 
static TransactionId set_newest_commit_ts_xid = 0
 
static Oid set_oid = 0
 
static MultiXactId set_mxid = 0
 
static MultiXactOffset set_mxoff = (MultiXactOffset) -1
 
static uint32 minXlogTli = 0
 
static XLogSegNo minXlogSegNo = 0
 

Macro Definition Documentation

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

Definition at line 36 of file pg_resetwal.c.

Function Documentation

static void CheckDataVersion ( void  )
static

Definition at line 472 of file pg_resetwal.c.

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

Referenced by main().

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

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

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

Definition at line 602 of file pg_resetwal.c.

References ControlFileData::blcksz, CATALOG_VERSION_NO, ControlFileData::catalog_version_no, ControlFileData::checkPoint, ControlFileData::checkPointCopy, DB_SHUTDOWNED, FirstBootstrapObjectId, FirstMultiXactId, FirstNormalTransactionId, ControlFileData::float4ByVal, ControlFileData::float8ByVal, ControlFileData::floatFormat, FLOATFORMAT_VALUE, CheckPoint::fullPageWrites, gettimeofday(), guessed, INDEX_MAX_KEYS, ControlFileData::indexMaxKeys, InvalidOid, InvalidTransactionId, LOBLKSIZE, ControlFileData::loblksize, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_worker_processes, ControlFileData::maxAlign, ControlFileData::MaxConnections, NAMEDATALEN, ControlFileData::nameDataLen, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, CheckPoint::nextXidEpoch, NULL, CheckPoint::oldestActiveXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, PG_CONTROL_VERSION, ControlFileData::pg_control_version, CheckPoint::PrevTimeLineID, CheckPoint::redo, ControlFileData::relseg_size, SizeOfXLogLongPHD, ControlFileData::state, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, CheckPoint::time, ControlFileData::time, TOAST_MAX_CHUNK_SIZE, ControlFileData::toast_max_chunk_size, ControlFileData::track_commit_timestamp, ControlFileData::unloggedLSN, ControlFileData::wal_level, WAL_LEVEL_MINIMAL, ControlFileData::wal_log_hints, ControlFileData::xlog_blcksz, and ControlFileData::xlog_seg_size.

Referenced by main().

603 {
604  uint64 sysidentifier;
605  struct timeval tv;
606 
607  /*
608  * Set up a completely default set of pg_control values.
609  */
610  guessed = true;
611  memset(&ControlFile, 0, sizeof(ControlFile));
612 
615 
616  /*
617  * Create a new unique installation identifier, since we can no longer use
618  * any old XLOG records. See notes in xlog.c about the algorithm.
619  */
620  gettimeofday(&tv, NULL);
621  sysidentifier = ((uint64) tv.tv_sec) << 32;
622  sysidentifier |= ((uint64) tv.tv_usec) << 12;
623  sysidentifier |= getpid() & 0xFFF;
624 
625  ControlFile.system_identifier = sysidentifier;
626 
642 
644  ControlFile.time = (pg_time_t) time(NULL);
647 
648  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
649 
651  ControlFile.wal_log_hints = false;
657 
658  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
660  ControlFile.blcksz = BLCKSZ;
661  ControlFile.relseg_size = RELSEG_SIZE;
662  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
663  ControlFile.xlog_seg_size = XLOG_SEG_SIZE;
668  ControlFile.float4ByVal = FLOAT4PASSBYVAL;
669  ControlFile.float8ByVal = FLOAT8PASSBYVAL;
670 
671  /*
672  * XXX eventually, should try to grovel through old XLOG to develop more
673  * accurate values for TimeLineID, nextXID, etc.
674  */
675 }
#define LOBLKSIZE
Definition: large_object.h:72
int max_locks_per_xact
Definition: pg_control.h: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 1074 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().

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

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

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

Definition at line 88 of file pg_resetwal.c.

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

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

Definition at line 685 of file pg_resetwal.c.

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

Referenced by main().

686 {
687  char sysident_str[32];
688 
689  if (guessed)
690  printf(_("Guessed pg_control values:\n\n"));
691  else
692  printf(_("Current pg_control values:\n\n"));
693 
694  /*
695  * Format system_identifier separately to keep platform-dependent format
696  * code out of the translatable message string.
697  */
698  snprintf(sysident_str, sizeof(sysident_str), UINT64_FORMAT,
700 
701  printf(_("pg_control version number: %u\n"),
703  printf(_("Catalog version number: %u\n"),
705  printf(_("Database system identifier: %s\n"),
706  sysident_str);
707  printf(_("Latest checkpoint's TimeLineID: %u\n"),
709  printf(_("Latest checkpoint's full_page_writes: %s\n"),
710  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
711  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
714  printf(_("Latest checkpoint's NextOID: %u\n"),
716  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
718  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
720  printf(_("Latest checkpoint's oldestXID: %u\n"),
722  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
724  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
726  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
728  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
730  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
732  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
734  printf(_("Maximum data alignment: %u\n"),
736  /* we don't print floatFormat since can't say much useful about it */
737  printf(_("Database block size: %u\n"),
739  printf(_("Blocks per segment of large relation: %u\n"),
741  printf(_("WAL block size: %u\n"),
743  printf(_("Bytes per WAL segment: %u\n"),
745  printf(_("Maximum length of identifiers: %u\n"),
747  printf(_("Maximum columns in an index: %u\n"),
749  printf(_("Maximum size of a TOAST chunk: %u\n"),
751  printf(_("Size of a large-object chunk: %u\n"),
753  /* This is no longer configurable, but users may still expect to see it: */
754  printf(_("Date/time type storage: %s\n"),
755  _("64-bit integers"));
756  printf(_("Float4 argument passing: %s\n"),
757  (ControlFile.float4ByVal ? _("by value") : _("by reference")));
758  printf(_("Float8 argument passing: %s\n"),
759  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
760  printf(_("Data page checksum version: %u\n"),
762 }
TransactionId oldestActiveXid
Definition: pg_control.h: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 769 of file pg_resetwal.c.

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

Referenced by main().

770 {
771  char fname[MAXFNAMELEN];
772 
773  /* This will be always printed in order to keep format same. */
774  printf(_("\n\nValues to be changed:\n\n"));
775 
777  printf(_("First log segment after reset: %s\n"), fname);
778 
779  if (set_mxid != 0)
780  {
781  printf(_("NextMultiXactId: %u\n"),
783  printf(_("OldestMultiXid: %u\n"),
785  printf(_("OldestMulti's DB: %u\n"),
787  }
788 
789  if (set_mxoff != -1)
790  {
791  printf(_("NextMultiOffset: %u\n"),
793  }
794 
795  if (set_oid != 0)
796  {
797  printf(_("NextOID: %u\n"),
799  }
800 
801  if (set_xid != 0)
802  {
803  printf(_("NextXID: %u\n"),
805  printf(_("OldestXID: %u\n"),
807  printf(_("OldestXID's DB: %u\n"),
809  }
810 
811  if (set_xid_epoch != -1)
812  {
813  printf(_("NextXID epoch: %u\n"),
815  }
816 
817  if (set_oldest_commit_ts_xid != 0)
818  {
819  printf(_("oldestCommitTsXid: %u\n"),
821  }
822  if (set_newest_commit_ts_xid != 0)
823  {
824  printf(_("newestCommitTsXid: %u\n"),
826  }
827 }
static MultiXactId set_mxid
Definition: pg_resetwal.c:69
static TransactionId set_xid
Definition: pg_resetwal.c:65
#define XLogFileName(fname, tli, logSegNo)
MultiXactId oldestMulti
Definition: pg_control.h: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 530 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().

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

Definition at line 834 of file pg_resetwal.c.

References _, ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, buffer, ControlFileData::checkPoint, ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFileData::crc, DB_SHUTDOWNED, fd(), FIN_CRC32C, fsync, INIT_CRC32C, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_worker_processes, ControlFileData::MaxConnections, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, newXlogSegNo, NULL, offsetof, PG_BINARY, PG_CONTROL_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().

835 {
836  int fd;
837  char buffer[PG_CONTROL_SIZE]; /* need not be aligned */
838 
839  /*
840  * Adjust fields as needed to force an empty XLOG starting at
841  * newXlogSegNo.
842  */
846 
848  ControlFile.time = (pg_time_t) time(NULL);
856 
857  /*
858  * Force the defaults for max_* settings. The values don't really matter
859  * as long as wal_level='minimal'; the postmaster will reset these fields
860  * anyway at startup.
861  */
863  ControlFile.wal_log_hints = false;
869 
870  /* Now we can force the recorded xlog seg size to the right thing. */
872 
873  /* Contents are protected with a CRC */
876  (char *) &ControlFile,
877  offsetof(ControlFileData, crc));
879 
880  /*
881  * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
882  * excess over sizeof(ControlFileData). This reduces the odds of
883  * premature-EOF errors when reading pg_control. We'll still fail when we
884  * check the contents of the file, but hopefully with a more specific
885  * error than "couldn't read pg_control".
886  */
887  if (sizeof(ControlFileData) > PG_CONTROL_SIZE)
888  {
889  fprintf(stderr,
890  _("%s: internal error -- sizeof(ControlFileData) is too large ... fix PG_CONTROL_SIZE\n"),
891  progname);
892  exit(1);
893  }
894 
895  memset(buffer, 0, PG_CONTROL_SIZE);
896  memcpy(buffer, &ControlFile, sizeof(ControlFileData));
897 
899 
900  fd = open(XLOG_CONTROL_FILE,
901  O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
902  S_IRUSR | S_IWUSR);
903  if (fd < 0)
904  {
905  fprintf(stderr, _("%s: could not create pg_control file: %s\n"),
906  progname, strerror(errno));
907  exit(1);
908  }
909 
910  errno = 0;
911  if (write(fd, buffer, PG_CONTROL_SIZE) != PG_CONTROL_SIZE)
912  {
913  /* if write didn't set errno, assume problem is no disk space */
914  if (errno == 0)
915  errno = ENOSPC;
916  fprintf(stderr, _("%s: could not write pg_control file: %s\n"),
917  progname, strerror(errno));
918  exit(1);
919  }
920 
921  if (fsync(fd) != 0)
922  {
923  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
924  exit(1);
925  }
926 
927  close(fd);
928 }
#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:14
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:62
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:214
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:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
XLogRecPtr backupStartPoint
Definition: pg_control.h: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 1228 of file pg_resetwal.c.

References _, and progname.

Referenced by main().

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

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

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