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

554 {
555  const char *ver_file = "PG_VERSION";
556  FILE *ver_fd;
557  char rawline[64];
558 
559  if ((ver_fd = fopen(ver_file, "r")) == NULL)
560  {
561  pg_log_error("could not open file \"%s\" for reading: %m",
562  ver_file);
563  exit(1);
564  }
565 
566  /* version number has to be the first line read */
567  if (!fgets(rawline, sizeof(rawline), ver_fd))
568  {
569  if (!ferror(ver_fd))
570  pg_log_error("unexpected empty file \"%s\"", ver_file);
571  else
572  pg_log_error("could not read file \"%s\": %m", ver_file);
573  exit(1);
574  }
575 
576  /* strip trailing newline and carriage return */
577  (void) pg_strip_crlf(rawline);
578 
579  if (strcmp(rawline, PG_MAJORVERSION) != 0)
580  {
581  pg_log_error("data directory is of wrong version");
582  pg_log_info("File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
583  ver_file, rawline, PG_MAJORVERSION);
584  exit(1);
585  }
586 
587  fclose(ver_fd);
588 }
exit(1)
#define pg_log_error(...)
Definition: logging.h:80
#define pg_log_info(...)
Definition: logging.h:88
int pg_strip_crlf(char *str)
Definition: string.c:121

References exit(), pg_log_error, pg_log_info, and pg_strip_crlf().

Referenced by main().

◆ FindEndOfXLOG()

static void FindEndOfXLOG ( void  )
static

Definition at line 949 of file pg_resetwal.c.

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

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

Referenced by main().

◆ GuessControlValues()

static void GuessControlValues ( void  )
static

Definition at line 675 of file pg_resetwal.c.

676 {
677  uint64 sysidentifier;
678  struct timeval tv;
679 
680  /*
681  * Set up a completely default set of pg_control values.
682  */
683  guessed = true;
684  memset(&ControlFile, 0, sizeof(ControlFile));
685 
688 
689  /*
690  * Create a new unique installation identifier, since we can no longer use
691  * any old XLOG records. See notes in xlog.c about the algorithm.
692  */
693  gettimeofday(&tv, NULL);
694  sysidentifier = ((uint64) tv.tv_sec) << 32;
695  sysidentifier |= ((uint64) tv.tv_usec) << 12;
696  sysidentifier |= getpid() & 0xFFF;
697 
698  ControlFile.system_identifier = sysidentifier;
699 
713  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
715 
717  ControlFile.time = (pg_time_t) time(NULL);
720 
721  /* minRecoveryPoint, backupStartPoint and backupEndPoint can be left zero */
722 
724  ControlFile.wal_log_hints = false;
731 
732  ControlFile.maxAlign = MAXIMUM_ALIGNOF;
734  ControlFile.blcksz = BLCKSZ;
735  ControlFile.relseg_size = RELSEG_SIZE;
736  ControlFile.xlog_blcksz = XLOG_BLCKSZ;
743 
744  /*
745  * XXX eventually, should try to grovel through old XLOG to develop more
746  * accurate values for TimeLineID, nextXID, etc.
747  */
748 }
#define FLOAT8PASSBYVAL
Definition: c.h:570
#define CATALOG_VERSION_NO
Definition: catversion.h:56
int gettimeofday(struct timeval *tp, struct timezone *tzp)
Definition: gettimeofday.c:104
#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:201
#define PG_CONTROL_VERSION
Definition: pg_control.h:25
@ DB_SHUTDOWNED
Definition: pg_control.h:90
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:181
uint32 pg_control_version
Definition: pg_control.h:123
bool track_commit_timestamp
Definition: pg_control.h:185
int max_locks_per_xact
Definition: pg_control.h:184
uint32 nameDataLen
Definition: pg_control.h:213
XLogRecPtr unloggedLSN
Definition: pg_control.h:135
uint32 indexMaxKeys
Definition: pg_control.h:214
uint32 relseg_size
Definition: pg_control.h:208
pg_time_t time
Definition: pg_control.h:130
XLogRecPtr checkPoint
Definition: pg_control.h:131
uint64 system_identifier
Definition: pg_control.h:108
uint32 catalog_version_no
Definition: pg_control.h:124
double floatFormat
Definition: pg_control.h:200
int max_prepared_xacts
Definition: pg_control.h:183
uint32 xlog_blcksz
Definition: pg_control.h:210
uint32 loblksize
Definition: pg_control.h:217
uint32 toast_max_chunk_size
Definition: pg_control.h:216
#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
@ WAL_LEVEL_MINIMAL
Definition: xlog.h:121
#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 1076 of file pg_resetwal.c.

