PostgreSQL Source Code  git master
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/heaptoast.h"
#include "access/multixact.h"
#include "access/transam.h"
#include "access/xlog.h"
#include "access/xlog_internal.h"
#include "common/controldata_utils.h"
#include "common/fe_memutils.h"
#include "common/file_perm.h"
#include "common/logging.h"
#include "common/restricted_token.h"
#include "common/string.h"
#include "getopt_long.h"
#include "pg_getopt.h"
#include "storage/large_object.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
 
static int set_wal_segsize
 

Macro Definition Documentation

◆ ARCHSTATDIR

#define ARCHSTATDIR   XLOGDIR "/archive_status"

◆ FRONTEND

#define FRONTEND   1

Definition at line 36 of file pg_resetwal.c.

Function Documentation

◆ CheckDataVersion()

static void CheckDataVersion ( void  )
static

Definition at line 536 of file pg_resetwal.c.

References pg_log_error, pg_log_info, and pg_strip_crlf().

Referenced by main().

537 {
538  const char *ver_file = "PG_VERSION";
539  FILE *ver_fd;
540  char rawline[64];
541 
542  if ((ver_fd = fopen(ver_file, "r")) == NULL)
543  {
544  pg_log_error("could not open file \"%s\" for reading: %m",
545  ver_file);
546  exit(1);
547  }
548 
549  /* version number has to be the first line read */
550  if (!fgets(rawline, sizeof(rawline), ver_fd))
551  {
552  if (!ferror(ver_fd))
553  pg_log_error("unexpected empty file \"%s\"", ver_file);
554  else
555  pg_log_error("could not read file \"%s\": %m", ver_file);
556  exit(1);
557  }
558 
559  /* strip trailing newline and carriage return */
560  (void) pg_strip_crlf(rawline);
561 
562  if (strcmp(rawline, PG_MAJORVERSION) != 0)
563  {
564  pg_log_error("data directory is of wrong version");
565  pg_log_info("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
566  ver_file, rawline, PG_MAJORVERSION);
567  exit(1);
568  }
569 
570  fclose(ver_fd);
571 }
int pg_strip_crlf(char *str)
Definition: string.c:105
#define pg_log_error(...)
Definition: logging.h:79
#define pg_log_info(...)
Definition: logging.h:87

◆ FindEndOfXLOG()

static void FindEndOfXLOG ( void  )
static

Definition at line 933 of file pg_resetwal.c.

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

Referenced by main().

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

◆ GuessControlValues()

static void GuessControlValues ( void  )
static

Definition at line 658 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, FirstNormalUnloggedLSN, ControlFileData::float8ByVal, FLOAT8PASSBYVAL, ControlFileData::floatFormat, FLOATFORMAT_VALUE, CheckPoint::fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), guessed, INDEX_MAX_KEYS, ControlFileData::indexMaxKeys, InvalidOid, InvalidTransactionId, LOBLKSIZE, ControlFileData::loblksize, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_wal_senders, ControlFileData::max_worker_processes, ControlFileData::maxAlign, ControlFileData::MaxConnections, NAMEDATALEN, ControlFileData::nameDataLen, CheckPoint::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, 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().

659 {
660  uint64 sysidentifier;
661  struct timeval tv;
662 
663  /*
664  * Set up a completely default set of pg_control values.
665  */
666  guessed = true;
667  memset(&ControlFile, 0, sizeof(ControlFile));
668 
671 
672  /*
673  * Create a new unique installation identifier, since we can no longer use
674  * any old XLOG records. See notes in xlog.c about the algorithm.
675  */
676  gettimeofday(&tv, NULL);
677  sysidentifier = ((uint64) tv.tv_sec) << 32;
678  sysidentifier |= ((uint64) tv.tv_usec) << 12;
679  sysidentifier |= getpid() & 0xFFF;
680 
681  ControlFile.system_identifier = sysidentifier;
682 
696  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
698 
700  ControlFile.time = (pg_time_t) time(NULL);
703 
704  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
705 
707  ControlFile.wal_log_hints = false;
714 
715  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
717  ControlFile.blcksz = BLCKSZ;
718  ControlFile.relseg_size = RELSEG_SIZE;
719  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
726 
727  /*
728  * XXX eventually, should try to grovel through old XLOG to develop more
729  * accurate values for TimeLineID, nextXID, etc.
730  */
731 }
#define LOBLKSIZE
Definition: large_object.h:70
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
#define TOAST_MAX_CHUNK_SIZE
Definition: heaptoast.h:84
pg_time_t time
Definition: pg_control.h:128
int max_worker_processes
Definition: pg_control.h:179
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:40
#define CATALOG_VERSION_NO
Definition: catversion.h:56
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
uint32 pg_control_version
Definition: pg_control.h:121
CheckPoint checkPointCopy
Definition: pg_control.h:131
uint32 xlog_blcksz
Definition: pg_control.h:208
TransactionId oldestXid
Definition: pg_control.h:47
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
XLogRecPtr unloggedLSN
Definition: pg_control.h:133
#define InvalidTransactionId
Definition: transam.h:31
#define FirstBootstrapObjectId
Definition: transam.h:140
#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:64
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:36
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:42
#define FLOAT8PASSBYVAL
Definition: c.h:497
bool track_commit_timestamp
Definition: pg_control.h:183
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
double floatFormat
Definition: pg_control.h:198
#define INDEX_MAX_KEYS
MultiXactId nextMulti
Definition: pg_control.h:45
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:65
uint32 catalog_version_no
Definition: pg_control.h:122
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
#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:37
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72

