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
 
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, NULL, pg_fatal(), XLogReaderState::ReadRecPtr, SimpleXLogPageRead(), 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;
72  xlogreader = XLogReaderAllocate(&SimpleXLogPageRead, &private);
73  if (xlogreader == NULL)
74  pg_fatal("out of memory\n");
75 
76  do
77  {
78  record = XLogReadRecord(xlogreader, startpoint, &errormsg);
79 
80  if (record == NULL)
81  {
82  XLogRecPtr errptr;
83 
84  errptr = startpoint ? startpoint : xlogreader->EndRecPtr;
85 
86  if (errormsg)
87  pg_fatal("could not read WAL record at %X/%X: %s\n",
88  (uint32) (errptr >> 32), (uint32) (errptr),
89  errormsg);
90  else
91  pg_fatal("could not read WAL record at %X/%X\n",
92  (uint32) (startpoint >> 32),
93  (uint32) (startpoint));
94  }
95 
96  extractPageInfo(xlogreader);
97 
98  startpoint = InvalidXLogRecPtr; /* continue reading at next record */
99 
100  } while (xlogreader->ReadRecPtr != endpoint);
101 
102  XLogReaderFree(xlogreader);
103  if (xlogreadfd != -1)
104  {
105  close(xlogreadfd);
106  xlogreadfd = -1;
107  }
108 }
XLogReaderState * XLogReaderAllocate(XLogPageReadCB pagereadfunc, void *private_data)
Definition: xlogreader.c:67
#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:193
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:114
char * datadir
unsigned int uint32
Definition: c.h:268
const char * datadir
Definition: parsexlog.c:47
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:125
static int xlogreadfd
Definition: parsexlog.c:41
static void extractPageInfo(XLogReaderState *record)
Definition: parsexlog.c:319
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *pageTLI)
Definition: parsexlog.c:233
#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 155 of file parsexlog.c.

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

Referenced by main().

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

Definition at line 115 of file parsexlog.c.

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

Referenced by main().

116 {
117  XLogRecord *record;
118  XLogReaderState *xlogreader;
119  char *errormsg;
120  XLogPageReadPrivate private;
121  XLogRecPtr endptr;
122 
123  private.datadir = datadir;
124  private.tliIndex = tliIndex;
125  xlogreader = XLogReaderAllocate(&SimpleXLogPageRead, &private);
126  if (xlogreader == NULL)
127  pg_fatal("out of memory\n");
128 
129  record = XLogReadRecord(xlogreader, ptr, &errormsg);
130  if (record == NULL)
131  {
132  if (errormsg)
133  pg_fatal("could not read WAL record at %X/%X: %s\n",
134  (uint32) (ptr >> 32), (uint32) (ptr), errormsg);
135  else
136  pg_fatal("could not read WAL record at %X/%X\n",
137  (uint32) (ptr >> 32), (uint32) (ptr));
138  }
139  endptr = xlogreader->EndRecPtr;
140 
141  XLogReaderFree(xlogreader);
142  if (xlogreadfd != -1)
143  {
144  close(xlogreadfd);
145  xlogreadfd = -1;
146  }
147 
148  return endptr;
149 }
XLogReaderState * XLogReaderAllocate(XLogPageReadCB pagereadfunc, void *private_data)
Definition: xlogreader.c:67
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
XLogRecord * XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
Definition: xlogreader.c:193
XLogRecPtr EndRecPtr
Definition: xlogreader.h:115
char * datadir
unsigned int uint32
Definition: c.h:268
const char * datadir
Definition: parsexlog.c:47
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:125
static int xlogreadfd
Definition: parsexlog.c:41
#define NULL
Definition: c.h:229
uint64 XLogRecPtr
Definition: xlogdefs.h:21
static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf, TimeLineID *pageTLI)
Definition: parsexlog.c:233
#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, NULL, 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:268
void * pg_realloc(void *ptr, size_t size)
Definition: fe_memutils.c:65
#define NULL
Definition: c.h:229
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 51 of file pg_rewind.c.

Referenced by main().

char* datadir_source
bool debug

Definition at line 46 of file pg_standby.c.

bool showprogress

Definition at line 54 of file pg_rewind.c.

Referenced by main().

TimeLineHistoryEntry* targetHistory

Definition at line 58 of file pg_rewind.c.

Referenced by SimpleXLogPageRead().

int targetNentries