PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_rewind.h File Reference
#include "datapagemap.h"
#include "access/timeline.h"
#include "storage/block.h"
#include "storage/relfilenode.h"
Include dependency graph for pg_rewind.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void extractPageMap (const char *datadir, XLogRecPtr startpoint, int tliIndex, XLogRecPtr endpoint)
 
void findLastCheckpoint (const char *datadir, XLogRecPtr searchptr, int tliIndex, XLogRecPtr *lastchkptrec, TimeLineID *lastchkpttli, XLogRecPtr *lastchkptredo)
 
XLogRecPtr readOneRecord (const char *datadir, XLogRecPtr ptr, int tliIndex)
 
TimeLineHistoryEntryrewind_parseTimeLineHistory (char *buffer, TimeLineID targetTLI, int *nentries)
 

Variables

char * datadir_target
 
char * datadir_source
 
char * connstr_source
 
bool debug
 
bool showprogress
 
bool dry_run
 
int WalSegSz
 
TimeLineHistoryEntrytargetHistory
 
int targetNentries
 

Function Documentation

void extractPageMap ( const char *  datadir,
XLogRecPtr  startpoint,
int  tliIndex,
XLogRecPtr  endpoint 
)

Definition at line 62 of file parsexlog.c.

References close, datadir, XLogPageReadPrivate::datadir, XLogReaderState::EndRecPtr, extractPageInfo(), InvalidXLogRecPtr, pg_fatal(), XLogReaderState::ReadRecPtr, SimpleXLogPageRead(), WalSegSz, XLogReaderAllocate(), XLogReaderFree(), xlogreadfd, and XLogReadRecord().

Referenced by main().

64 {
65  XLogRecord *record;
66  XLogReaderState *xlogreader;
67  char *errormsg;
68  XLogPageReadPrivate private;
69 
70  private.datadir = datadir;
71  private.tliIndex = tliIndex;
73  &private);
74  if (xlogreader == NULL)
75  pg_fatal("out of memory\n");
76 
77  do
78  {
79  record = XLogReadRecord(xlogreader, startpoint, &errormsg);
80 
81  if (record == NULL)
82  {
83  XLogRecPtr errptr;
84 
85  errptr = startpoint ? startpoint : xlogreader->EndRecPtr;
86 
87  if (errormsg)
88  pg_fatal("could not read WAL record at %X/%X: %s\n",
89  (uint32) (errptr >> 32), (uint32) (errptr),
90  errormsg);
91  else
92  pg_fatal("could not read WAL record at %X/%X\n",
93  (uint32) (startpoint >> 32),
94  (uint32) (startpoint));
95  }
96 
97  extractPageInfo(xlogreader);
98 
99  startpoint = InvalidXLogRecPtr; /* continue reading at next record */
100 
101  } while (xlogreader->ReadRecPtr != endpoint);
102 
103  XLogReaderFree(xlogreader);
104  if (xlogreadfd != -1)
105  {
106  close(xlogreadfd);
107  xlogreadfd = -1;
108  }
109 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
XLogRecord * XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
Definition: xlogreader.c:195
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:119
char * datadir
unsigned int uint32
Definition: c.h:258
const char * datadir
Definition: parsexlog.c:47
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:127
XLogReaderState * XLogReaderAllocate(int wal_segment_size, XLogPageReadCB pagereadfunc, void *private_data)
Definition: xlogreader.c:67
static int xlogreadfd
Definition: parsexlog.c:41
static void extractPageInfo(XLogReaderState *record)
Definition: parsexlog.c:329
uint64 XLogRecPtr
Definition: xlogdefs.h:21
int WalSegSz
Definition: pg_standby.c:39
static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *pageTLI)
Definition: parsexlog.c:241
#define close(a)
Definition: win32.h:12
void findLastCheckpoint ( const char *  datadir,
XLogRecPtr  searchptr,
int  tliIndex,
XLogRecPtr lastchkptrec,
TimeLineID lastchkpttli,
XLogRecPtr lastchkptredo 
)