◆ KillExistingArchiveStatus()

static void KillExistingArchiveStatus ( void  )
static

Definition at line 1060 of file pg_resetwal.c.

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

Referenced by main().

1061 {
1062 #define ARCHSTATDIR XLOGDIR "/archive_status"
1063 
1064  DIR *xldir;
1065  struct dirent *xlde;
1066  char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1067 
1068  xldir = opendir(ARCHSTATDIR);
1069  if (xldir == NULL)
1070  {
1071  pg_log_error("could not open directory \"%s\": %m", ARCHSTATDIR);
1072  exit(1);
1073  }
1074 
1075  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1076  {
1077  if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1078  (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1079  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1080  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1081  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1082  {
1083  snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1084  if (unlink(path) < 0)
1085  {
1086  pg_log_error("could not delete file \"%s\": %m", path);
1087  exit(1);
1088  }
1089  }
1090  }
1091 
1092  if (errno)
1093  {
1094  pg_log_error("could not read directory \"%s\": %m", ARCHSTATDIR);
1095  exit(1);
1096  }
1097 
1098  if (closedir(xldir))
1099  {
1100  pg_log_error("could not close directory \"%s\": %m", ARCHSTATDIR);
1101  exit(1);
1102  }
1103 }
#define pg_log_error(...)
Definition: logging.h:79
int closedir(DIR *)
Definition: dirent.c:113
Definition: dirent.h:9
Definition: dirent.c:25
#define MAXPGPATH
DIR * opendir(const char *)
Definition: dirent.c:33
struct dirent * readdir(DIR *)
Definition: dirent.c:77
#define ARCHSTATDIR
#define XLOG_FNAME_LEN
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192

◆ KillExistingXLOG()

static void KillExistingXLOG ( void  )
static

Definition at line 1015 of file pg_resetwal.c.

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

Referenced by main().

1016 {
1017  DIR *xldir;
1018  struct dirent *xlde;
1019  char path[MAXPGPATH + sizeof(XLOGDIR)];
1020 
1021  xldir = opendir(XLOGDIR);
1022  if (xldir == NULL)
1023  {
1024  pg_log_error("could not open directory \"%s\": %m", XLOGDIR);
1025  exit(1);
1026  }
1027 
1028  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1029  {
1030  if (IsXLogFileName(xlde->d_name) ||
1032  {
1033  snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
1034  if (unlink(path) < 0)
1035  {
1036  pg_log_error("could not delete file \"%s\": %m", path);
1037  exit(1);
1038  }
1039  }
1040  }
1041 
1042  if (errno)
1043  {
1044  pg_log_error("could not read directory \"%s\": %m", XLOGDIR);
1045  exit(1);
1046  }
1047 
1048  if (closedir(xldir))
1049  {
1050  pg_log_error("could not close directory \"%s\": %m", XLOGDIR);
1051  exit(1);
1052  }
1053 }
#define pg_log_error(...)
Definition: logging.h:79
int closedir(DIR *)
Definition: dirent.c:113
Definition: dirent.h:9
Definition: dirent.c:25
#define IsXLogFileName(fname)
#define MAXPGPATH
DIR * opendir(const char *)
Definition: dirent.c:33
#define XLOGDIR
struct dirent * readdir(DIR *)
Definition: dirent.c:77
#define IsPartialXLogFileName(fname)
char d_name[MAX_PATH]
Definition: dirent.h:14
#define snprintf
Definition: port.h:192

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 92 of file pg_resetwal.c.

References _, CheckDataVersion(), ControlFileData::checkPointCopy, DataDir, DB_SHUTDOWNED, EpochFromFullTransactionId, fd(), FindEndOfXLOG(), FirstMultiXactId, FirstNormalTransactionId, fprintf, FullTransactionIdFromEpochAndXid(), get_progname(), get_restricted_token(), GetDataDirectoryCreatePerm(), getopt_long(), GuessControlValues(), guessed, InvalidOid, IsValidWalSegSize, KillExistingArchiveStatus(), KillExistingXLOG(), minXlogSegNo, minXlogTli, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, no_argument, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, optarg, optind, pg_log_error, pg_log_info, pg_logging_init(), pg_mode_mask, pg_strdup(), PG_TEXTDOMAIN, CheckPoint::PrevTimeLineID, PrintControlValues(), printf, PrintNewControlValues(), progname, ReadControlFile(), required_argument, RewriteControlFile(), set_mxid, set_mxoff, set_newest_commit_ts_xid, set_oid, set_oldest_commit_ts_xid, set_pglocale_pgservice(), set_wal_segsize, set_xid, set_xid_epoch, ControlFileData::state, CheckPoint::ThisTimeLineID, usage(), WalSegSz, WriteEmptyXLOG(), XidFromFullTransactionId, XLOG_FNAME_LEN, ControlFileData::xlog_seg_size, and XLogFromFileName.

93 {
94  static struct option long_options[] = {
95  {"commit-timestamp-ids", required_argument, NULL, 'c'},
96  {"pgdata", required_argument, NULL, 'D'},
97  {"epoch", required_argument, NULL, 'e'},
98  {"force", no_argument, NULL, 'f'},
99  {"next-wal-file", required_argument, NULL, 'l'},
100  {"multixact-ids", required_argument, NULL, 'm'},
101  {"dry-run", no_argument, NULL, 'n'},
102  {"next-oid", required_argument, NULL, 'o'},
103  {"multixact-offset", required_argument, NULL, 'O'},
104  {"next-transaction-id", required_argument, NULL, 'x'},
105  {"wal-segsize", required_argument, NULL, 1},
106  {NULL, 0, NULL, 0}
107  };
108 
109  int c;
110  bool force = false;
111  bool noupdate = false;
112  MultiXactId set_oldestmxid = 0;
113  char *endptr;
114  char *endptr2;
115  char *DataDir = NULL;
116  char *log_fname = NULL;
117  int fd;
118 
119  pg_logging_init(argv[0]);
120  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
121  progname = get_progname(argv[0]);
122 
123  if (argc > 1)
124  {
125  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
126  {
127  usage();
128  exit(0);
129  }
130  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
131  {
132  puts("pg_resetwal (PostgreSQL) " PG_VERSION);
133  exit(0);
134  }
135  }
136 
137 
138  while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:x:", long_options, NULL)) != -1)
139  {
140  switch (c)
141  {
142  case 'D':
143  DataDir = optarg;
144  break;
145 
146  case 'f':
147  force = true;
148  break;
149 
150  case 'n':
151  noupdate = true;
152  break;
153 
154  case 'e':
155  set_xid_epoch = strtoul(optarg, &endptr, 0);
156  if (endptr == optarg || *endptr != '\0')
157  {
158  /*------
159  translator: the second %s is a command line argument (-e, etc) */
160  pg_log_error("invalid argument for option %s", "-e");
161  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
162  exit(1);
163  }
164  if (set_xid_epoch == -1)
165  {
166  pg_log_error("transaction ID epoch (-e) must not be -1");
167  exit(1);
168  }
169  break;
170 
171  case 'x':
172  set_xid = strtoul(optarg, &endptr, 0);
173  if (endptr == optarg || *endptr != '\0')
174  {
175  pg_log_error("invalid argument for option %s", "-x");
176  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
177  exit(1);
178  }
179  if (set_xid == 0)
180  {
181  pg_log_error("transaction ID (-x) must not be 0");
182  exit(1);
183  }
184  break;
185 
186  case 'c':
187  set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
188  if (endptr == optarg || *endptr != ',')
189  {
190  pg_log_error("invalid argument for option %s", "-c");
191  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
192  exit(1);
193  }
194  set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
195  if (endptr2 == endptr + 1 || *endptr2 != '\0')
196  {
197  pg_log_error("invalid argument for option %s", "-c");
198  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
199  exit(1);
200  }
201 
202  if (set_oldest_commit_ts_xid < 2 &&
204  {
205  pg_log_error("transaction ID (-c) must be either 0 or greater than or equal to 2");
206  exit(1);
207  }
208 
209  if (set_newest_commit_ts_xid < 2 &&
211  {
212  pg_log_error("transaction ID (-c) must be either 0 or greater than or equal to 2");
213  exit(1);
214  }
215  break;
216 
217  case 'o':
218  set_oid = strtoul(optarg, &endptr, 0);
219  if (endptr == optarg || *endptr != '\0')
220  {
221  pg_log_error("invalid argument for option %s", "-o");
222  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
223  exit(1);
224  }
225  if (set_oid == 0)
226  {
227  pg_log_error("OID (-o) must not be 0");
228  exit(1);
229  }
230  break;
231 
232  case 'm':
233  set_mxid = strtoul(optarg, &endptr, 0);
234  if (endptr == optarg || *endptr != ',')
235  {
236  pg_log_error("invalid argument for option %s", "-m");
237  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
238  exit(1);
239  }
240 
241  set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
242  if (endptr2 == endptr + 1 || *endptr2 != '\0')
243  {
244  pg_log_error("invalid argument for option %s", "-m");
245  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
246  exit(1);
247  }
248  if (set_mxid == 0)
249  {
250  pg_log_error("multitransaction ID (-m) must not be 0");
251  exit(1);
252  }
253 
254  /*
255  * XXX It'd be nice to have more sanity checks here, e.g. so
256  * that oldest is not wrapped around w.r.t. nextMulti.
257  */
258  if (set_oldestmxid == 0)
259  {
260  pg_log_error("oldest multitransaction ID (-m) must not be 0");
261  exit(1);
262  }
263  break;
264 
265  case 'O':
266  set_mxoff = strtoul(optarg, &endptr, 0);
267  if (endptr == optarg || *endptr != '\0')
268  {
269  pg_log_error("invalid argument for option %s", "-O");
270  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
271  exit(1);
272  }
273  if (set_mxoff == -1)
274  {
275  pg_log_error("multitransaction offset (-O) must not be -1");
276  exit(1);
277  }
278  break;
279 
280  case 'l':
281  if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
282  {
283  pg_log_error("invalid argument for option %s", "-l");
284  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
285  exit(1);
286  }
287 
288  /*
289  * XLogFromFileName requires wal segment size which is not yet
290  * set. Hence wal details are set later on.
291  */
292  log_fname = pg_strdup(optarg);
293  break;
294 
295  case 1:
296  set_wal_segsize = strtol(optarg, &endptr, 10) * 1024 * 1024;
297  if (endptr == optarg || *endptr != '\0')
298  {
299  pg_log_error("argument of --wal-segsize must be a number");
300  exit(1);
301  }
303  {
304  pg_log_error("argument of --wal-segsize must be a power of 2 between 1 and 1024");
305  exit(1);
306  }
307  break;
308 
309  default:
310  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
311  exit(1);
312  }
313  }
314 
315  if (DataDir == NULL && optind < argc)
316  DataDir = argv[optind++];
317 
318  /* Complain if any arguments remain */
319  if (optind < argc)
320  {
321  pg_log_error("too many command-line arguments (first is \"%s\")",
322  argv[optind]);
323  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
324  progname);
325  exit(1);
326  }
327 
328  if (DataDir == NULL)
329  {
330  pg_log_error("no data directory specified");
331  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
332  exit(1);
333  }
334 
335  /*
336  * Don't allow pg_resetwal to be run as root, to avoid overwriting the
337  * ownership of files in the data directory. We need only check for root
338  * -- any other user won't have sufficient permissions to modify files in
339  * the data directory.
340  */
341 #ifndef WIN32
342  if (geteuid() == 0)
343  {
344  pg_log_error("cannot be executed by \"root\"");
345  pg_log_info("You must run %s as the PostgreSQL superuser.",
346  progname);
347  exit(1);
348  }
349 #endif
350 
352 
353  /* Set mask based on PGDATA permissions */
354  if (!GetDataDirectoryCreatePerm(DataDir))
355  {
356  pg_log_error("could not read permissions of directory \"%s\": %m",
357  DataDir);
358  exit(1);
359  }
360 
361  umask(pg_mode_mask);
362 
363  if (chdir(DataDir) < 0)
364  {
365  pg_log_error("could not change directory to \"%s\": %m",
366  DataDir);
367  exit(1);
368  }
369 
370  /* Check that data directory matches our server version */
372 
373  /*
374  * Check for a postmaster lock file --- if there is one, refuse to
375  * proceed, on grounds we might be interfering with a live installation.
376  */
377  if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
378  {
379  if (errno != ENOENT)
380  {
381  pg_log_error("could not open file \"%s\" for reading: %m",
382  "postmaster.pid");
383  exit(1);
384  }
385  }
386  else
387  {
388  pg_log_error("lock file \"%s\" exists", "postmaster.pid");
389  pg_log_info("Is a server running? If not, delete the lock file and try again.");
390  exit(1);
391  }
392 
393  /*
394  * Attempt to read the existing pg_control file
395  */
396  if (!ReadControlFile())
398 
399  /*
400  * If no new WAL segment size was specified, use the control file value.
401  */
402  if (set_wal_segsize != 0)
404  else
406 
407  if (log_fname != NULL)
409 
410  /*
411  * Also look at existing segment files to set up newXlogSegNo
412  */
413  FindEndOfXLOG();
414 
415  /*
416  * If we're not going to proceed with the reset, print the current control
417  * file parameters.
418  */
419  if ((guessed && !force) || noupdate)
421 
422  /*
423  * Adjust fields if required by switches. (Do this now so that printout,
424  * if any, includes these values.)
425  */
426  if (set_xid_epoch != -1)
430 
431  if (set_xid != 0)
432  {
435  set_xid);
436 
437  /*
438  * For the moment, just set oldestXid to a value that will force
439  * immediate autovacuum-for-wraparound. It's not clear whether adding
440  * user control of this is useful, so let's just do something that's
441  * reasonably safe. The magic constant here corresponds to the
442  * maximum allowed value of autovacuum_freeze_max_age.
443  */
448  }
449 
450  if (set_oldest_commit_ts_xid != 0)
452  if (set_newest_commit_ts_xid != 0)
454 
455  if (set_oid != 0)
457 
458  if (set_mxid != 0)
459  {
461 
462  ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
466  }
467 
468  if (set_mxoff != -1)
470 
472  {
475  }
476 
477  if (set_wal_segsize != 0)
479 
482 
483  /*
484  * If we had to guess anything, and -f was not given, just print the
485  * guessed values and exit. Also print if -n is given.
486  */
487  if ((guessed && !force) || noupdate)
488  {
490  if (!noupdate)
491  {
492  printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
493  exit(1);
494  }
495  else
496  exit(0);
497  }
498 
499  /*
500  * Don't reset from a dirty pg_control without -f, either.
501  */
502  if (ControlFile.state != DB_SHUTDOWNED && !force)
503  {
504  printf(_("The database server was not shut down cleanly.\n"
505  "Resetting the write-ahead log might cause data to be lost.\n"
506  "If you want to proceed anyway, use -f to force reset.\n"));
507  exit(1);
508  }
509 
510  /*
511  * Else, do the dirty deed.
512  */
516  WriteEmptyXLOG();
517 
518  printf(_("Write-ahead log reset\n"));
519  return 0;
520 }
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:741
#define IsValidWalSegSize(size)
Definition: xlog_internal.h:97
static MultiXactId set_mxid
Definition: pg_resetwal.c:71
static void usage(void)
Definition: pg_resetwal.c:1206
static TransactionId set_xid
Definition: pg_resetwal.c:67
static int set_wal_segsize
Definition: pg_resetwal.c:76
const char * get_progname(const char *argv0)
Definition: path.c:453
#define pg_log_error(...)
Definition: logging.h:79
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
void get_restricted_token(void)
static void PrintNewControlValues(void)
Definition: pg_resetwal.c:814
void pg_logging_init(const char *argv0)
Definition: logging.c:39
MultiXactId oldestMulti
Definition: pg_control.h:49
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:933
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1111
static Oid set_oid
Definition: pg_resetwal.c:70
#define printf(...)
Definition: port.h:198
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
#define fprintf
Definition: port.h:196
static void CheckDataVersion(void)
Definition: pg_resetwal.c:536
static int fd(const char *x, int i)
Definition: preproc-init.c:105
static bool ReadControlFile(void)
Definition: pg_resetwal.c:581
#define XidFromFullTransactionId(x)
Definition: transam.h:48
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:69
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:1015
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
#define required_argument
Definition: getopt_long.h:25
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
uint32 xlog_seg_size
Definition: pg_control.h:209
int optind
Definition: getopt.c:50
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1060
#define FirstNormalTransactionId
Definition: transam.h:34
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:68
#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:65
static bool guessed
Definition: pg_resetwal.c:64
#define no_argument
Definition: getopt_long.h:24
TransactionId newestCommitTsXid
Definition: pg_control.h:54
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1166
Oid oldestMultiDB
Definition: pg_control.h:50
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
#define InvalidOid
Definition: postgres_ext.h:36
Oid nextOid
Definition: pg_control.h:44
static int WalSegSz
Definition: pg_resetwal.c:75
TransactionId MultiXactId
Definition: c.h:524
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
MultiXactId nextMulti
Definition: pg_control.h:45
static void RewriteControlFile(void)
Definition: pg_resetwal.c:886
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:72
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:65
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:63
bool GetDataDirectoryCreatePerm(const char *dataDir)
static void GuessControlValues(void)
Definition: pg_resetwal.c:658
static uint32 minXlogTli
Definition: pg_resetwal.c:73
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:565
char * optarg
Definition: getopt.c:52
char * DataDir
Definition: globals.c:62
#define XLOG_FNAME_LEN
#define _(x)
Definition: elog.c:87
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:74
int pg_mode_mask
Definition: file_perm.c:25
#define pg_log_info(...)
Definition: logging.h:87
static uint32 set_xid_epoch
Definition: pg_resetwal.c:66

◆ PrintControlValues()

static void PrintControlValues ( bool  guessed)
static

Definition at line 741 of file pg_resetwal.c.

References _, ControlFileData::blcksz, ControlFileData::catalog_version_no, ControlFileData::checkPointCopy, ControlFileData::data_checksum_version, EpochFromFullTransactionId, ControlFileData::float8ByVal, CheckPoint::fullPageWrites, ControlFileData::indexMaxKeys, ControlFileData::loblksize, ControlFileData::maxAlign, ControlFileData::nameDataLen, CheckPoint::newestCommitTsXid, CheckPoint::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::oldestActiveXid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, ControlFileData::pg_control_version, printf, ControlFileData::relseg_size, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, ControlFileData::toast_max_chunk_size, XidFromFullTransactionId, ControlFileData::xlog_blcksz, and ControlFileData::xlog_seg_size.

Referenced by main().

742 {
743  if (guessed)
744  printf(_("Guessed pg_control values:\n\n"));
745  else
746  printf(_("Current pg_control values:\n\n"));
747 
748  printf(_("pg_control version number: %u\n"),
750  printf(_("Catalog version number: %u\n"),
752  printf(_("Database system identifier: %llu\n"),
753  (unsigned long long) ControlFile.system_identifier);
754  printf(_("Latest checkpoint's TimeLineID: %u\n"),
756  printf(_("Latest checkpoint's full_page_writes: %s\n"),
757  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
758  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
761  printf(_("Latest checkpoint's NextOID: %u\n"),
763  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
765  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
767  printf(_("Latest checkpoint's oldestXID: %u\n"),
769  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
771  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
773  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
775  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
777  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
779  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
781  printf(_("Maximum data alignment: %u\n"),
783  /* we don't print floatFormat since can't say much useful about it */
784  printf(_("Database block size: %u\n"),
786  printf(_("Blocks per segment of large relation: %u\n"),
788  printf(_("WAL block size: %u\n"),
790  printf(_("Bytes per WAL segment: %u\n"),
792  printf(_("Maximum length of identifiers: %u\n"),
794  printf(_("Maximum columns in an index: %u\n"),
796  printf(_("Maximum size of a TOAST chunk: %u\n"),
798  printf(_("Size of a large-object chunk: %u\n"),
800  /* This is no longer configurable, but users may still expect to see it: */
801  printf(_("Date/time type storage: %s\n"),
802  _("64-bit integers"));
803  printf(_("Float8 argument passing: %s\n"),
804  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
805  printf(_("Data page checksum version: %u\n"),
807 }
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
#define printf(...)
Definition: port.h:198
CheckPoint checkPointCopy
Definition: pg_control.h:131
uint32 xlog_blcksz
Definition: pg_control.h:208
TransactionId oldestXid
Definition: pg_control.h:47
#define XidFromFullTransactionId(x)
Definition: transam.h:48
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 data_checksum_version
Definition: pg_control.h:220
uint32 loblksize
Definition: pg_control.h:215
uint32 indexMaxKeys
Definition: pg_control.h:212
static bool guessed
Definition: pg_resetwal.c:64
TransactionId newestCommitTsXid
Definition: pg_control.h:54
Oid oldestMultiDB
Definition: pg_control.h:50
uint32 toast_max_chunk_size
Definition: pg_control.h:214
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
Oid nextOid
Definition: pg_control.h:44
bool fullPageWrites
Definition: pg_control.h:42
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
MultiXactId nextMulti
Definition: pg_control.h:45
uint32 catalog_version_no
Definition: pg_control.h:122
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
#define _(x)
Definition: elog.c:87
uint32 relseg_size
Definition: pg_control.h:206

◆ PrintNewControlValues()

static void PrintNewControlValues ( void  )
static

Definition at line 814 of file pg_resetwal.c.

References _, ControlFileData::checkPointCopy, EpochFromFullTransactionId, MAXFNAMELEN, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextFullXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::oldestCommitTsXid, CheckPoint::oldestMulti, CheckPoint::oldestMultiDB, CheckPoint::oldestXid, CheckPoint::oldestXidDB, printf, set_mxid, set_mxoff, set_newest_commit_ts_xid, set_oid, set_oldest_commit_ts_xid, set_wal_segsize, set_xid, set_xid_epoch, CheckPoint::ThisTimeLineID, WalSegSz, XidFromFullTransactionId, ControlFileData::xlog_seg_size, and XLogFileName.

Referenced by main().

815 {
816  char fname[MAXFNAMELEN];
817 
818  /* This will be always printed in order to keep format same. */
819  printf(_("\n\nValues to be changed:\n\n"));
820 
823  printf(_("First log segment after reset: %s\n"), fname);
824 
825  if (set_mxid != 0)
826  {
827  printf(_("NextMultiXactId: %u\n"),
829  printf(_("OldestMultiXid: %u\n"),
831  printf(_("OldestMulti's DB: %u\n"),
833  }
834 
835  if (set_mxoff != -1)
836  {
837  printf(_("NextMultiOffset: %u\n"),
839  }
840 
841  if (set_oid != 0)
842  {
843  printf(_("NextOID: %u\n"),
845  }
846 
847  if (set_xid != 0)
848  {
849  printf(_("NextXID: %u\n"),
851  printf(_("OldestXID: %u\n"),
853  printf(_("OldestXID's DB: %u\n"),
855  }
856 
857  if (set_xid_epoch != -1)
858  {
859  printf(_("NextXID epoch: %u\n"),
861  }
862 
863  if (set_oldest_commit_ts_xid != 0)
864  {
865  printf(_("oldestCommitTsXid: %u\n"),
867  }
868  if (set_newest_commit_ts_xid != 0)
869  {
870  printf(_("newestCommitTsXid: %u\n"),
872  }
873 
874  if (set_wal_segsize != 0)
875  {
876  printf(_("Bytes per WAL segment: %u\n"),
878  }
879 }
static MultiXactId set_mxid
Definition: pg_resetwal.c:71
static TransactionId set_xid
Definition: pg_resetwal.c:67
static int set_wal_segsize
Definition: pg_resetwal.c:76
MultiXactId oldestMulti
Definition: pg_control.h:49
static Oid set_oid
Definition: pg_resetwal.c:70
#define printf(...)
Definition: port.h:198
CheckPoint checkPointCopy
Definition: pg_control.h:131
TransactionId oldestXid
Definition: pg_control.h:47
#define XidFromFullTransactionId(x)
Definition: transam.h:48
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:69
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
uint32 xlog_seg_size
Definition: pg_control.h:209
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:68
#define MAXFNAMELEN
TransactionId newestCommitTsXid
Definition: pg_control.h:54
Oid oldestMultiDB
Definition: pg_control.h:50
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
Oid nextOid
Definition: pg_control.h:44
static int WalSegSz
Definition: pg_resetwal.c:75
FullTransactionId nextFullXid
Definition: pg_control.h:43
Oid oldestXidDB
Definition: pg_control.h:48
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
MultiXactId nextMulti
Definition: pg_control.h:45
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:72
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:63
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
#define _(x)
Definition: elog.c:87
static uint32 set_xid_epoch
Definition: pg_resetwal.c:66

◆ ReadControlFile()

static bool ReadControlFile ( void  )
static

Definition at line 581 of file pg_resetwal.c.

References close, COMP_CRC32C, EQ_CRC32C, fd(), FIN_CRC32C, guessed, INIT_CRC32C, IsValidWalSegSize, ngettext, offsetof, PG_BINARY, PG_CONTROL_FILE_SIZE, PG_CONTROL_VERSION, pg_log_error, pg_log_info, pg_log_warning, pg_malloc(), read, XLOG_CONTROL_FILE, and ControlFileData::xlog_seg_size.

Referenced by main().

582 {
583  int fd;
584  int len;
585  char *buffer;
586  pg_crc32c crc;
587 
588  if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
589  {
590  /*
591  * If pg_control is not there at all, or we can't read it, the odds
592  * are we've been handed a bad DataDir path, so give up. User can do
593  * "touch pg_control" to force us to proceed.
594  */
595  pg_log_error("could not open file \"%s\" for reading: %m",
597  if (errno == ENOENT)
598  pg_log_info("If you are sure the data directory path is correct, execute\n"
599  " touch %s\n"
600  "and try again.",
602  exit(1);
603  }
604 
605  /* Use malloc to ensure we have a maxaligned buffer */
606  buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
607 
608  len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
609  if (len < 0)
610  {
611  pg_log_error("could not read file \"%s\": %m", XLOG_CONTROL_FILE);
612  exit(1);
613  }
614  close(fd);
615 
616  if (len >= sizeof(ControlFileData) &&
617  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
618  {
619  /* Check the CRC. */
620  INIT_CRC32C(crc);
621  COMP_CRC32C(crc,
622  buffer,
623  offsetof(ControlFileData, crc));
624  FIN_CRC32C(crc);
625 
626  if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
627  {
628  /* We will use the data but treat it as guessed. */
629  pg_log_warning("pg_control exists but has invalid CRC; proceed with caution");
630  guessed = true;
631  }
632 
633  memcpy(&ControlFile, buffer, sizeof(ControlFile));
634 
635  /* return false if WAL segment size is not valid */
637  {
638  pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution",
639  "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
642  return false;
643  }
644 
645  return true;
646  }
647 
648  /* Looks like it's a mess. */
649  pg_log_warning("pg_control exists but is broken or wrong version; ignoring it");
650  return false;
651 }
#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
#define pg_log_error(...)
Definition: logging.h:79
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1222
uint32 xlog_seg_size
Definition: pg_control.h:209
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
static bool guessed
Definition: pg_resetwal.c:64
#define ngettext(s, p, n)
Definition: c.h:1134
#define XLOG_CONTROL_FILE
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:248
#define close(a)
Definition: win32.h:12
#define pg_log_warning(...)
Definition: pgfnames.c:24
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
#define read(a, b, c)
Definition: win32.h:13
#define offsetof(type, field)
Definition: c.h:662
#define pg_log_info(...)
Definition: logging.h:87

◆ RewriteControlFile()

static void RewriteControlFile ( void  )
static

Definition at line 886 of file pg_resetwal.c.

References ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, ControlFileData::checkPoint, ControlFileData::checkPointCopy, DB_SHUTDOWNED, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_wal_senders, ControlFileData::max_worker_processes, ControlFileData::MaxConnections, ControlFileData::minRecoveryPoint, ControlFileData::minRecoveryPointTLI, newXlogSegNo, CheckPoint::redo, SizeOfXLogLongPHD, ControlFileData::state, CheckPoint::time, ControlFileData::time, ControlFileData::track_commit_timestamp, update_controlfile(), ControlFileData::wal_level, WAL_LEVEL_MINIMAL, ControlFileData::wal_log_hints, WalSegSz, and XLogSegNoOffsetToRecPtr.

Referenced by main().

887 {
888  /*
889  * Adjust fields as needed to force an empty XLOG starting at
890  * newXlogSegNo.
891  */
894  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
895 
897  ControlFile.time = (pg_time_t) time(NULL);
904 
905  /*
906  * Force the defaults for max_* settings. The values don't really matter
907  * as long as wal_level='minimal'; the postmaster will reset these fields
908  * anyway at startup.
909  */
911  ControlFile.wal_log_hints = false;
918 
919  /* The control file gets flushed here. */
920  update_controlfile(".", &ControlFile, true);
921 }
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:167
int max_worker_processes
Definition: pg_control.h:179
CheckPoint checkPointCopy
Definition: pg_control.h:131
pg_time_t time
Definition: pg_control.h:51
bool backupEndRequired
Definition: pg_control.h:170
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
XLogRecPtr backupEndPoint
Definition: pg_control.h:169
static int WalSegSz
Definition: pg_resetwal.c:75
#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest)
bool track_commit_timestamp
Definition: pg_control.h:183
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:63
XLogRecPtr backupStartPoint
Definition: pg_control.h:168
XLogRecPtr checkPoint
Definition: pg_control.h:129
XLogRecPtr redo
Definition: pg_control.h:37
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:166
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72

◆ usage()

static void usage ( void  )
static

Definition at line 1206 of file pg_resetwal.c.

References _, printf, and progname.

Referenced by main().

1207 {
1208  printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1209  printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
1210  printf(_("Options:\n"));
1211  printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
1212  " set oldest and newest transactions bearing\n"
1213  " commit timestamp (zero means no change)\n"));
1214  printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
1215  printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
1216  printf(_(" -f, --force force update to be done\n"));
1217  printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
1218  printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
1219  printf(_(" -n, --dry-run no update, just show what would be done\n"));
1220  printf(_(" -o, --next-oid=OID set next OID\n"));
1221  printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
1222  printf(_(" -V, --version output version information, then exit\n"));
1223  printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
1224  printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
1225  printf(_(" -?, --help show this help, then exit\n"));
1226  printf(_("\nReport bugs to <pgsql-bugs@lists.postgresql.org>.\n"));
1227 }
#define printf(...)
Definition: port.h:198
static const char * progname
Definition: pg_resetwal.c:65
#define _(x)
Definition: elog.c:87

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1111 of file pg_resetwal.c.

References ControlFileData::checkPointCopy, close, COMP_CRC32C, PGAlignedXLogBlock::data, fd(), FIN_CRC32C, fsync, INIT_CRC32C, InvalidTransactionId, MAXPGPATH, newXlogSegNo, offsetof, PG_BINARY, pg_file_create_mode, pg_log_error, CheckPoint::redo, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, ControlFileData::system_identifier, CheckPoint::ThisTimeLineID, WalSegSz, write, 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().

1112 {
1113  PGAlignedXLogBlock buffer;
1114  XLogPageHeader page;
1115  XLogLongPageHeader longpage;
1116  XLogRecord *record;
1117  pg_crc32c crc;
1118  char path[MAXPGPATH];
1119  int fd;
1120  int nbytes;
1121  char *recptr;
1122 
1123  memset(buffer.data, 0, XLOG_BLCKSZ);
1124 
1125  /* Set up the XLOG page header */
1126  page = (XLogPageHeader) buffer.data;
1127  page->xlp_magic = XLOG_PAGE_MAGIC;
1128  page->xlp_info = XLP_LONG_HEADER;
1131  longpage = (XLogLongPageHeader) page;
1133  longpage->xlp_seg_size = WalSegSz;
1134  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1135 
1136  /* Insert the initial checkpoint record */
1137  recptr = (char *) page + SizeOfXLogLongPHD;
1138  record = (XLogRecord *) recptr;
1139  record->xl_prev = 0;
1140  record->xl_xid = InvalidTransactionId;
1143  record->xl_rmid = RM_XLOG_ID;
1144 
1145  recptr += SizeOfXLogRecord;
1146  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1147  *(recptr++) = sizeof(CheckPoint);
1148  memcpy(recptr, &ControlFile.checkPointCopy,
1149  sizeof(CheckPoint));
1150 
1151  INIT_CRC32C(crc);
1152  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1153  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1154  FIN_CRC32C(crc);
1155  record->xl_crc = crc;
1156 
1157  /* Write the first page */
1160 
1161  unlink(path);
1162 
1163  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1165  if (fd < 0)
1166  {
1167  pg_log_error("could not open file \"%s\": %m", path);
1168  exit(1);
1169  }
1170 
1171  errno = 0;
1172  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1173  {
1174  /* if write didn't set errno, assume problem is no disk space */
1175  if (errno == 0)
1176  errno = ENOSPC;
1177  pg_log_error("could not write file \"%s\": %m", path);
1178  exit(1);
1179  }
1180 
1181  /* Fill the rest of the file with zeroes */
1182  memset(buffer.data, 0, XLOG_BLCKSZ);
1183  for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1184  {
1185  errno = 0;
1186  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1187  {
1188  if (errno == 0)
1189  errno = ENOSPC;
1190  pg_log_error("could not write file \"%s\": %m", path);
1191  exit(1);
1192  }
1193  }
1194 
1195  if (fsync(fd) != 0)
1196  {
1197  pg_log_error("fsync error: %m");
1198  exit(1);
1199  }
1200 
1201  close(fd);
1202 }
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
int pg_file_create_mode
Definition: file_perm.c:19
#define write(a, b, c)
Definition: win32.h:14
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:200
#define pg_log_error(...)
Definition: logging.h:79
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:131
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define PG_BINARY
Definition: c.h:1222
#define fsync(fd)
Definition: win32_port.h:63
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
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:75
#define XLP_LONG_HEADER
Definition: xlog_internal.h:79
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
uint8 xl_info
Definition: xlogrecord.h:46
struct CheckPoint CheckPoint
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:223
#define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes)
TransactionId xl_xid
Definition: xlogrecord.h:44
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:63
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
#define close(a)
Definition: win32.h:12
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
char data[XLOG_BLCKSZ]
Definition: c.h:1099
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:94
XLogRecPtr redo
Definition: pg_control.h:37
#define offsetof(type, field)
Definition: c.h:662
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72

Variable Documentation

◆ ControlFile

ControlFileData ControlFile
static

Definition at line 62 of file pg_resetwal.c.

◆ guessed

bool guessed = false
static

Definition at line 64 of file pg_resetwal.c.

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

◆ minXlogSegNo

XLogSegNo minXlogSegNo = 0
static

Definition at line 74 of file pg_resetwal.c.

Referenced by main().

◆ minXlogTli

uint32 minXlogTli = 0
static

Definition at line 73 of file pg_resetwal.c.

Referenced by main().

◆ newXlogSegNo

XLogSegNo newXlogSegNo
static

◆ progname

const char* progname
static

Definition at line 65 of file pg_resetwal.c.

Referenced by main(), and usage().

◆ set_mxid

MultiXactId set_mxid = 0
static

Definition at line 71 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_mxoff

MultiXactOffset set_mxoff = (MultiXactOffset) -1
static

Definition at line 72 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_newest_commit_ts_xid

TransactionId set_newest_commit_ts_xid = 0
static

Definition at line 69 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oid

Oid set_oid = 0
static

Definition at line 70 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oldest_commit_ts_xid

TransactionId set_oldest_commit_ts_xid = 0
static

Definition at line 68 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_wal_segsize

int set_wal_segsize
static

Definition at line 76 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid

TransactionId set_xid = 0
static

Definition at line 67 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid_epoch

uint32 set_xid_epoch = (uint32) -1
static

Definition at line 66 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ WalSegSz

int WalSegSz
static