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
 
static int WalSegSz
 

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 482 of file pg_resetwal.c.

References _, progname, and strerror().

Referenced by main().

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

Definition at line 961 of file pg_resetwal.c.

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

Referenced by main().

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

Definition at line 621 of file pg_resetwal.c.

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

622 {
623  uint64 sysidentifier;
624  struct timeval tv;
625 
626  /*
627  * Set up a completely default set of pg_control values.
628  */
629  guessed = true;
630  memset(&ControlFile, 0, sizeof(ControlFile));
631 
634 
635  /*
636  * Create a new unique installation identifier, since we can no longer use
637  * any old XLOG records. See notes in xlog.c about the algorithm.
638  */
639  gettimeofday(&tv, NULL);
640  sysidentifier = ((uint64) tv.tv_sec) << 32;
641  sysidentifier |= ((uint64) tv.tv_usec) << 12;
642  sysidentifier |= getpid() & 0xFFF;
643 
644  ControlFile.system_identifier = sysidentifier;
645 
659  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
661 
663  ControlFile.time = (pg_time_t) time(NULL);
666 
667  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
668 
670  ControlFile.wal_log_hints = false;
676 
677  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
679  ControlFile.blcksz = BLCKSZ;
680  ControlFile.relseg_size = RELSEG_SIZE;
681  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
687  ControlFile.float4ByVal = FLOAT4PASSBYVAL;
688  ControlFile.float8ByVal = FLOAT8PASSBYVAL;
689 
690  /*
691  * XXX eventually, should try to grovel through old XLOG to develop more
692  * accurate values for TimeLineID, nextXID, etc.
693  */
694 }
#define LOBLKSIZE
Definition: large_object.h:72
int max_locks_per_xact
Definition: pg_control.h:182
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:105
int max_prepared_xacts
Definition: pg_control.h:181
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:128
int max_worker_processes
Definition: pg_control.h:180
TransactionId oldestActiveXid
Definition: pg_control.h:63
uint32 nameDataLen
Definition: pg_control.h:211
MultiXactId oldestMulti
Definition: pg_control.h:49
#define DEFAULT_XLOG_SEG_SIZE
TimeLineID PrevTimeLineID
Definition: pg_control.h:39
#define CATALOG_VERSION_NO
Definition: catversion.h:56
#define PG_CONTROL_VERSION
Definition: pg_control.h:24
uint32 pg_control_version
Definition: pg_control.h:121
CheckPoint checkPointCopy
Definition: pg_control.h:132
uint32 xlog_blcksz
Definition: pg_control.h:208
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
#define NAMEDATALEN
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
uint32 xlog_seg_size
Definition: pg_control.h:209
#define FirstNormalTransactionId
Definition: transam.h:34
uint64 system_identifier
Definition: pg_control.h:106
uint32 nextXidEpoch
Definition: pg_control.h:42
XLogRecPtr unloggedLSN
Definition: pg_control.h:134
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:93
#define FirstMultiXactId
Definition: multixact.h:24
uint32 loblksize
Definition: pg_control.h:215
uint32 indexMaxKeys
Definition: pg_control.h:212
static bool guessed
Definition: pg_resetwal.c:62
#define TOAST_MAX_CHUNK_SIZE
Definition: tuptoaster.h:91
Oid oldestMultiDB
Definition: pg_control.h:50
uint32 toast_max_chunk_size
Definition: pg_control.h:214
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:44
bool fullPageWrites
Definition: pg_control.h:41
bool track_commit_timestamp
Definition: pg_control.h:183
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
double floatFormat
Definition: pg_control.h:198
#define INDEX_MAX_KEYS
MultiXactId nextMulti
Definition: pg_control.h:45
uint32 catalog_version_no
Definition: pg_control.h:122
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
#define FLOATFORMAT_VALUE
Definition: pg_control.h:199
uint32 relseg_size
Definition: pg_control.h:206
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void KillExistingArchiveStatus ( void  )
static

Definition at line 1095 of file pg_resetwal.c.

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

Referenced by main().