1077 {
1078 #define ARCHSTATDIR XLOGDIR "/archive_status"
1079 
1080  DIR *xldir;
1081  struct dirent *xlde;
1082  char path[MAXPGPATH + sizeof(ARCHSTATDIR)];
1083 
1084  xldir = opendir(ARCHSTATDIR);
1085  if (xldir == NULL)
1086  {
1087  pg_log_error("could not open directory \"%s\": %m", ARCHSTATDIR);
1088  exit(1);
1089  }
1090 
1091  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1092  {
1093  if (strspn(xlde->d_name, "0123456789ABCDEF") == XLOG_FNAME_LEN &&
1094  (strcmp(xlde->d_name + XLOG_FNAME_LEN, ".ready") == 0 ||
1095  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".done") == 0 ||
1096  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.ready") == 0 ||
1097  strcmp(xlde->d_name + XLOG_FNAME_LEN, ".partial.done") == 0))
1098  {
1099  snprintf(path, sizeof(path), "%s/%s", ARCHSTATDIR, xlde->d_name);
1100  if (unlink(path) < 0)
1101  {
1102  pg_log_error("could not delete file \"%s\": %m", path);
1103  exit(1);
1104  }
1105  }
1106  }
1107 
1108  if (errno)
1109  {
1110  pg_log_error("could not read directory \"%s\": %m", ARCHSTATDIR);
1111  exit(1);
1112  }
1113 
1114  if (closedir(xldir))
1115  {
1116  pg_log_error("could not close directory \"%s\": %m", ARCHSTATDIR);
1117  exit(1);
1118  }
1119 }
#define MAXPGPATH
#define ARCHSTATDIR
#define snprintf
Definition: port.h:225
#define XLOG_FNAME_LEN

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

Referenced by main().

◆ KillExistingXLOG()

static void KillExistingXLOG ( void  )
static

Definition at line 1031 of file pg_resetwal.c.