Definition at line 157 of file parsexlog.c.

References close, datadir, pg_fatal(), CheckPoint::redo, SimpleXLogPageRead(), SizeOfXLogLongPHD, SizeOfXLogShortPHD, CheckPoint::ThisTimeLineID, WalSegSz, XLogRecord::xl_prev, XLOG_CHECKPOINT_ONLINE, XLOG_CHECKPOINT_SHUTDOWN, XLogReaderAllocate(), XLogReaderFree(), xlogreadfd, XLogReadRecord(), XLogRecGetData, XLogRecGetInfo, XLogRecGetRmid, XLogSegmentOffset, and XLR_INFO_MASK.

Referenced by main().

160 {
161  /* Walk backwards, starting from the given record */
162  XLogRecord *record;
163  XLogRecPtr searchptr;
164  XLogReaderState *xlogreader;
165  char *errormsg;
166  XLogPageReadPrivate private;
167 
168  /*
169  * The given fork pointer points to the end of the last common record,
170  * which is not necessarily the beginning of the next record, if the
171  * previous record happens to end at a page boundary. Skip over the page
172  * header in that case to find the next record.
173  */
174  if (forkptr % XLOG_BLCKSZ == 0)
175  {
176  if (XLogSegmentOffset(forkptr, WalSegSz) == 0)
177  forkptr += SizeOfXLogLongPHD;
178  else
179  forkptr += SizeOfXLogShortPHD;
180  }
181 
182  private.datadir = datadir;
183  private.tliIndex = tliIndex;
185  &private);
186  if (xlogreader == NULL)
187  pg_fatal("out of memory\n");
188 
189  searchptr = forkptr;
190  for (;;)
191  {
192  uint8 info;
193 
194  record = XLogReadRecord(xlogreader, searchptr, &errormsg);
195 
196  if (record == NULL)
197  {
198  if (errormsg)
199  pg_fatal("could not find previous WAL record at %X/%X: %s\n",
200  (uint32) (searchptr >> 32), (uint32) (searchptr),
201  errormsg);
202  else
203  pg_fatal("could not find previous WAL record at %X/%X\n",
204  (uint32) (searchptr >> 32), (uint32) (searchptr));
205  }
206 
207  /*
208  * Check if it is a checkpoint record. This checkpoint record needs to
209  * be the latest checkpoint before WAL forked and not the checkpoint
210  * where the master has been stopped to be rewinded.
211  */
212  info = XLogRecGetInfo(xlogreader) & ~XLR_INFO_MASK;
213  if (searchptr < forkptr &&
214  XLogRecGetRmid(xlogreader) == RM_XLOG_ID &&
215  (info == XLOG_CHECKPOINT_SHUTDOWN ||
216  info == XLOG_CHECKPOINT_ONLINE))
217  {
218  CheckPoint checkPoint;
219 
220  memcpy(&checkPoint, XLogRecGetData(xlogreader), sizeof(CheckPoint));
221  *lastchkptrec = searchptr;
222  *lastchkpttli = checkPoint.ThisTimeLineID;
223  *lastchkptredo = checkPoint.redo;
224  break;
225  }
226 
227  /* Walk backwards to previous record. */
228  searchptr = record->xl_prev;
229  }
230 
231  XLogReaderFree(xlogreader);
232  if (xlogreadfd != -1)
233  {
234  close(xlogreadfd);
235  xlogreadfd = -1;
236  }
237 }
XLogRecPtr xl_prev
Definition: xlogrecord.h:45
#define XLOG_CHECKPOINT_ONLINE
Definition: pg_control.h:68
unsigned char uint8
Definition: c.h:256
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
XLogRecord * XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
Definition: xlogreader.c:195
#define XLogRecGetData(decoder)
Definition: xlogreader.h:226
#define XLOG_CHECKPOINT_SHUTDOWN
Definition: pg_control.h:67
char * datadir
unsigned int uint32
Definition: c.h:258
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:222
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:127
XLogReaderState * XLogReaderAllocate(int wal_segment_size, XLogPageReadCB pagereadfunc, void *private_data)
Definition: xlogreader.c:67
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
static int xlogreadfd
Definition: parsexlog.c:41
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define SizeOfXLogShortPHD
Definition: xlog_internal.h:55
int WalSegSz
Definition: pg_standby.c:39
TimeLineID ThisTimeLineID
Definition: pg_control.h:38
static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *pageTLI)
Definition: parsexlog.c:241
#define close(a)
Definition: win32.h:12
XLogRecPtr redo
Definition: pg_control.h:36
#define XLogRecGetRmid(decoder)
Definition: xlogreader.h:223
#define SizeOfXLogLongPHD
Definition: xlog_internal.h:72
XLogRecPtr readOneRecord ( const char *  datadir,
XLogRecPtr  ptr,
int  tliIndex 
)

