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 "fe_utils/option_utils.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"
 
#define WALSUMMARYDIR   XLOGDIR "/summaries"
 
#define WALSUMMARY_NHEXCHARS   40
 

Functions

static void CheckDataVersion (void)
 
static bool read_controlfile (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 KillExistingWALSummaries (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_oldest_xid = 0
 
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 TimeLineID 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 35 of file pg_resetwal.c.

◆ WALSUMMARY_NHEXCHARS

#define WALSUMMARY_NHEXCHARS   40

◆ WALSUMMARYDIR

#define WALSUMMARYDIR   XLOGDIR "/summaries"

Function Documentation

◆ CheckDataVersion()

static void CheckDataVersion ( void  )
static

Definition at line 518 of file pg_resetwal.c.

519 {
520  const char *ver_file = "PG_VERSION";
521  FILE *ver_fd;
522  char rawline[64];
523 
524  if ((ver_fd = fopen(ver_file, "r")) == NULL)
525  pg_fatal("could not open file \"%s\" for reading: %m",
526  ver_file);
527 
528  /* version number has to be the first line read */
529  if (!fgets(rawline, sizeof(rawline), ver_fd))
530  {
531  if (!ferror(ver_fd))
532  pg_fatal("unexpected empty file \"%s\"", ver_file);
533  else
534  pg_fatal("could not read file \"%s\": %m", ver_file);
535  }
536 
537  /* strip trailing newline and carriage return */
538  (void) pg_strip_crlf(rawline);
539 
540  if (strcmp(rawline, PG_MAJORVERSION) != 0)
541  {
542  pg_log_error("data directory is of wrong version");
543  pg_log_error_detail("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
544  ver_file, rawline, PG_MAJORVERSION);
545  exit(1);
546  }
547 
548  fclose(ver_fd);
549 }
exit(1)
#define pg_log_error(...)
Definition: logging.h:106
#define pg_log_error_detail(...)
Definition: logging.h:109
#define pg_fatal(...)
int pg_strip_crlf(char *str)
Definition: string.c:155

References exit(), pg_fatal, pg_log_error, pg_log_error_detail, and pg_strip_crlf().

Referenced by main().

◆ FindEndOfXLOG()

static void FindEndOfXLOG ( void  )
static

Definition at line 907 of file pg_resetwal.c.

908 {
909  DIR *xldir;
910  struct dirent *xlde;
911  uint64 xlogbytepos;
912 
913  /*
914  * Initialize the max() computation using the last checkpoint address from
915  * old pg_control. Note that for the moment we are working with segment
916  * numbering according to the old xlog seg size.
917  */
920 
921  /*
922  * Scan the pg_wal directory to find existing WAL segment files. We assume
923  * any present have been used; in most scenarios this should be
924  * conservative, because of xlog.c's attempts to pre-create files.
925  */
926  xldir = opendir(XLOGDIR);
927  if (xldir == NULL)
928  pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
929 
930  while (errno = 0, (xlde = readdir(xldir)) != NULL)
931  {
932  if (IsXLogFileName(xlde->d_name) ||
934  {
935  TimeLineID tli;
936  XLogSegNo segno;
937 
938  /* Use the segment size from the control file */
939  XLogFromFileName(xlde->d_name, &tli, &segno,
941 
942  /*
943  * Note: we take the max of all files found, regardless of their
944  * timelines. Another possibility would be to ignore files of
945  * timelines other than the target TLI, but this seems safer.
946  * Better too large a result than too small...
947  */
948  if (segno > newXlogSegNo)
949  newXlogSegNo = segno;
950  }
951  }
952 
953  if (errno)
954  pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
955 
956  if (closedir(xldir))
957  pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
958 
959  /*
960  * Finally, convert to new xlog seg size, and advance by one to ensure we
961  * are in virgin territory.
962  */
963  xlogbytepos = newXlogSegNo * ControlFile.xlog_seg_size;
964  newXlogSegNo = (xlogbytepos + ControlFile.xlog_seg_size - 1) / WalSegSz;
965  newXlogSegNo++;
966 }
int closedir(DIR *)
Definition: dirent.c:127
struct dirent * readdir(DIR *)
Definition: dirent.c:78
DIR * opendir(const char *)
Definition: dirent.c:33
static int WalSegSz
Definition: pg_resetwal.c:76
static ControlFileData ControlFile
Definition: pg_resetwal.c:62
static XLogSegNo newXlogSegNo
Definition: pg_resetwal.c:63
XLogRecPtr redo
Definition: pg_control.h:37
uint32 xlog_seg_size
Definition: pg_control.h:210
CheckPoint checkPointCopy
Definition: pg_control.h:134
Definition: dirent.c:26
Definition: dirent.h:10
char d_name[MAX_PATH]
Definition: dirent.h:15
static bool IsXLogFileName(const char *fname)
static void XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)
#define XLOGDIR
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
static bool IsPartialXLogFileName(const char *fname)
uint32 TimeLineID
Definition: xlogdefs.h:59
uint64 XLogSegNo
Definition: xlogdefs.h:48

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

Referenced by main().

◆ GuessControlValues()

static void GuessControlValues ( void  )
static

Definition at line 633 of file pg_resetwal.c.

634 {
635  uint64 sysidentifier;
636  struct timeval tv;
637 
638  /*
639  * Set up a completely default set of pg_control values.
640  */
641  guessed = true;
642  memset(&ControlFile, 0, sizeof(ControlFile));
643 
646 
647  /*
648  * Create a new unique installation identifier, since we can no longer use
649  * any old XLOG records. See notes in xlog.c about the algorithm.
650  */
651  gettimeofday(&tv, NULL);
652  sysidentifier = ((uint64) tv.tv_sec) << 32;
653  sysidentifier |= ((uint64) tv.tv_usec) << 12;
654  sysidentifier |= getpid() & 0xFFF;
655 
656  ControlFile.system_identifier = sysidentifier;
657 
671  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
673 
675  ControlFile.time = (pg_time_t) time(NULL);
678 
679  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
680 
682  ControlFile.wal_log_hints = false;
689 
690  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
692  ControlFile.blcksz = BLCKSZ;
693  ControlFile.relseg_size = RELSEG_SIZE;
694  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
701 
702  /*
703  * XXX eventually, should try to grovel through old XLOG to develop more
704  * accurate values for TimeLineID, nextXID, etc.
705  */
706 }
#define FLOAT8PASSBYVAL
Definition: c.h:635
#define CATALOG_VERSION_NO
Definition: catversion.h:60
#define TOAST_MAX_CHUNK_SIZE
Definition: heaptoast.h:84
#define LOBLKSIZE
Definition: large_object.h:70
#define FirstMultiXactId
Definition: multixact.h:25
#define INDEX_MAX_KEYS
#define NAMEDATALEN
#define DEFAULT_XLOG_SEG_SIZE
#define FLOATFORMAT_VALUE
Definition: pg_control.h:200
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
@ DB_SHUTDOWNED
Definition: pg_control.h:91
static bool guessed
Definition: pg_resetwal.c:64
int64 pg_time_t
Definition: pgtime.h:23
#define InvalidOid
Definition: postgres_ext.h:36
Oid oldestMultiDB
Definition: pg_control.h:50
MultiXactId oldestMulti
Definition: pg_control.h:49
MultiXactOffset nextMultiOffset
Definition: pg_control.h:46
TransactionId oldestXid
Definition: pg_control.h:47
TimeLineID PrevTimeLineID
Definition: pg_control.h:40
TimeLineID ThisTimeLineID
Definition: pg_control.h:39
Oid nextOid
Definition: pg_control.h:44
TransactionId oldestActiveXid
Definition: pg_control.h:63
bool fullPageWrites
Definition: pg_control.h:42
MultiXactId nextMulti
Definition: pg_control.h:45
FullTransactionId nextXid
Definition: pg_control.h:43
pg_time_t time
Definition: pg_control.h:51
Oid oldestXidDB
Definition: pg_control.h:48
int max_worker_processes
Definition: pg_control.h:180
uint32 pg_control_version
Definition: pg_control.h:124
bool track_commit_timestamp
Definition: pg_control.h:184
int max_locks_per_xact
Definition: pg_control.h:183
uint32 nameDataLen
Definition: pg_control.h:212
XLogRecPtr unloggedLSN
Definition: pg_control.h:136
uint32 indexMaxKeys
Definition: pg_control.h:213
uint32 relseg_size
Definition: pg_control.h:207
pg_time_t time
Definition: pg_control.h:131
XLogRecPtr checkPoint
Definition: pg_control.h:132
uint64 system_identifier
Definition: pg_control.h:109
uint32 catalog_version_no
Definition: pg_control.h:125
double floatFormat
Definition: pg_control.h:199
int max_prepared_xacts
Definition: pg_control.h:182
uint32 xlog_blcksz
Definition: pg_control.h:209
uint32 loblksize
Definition: pg_control.h:216
uint32 toast_max_chunk_size
Definition: pg_control.h:215
#define InvalidTransactionId
Definition: transam.h:31
#define FirstGenbkiObjectId
Definition: transam.h:195
#define FirstNormalTransactionId
Definition: transam.h:34
static FullTransactionId FullTransactionIdFromEpochAndXid(uint32 epoch, TransactionId xid)
Definition: transam.h:71
int gettimeofday(struct timeval *tp, void *tzp)
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:72
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:69
#define FirstNormalUnloggedLSN
Definition: xlogdefs.h:36

References ControlFileData::blcksz, CATALOG_VERSION_NO, ControlFileData::catalog_version_no, ControlFileData::checkPoint, ControlFileData::checkPointCopy, ControlFile, DB_SHUTDOWNED, DEFAULT_XLOG_SEG_SIZE, FirstGenbkiObjectId, FirstMultiXactId, FirstNormalTransactionId, FirstNormalUnloggedLSN, ControlFileData::float8ByVal, FLOAT8PASSBYVAL, ControlFileData::floatFormat, FLOATFORMAT_VALUE, CheckPoint::fullPageWrites, FullTransactionIdFromEpochAndXid(), gettimeofday(), guessed, INDEX_MAX_KEYS, ControlFileData::indexMaxKeys, InvalidOid, InvalidTransactionId, ControlFileData::loblksize, LOBLKSIZE, ControlFileData::max_locks_per_xact, ControlFileData::max_prepared_xacts, ControlFileData::max_wal_senders, ControlFileData::max_worker_processes, ControlFileData::maxAlign, ControlFileData::MaxConnections, ControlFileData::nameDataLen, NAMEDATALEN, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, 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().

◆ KillExistingArchiveStatus()

static void KillExistingArchiveStatus ( void  )
static

Definition at line 1006 of file pg_resetwal.c.

1007 {
1008 #define ARCHSTATDIR XLOGDIR "/archive_status"
1009 
1010  DIR *xldir;
1011  struct dirent *xlde;
1012  char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1013 
1014  xldir = opendir(ARCHSTATDIR);
1015  if (xldir == NULL)
1016  pg_fatal("could not open directory \"%s\": %m", ARCHSTATDIR);
1017 
1018  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1019  {
1020  if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1021  (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1022  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1023  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1024  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1025  {
1026  snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1027  if (unlink(path) < 0)
1028  pg_fatal("could not delete file \"%s\": %m", path);
1029  }
1030  }
1031 
1032  if (errno)
1033  pg_fatal("could not read directory \"%s\": %m", ARCHSTATDIR);
1034 
1035  if (closedir(xldir))
1036  pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1037 }
#define MAXPGPATH
#define ARCHSTATDIR
#define snprintf
Definition: port.h:238
#define XLOG_FNAME_LEN

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

Referenced by main().

◆ KillExistingWALSummaries()

static void KillExistingWALSummaries ( void  )
static

Definition at line 1043 of file pg_resetwal.c.

1044 {
1045 #define WALSUMMARYDIR XLOGDIR "/summaries"
1046 #define WALSUMMARY_NHEXCHARS 40
1047 
1048  DIR *xldir;
1049  struct dirent *xlde;
1050  char path[MAXPGPATH + sizeof(WALSUMMARYDIR)];
1051 
1052  xldir = opendir(WALSUMMARYDIR);
1053  if (xldir == NULL)
1054  pg_fatal("could not open directory \"%s\": %m", WALSUMMARYDIR);
1055 
1056  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1057  {
1058  if (strspn(xlde->d_name, "0123456789ABCDEF") == WALSUMMARY_NHEXCHARS &&
1059  strcmp(xlde->d_name + WALSUMMARY_NHEXCHARS, ".summary") == 0)
1060  {
1061  snprintf(path, sizeof(path), "%s/%s", WALSUMMARYDIR, xlde->d_name);
1062  if (unlink(path) < 0)
1063  pg_fatal("could not delete file \"%s\": %m", path);
1064  }
1065  }
1066 
1067  if (errno)
1068  pg_fatal("could not read directory \"%s\": %m", WALSUMMARYDIR);
1069 
1070  if (closedir(xldir))
1071  pg_fatal("could not close directory \"%s\": %m", ARCHSTATDIR);
1072 }
#define WALSUMMARY_NHEXCHARS
#define WALSUMMARYDIR

References ARCHSTATDIR, closedir(), dirent::d_name, MAXPGPATH, opendir(), pg_fatal, readdir(), snprintf, WALSUMMARY_NHEXCHARS, and WALSUMMARYDIR.

Referenced by main().

◆ KillExistingXLOG()

static void KillExistingXLOG ( void  )
static

Definition at line 973 of file pg_resetwal.c.

974 {
975  DIR *xldir;
976  struct dirent *xlde;
977  char path[MAXPGPATH + sizeof(XLOGDIR)];
978 
979  xldir = opendir(XLOGDIR);
980  if (xldir == NULL)
981  pg_fatal("could not open directory \"%s\": %m", XLOGDIR);
982 
983  while (errno = 0, (xlde = readdir(xldir)) != NULL)
984  {
985  if (IsXLogFileName(xlde->d_name) ||
987  {
988  snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
989  if (unlink(path) < 0)
990  pg_fatal("could not delete file \"%s\": %m", path);
991  }
992  }
993 
994  if (errno)
995  pg_fatal("could not read directory \"%s\": %m", XLOGDIR);
996 
997  if (closedir(xldir))
998  pg_fatal("could not close directory \"%s\": %m", XLOGDIR);
999 }

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

Referenced by main().

◆ main()

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

Definition at line 94 of file pg_resetwal.c.

95 {
96  static struct option long_options[] = {
97  {"commit-timestamp-ids", required_argument, NULL, 'c'},
98  {"pgdata", required_argument, NULL, 'D'},
99  {"epoch", required_argument, NULL, 'e'},
100  {"force", no_argument, NULL, 'f'},
101  {"next-wal-file", required_argument, NULL, 'l'},
102  {"multixact-ids", required_argument, NULL, 'm'},
103  {"dry-run", no_argument, NULL, 'n'},
104  {"next-oid", required_argument, NULL, 'o'},
105  {"multixact-offset", required_argument, NULL, 'O'},
106  {"oldest-transaction-id", required_argument, NULL, 'u'},
107  {"next-transaction-id", required_argument, NULL, 'x'},
108  {"wal-segsize", required_argument, NULL, 1},
109  {NULL, 0, NULL, 0}
110  };
111 
112  int c;
113  bool force = false;
114  bool noupdate = false;
115  MultiXactId set_oldestmxid = 0;
116  char *endptr;
117  char *endptr2;
118  char *DataDir = NULL;
119  char *log_fname = NULL;
120  int fd;
121 
122  pg_logging_init(argv[0]);
123  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
124  progname = get_progname(argv[0]);
125 
126  if (argc > 1)
127  {
128  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
129  {
130  usage();
131  exit(0);
132  }
133  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
134  {
135  puts("pg_resetwal (PostgreSQL) " PG_VERSION);
136  exit(0);
137  }
138  }
139 
140 
141  while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:u:x:", long_options, NULL)) != -1)
142  {
143  switch (c)
144  {
145  case 'D':
146  DataDir = optarg;
147  break;
148 
149  case 'f':
150  force = true;
151  break;
152 
153  case 'n':
154  noupdate = true;
155  break;
156 
157  case 'e':
158  errno = 0;
159  set_xid_epoch = strtoul(optarg, &endptr, 0);
160  if (endptr == optarg || *endptr != '\0' || errno != 0)
161  {
162  /*------
163  translator: the second %s is a command line argument (-e, etc) */
164  pg_log_error("invalid argument for option %s", "-e");
165  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
166  exit(1);
167  }
168  if (set_xid_epoch == -1)
169  pg_fatal("transaction ID epoch (-e) must not be -1");
170  break;
171 
172  case 'u':
173  errno = 0;
174  set_oldest_xid = strtoul(optarg, &endptr, 0);
175  if (endptr == optarg || *endptr != '\0' || errno != 0)
176  {
177  pg_log_error("invalid argument for option %s", "-u");
178  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
179  exit(1);
180  }
182  pg_fatal("oldest transaction ID (-u) must be greater than or equal to %u", FirstNormalTransactionId);
183  break;
184 
185  case 'x':
186  errno = 0;
187  set_xid = strtoul(optarg, &endptr, 0);
188  if (endptr == optarg || *endptr != '\0' || errno != 0)
189  {
190  pg_log_error("invalid argument for option %s", "-x");
191  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
192  exit(1);
193  }
195  pg_fatal("transaction ID (-x) must be greater than or equal to %u", FirstNormalTransactionId);
196  break;
197 
198  case 'c':
199  errno = 0;
200  set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
201  if (endptr == optarg || *endptr != ',' || errno != 0)
202  {
203  pg_log_error("invalid argument for option %s", "-c");
204  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
205  exit(1);
206  }
207  set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
208  if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
209  {
210  pg_log_error("invalid argument for option %s", "-c");
211  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
212  exit(1);
213  }
214 
217  pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
218 
221  pg_fatal("transaction ID (-c) must be either %u or greater than or equal to %u", InvalidTransactionId, FirstNormalTransactionId);
222  break;
223 
224  case 'o':
225  errno = 0;
226  set_oid = strtoul(optarg, &endptr, 0);
227  if (endptr == optarg || *endptr != '\0' || errno != 0)
228  {
229  pg_log_error("invalid argument for option %s", "-o");
230  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
231  exit(1);
232  }
233  if (set_oid == 0)
234  pg_fatal("OID (-o) must not be 0");
235  break;
236 
237  case 'm':
238  errno = 0;
239  set_mxid = strtoul(optarg, &endptr, 0);
240  if (endptr == optarg || *endptr != ',' || errno != 0)
241  {
242  pg_log_error("invalid argument for option %s", "-m");
243  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
244  exit(1);
245  }
246 
247  set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
248  if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
249  {
250  pg_log_error("invalid argument for option %s", "-m");
251  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
252  exit(1);
253  }
254  if (set_mxid == 0)
255  pg_fatal("multitransaction ID (-m) must not be 0");
256 
257  /*
258  * XXX It'd be nice to have more sanity checks here, e.g. so
259  * that oldest is not wrapped around w.r.t. nextMulti.
260  */
261  if (set_oldestmxid == 0)
262  pg_fatal("oldest multitransaction ID (-m) must not be 0");
263  break;
264 
265  case 'O':
266  errno = 0;
267  set_mxoff = strtoul(optarg, &endptr, 0);
268  if (endptr == optarg || *endptr != '\0' || errno != 0)
269  {
270  pg_log_error("invalid argument for option %s", "-O");
271  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
272  exit(1);
273  }
274  if (set_mxoff == -1)
275  pg_fatal("multitransaction offset (-O) must not be -1");
276  break;
277 
278  case 'l':
279  if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
280  {
281  pg_log_error("invalid argument for option %s", "-l");
282  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
283  exit(1);
284  }
285 
286  /*
287  * XLogFromFileName requires wal segment size which is not yet
288  * set. Hence wal details are set later on.
289  */
290  log_fname = pg_strdup(optarg);
291  break;
292 
293  case 1:
294  {
295  int wal_segsize_mb;
296 
297  if (!option_parse_int(optarg, "--wal-segsize", 1, 1024, &wal_segsize_mb))
298  exit(1);
299  set_wal_segsize = wal_segsize_mb * 1024 * 1024;
301  pg_fatal("argument of %s must be a power of two between 1 and 1024", "--wal-segsize");
302  break;
303  }
304 
305  default:
306  /* getopt_long already emitted a complaint */
307  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
308  exit(1);
309  }
310  }
311 
312  if (DataDir == NULL && optind < argc)
313  DataDir = argv[optind++];
314 
315  /* Complain if any arguments remain */
316  if (optind < argc)
317  {
318  pg_log_error("too many command-line arguments (first is \"%s\")",
319  argv[optind]);
320  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
321  exit(1);
322  }
323 
324  if (DataDir == NULL)
325  {
326  pg_log_error("no data directory specified");
327  pg_log_error_hint("Try \"%s --help\" for more information.", progname);
328  exit(1);
329  }
330 
331  /*
332  * Don't allow pg_resetwal to be run as root, to avoid overwriting the
333  * ownership of files in the data directory. We need only check for root
334  * -- any other user won't have sufficient permissions to modify files in
335  * the data directory.
336  */
337 #ifndef WIN32
338  if (geteuid() == 0)
339  {
340  pg_log_error("cannot be executed by \"root\"");
341  pg_log_error_hint("You must run %s as the PostgreSQL superuser.",
342  progname);
343  exit(1);
344  }
345 #endif
346 
348 
349  /* Set mask based on PGDATA permissions */
351  pg_fatal("could not read permissions of directory \"%s\": %m",
352  DataDir);
353 
354  umask(pg_mode_mask);
355 
356  if (chdir(DataDir) < 0)
357  pg_fatal("could not change directory to \"%s\": %m",
358  DataDir);
359 
360  /* Check that data directory matches our server version */
362 
363  /*
364  * Check for a postmaster lock file --- if there is one, refuse to
365  * proceed, on grounds we might be interfering with a live installation.
366  */
367  if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
368  {
369  if (errno != ENOENT)
370  pg_fatal("could not open file \"%s\" for reading: %m",
371  "postmaster.pid");
372  }
373  else
374  {
375  pg_log_error("lock file \"%s\" exists", "postmaster.pid");
376  pg_log_error_hint("Is a server running? If not, delete the lock file and try again.");
377  exit(1);
378  }
379 
380  /*
381  * Attempt to read the existing pg_control file
382  */
383  if (!read_controlfile())
385 
386  /*
387  * If no new WAL segment size was specified, use the control file value.
388  */
389  if (set_wal_segsize != 0)
391  else
393 
394  if (log_fname != NULL)
396 
397  /*
398  * Also look at existing segment files to set up newXlogSegNo
399  */
400  FindEndOfXLOG();
401 
402  /*
403  * If we're not going to proceed with the reset, print the current control
404  * file parameters.
405  */
406  if ((guessed && !force) || noupdate)
408 
409  /*
410  * Adjust fields if required by switches. (Do this now so that printout,
411  * if any, includes these values.)
412  */
413  if (set_xid_epoch != -1)
417 
418  if (set_oldest_xid != 0)
419  {
422  }
423 
424  if (set_xid != 0)
427  set_xid);
428 
429  if (set_oldest_commit_ts_xid != 0)
431  if (set_newest_commit_ts_xid != 0)
433 
434  if (set_oid != 0)
436 
437  if (set_mxid != 0)
438  {
440 
441  ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
445  }
446 
447  if (set_mxoff != -1)
449 
451  {
454  }
455 
456  if (set_wal_segsize != 0)
458 
461 
462  if (noupdate)
463  {
465  exit(0);
466  }
467 
468  /*
469  * If we had to guess anything, and -f was not given, just print the
470  * guessed values and exit.
471  */
472  if (guessed && !force)
473  {
475  pg_log_error("not proceeding because control file values were guessed");
476  pg_log_error_hint("If these values seem acceptable, use -f to force reset.");
477  exit(1);
478  }
479 
480  /*
481  * Don't reset from a dirty pg_control without -f, either.
482  */
483  if (ControlFile.state != DB_SHUTDOWNED && !force)
484  {
485  pg_log_error("database server was not shut down cleanly");
486  pg_log_error_detail("Resetting the write-ahead log might cause data to be lost.");
487  pg_log_error_hint("If you want to proceed anyway, use -f to force reset.");
488  exit(1);
489  }
490 
491  /*
492  * Else, do the dirty deed.
493  */
498  WriteEmptyXLOG();
499 
500  printf(_("Write-ahead log reset\n"));
501  return 0;
502 }
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1214
TransactionId MultiXactId
Definition: c.h:662
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:448
#define _(x)
Definition: elog.c:90
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
int pg_mode_mask
Definition: file_perm.c:25
bool GetDataDirectoryCreatePerm(const char *dataDir)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:60
#define no_argument
Definition: getopt_long.h:24
#define required_argument
Definition: getopt_long.h:25
char * DataDir
Definition: globals.c:68
void pg_logging_init(const char *argv0)
Definition: logging.c:83
#define pg_log_error_hint(...)
Definition: logging.h:112
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
PGDLLIMPORT int optind
Definition: getopt.c:50
PGDLLIMPORT char * optarg
Definition: getopt.c:52
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:907
static void RewriteControlFile(void)
Definition: pg_resetwal.c:861
static void KillExistingWALSummaries(void)
Definition: pg_resetwal.c:1043
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:973
static void CheckDataVersion(void)
Definition: pg_resetwal.c:518
static XLogSegNo minXlogSegNo
Definition: pg_resetwal.c:75
static int set_wal_segsize
Definition: pg_resetwal.c:77
static MultiXactOffset set_mxoff
Definition: pg_resetwal.c:73
static MultiXactId set_mxid
Definition: pg_resetwal.c:72
static TimeLineID minXlogTli
Definition: pg_resetwal.c:74
static TransactionId set_oldest_xid
Definition: pg_resetwal.c:67
static TransactionId set_oldest_commit_ts_xid
Definition: pg_resetwal.c:69
static TransactionId set_xid
Definition: pg_resetwal.c:68
static Oid set_oid
Definition: pg_resetwal.c:71
static void PrintNewControlValues(void)
Definition: pg_resetwal.c:789
static bool read_controlfile(void)
Definition: pg_resetwal.c:559
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1006
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1079
static const char * progname
Definition: pg_resetwal.c:65
static void usage(void)
Definition: pg_resetwal.c:1166
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:716
static TransactionId set_newest_commit_ts_xid
Definition: pg_resetwal.c:70
static uint32 set_xid_epoch
Definition: pg_resetwal.c:66
static void GuessControlValues(void)
Definition: pg_resetwal.c:633
const char * get_progname(const char *argv0)
Definition: path.c:574
#define printf(...)
Definition: port.h:244
char * c
static int fd(const char *x, int i)
Definition: preproc-init.c:105
void get_restricted_token(void)
TransactionId newestCommitTsXid
Definition: pg_control.h:54
TransactionId oldestCommitTsXid
Definition: pg_control.h:52
#define EpochFromFullTransactionId(x)
Definition: transam.h:47
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
#define IsValidWalSegSize(size)
Definition: xlog_internal.h:96

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

◆ PrintControlValues()

static void PrintControlValues ( bool  guessed)
static

Definition at line 716 of file pg_resetwal.c.

717 {
718  if (guessed)
719  printf(_("Guessed pg_control values:\n\n"));
720  else
721  printf(_("Current pg_control values:\n\n"));
722 
723  printf(_("pg_control version number: %u\n"),
725  printf(_("Catalog version number: %u\n"),
727  printf(_("Database system identifier: %llu\n"),
728  (unsigned long long) ControlFile.system_identifier);
729  printf(_("Latest checkpoint's TimeLineID: %u\n"),
731  printf(_("Latest checkpoint's full_page_writes: %s\n"),
732  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
733  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
736  printf(_("Latest checkpoint's NextOID: %u\n"),
738  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
740  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
742  printf(_("Latest checkpoint's oldestXID: %u\n"),
744  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
746  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
748  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
750  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
752  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
754  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
756  printf(_("Maximum data alignment: %u\n"),
758  /* we don't print floatFormat since can't say much useful about it */
759  printf(_("Database block size: %u\n"),
761  printf(_("Blocks per segment of large relation: %u\n"),
763  printf(_("WAL block size: %u\n"),
765  printf(_("Bytes per WAL segment: %u\n"),
767  printf(_("Maximum length of identifiers: %u\n"),
769  printf(_("Maximum columns in an index: %u\n"),
771  printf(_("Maximum size of a TOAST chunk: %u\n"),
773  printf(_("Size of a large-object chunk: %u\n"),
775  /* This is no longer configurable, but users may still expect to see it: */
776  printf(_("Date/time type storage: %s\n"),
777  _("64-bit integers"));
778  printf(_("Float8 argument passing: %s\n"),
779  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
780  printf(_("Data page checksum version: %u\n"),
782 }
uint32 data_checksum_version
Definition: pg_control.h:221

References _, ControlFileData::blcksz, ControlFileData::catalog_version_no, ControlFileData::checkPointCopy, ControlFile, ControlFileData::data_checksum_version, EpochFromFullTransactionId, ControlFileData::float8ByVal, CheckPoint::fullPageWrites, guessed, ControlFileData::indexMaxKeys, ControlFileData::loblksize, ControlFileData::maxAlign, ControlFileData::nameDataLen, CheckPoint::newestCommitTsXid, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, 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().

◆ PrintNewControlValues()

static void PrintNewControlValues ( void  )
static

Definition at line 789 of file pg_resetwal.c.

790 {
791  char fname[MAXFNAMELEN];
792 
793  /* This will be always printed in order to keep format same. */
794  printf(_("\n\nValues to be changed:\n\n"));
795 
798  printf(_("First log segment after reset: %s\n"), fname);
799 
800  if (set_mxid != 0)
801  {
802  printf(_("NextMultiXactId: %u\n"),
804  printf(_("OldestMultiXid: %u\n"),
806  printf(_("OldestMulti's DB: %u\n"),
808  }
809 
810  if (set_mxoff != -1)
811  {
812  printf(_("NextMultiOffset: %u\n"),
814  }
815 
816  if (set_oid != 0)
817  {
818  printf(_("NextOID: %u\n"),
820  }
821 
822  if (set_xid != 0)
823  {
824  printf(_("NextXID: %u\n"),
826  printf(_("OldestXID: %u\n"),
828  printf(_("OldestXID's DB: %u\n"),
830  }
831 
832  if (set_xid_epoch != -1)
833  {
834  printf(_("NextXID epoch: %u\n"),
836  }
837 
838  if (set_oldest_commit_ts_xid != 0)
839  {
840  printf(_("oldestCommitTsXid: %u\n"),
842  }
843  if (set_newest_commit_ts_xid != 0)
844  {
845  printf(_("newestCommitTsXid: %u\n"),
847  }
848 
849  if (set_wal_segsize != 0)
850  {
851  printf(_("Bytes per WAL segment: %u\n"),
853  }
854 }
#define MAXFNAMELEN
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)

References _, ControlFileData::checkPointCopy, ControlFile, EpochFromFullTransactionId, MAXFNAMELEN, CheckPoint::newestCommitTsXid, newXlogSegNo, CheckPoint::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, 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().

◆ read_controlfile()

static bool read_controlfile ( void  )
static

Definition at line 559 of file pg_resetwal.c.

560 {
561  int fd;
562  int len;
563  char *buffer;
564  pg_crc32c crc;
565 
566  if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
567  {
568  /*
569  * If pg_control is not there at all, or we can't read it, the odds
570  * are we've been handed a bad DataDir path, so give up. User can do
571  * "touch pg_control" to force us to proceed.
572  */
573  pg_log_error("could not open file \"%s\" for reading: %m",
575  if (errno == ENOENT)
576  pg_log_error_hint("If you are sure the data directory path is correct, execute\n"
577  " touch %s\n"
578  "and try again.",
580  exit(1);
581  }
582 
583  /* Use malloc to ensure we have a maxaligned buffer */
584  buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
585 
586  len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
587  if (len < 0)
588  pg_fatal("could not read file \"%s\": %m", XLOG_CONTROL_FILE);
589  close(fd);
590 
591  if (len >= sizeof(ControlFileData) &&
592  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
593  {
594  /* Check the CRC. */
595  INIT_CRC32C(crc);
597  buffer,
598  offsetof(ControlFileData, crc));
599  FIN_CRC32C(crc);
600 
601  if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
602  {
603  /* We will use the data but treat it as guessed. */
604  pg_log_warning("pg_control exists but has invalid CRC; proceed with caution");
605  guessed = true;
606  }
607 
608  memcpy(&ControlFile, buffer, sizeof(ControlFile));
609 
610  /* return false if WAL segment size is not valid */
612  {
613  pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution",
614  "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
617  return false;
618  }
619 
620  return true;
621  }
622 
623  /* Looks like it's a mess. */
624  pg_log_warning("pg_control exists but is broken or wrong version; ignoring it");
625  return false;
626 }
#define ngettext(s, p, n)
Definition: c.h:1181
#define PG_BINARY
Definition: c.h:1273
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
#define PG_CONTROL_FILE_SIZE
Definition: pg_control.h:249
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:98
#define EQ_CRC32C(c1, c2)
Definition: pg_crc32c.h:42
#define INIT_CRC32C(crc)
Definition: pg_crc32c.h:41
#define FIN_CRC32C(crc)
Definition: pg_crc32c.h:103
const void size_t len
return crc
#define pg_log_warning(...)
Definition: pgfnames.c:24
#define XLOG_CONTROL_FILE

References close, COMP_CRC32C, ControlFile, crc, EQ_CRC32C, exit(), fd(), FIN_CRC32C, guessed, INIT_CRC32C, IsValidWalSegSize, len, ngettext, PG_BINARY, PG_CONTROL_FILE_SIZE, PG_CONTROL_VERSION, pg_fatal, pg_log_error, pg_log_error_hint, pg_log_warning, pg_malloc(), read, XLOG_CONTROL_FILE, and ControlFileData::xlog_seg_size.

Referenced by main().

◆ RewriteControlFile()

static void RewriteControlFile ( void  )
static

Definition at line 861 of file pg_resetwal.c.

862 {
863  /*
864  * Adjust fields as needed to force an empty XLOG starting at
865  * newXlogSegNo.
866  */
869  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
870 
878 
879  /*
880  * Force the defaults for max_* settings. The values don't really matter
881  * as long as wal_level='minimal'; the postmaster will reset these fields
882  * anyway at startup.
883  */
885  ControlFile.wal_log_hints = false;
892 
893  /* The control file gets flushed here. */
894  update_controlfile(".", &ControlFile, true);
895 }
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
XLogRecPtr backupStartPoint
Definition: pg_control.h:169
bool backupEndRequired
Definition: pg_control.h:171
XLogRecPtr backupEndPoint
Definition: pg_control.h:170
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:167
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:168
#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest)

References ControlFileData::backupEndPoint, ControlFileData::backupEndRequired, ControlFileData::backupStartPoint, ControlFileData::checkPoint, ControlFileData::checkPointCopy, ControlFile, 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::track_commit_timestamp, update_controlfile(), ControlFileData::wal_level, WAL_LEVEL_MINIMAL, ControlFileData::wal_log_hints, WalSegSz, and XLogSegNoOffsetToRecPtr.

Referenced by main().

◆ usage()

static void usage ( void  )
static

Definition at line 1166 of file pg_resetwal.c.

1167 {
1168  printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1169  printf(_("Usage:\n"));
1170  printf(_(" %s [OPTION]... DATADIR\n"), progname);
1171 
1172  printf(_("\nOptions:\n"));
1173  printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
1174  printf(_(" -f, --force force update to be done even after unclean shutdown or\n"
1175  " if pg_control values had to be guessed\n"));
1176  printf(_(" -n, --dry-run no update, just show what would be done\n"));
1177  printf(_(" -V, --version output version information, then exit\n"));
1178  printf(_(" -?, --help show this help, then exit\n"));
1179 
1180  printf(_("\nOptions to override control file values:\n"));
1181  printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
1182  " set oldest and newest transactions bearing\n"
1183  " commit timestamp (zero means no change)\n"));
1184  printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
1185  printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
1186  printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
1187  printf(_(" -o, --next-oid=OID set next OID\n"));
1188  printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
1189  printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n"));
1190  printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
1191  printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
1192 
1193  printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1194  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1195 }

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1079 of file pg_resetwal.c.

1080 {
1081  PGAlignedXLogBlock buffer;
1082  XLogPageHeader page;
1083  XLogLongPageHeader longpage;
1084  XLogRecord *record;
1085  pg_crc32c crc;
1086  char path[MAXPGPATH];
1087  int fd;
1088  int nbytes;
1089  char *recptr;
1090 
1091  memset(buffer.data, 0, XLOG_BLCKSZ);
1092 
1093  /* Set up the XLOG page header */
1094  page = (XLogPageHeader) buffer.data;
1095  page->xlp_magic = XLOG_PAGE_MAGIC;
1096  page->xlp_info = XLP_LONG_HEADER;
1099  longpage = (XLogLongPageHeader) page;
1101  longpage->xlp_seg_size = WalSegSz;
1102  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1103 
1104  /* Insert the initial checkpoint record */
1105  recptr = (char *) page + SizeOfXLogLongPHD;
1106  record = (XLogRecord *) recptr;
1107  record->xl_prev = 0;
1108  record->xl_xid = InvalidTransactionId;
1111  record->xl_rmid = RM_XLOG_ID;
1112 
1113  recptr += SizeOfXLogRecord;
1114  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1115  *(recptr++) = sizeof(CheckPoint);
1116  memcpy(recptr, &ControlFile.checkPointCopy,
1117  sizeof(CheckPoint));
1118 
1119  INIT_CRC32C(crc);
1120  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1121  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1122  FIN_CRC32C(crc);
1123  record->xl_crc = crc;
1124 
1125  /* Write the first page */
1128 
1129  unlink(path);
1130 
1131  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1133  if (fd < 0)
1134  pg_fatal("could not open file \"%s\": %m", path);
1135 
1136  errno = 0;
1137  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1138  {
1139  /* if write didn't set errno, assume problem is no disk space */
1140  if (errno == 0)
1141  errno = ENOSPC;
1142  pg_fatal("could not write file \"%s\": %m", path);
1143  }
1144 
1145  /* Fill the rest of the file with zeroes */
1146  memset(buffer.data, 0, XLOG_BLCKSZ);
1147  for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1148  {
1149  errno = 0;
1150  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1151  {
1152  if (errno == 0)
1153  errno = ENOSPC;
1154  pg_fatal("could not write file \"%s\": %m", path);
1155  }
1156  }
1157 
1158  if (fsync(fd) != 0)
1159  pg_fatal("fsync error: %m");
1160 
1161  close(fd);
1162 }
int pg_file_create_mode
Definition: file_perm.c:19
#define write(a, b, c)
Definition: win32.h:14
struct CheckPoint CheckPoint
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
TimeLineID xlp_tli
Definition: xlog_internal.h:40
XLogRecPtr xlp_pageaddr
Definition: xlog_internal.h:41
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
uint8 xl_info
Definition: xlogrecord.h:46
uint32 xl_tot_len
Definition: xlogrecord.h:43
TransactionId xl_xid
Definition: xlogrecord.h:44
RmgrId xl_rmid
Definition: xlogrecord.h:47
char data[XLOG_BLCKSZ]
Definition: c.h:1148
#define fsync(fd)
Definition: win32_port.h:85
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
static void XLogFilePath(char *path, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:217
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:241
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

References ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFile, crc, PGAlignedXLogBlock::data, fd(), FIN_CRC32C, fsync, INIT_CRC32C, InvalidTransactionId, MAXPGPATH, newXlogSegNo, PG_BINARY, pg_fatal, pg_file_create_mode, CheckPoint::redo, SizeOfXLogLongPHD, SizeOfXLogRecord, SizeOfXLogRecordDataHeaderShort, 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().

Variable Documentation

◆ ControlFile

◆ guessed

bool guessed = false
static

Definition at line 64 of file pg_resetwal.c.

Referenced by GuessControlValues(), main(), PrintControlValues(), and read_controlfile().

◆ minXlogSegNo

XLogSegNo minXlogSegNo = 0
static

Definition at line 75 of file pg_resetwal.c.

Referenced by main().

◆ minXlogTli

TimeLineID minXlogTli = 0
static

Definition at line 74 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 72 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_mxoff

MultiXactOffset set_mxoff = (MultiXactOffset) -1
static

Definition at line 73 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 70 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oid

Oid set_oid = 0
static

Definition at line 71 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 69 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_oldest_xid

TransactionId set_oldest_xid = 0
static

Definition at line 67 of file pg_resetwal.c.

Referenced by main().

◆ set_wal_segsize

int set_wal_segsize
static

Definition at line 77 of file pg_resetwal.c.

Referenced by main(), and PrintNewControlValues().

◆ set_xid

TransactionId set_xid = 0
static

Definition at line 68 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