1096 {
1097 #define ARCHSTATDIR XLOGDIR "/archive_status"
1098 
1099  DIR *xldir;
1100  struct dirent *xlde;
1101  char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1102 
1103  xldir = opendir(ARCHSTATDIR);
1104  if (xldir == NULL)
1105  {
1106  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
1107  progname, ARCHSTATDIR, strerror(errno));
1108  exit(1);
1109  }
1110 
1111  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1112  {
1113  if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1114  (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1115  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1116  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1117  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1118  {
1119  snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1120  if (unlink(path) < 0)
1121  {
1122  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
1123  progname, path, strerror(errno));
1124  exit(1);
1125  }
1126  }
1127  }
1128 
1129  if (errno)
1130  {
1131  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
1132  progname, ARCHSTATDIR, strerror(errno));
1133  exit(1);
1134  }
1135 
1136  if (closedir(xldir))
1137  {
1138  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1139  progname, ARCHSTATDIR, strerror(errno));
1140  exit(1);
1141  }
1142 }
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
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 1046 of file pg_resetwal.c.

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

Referenced by main().

1047 {
1048  DIR *xldir;
1049  struct dirent *xlde;
1050  char path[MAXPGPATH + sizeof(XLOGDIR)];
1051 
1052  xldir = opendir(XLOGDIR);
1053  if (xldir == NULL)
1054  {
1055  fprintf(stderr, _("%s: could not open directory \"%s\": %s\n"),
1056  progname, XLOGDIR, strerror(errno));
1057  exit(1);
1058  }
1059 
1060  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1061  {
1062  if (IsXLogFileName(xlde->d_name) ||
1064  {
1065  snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
1066  if (unlink(path) < 0)
1067  {
1068  fprintf(stderr, _("%s: could not delete file \"%s\": %s\n"),
1069  progname, path, strerror(errno));
1070  exit(1);
1071  }
1072  }
1073  }
1074 
1075  if (errno)
1076  {
1077  fprintf(stderr, _("%s: could not read directory \"%s\": %s\n"),
1078  progname, XLOGDIR, strerror(errno));
1079  exit(1);
1080  }
1081 
1082  if (closedir(xldir))
1083  {
1084  fprintf(stderr, _("%s: could not close directory \"%s\": %s\n"),
1085  progname, XLOGDIR, strerror(errno));
1086  exit(1);
1087  }
1088 }
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
#define XLOGDIR
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 89 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, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, optarg, optind, pg_strdup(), 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(), WalSegSz, WriteEmptyXLOG(), XLOG_FNAME_LEN, and XLogFromFileName.

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

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

Definition at line 788 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, WalSegSz, and XLogFileName.

Referenced by main().

789 {
790  char fname[MAXFNAMELEN];
791 
792  /* This will be always printed in order to keep format same. */
793  printf(_("\n\nValues to be changed:\n\n"));
794 
797  printf(_("First log segment after reset: %s\n"), fname);
798 
799  if (set_mxid != 0)
800  {
801  printf(_("NextMultiXactId: %u\n"),
803  printf(_("OldestMultiXid: %u\n"),
805  printf(_("OldestMulti's DB: %u\n"),
807  }
808 
809  if (set_mxoff != -1)
810  {
811  printf(_("NextMultiOffset: %u\n"),
813  }
814 
815  if (set_oid != 0)
816  {
817  printf(_("NextOID: %u\n"),
819  }
820 
821  if (set_xid != 0)
822  {
823  printf(_("NextXID: %u\n"),
825  printf(_("OldestXID: %u\n"),
827  printf(_("OldestXID's DB: %u\n"),
829  }
830 
831  if (set_xid_epoch != -1)
832  {
833  printf(_("NextXID epoch: %u\n"),
835  }
836 
837  if (set_oldest_commit_ts_xid != 0)
838  {
839  printf(_("oldestCommitTsXid: %u\n"),
841  }
842  if (set_newest_commit_ts_xid != 0)
843  {
844  printf(_("newestCommitTsXid: %u\n"),
846  }
847 }
static MultiXactId set_mxid
Definition: pg_resetwal.c:69
static TransactionId set_xid
Definition: pg_resetwal.c:65
MultiXactId oldestMulti
Definition: pg_control.h:49
static Oid set_oid
Definition: pg_resetwal.c:68
CheckPoint checkPointCopy
Definition: pg_control.h:132
TransactionId oldestXid
Definition: pg_control.h:47
TransactionId nextXid
Definition: pg_control.h:43
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:67
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
uint32 nextXidEpoch
Definition: pg_control.h:42
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:66
#define MAXFNAMELEN
TransactionId newestCommitTsXid
Definition: pg_control.h:54
Oid oldestMultiDB
Definition: pg_control.h:50
Oid nextOid
Definition: pg_control.h:44
static int WalSegSz
Definition: pg_resetwal.c:73
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
MultiXactId nextMulti
Definition: pg_control.h:45
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:70
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
#define _(x)
Definition: elog.c:84
static uint32 set_xid_epoch
Definition: pg_resetwal.c:64
static bool ReadControlFile ( void  )
static

Definition at line 540 of file pg_resetwal.c.

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

Referenced by main().

541 {
542  int fd;
543  int len;
544  char *buffer;
545  pg_crc32c crc;
546 
547  if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
548  {
549  /*
550  * If pg_control is not there at all, or we can't read it, the odds
551  * are we've been handed a bad DataDir path, so give up. User can do
552  * "touch pg_control" to force us to proceed.
553  */
554  fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),
556  if (errno == ENOENT)
557  fprintf(stderr, _("If you are sure the data directory path is correct, execute\n"
558  " touch %s\n"
559  "and try again.\n"),
561  exit(1);
562  }
563 
564  /* Use malloc to ensure we have a maxaligned buffer */
565  buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
566 
567  len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
568  if (len < 0)
569  {
570  fprintf(stderr, _("%s: could not read file \"%s\": %s\n"),
572  exit(1);
573  }
574  close(fd);
575 
576  if (len >= sizeof(ControlFileData) &&
577  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
578  {
579  /* Check the CRC. */
580  INIT_CRC32C(crc);
581  COMP_CRC32C(crc,
582  buffer,
583  offsetof(ControlFileData, crc));
584  FIN_CRC32C(crc);
585 
586  if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
587  {
588  /* We will use the data but treat it as guessed. */
589  fprintf(stderr,
590  _("%s: pg_control exists but has invalid CRC; proceed with caution\n"),
591  progname);
592  guessed = true;
593  }
594 
595  memcpy(&ControlFile, buffer, sizeof(ControlFile));
597 
598  /* return false if WalSegSz is not valid */
600  {
601  fprintf(stderr,
602  _("%s: pg_control specifies invalid WAL segment size (%d bytes); proceed with caution \n"),
603  progname, WalSegSz);
604  guessed = true;
605  }
606 
607  return true;
608  }
609 
610  /* Looks like it's a mess. */
611  fprintf(stderr, _("%s: pg_control exists but is broken or wrong version; ignoring it\n"),
612  progname);
613  return false;
614 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define IsValidWalSegSize(size)
Definition: xlog_internal.h:97
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define PG_CONTROL_VERSION
Definition: pg_control.h:24
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1044
uint32 xlog_seg_size
Definition: pg_control.h:209
#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
static int WalSegSz
Definition: pg_resetwal.c:73
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:250
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
#define read(a, b, c)
Definition: win32.h:13
#define offsetof(type, field)
Definition: c.h:549
static void RewriteControlFile ( void  )
static

Definition at line 854 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, offsetof, PG_BINARY, PG_CONTROL_FILE_SIZE, PG_CONTROL_MAX_SAFE_SIZE, ControlFileData::prevCheckPoint, progname, CheckPoint::redo, SizeOfXLogLongPHD, ControlFileData::state, StaticAssertStmt, strerror(), CheckPoint::time, ControlFileData::time, ControlFileData::track_commit_timestamp, ControlFileData::wal_level, WAL_LEVEL_MINIMAL, ControlFileData::wal_log_hints, WalSegSz, write, XLOG_CONTROL_FILE, ControlFileData::xlog_seg_size, and XLogSegNoOffsetToRecPtr.

Referenced by main().

855 {
856  int fd;
857  char buffer[PG_CONTROL_FILE_SIZE]; /* need not be aligned */
858 
859  /*
860  * For good luck, apply the same static assertions as in backend's
861  * WriteControlFile().
862  */
864  "pg_control is too large for atomic disk writes");
866  "sizeof(ControlFileData) exceeds PG_CONTROL_FILE_SIZE");
867 
868  /*
869  * Adjust fields as needed to force an empty XLOG starting at
870  * newXlogSegNo.
871  */
874  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
875 
877  ControlFile.time = (pg_time_t) time(NULL);
885 
886  /*
887  * Force the defaults for max_* settings. The values don't really matter
888  * as long as wal_level='minimal'; the postmaster will reset these fields
889  * anyway at startup.
890  */
892  ControlFile.wal_log_hints = false;
898 
899  /* Now we can force the recorded xlog seg size to the right thing. */
901 
902  /* Contents are protected with a CRC */
905  (char *) &ControlFile,
906  offsetof(ControlFileData, crc));
908 
909  /*
910  * We write out PG_CONTROL_FILE_SIZE bytes into pg_control, zero-padding
911  * the excess over sizeof(ControlFileData). This reduces the odds of
912  * premature-EOF errors when reading pg_control. We'll still fail when we
913  * check the contents of the file, but hopefully with a more specific
914  * error than "couldn't read pg_control".
915  */
916  memset(buffer, 0, PG_CONTROL_FILE_SIZE);
917  memcpy(buffer, &ControlFile, sizeof(ControlFileData));
918 
919  unlink(XLOG_CONTROL_FILE);
920 
921  fd = open(XLOG_CONTROL_FILE,
922  O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
923  S_IRUSR | S_IWUSR);
924  if (fd < 0)
925  {
926  fprintf(stderr, _("%s: could not create pg_control file: %s\n"),
927  progname, strerror(errno));
928  exit(1);
929  }
930 
931  errno = 0;
932  if (write(fd, buffer, PG_CONTROL_FILE_SIZE) != PG_CONTROL_FILE_SIZE)
933  {
934  /* if write didn't set errno, assume problem is no disk space */
935  if (errno == 0)
936  errno = ENOSPC;
937  fprintf(stderr, _("%s: could not write pg_control file: %s\n"),
938  progname, strerror(errno));
939  exit(1);
940  }
941 
942  if (fsync(fd) != 0)
943  {
944  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
945  exit(1);
946  }
947 
948  close(fd);
949 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
int max_locks_per_xact
Definition: pg_control.h:182
int max_prepared_xacts
Definition: pg_control.h:181
int64 pg_time_t
Definition: pgtime.h:23
pg_time_t time
Definition: pg_control.h:128
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:168
#define write(a, b, c)
Definition: win32.h:14
int max_worker_processes
Definition: pg_control.h:180
CheckPoint checkPointCopy
Definition: pg_control.h:132
#define PG_CONTROL_MAX_SAFE_SIZE
Definition: pg_control.h:241
pg_time_t time
Definition: pg_control.h:51
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1044
bool backupEndRequired
Definition: pg_control.h:171
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:763
uint32 xlog_seg_size
Definition: pg_control.h:209
#define XLogSegNoOffsetToRecPtr(segno, offset, dest, wal_segsz_bytes)
pg_crc32c crc
Definition: pg_control.h:232
static const char * progname
Definition: pg_resetwal.c:63
#define fsync(fd)
Definition: win32.h:62
XLogRecPtr prevCheckPoint
Definition: pg_control.h:130
#define XLOG_CONTROL_FILE
XLogRecPtr backupEndPoint
Definition: pg_control.h:170
static int WalSegSz
Definition: pg_resetwal.c:73
bool track_commit_timestamp
Definition: pg_control.h:183
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
static ControlFileData ControlFile
Definition: pg_resetwal.c:60
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:250
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
XLogRecPtr backupStartPoint
Definition: pg_control.h:169
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:549
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:167
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
static void usage ( void  )
static

Definition at line 1250 of file pg_resetwal.c.

References _, and progname.

Referenced by main().

1251 {
1252  printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1253  printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
1254  printf(_("Options:\n"));
1255  printf(_(" -c XID,XID set oldest and newest transactions bearing commit timestamp\n"));
1256  printf(_(" (zero in either value means no change)\n"));
1257  printf(_(" [-D] DATADIR data directory\n"));
1258  printf(_(" -e XIDEPOCH set next transaction ID epoch\n"));
1259  printf(_(" -f force update to be done\n"));
1260  printf(_(" -l WALFILE force minimum WAL starting location for new write-ahead log\n"));
1261  printf(_(" -m MXID,MXID set next and oldest multitransaction ID\n"));
1262  printf(_(" -n no update, just show what would be done (for testing)\n"));
1263  printf(_(" -o OID set next OID\n"));
1264  printf(_(" -O OFFSET set next multitransaction offset\n"));
1265  printf(_(" -V, --version output version information, then exit\n"));
1266  printf(_(" -x XID set next transaction ID\n"));
1267  printf(_(" -?, --help show this help, then exit\n"));
1268  printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
1269 }
static const char * progname
Definition: pg_resetwal.c:63
#define _(x)
Definition: elog.c:84
static void WriteEmptyXLOG ( void  )
static

Definition at line 1150 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, WalSegSz, 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, 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().

1151 {
1152  char *buffer;
1153  XLogPageHeader page;
1154  XLogLongPageHeader longpage;
1155  XLogRecord *record;
1156  pg_crc32c crc;
1157  char path[MAXPGPATH];
1158  int fd;
1159  int nbytes;
1160  char *recptr;
1161 
1162  /* Use malloc() to ensure buffer is MAXALIGNED */
1163  buffer = (char *) pg_malloc(XLOG_BLCKSZ);
1164  page = (XLogPageHeader) buffer;
1165  memset(buffer, 0, XLOG_BLCKSZ);
1166 
1167  /* Set up the XLOG page header */
1168  page->xlp_magic = XLOG_PAGE_MAGIC;
1169  page->xlp_info = XLP_LONG_HEADER;
1172  longpage = (XLogLongPageHeader) page;
1174  longpage->xlp_seg_size = WalSegSz;
1175  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1176 
1177  /* Insert the initial checkpoint record */
1178  recptr = (char *) page + SizeOfXLogLongPHD;
1179  record = (XLogRecord *) recptr;
1180  record->xl_prev = 0;
1181  record->xl_xid = InvalidTransactionId;
1184  record->xl_rmid = RM_XLOG_ID;
1185 
1186  recptr += SizeOfXLogRecord;
1187  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1188  *(recptr++) = sizeof(CheckPoint);
1189  memcpy(recptr, &ControlFile.checkPointCopy,
1190  sizeof(CheckPoint));
1191 
1192  INIT_CRC32C(crc);
1193  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1194  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1195  FIN_CRC32C(crc);
1196  record->xl_crc = crc;
1197 
1198  /* Write the first page */
1201 
1202  unlink(path);
1203 
1204  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1205  S_IRUSR | S_IWUSR);
1206  if (fd < 0)
1207  {
1208  fprintf(stderr, _("%s: could not open file \"%s\": %s\n"),
1209  progname, path, strerror(errno));
1210  exit(1);
1211  }
1212 
1213  errno = 0;
1214  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1215  {
1216  /* if write didn't set errno, assume problem is no disk space */
1217  if (errno == 0)
1218  errno = ENOSPC;
1219  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1220  progname, path, strerror(errno));
1221  exit(1);
1222  }
1223 
1224  /* Fill the rest of the file with zeroes */
1225  memset(buffer, 0, XLOG_BLCKSZ);
1226  for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1227  {
1228  errno = 0;
1229  if (write(fd, buffer, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1230  {
1231  if (errno == 0)
1232  errno = ENOSPC;
1233  fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
1234  progname, path, strerror(errno));
1235  exit(1);
1236  }
1237  }
1238 
1239  if (fsync(fd) != 0)
1240  {
1241  fprintf(stderr, _("%s: fsync error: %s\n"), progname, strerror(errno));
1242  exit(1);
1243  }
1244 
1245  close(fd);
1246 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:201
uint32 pg_crc32c
Definition: pg_crc32c.h:38
RmgrId xl_rmid
Definition: xlogrecord.h:47
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:57
CheckPoint checkPointCopy
Definition: pg_control.h:132
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1044
XLogLongPageHeaderData * XLogLongPageHeader
Definition: xlog_internal.h:74
uint64 system_identifier
Definition: pg_control.h:106
uint32 xl_tot_len
Definition: xlogrecord.h:43
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define MAXPGPATH
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
#define InvalidTransactionId
Definition: transam.h:31
static const char * progname
Definition: pg_resetwal.c:63
#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
static int WalSegSz
Definition: pg_resetwal.c:73
#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
#define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes)
TransactionId xl_xid
Definition: xlogrecord.h:44
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:61
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:73
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:78
#define _(x)
Definition: elog.c:84
XLogRecPtr redo
Definition: pg_control.h:36
#define offsetof(type, field)
Definition: c.h:549
#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().

int WalSegSz
static