Definition at line 116 of file parsexlog.c.

References close, datadir, XLogPageReadPrivate::datadir, XLogReaderState::EndRecPtr, pg_fatal(), SimpleXLogPageRead(), WalSegSz, XLogReaderAllocate(), XLogReaderFree(), xlogreadfd, and XLogReadRecord().

Referenced by main().

117 {
118  XLogRecord *record;
119  XLogReaderState *xlogreader;
120  char *errormsg;
121  XLogPageReadPrivate private;
122  XLogRecPtr endptr;
123 
124  private.datadir = datadir;
125  private.tliIndex = tliIndex;
127  &private);
128  if (xlogreader == NULL)
129  pg_fatal("out of memory\n");
130 
131  record = XLogReadRecord(xlogreader, ptr, &errormsg);
132  if (record == NULL)
133  {
134  if (errormsg)
135  pg_fatal("could not read WAL record at %X/%X: %s\n",
136  (uint32) (ptr >> 32), (uint32) (ptr), errormsg);
137  else
138  pg_fatal("could not read WAL record at %X/%X\n",
139  (uint32) (ptr >> 32), (uint32) (ptr));
140  }
141  endptr = xlogreader->EndRecPtr;
142 
143  XLogReaderFree(xlogreader);
144  if (xlogreadfd != -1)
145  {
146  close(xlogreadfd);
147  xlogreadfd = -1;
148  }
149 
150  return endptr;
151 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
XLogRecord * XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
Definition: xlogreader.c:195
XLogRecPtr EndRecPtr
Definition: xlogreader.h:120
char * datadir
unsigned int uint32
Definition: c.h:258
const char * datadir
Definition: parsexlog.c:47
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:127
XLogReaderState * XLogReaderAllocate(int wal_segment_size, XLogPageReadCB pagereadfunc, void *private_data)
Definition: xlogreader.c:67
static int xlogreadfd
Definition: parsexlog.c:41
uint64 XLogRecPtr
Definition: xlogdefs.h:21
int WalSegSz
Definition: pg_standby.c:39
static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *pageTLI)
Definition: parsexlog.c:241
#define close(a)
Definition: win32.h:12
TimeLineHistoryEntry* rewind_parseTimeLineHistory ( char *  buffer,
TimeLineID  targetTLI,
int *  nentries 
)

Definition at line 30 of file timeline.c.

References _, TimeLineHistoryEntry::begin, buffer, TimeLineHistoryEntry::end, InvalidXLogRecPtr, pg_malloc(), pg_realloc(), and TimeLineHistoryEntry::tli.

Referenced by getTimelineHistory().