1032 {
1033  DIR *xldir;
1034  struct dirent *xlde;
1035  char path[MAXPGPATH + sizeof(XLOGDIR)];
1036 
1037  xldir = opendir(XLOGDIR);
1038  if (xldir == NULL)
1039  {
1040  pg_log_error("could not open directory \"%s\": %m", XLOGDIR);
1041  exit(1);
1042  }
1043 
1044  while (errno = 0, (xlde = readdir(xldir)) != NULL)
1045  {
1046  if (IsXLogFileName(xlde->d_name) ||
1048  {
1049  snprintf(path, sizeof(path), "%s/%s", XLOGDIR, xlde->d_name);
1050  if (unlink(path) < 0)
1051  {
1052  pg_log_error("could not delete file \"%s\": %m", path);
1053  exit(1);
1054  }
1055  }
1056  }
1057 
1058  if (errno)
1059  {
1060  pg_log_error("could not read directory \"%s\": %m", XLOGDIR);
1061  exit(1);
1062  }
1063 
1064  if (closedir(xldir))
1065  {
1066  pg_log_error("could not close directory \"%s\": %m", XLOGDIR);
1067  exit(1);
1068  }
1069 }

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

Referenced by main().

◆ main()

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

Definition at line 93 of file pg_resetwal.c.

94 {
95  static struct option long_options[] = {
96  {"commit-timestamp-ids", required_argument, NULL, 'c'},
97  {"pgdata", required_argument, NULL, 'D'},
98  {"epoch", required_argument, NULL, 'e'},
99  {"force", no_argument, NULL, 'f'},
100  {"next-wal-file", required_argument, NULL, 'l'},
101  {"multixact-ids", required_argument, NULL, 'm'},
102  {"dry-run", no_argument, NULL, 'n'},
103  {"next-oid", required_argument, NULL, 'o'},
104  {"multixact-offset", required_argument, NULL, 'O'},
105  {"oldest-transaction-id", required_argument, NULL, 'u'},
106  {"next-transaction-id", required_argument, NULL, 'x'},
107  {"wal-segsize", required_argument, NULL, 1},
108  {NULL, 0, NULL, 0}
109  };
110 
111  int c;
112  bool force = false;
113  bool noupdate = false;
114  MultiXactId set_oldestmxid = 0;
115  char *endptr;
116  char *endptr2;
117  char *DataDir = NULL;
118  char *log_fname = NULL;
119  int fd;
120 
121  pg_logging_init(argv[0]);
122  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_resetwal"));
123  progname = get_progname(argv[0]);
124 
125  if (argc > 1)
126  {
127  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
128  {
129  usage();
130  exit(0);
131  }
132  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
133  {
134  puts("pg_resetwal (PostgreSQL) " PG_VERSION);
135  exit(0);
136  }
137  }
138 
139 
140  while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:u:x:", long_options, NULL)) != -1)
141  {
142  switch (c)
143  {
144  case 'D':
145  DataDir = optarg;
146  break;
147 
148  case 'f':
149  force = true;
150  break;
151 
152  case 'n':
153  noupdate = true;
154  break;
155 
156  case 'e':
157  errno = 0;
158  set_xid_epoch = strtoul(optarg, &endptr, 0);
159  if (endptr == optarg || *endptr != '\0' || errno != 0)
160  {
161  /*------
162  translator: the second %s is a command line argument (-e, etc) */
163  pg_log_error("invalid argument for option %s", "-e");
164  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
165  exit(1);
166  }
167  if (set_xid_epoch == -1)
168  {
169  pg_log_error("transaction ID epoch (-e) must not be -1");
170  exit(1);
171  }
172  break;
173 
174  case 'u':
175  errno = 0;
176  set_oldest_xid = strtoul(optarg, &endptr, 0);
177  if (endptr == optarg || *endptr != '\0' || errno != 0)
178  {
179  pg_log_error("invalid argument for option %s", "-u");
180  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
181  exit(1);
182  }
184  {
185  pg_log_error("oldest transaction ID (-u) must be greater than or equal to %u", FirstNormalTransactionId);
186  exit(1);
187  }
188  break;
189 
190  case 'x':
191  errno = 0;
192  set_xid = strtoul(optarg, &endptr, 0);
193  if (endptr == optarg || *endptr != '\0' || errno != 0)
194  {
195  pg_log_error("invalid argument for option %s", "-x");
196  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
197  exit(1);
198  }
200  {
201  pg_log_error("transaction ID (-x) must be greater than or equal to %u", FirstNormalTransactionId);
202  exit(1);
203  }
204  break;
205 
206  case 'c':
207  errno = 0;
208  set_oldest_commit_ts_xid = strtoul(optarg, &endptr, 0);
209  if (endptr == optarg || *endptr != ',' || errno != 0)
210  {
211  pg_log_error("invalid argument for option %s", "-c");
212  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
213  exit(1);
214  }
215  set_newest_commit_ts_xid = strtoul(endptr + 1, &endptr2, 0);
216  if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
217  {
218  pg_log_error("invalid argument for option %s", "-c");
219  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
220  exit(1);
221  }
222 
223  if (set_oldest_commit_ts_xid < 2 &&
225  {
226  pg_log_error("transaction ID (-c) must be either 0 or greater than or equal to 2");
227  exit(1);
228  }
229 
230  if (set_newest_commit_ts_xid < 2 &&
232  {
233  pg_log_error("transaction ID (-c) must be either 0 or greater than or equal to 2");
234  exit(1);
235  }
236  break;
237 
238  case 'o':
239  errno = 0;
240  set_oid = strtoul(optarg, &endptr, 0);
241  if (endptr == optarg || *endptr != '\0' || errno != 0)
242  {
243  pg_log_error("invalid argument for option %s", "-o");
244  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
245  exit(1);
246  }
247  if (set_oid == 0)
248  {
249  pg_log_error("OID (-o) must not be 0");
250  exit(1);
251  }
252  break;
253 
254  case 'm':
255  errno = 0;
256  set_mxid = strtoul(optarg, &endptr, 0);
257  if (endptr == optarg || *endptr != ',' || errno != 0)
258  {
259  pg_log_error("invalid argument for option %s", "-m");
260  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
261  exit(1);
262  }
263 
264  set_oldestmxid = strtoul(endptr + 1, &endptr2, 0);
265  if (endptr2 == endptr + 1 || *endptr2 != '\0' || errno != 0)
266  {
267  pg_log_error("invalid argument for option %s", "-m");
268  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
269  exit(1);
270  }
271  if (set_mxid == 0)
272  {
273  pg_log_error("multitransaction ID (-m) must not be 0");
274  exit(1);
275  }
276 
277  /*
278  * XXX It'd be nice to have more sanity checks here, e.g. so
279  * that oldest is not wrapped around w.r.t. nextMulti.
280  */
281  if (set_oldestmxid == 0)
282  {
283  pg_log_error("oldest multitransaction ID (-m) must not be 0");
284  exit(1);
285  }
286  break;
287 
288  case 'O':
289  errno = 0;
290  set_mxoff = strtoul(optarg, &endptr, 0);
291  if (endptr == optarg || *endptr != '\0' || errno != 0)
292  {
293  pg_log_error("invalid argument for option %s", "-O");
294  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
295  exit(1);
296  }
297  if (set_mxoff == -1)
298  {
299  pg_log_error("multitransaction offset (-O) must not be -1");
300  exit(1);
301  }
302  break;
303 
304  case 'l':
305  if (strspn(optarg, "01234567890ABCDEFabcdef") != XLOG_FNAME_LEN)
306  {
307  pg_log_error("invalid argument for option %s", "-l");
308  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
309  exit(1);
310  }
311 
312  /*
313  * XLogFromFileName requires wal segment size which is not yet
314  * set. Hence wal details are set later on.
315  */
316  log_fname = pg_strdup(optarg);
317  break;
318 
319  case 1:
320  errno = 0;
321  set_wal_segsize = strtol(optarg, &endptr, 10) * 1024 * 1024;
322  if (endptr == optarg || *endptr != '\0' || errno != 0)
323  {
324  pg_log_error("argument of --wal-segsize must be a number");
325  exit(1);
326  }
328  {
329  pg_log_error("argument of --wal-segsize must be a power of 2 between 1 and 1024");
330  exit(1);
331  }
332  break;
333 
334  default:
335  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
336  exit(1);
337  }
338  }
339 
340  if (DataDir == NULL && optind < argc)
341  DataDir = argv[optind++];
342 
343  /* Complain if any arguments remain */
344  if (optind < argc)
345  {
346  pg_log_error("too many command-line arguments (first is \"%s\")",
347  argv[optind]);
348  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
349  progname);
350  exit(1);
351  }
352 
353  if (DataDir == NULL)
354  {
355  pg_log_error("no data directory specified");
356  fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
357  exit(1);
358  }
359 
360  /*
361  * Don't allow pg_resetwal to be run as root, to avoid overwriting the
362  * ownership of files in the data directory. We need only check for root
363  * -- any other user won't have sufficient permissions to modify files in
364  * the data directory.
365  */
366 #ifndef WIN32
367  if (geteuid() == 0)
368  {
369  pg_log_error("cannot be executed by \"root\"");
370  pg_log_info("You must run %s as the PostgreSQL superuser.",
371  progname);
372  exit(1);
373  }
374 #endif
375 
377 
378  /* Set mask based on PGDATA permissions */
380  {
381  pg_log_error("could not read permissions of directory \"%s\": %m",
382  DataDir);
383  exit(1);
384  }
385 
386  umask(pg_mode_mask);
387 
388  if (chdir(DataDir) < 0)
389  {
390  pg_log_error("could not change directory to \"%s\": %m",
391  DataDir);
392  exit(1);
393  }
394 
395  /* Check that data directory matches our server version */
397 
398  /*
399  * Check for a postmaster lock file --- if there is one, refuse to
400  * proceed, on grounds we might be interfering with a live installation.
401  */
402  if ((fd = open("postmaster.pid", O_RDONLY, 0)) < 0)
403  {
404  if (errno != ENOENT)
405  {
406  pg_log_error("could not open file \"%s\" for reading: %m",
407  "postmaster.pid");
408  exit(1);
409  }
410  }
411  else
412  {
413  pg_log_error("lock file \"%s\" exists", "postmaster.pid");
414  pg_log_info("Is a server running? If not, delete the lock file and try again.");
415  exit(1);
416  }
417 
418  /*
419  * Attempt to read the existing pg_control file
420  */
421  if (!read_controlfile())
423 
424  /*
425  * If no new WAL segment size was specified, use the control file value.
426  */
427  if (set_wal_segsize != 0)
429  else
431 
432  if (log_fname != NULL)
434 
435  /*
436  * Also look at existing segment files to set up newXlogSegNo
437  */
438  FindEndOfXLOG();
439 
440  /*
441  * If we're not going to proceed with the reset, print the current control
442  * file parameters.
443  */
444  if ((guessed && !force) || noupdate)
446 
447  /*
448  * Adjust fields if required by switches. (Do this now so that printout,
449  * if any, includes these values.)
450  */
451  if (set_xid_epoch != -1)
455 
456  if (set_oldest_xid != 0)
457  {
460  }
461 
462  if (set_xid != 0)
465  set_xid);
466 
467  if (set_oldest_commit_ts_xid != 0)
469  if (set_newest_commit_ts_xid != 0)
471 
472  if (set_oid != 0)
474 
475  if (set_mxid != 0)
476  {
478 
479  ControlFile.checkPointCopy.oldestMulti = set_oldestmxid;
483  }
484 
485  if (set_mxoff != -1)
487 
489  {
492  }
493 
494  if (set_wal_segsize != 0)
496 
499 
500  /*
501  * If we had to guess anything, and -f was not given, just print the
502  * guessed values and exit. Also print if -n is given.
503  */
504  if ((guessed && !force) || noupdate)
505  {
507  if (!noupdate)
508  {
509  printf(_("\nIf these values seem acceptable, use -f to force reset.\n"));
510  exit(1);
511  }
512  else
513  exit(0);
514  }
515 
516  /*
517  * Don't reset from a dirty pg_control without -f, either.
518  */
519  if (ControlFile.state != DB_SHUTDOWNED && !force)
520  {
521  printf(_("The database server was not shut down cleanly.\n"
522  "Resetting the write-ahead log might cause data to be lost.\n"
523  "If you want to proceed anyway, use -f to force reset.\n"));
524  exit(1);
525  }
526 
527  /*
528  * Else, do the dirty deed.
529  */
533  WriteEmptyXLOG();
534 
535  printf(_("Write-ahead log reset\n"));
536  return 0;
537 }
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1212
TransactionId MultiXactId
Definition: c.h:597
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:441
#define _(x)
Definition: elog.c:89
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:57
#define no_argument
Definition: getopt_long.h:24
#define required_argument
Definition: getopt_long.h:25
char * DataDir
Definition: globals.c:65
void pg_logging_init(const char *argv0)
Definition: logging.c:81
int optind
Definition: getopt.c:50
char * optarg
Definition: getopt.c:52
static void FindEndOfXLOG(void)
Definition: pg_resetwal.c:949
static void RewriteControlFile(void)
Definition: pg_resetwal.c:903
static void KillExistingXLOG(void)
Definition: pg_resetwal.c:1031
static void CheckDataVersion(void)
Definition: pg_resetwal.c:553
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 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:831
static bool read_controlfile(void)
Definition: pg_resetwal.c:598
static uint32 minXlogTli
Definition: pg_resetwal.c:74
static void KillExistingArchiveStatus(void)
Definition: pg_resetwal.c:1076
static void WriteEmptyXLOG(void)
Definition: pg_resetwal.c:1127
static const char * progname
Definition: pg_resetwal.c:65
static void usage(void)
Definition: pg_resetwal.c:1222
static void PrintControlValues(bool guessed)
Definition: pg_resetwal.c:758
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:675
const char * get_progname(const char *argv0)
Definition: path.c:453
#define fprintf
Definition: port.h:229
#define printf(...)
Definition: port.h:231
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
#define XLogFromFileName(fname, tli, logSegNo, wal_segsz_bytes)

References _, CheckDataVersion(), ControlFileData::checkPointCopy, ControlFile, DataDir, DB_SHUTDOWNED, EpochFromFullTransactionId, exit(), 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::nextMulti, CheckPoint::nextMultiOffset, CheckPoint::nextOid, CheckPoint::nextXid, 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, 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 758 of file pg_resetwal.c.

759 {
760  if (guessed)
761  printf(_("Guessed pg_control values:\n\n"));
762  else
763  printf(_("Current pg_control values:\n\n"));
764 
765  printf(_("pg_control version number: %u\n"),
767  printf(_("Catalog version number: %u\n"),
769  printf(_("Database system identifier: %llu\n"),
770  (unsigned long long) ControlFile.system_identifier);
771  printf(_("Latest checkpoint's TimeLineID: %u\n"),
773  printf(_("Latest checkpoint's full_page_writes: %s\n"),
774  ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"));
775  printf(_("Latest checkpoint's NextXID: %u:%u\n"),
778  printf(_("Latest checkpoint's NextOID: %u\n"),
780  printf(_("Latest checkpoint's NextMultiXactId: %u\n"),
782  printf(_("Latest checkpoint's NextMultiOffset: %u\n"),
784  printf(_("Latest checkpoint's oldestXID: %u\n"),
786  printf(_("Latest checkpoint's oldestXID's DB: %u\n"),
788  printf(_("Latest checkpoint's oldestActiveXID: %u\n"),
790  printf(_("Latest checkpoint's oldestMultiXid: %u\n"),
792  printf(_("Latest checkpoint's oldestMulti's DB: %u\n"),
794  printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"),
796  printf(_("Latest checkpoint's newestCommitTsXid:%u\n"),
798  printf(_("Maximum data alignment: %u\n"),
800  /* we don't print floatFormat since can't say much useful about it */
801  printf(_("Database block size: %u\n"),
803  printf(_("Blocks per segment of large relation: %u\n"),
805  printf(_("WAL block size: %u\n"),
807  printf(_("Bytes per WAL segment: %u\n"),
809  printf(_("Maximum length of identifiers: %u\n"),
811  printf(_("Maximum columns in an index: %u\n"),
813  printf(_("Maximum size of a TOAST chunk: %u\n"),
815  printf(_("Size of a large-object chunk: %u\n"),
817  /* This is no longer configurable, but users may still expect to see it: */
818  printf(_("Date/time type storage: %s\n"),
819  _("64-bit integers"));
820  printf(_("Float8 argument passing: %s\n"),
821  (ControlFile.float8ByVal ? _("by value") : _("by reference")));
822  printf(_("Data page checksum version: %u\n"),
824 }
uint32 data_checksum_version
Definition: pg_control.h:222

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

832 {
833  char fname[MAXFNAMELEN];
834 
835  /* This will be always printed in order to keep format same. */
836  printf(_("\n\nValues to be changed:\n\n"));
837 
840  printf(_("First log segment after reset: %s\n"), fname);
841 
842  if (set_mxid != 0)
843  {
844  printf(_("NextMultiXactId: %u\n"),
846  printf(_("OldestMultiXid: %u\n"),
848  printf(_("OldestMulti's DB: %u\n"),
850  }
851 
852  if (set_mxoff != -1)
853  {
854  printf(_("NextMultiOffset: %u\n"),
856  }
857 
858  if (set_oid != 0)
859  {
860  printf(_("NextOID: %u\n"),
862  }
863 
864  if (set_xid != 0)
865  {
866  printf(_("NextXID: %u\n"),
868  printf(_("OldestXID: %u\n"),
870  printf(_("OldestXID's DB: %u\n"),
872  }
873 
874  if (set_xid_epoch != -1)
875  {
876  printf(_("NextXID epoch: %u\n"),
878  }
879 
880  if (set_oldest_commit_ts_xid != 0)
881  {
882  printf(_("oldestCommitTsXid: %u\n"),
884  }
885  if (set_newest_commit_ts_xid != 0)
886  {
887  printf(_("newestCommitTsXid: %u\n"),
889  }
890 
891  if (set_wal_segsize != 0)
892  {
893  printf(_("Bytes per WAL segment: %u\n"),
895  }
896 }
#define XLogFileName(fname, tli, logSegNo, wal_segsz_bytes)
#define MAXFNAMELEN

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

599 {
600  int fd;
601  int len;
602  char *buffer;
603  pg_crc32c crc;
604 
605  if ((fd = open(XLOG_CONTROL_FILE, O_RDONLY | PG_BINARY, 0)) < 0)
606  {
607  /*
608  * If pg_control is not there at all, or we can't read it, the odds
609  * are we've been handed a bad DataDir path, so give up. User can do
610  * "touch pg_control" to force us to proceed.
611  */
612  pg_log_error("could not open file \"%s\" for reading: %m",
614  if (errno == ENOENT)
615  pg_log_info("If you are sure the data directory path is correct, execute\n"
616  " touch %s\n"
617  "and try again.",
619  exit(1);
620  }
621 
622  /* Use malloc to ensure we have a maxaligned buffer */
623  buffer = (char *) pg_malloc(PG_CONTROL_FILE_SIZE);
624 
625  len = read(fd, buffer, PG_CONTROL_FILE_SIZE);
626  if (len < 0)
627  {
628  pg_log_error("could not read file \"%s\": %m", XLOG_CONTROL_FILE);
629  exit(1);
630  }
631  close(fd);
632 
633  if (len >= sizeof(ControlFileData) &&
634  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
635  {
636  /* Check the CRC. */
637  INIT_CRC32C(crc);
639  buffer,
641  FIN_CRC32C(crc);
642 
643  if (!EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
644  {
645  /* We will use the data but treat it as guessed. */
646  pg_log_warning("pg_control exists but has invalid CRC; proceed with caution");
647  guessed = true;
648  }
649 
650  memcpy(&ControlFile, buffer, sizeof(ControlFile));
651 
652  /* return false if WAL segment size is not valid */
654  {
655  pg_log_warning(ngettext("pg_control specifies invalid WAL segment size (%d byte); proceed with caution",
656  "pg_control specifies invalid WAL segment size (%d bytes); proceed with caution",
659  return false;
660  }
661 
662  return true;
663  }
664 
665  /* Looks like it's a mess. */
666  pg_log_warning("pg_control exists but is broken or wrong version; ignoring it");
667  return false;
668 }
#define offsetof(type, field)
Definition: c.h:727
#define ngettext(s, p, n)
Definition: c.h:1179
#define PG_BINARY
Definition: c.h:1268
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:250
uint32 pg_crc32c
Definition: pg_crc32c.h:38
#define COMP_CRC32C(crc, data, len)
Definition: pg_crc32c.h:89
#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:94
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, 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().

◆ RewriteControlFile()

static void RewriteControlFile ( void  )
static

Definition at line 903 of file pg_resetwal.c.

904 {
905  /*
906  * Adjust fields as needed to force an empty XLOG starting at
907  * newXlogSegNo.
908  */
911  ControlFile.checkPointCopy.time = (pg_time_t) time(NULL);
912 
920 
921  /*
922  * Force the defaults for max_* settings. The values don't really matter
923  * as long as wal_level='minimal'; the postmaster will reset these fields
924  * anyway at startup.
925  */
927  ControlFile.wal_log_hints = false;
934 
935  /* The control file gets flushed here. */
936  update_controlfile(".", &ControlFile, true);
937 }
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
XLogRecPtr backupStartPoint
Definition: pg_control.h:170
bool backupEndRequired
Definition: pg_control.h:172
XLogRecPtr backupEndPoint
Definition: pg_control.h:171
XLogRecPtr minRecoveryPoint
Definition: pg_control.h:168
TimeLineID minRecoveryPointTLI
Definition: pg_control.h:169
#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 1222 of file pg_resetwal.c.

1223 {
1224  printf(_("%s resets the PostgreSQL write-ahead log.\n\n"), progname);
1225  printf(_("Usage:\n %s [OPTION]... DATADIR\n\n"), progname);
1226  printf(_("Options:\n"));
1227  printf(_(" -c, --commit-timestamp-ids=XID,XID\n"
1228  " set oldest and newest transactions bearing\n"
1229  " commit timestamp (zero means no change)\n"));
1230  printf(_(" [-D, --pgdata=]DATADIR data directory\n"));
1231  printf(_(" -e, --epoch=XIDEPOCH set next transaction ID epoch\n"));
1232  printf(_(" -f, --force force update to be done\n"));
1233  printf(_(" -l, --next-wal-file=WALFILE set minimum starting location for new WAL\n"));
1234  printf(_(" -m, --multixact-ids=MXID,MXID set next and oldest multitransaction ID\n"));
1235  printf(_(" -n, --dry-run no update, just show what would be done\n"));
1236  printf(_(" -o, --next-oid=OID set next OID\n"));
1237  printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n"));
1238  printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n"));
1239  printf(_(" -V, --version output version information, then exit\n"));
1240  printf(_(" -x, --next-transaction-id=XID set next transaction ID\n"));
1241  printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n"));
1242  printf(_(" -?, --help show this help, then exit\n"));
1243  printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
1244  printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
1245 }

References _, printf, and progname.

Referenced by main().

◆ WriteEmptyXLOG()

static void WriteEmptyXLOG ( void  )
static

Definition at line 1127 of file pg_resetwal.c.

1128 {
1129  PGAlignedXLogBlock buffer;
1130  XLogPageHeader page;
1131  XLogLongPageHeader longpage;
1132  XLogRecord *record;
1133  pg_crc32c crc;
1134  char path[MAXPGPATH];
1135  int fd;
1136  int nbytes;
1137  char *recptr;
1138 
1139  memset(buffer.data, 0, XLOG_BLCKSZ);
1140 
1141  /* Set up the XLOG page header */
1142  page = (XLogPageHeader) buffer.data;
1143  page->xlp_magic = XLOG_PAGE_MAGIC;
1144  page->xlp_info = XLP_LONG_HEADER;
1147  longpage = (XLogLongPageHeader) page;
1149  longpage->xlp_seg_size = WalSegSz;
1150  longpage->xlp_xlog_blcksz = XLOG_BLCKSZ;
1151 
1152  /* Insert the initial checkpoint record */
1153  recptr = (char *) page + SizeOfXLogLongPHD;
1154  record = (XLogRecord *) recptr;
1155  record->xl_prev = 0;
1156  record->xl_xid = InvalidTransactionId;
1159  record->xl_rmid = RM_XLOG_ID;
1160 
1161  recptr += SizeOfXLogRecord;
1162  *(recptr++) = (char) XLR_BLOCK_ID_DATA_SHORT;
1163  *(recptr++) = sizeof(CheckPoint);
1164  memcpy(recptr, &ControlFile.checkPointCopy,
1165  sizeof(CheckPoint));
1166 
1167  INIT_CRC32C(crc);
1168  COMP_CRC32C(crc, ((char *) record) + SizeOfXLogRecord, record->xl_tot_len - SizeOfXLogRecord);
1169  COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
1170  FIN_CRC32C(crc);
1171  record->xl_crc = crc;
1172 
1173  /* Write the first page */
1176 
1177  unlink(path);
1178 
1179  fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
1181  if (fd < 0)
1182  {
1183  pg_log_error("could not open file \"%s\": %m", path);
1184  exit(1);
1185  }
1186 
1187  errno = 0;
1188  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1189  {
1190  /* if write didn't set errno, assume problem is no disk space */
1191  if (errno == 0)
1192  errno = ENOSPC;
1193  pg_log_error("could not write file \"%s\": %m", path);
1194  exit(1);
1195  }
1196 
1197  /* Fill the rest of the file with zeroes */
1198  memset(buffer.data, 0, XLOG_BLCKSZ);
1199  for (nbytes = XLOG_BLCKSZ; nbytes < WalSegSz; nbytes += XLOG_BLCKSZ)
1200  {
1201  errno = 0;
1202  if (write(fd, buffer.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
1203  {
1204  if (errno == 0)
1205  errno = ENOSPC;
1206  pg_log_error("could not write file \"%s\": %m", path);
1207  exit(1);
1208  }
1209  }
1210 
1211  if (fsync(fd) != 0)
1212  {
1213  pg_log_error("fsync error: %m");
1214  exit(1);
1215  }
1216 
1217  close(fd);
1218 }
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:1146
#define fsync(fd)
Definition: win32_port.h:76
XLogPageHeaderData * XLogPageHeader
Definition: xlog_internal.h:54
#define XLogFilePath(path, tli, logSegNo, wal_segsz_bytes)
#define XLP_LONG_HEADER
Definition: xlog_internal.h:76
#define XLOG_PAGE_MAGIC
Definition: xlog_internal.h:34
#define SizeOfXLogRecordDataHeaderShort
Definition: xlogrecord.h:203
#define XLR_BLOCK_ID_DATA_SHORT
Definition: xlogrecord.h:227
#define SizeOfXLogRecord
Definition: xlogrecord.h:55

References ControlFileData::checkPointCopy, close, COMP_CRC32C, ControlFile, crc, PGAlignedXLogBlock::data, exit(), 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_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

uint32 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