31 {
32  char *fline;
33  TimeLineHistoryEntry *entry;
34  TimeLineHistoryEntry *entries = NULL;
35  int nlines = 0;
36  TimeLineID lasttli = 0;
37  XLogRecPtr prevend;
38  char *bufptr;
39  bool lastline = false;
40 
41  /*
42  * Parse the file...
43  */
44  prevend = InvalidXLogRecPtr;
45  bufptr = buffer;
46  while (!lastline)
47  {
48  char *ptr;
49  TimeLineID tli;
50  uint32 switchpoint_hi;
51  uint32 switchpoint_lo;
52  int nfields;
53 
54  fline = bufptr;
55  while (*bufptr && *bufptr != '\n')
56  bufptr++;
57  if (!(*bufptr))
58  lastline = true;
59  else
60  *bufptr++ = '\0';
61 
62  /* skip leading whitespace and check for # comment */
63  for (ptr = fline; *ptr; ptr++)
64  {
65  if (!isspace((unsigned char) *ptr))
66  break;
67  }
68  if (*ptr == '\0' || *ptr == '#')
69  continue;
70 
71  nfields = sscanf(fline, "%u\t%X/%X", &tli, &switchpoint_hi, &switchpoint_lo);
72 
73  if (nfields < 1)
74  {
75  /* expect a numeric timeline ID as first field of line */
76  fprintf(stderr, _("syntax error in history file: %s\n"), fline);
77  fprintf(stderr, _("Expected a numeric timeline ID.\n"));
78  exit(1);
79  }
80  if (nfields != 3)
81  {
82  fprintf(stderr, _("syntax error in history file: %s\n"), fline);
83  fprintf(stderr, _("Expected a write-ahead log switchpoint location.\n"));
84  exit(1);
85  }
86  if (entries && tli <= lasttli)
87  {
88  fprintf(stderr, _("invalid data in history file: %s\n"), fline);
89  fprintf(stderr, _("Timeline IDs must be in increasing sequence.\n"));
90  exit(1);
91  }
92 
93  lasttli = tli;
94 
95  nlines++;
96  entries = pg_realloc(entries, nlines * sizeof(TimeLineHistoryEntry));
97 
98  entry = &entries[nlines - 1];
99  entry->tli = tli;
100  entry->begin = prevend;
101  entry->end = ((uint64) (switchpoint_hi)) << 32 | (uint64) switchpoint_lo;
102  prevend = entry->end;
103 
104  /* we ignore the remainder of each line */
105  }
106 
107  if (entries && targetTLI <= lasttli)
108  {
109  fprintf(stderr, _("invalid data in history file\n"));
110  fprintf(stderr, _("Timeline IDs must be less than child timeline's ID.\n"));
111  exit(1);
112  }
113 
114  /*
115  * Create one more entry for the "tip" of the timeline, which has no entry
116  * in the history file.
117  */
118  nlines++;
119  if (entries)
120  entries = pg_realloc(entries, nlines * sizeof(TimeLineHistoryEntry));
121  else
122  entries = pg_malloc(1 * sizeof(TimeLineHistoryEntry));
123 
124  entry = &entries[nlines - 1];
125  entry->tli = targetTLI;
126  entry->begin = prevend;
127  entry->end = InvalidXLogRecPtr;
128 
129  *nentries = nlines;
130  return entries;
131 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
uint32 TimeLineID
Definition: xlogdefs.h:45
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
TimeLineID tli
Definition: timeline.h:27
unsigned int uint32
Definition: c.h:258
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
XLogRecPtr end
Definition: timeline.h:29
uint64 XLogRecPtr
Definition: xlogdefs.h:21
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:214
XLogRecPtr begin
Definition: timeline.h:28
#define _(x)
Definition: elog.c:84

Variable Documentation

char* connstr_source

Definition at line 52 of file pg_rewind.c.

Referenced by main().

char* datadir_source
bool debug

Definition at line 48 of file pg_standby.c.

bool showprogress

Definition at line 55 of file pg_rewind.c.

Referenced by main().

TimeLineHistoryEntry* targetHistory

Definition at line 59 of file pg_rewind.c.

Referenced by SimpleXLogPageRead().

int targetNentries