PostgreSQL Source Code  git master
pg_rewind.h File Reference
#include "datapagemap.h"
#include "access/timeline.h"
#include "common/logging.h"
#include "libpq-fe.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.

Macros

#define pg_fatal(...)   do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0)
 

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)
 
void progress_report (bool force)
 
TimeLineHistoryEntryrewind_parseTimeLineHistory (char *buffer, TimeLineID targetTLI, int *nentries)
 

Variables

char * datadir_target
 
char * datadir_source
 
char * connstr_source
 
bool showprogress
 
bool dry_run
 
int WalSegSz
 
TimeLineHistoryEntrytargetHistory
 
int targetNentries
 
PGconnconn
 
uint64 fetch_size
 
uint64 fetch_done
 

Macro Definition Documentation

◆ pg_fatal

#define pg_fatal (   ...)    do { pg_log_fatal(__VA_ARGS__); exit(1); } while(0)

Definition at line 43 of file pg_rewind.h.

Referenced by adjust_data_dir(), check_cluster_compatibility(), check_cluster_versions(), check_control_data(), check_file_clone(), check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_for_tables_with_oids(), check_hard_link(), check_is_install_user(), check_loadable_libraries(), check_locale_and_encoding(), check_new_cluster_is_empty(), check_pghost_envvar(), check_proper_datallowconn(), check_required_directory(), checkControlFile(), cloneFile(), close_target_file(), copyFile(), create_script_for_cluster_analyze(), create_script_for_old_cluster_deletion(), create_target(), create_target_dir(), create_target_symlink(), createBackupLabel(), digestControlFile(), disable_old_cluster(), ensureCleanShutdown(), exec_prog(), extractPageInfo(), extractPageMap(), fetch_file_range(), findCommonAncestorTimeline(), findLastCheckpoint(), gen_db_file_maps(), get_bin_version(), get_canonical_locale_name(), get_control_data(), get_loadable_libraries(), get_major_server_version(), get_sock_dir(), getTimelineHistory(), init_tablespaces(), libpq_executeFileMap(), libpqConnect(), libpqGetCurrentXlogInsertLocation(), libpqGetFile(), libpqProcessFileList(), linkFile(), main(), new_9_0_populate_pg_largeobject_metadata(), old_11_check_for_sql_identifier_data_type_usage(), old_9_3_check_for_line_data_type_usage(), old_9_6_check_for_unknown_data_type_usage(), old_9_6_invalidate_hash_indexes(), open_target_file(), parallel_exec_prog(), parallel_transfer_all_new_dbs(), parseCommandLine(), pid_lock_file_exists(), process_block_change(), process_source_file(), process_target_file(), readOneRecord(), reap_child(), receiveFileChunks(), recurse_dir(), remove_new_subdir(), remove_target_dir(), remove_target_file(), remove_target_symlink(), rewind_copy_file_range(), rewriteVisibilityMap(), run_simple_command(), run_simple_query(), sanityChecks(), setup(), slurpFile(), start_postmaster(), transfer_all_new_dbs(), transfer_relfile(), truncate_target_file(), validate_exec(), verify_directories(), and write_target_range().

Function Documentation

◆ extractPageMap()

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

Definition at line 59 of file parsexlog.c.

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

Referenced by main().

61 {
62  XLogRecord *record;
63  XLogReaderState *xlogreader;
64  char *errormsg;
65  XLogPageReadPrivate private;
66 
67  private.tliIndex = tliIndex;
69  &private);
70  if (xlogreader == NULL)
71  pg_fatal("out of memory");
72 
73  do
74  {
75  record = XLogReadRecord(xlogreader, startpoint, &errormsg);
76 
77  if (record == NULL)
78  {
79  XLogRecPtr errptr;
80 
81  errptr = startpoint ? startpoint : xlogreader->EndRecPtr;
82 
83  if (errormsg)
84  pg_fatal("could not read WAL record at %X/%X: %s",
85  (uint32) (errptr >> 32), (uint32) (errptr),
86  errormsg);
87  else
88  pg_fatal("could not read WAL record at %X/%X",
89  (uint32) (errptr >> 32), (uint32) (errptr));
90  }
91 
92  extractPageInfo(xlogreader);
93 
94  startpoint = InvalidXLogRecPtr; /* continue reading at next record */
95 
96  } while (xlogreader->ReadRecPtr != endpoint);
97 
98  XLogReaderFree(xlogreader);
99  if (xlogreadfd != -1)
100  {
101  close(xlogreadfd);
102  xlogreadfd = -1;
103  }
104 }
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
#define pg_fatal(...)
Definition: pg_rewind.h:43
static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf)
Definition: parsexlog.c:234
XLogRecord * XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
Definition: xlogreader.c:237
XLogRecPtr EndRecPtr
Definition: xlogreader.h:133
XLogRecPtr ReadRecPtr
Definition: xlogreader.h:132
char * datadir
unsigned int uint32
Definition: c.h:358
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:133
static int xlogreadfd
Definition: parsexlog.c:40
static void extractPageInfo(XLogReaderState *record)
Definition: parsexlog.c:327
uint64 XLogRecPtr
Definition: xlogdefs.h:21
int WalSegSz
Definition: pg_standby.c:39
XLogReaderState * XLogReaderAllocate(int wal_segment_size, const char *waldir, XLogPageReadCB pagereadfunc, void *private_data)
Definition: xlogreader.c:71
#define close(a)
Definition: win32.h:12

◆ findLastCheckpoint()

void findLastCheckpoint ( const char *  datadir,
XLogRecPtr  searchptr,
int  tliIndex,
XLogRecPtr lastchkptrec,
TimeLineID lastchkpttli,
XLogRecPtr lastchkptredo 
)

Definition at line 151 of file parsexlog.c.

References close, pg_fatal, CheckPoint::redo, SimpleXLogPageRead(), SizeOfXLogLongPHD, SizeOfXLogShortPHD, CheckPoint::ThisTimeLineID, XLogPageReadPrivate::tliIndex, 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().

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

◆ progress_report()

void progress_report ( bool  force)

Definition at line 513 of file pg_rewind.c.

References _, fetch_done, fetch_size, fprintf, INT64_FORMAT, last_progress_report, now(), showprogress, and snprintf.

Referenced by main().

514 {
515  static pg_time_t last_progress_report = 0;
516  int percent;
517  char fetch_done_str[32];
518  char fetch_size_str[32];
519  pg_time_t now;
520 
521  if (!showprogress)
522  return;
523 
524  now = time(NULL);
525  if (now == last_progress_report && !force)
526  return; /* Max once per second */
527 
528  last_progress_report = now;
529  percent = fetch_size ? (int) ((fetch_done) * 100 / fetch_size) : 0;
530 
531  /*
532  * Avoid overflowing past 100% or the full size. This may make the total
533  * size number change as we approach the end of the backup (the estimate
534  * will always be wrong if WAL is included), but that's better than having
535  * the done column be bigger than the total.
536  */
537  if (percent > 100)
538  percent = 100;
539  if (fetch_done > fetch_size)
541 
542  /*
543  * Separate step to keep platform-dependent format code out of
544  * translatable strings. And we only test for INT64_FORMAT availability
545  * in snprintf, not fprintf.
546  */
547  snprintf(fetch_done_str, sizeof(fetch_done_str), INT64_FORMAT,
548  fetch_done / 1024);
549  snprintf(fetch_size_str, sizeof(fetch_size_str), INT64_FORMAT,
550  fetch_size / 1024);
551 
552  fprintf(stderr, _("%*s/%s kB (%d%%) copied"),
553  (int) strlen(fetch_size_str), fetch_done_str, fetch_size_str,
554  percent);
555  if (isatty(fileno(stderr)))
556  fprintf(stderr, "\r");
557  else
558  fprintf(stderr, "\n");
559 }
int64 pg_time_t
Definition: pgtime.h:23
static pg_time_t last_progress_report
Definition: pg_basebackup.c:97
#define fprintf
Definition: port.h:196
bool showprogress
Definition: pg_rewind.c:59
uint64 fetch_size
Definition: pg_rewind.c:68
#define INT64_FORMAT
Definition: c.h:400
uint64 fetch_done
Definition: pg_rewind.c:69
#define snprintf
Definition: port.h:192
#define _(x)
Definition: elog.c:84
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1547

◆ readOneRecord()

XLogRecPtr readOneRecord ( const char *  datadir,
XLogRecPtr  ptr,
int  tliIndex 
)

Definition at line 111 of file parsexlog.c.

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

Referenced by main().

112 {
113  XLogRecord *record;
114  XLogReaderState *xlogreader;
115  char *errormsg;
116  XLogPageReadPrivate private;
117  XLogRecPtr endptr;
118 
119  private.tliIndex = tliIndex;
121  &private);
122  if (xlogreader == NULL)
123  pg_fatal("out of memory");
124 
125  record = XLogReadRecord(xlogreader, ptr, &errormsg);
126  if (record == NULL)
127  {
128  if (errormsg)
129  pg_fatal("could not read WAL record at %X/%X: %s",
130  (uint32) (ptr >> 32), (uint32) (ptr), errormsg);
131  else
132  pg_fatal("could not read WAL record at %X/%X",
133  (uint32) (ptr >> 32), (uint32) (ptr));
134  }
135  endptr = xlogreader->EndRecPtr;
136 
137  XLogReaderFree(xlogreader);
138  if (xlogreadfd != -1)
139  {
140  close(xlogreadfd);
141  xlogreadfd = -1;
142  }
143 
144  return endptr;
145 }
#define pg_fatal(...)
Definition: pg_rewind.h:43
static int SimpleXLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen, XLogRecPtr targetRecPtr, char *readBuf)
Definition: parsexlog.c:234
XLogRecord * XLogReadRecord(XLogReaderState *state, XLogRecPtr RecPtr, char **errormsg)
Definition: xlogreader.c:237
XLogRecPtr EndRecPtr
Definition: xlogreader.h:133
char * datadir
unsigned int uint32
Definition: c.h:358
void XLogReaderFree(XLogReaderState *state)
Definition: xlogreader.c:133
static int xlogreadfd
Definition: parsexlog.c:40
uint64 XLogRecPtr
Definition: xlogdefs.h:21
int WalSegSz
Definition: pg_standby.c:39
XLogReaderState * XLogReaderAllocate(int wal_segment_size, const char *waldir, XLogPageReadCB pagereadfunc, void *private_data)
Definition: xlogreader.c:71
#define close(a)
Definition: win32.h:12

◆ rewind_parseTimeLineHistory()

TimeLineHistoryEntry* rewind_parseTimeLineHistory ( char *  buffer,
TimeLineID  targetTLI,
int *  nentries 
)

Definition at line 30 of file timeline.c.

References TimeLineHistoryEntry::begin, TimeLineHistoryEntry::end, InvalidXLogRecPtr, pg_log_error, 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  pg_log_error("syntax error in history file: %s", fline);
77  pg_log_error("Expected a numeric timeline ID.");
78  exit(1);
79  }
80  if (nfields != 3)
81  {
82  pg_log_error("syntax error in history file: %s", fline);
83  pg_log_error("Expected a write-ahead log switchpoint location.");
84  exit(1);
85  }
86  if (entries && tli <= lasttli)
87  {
88  pg_log_error("invalid data in history file: %s", fline);
89  pg_log_error("Timeline IDs must be in increasing sequence.");
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  pg_log_error("invalid data in history file");
110  pg_log_error("Timeline IDs must be less than child timeline's ID.");
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:52
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define pg_log_error(...)
Definition: logging.h:79
TimeLineID tli
Definition: timeline.h:27
unsigned int uint32
Definition: c.h:358
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
XLogRecPtr begin
Definition: timeline.h:28

Variable Documentation

◆ conn

PGconn* conn

Definition at line 56 of file streamutil.c.

Referenced by BaseBackup(), build_client_final_message(), build_client_first_message(), check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_for_tables_with_oids(), check_is_install_user(), check_loadable_libraries(), cluster_all_databases(), cluster_one_database(), connectDatabase(), connectMaintenanceDatabase(), connectToServer(), disconnect_atexit(), doConnect(), dumpBlobs(), dumpDatabase(), dumpDatabaseConfig(), dumpTableData_copy(), ExecuteSqlCommand(), freePGconn(), get_db_conn(), get_db_infos(), get_loadable_libraries(), get_rel_infos(), get_tablespace_paths(), init_slot(), libpqrcv_connect(), main(), makeEmptyPGconn(), new_9_0_populate_pg_largeobject_metadata(), old_11_check_for_sql_identifier_data_type_usage(), old_9_3_check_for_line_data_type_usage(), old_9_6_check_for_unknown_data_type_usage(), old_9_6_invalidate_hash_indexes(), ParallelSlotsTerminate(), pg_fe_scram_exchange(), pg_fe_scram_init(), pgtls_write(), PQconnectdb(), PQconnectdbParams(), PQconnectStart(), PQconnectStartParams(), PQfireResultCreateEvents(), PQgetResult(), PQping(), PQpingParams(), PQregisterEventProc(), PQreset(), PQresetPoll(), PQsetdbLogin(), read_server_final_message(), read_server_first_message(), reindex_all_databases(), reindex_one_database(), run_permutation(), set_frozenxids(), setKeepalivesCount(), setup_connection(), sql_conn(), start_postmaster(), StartLogStreamer(), StreamLog(), StreamLogicalLog(), try_complete_step(), vacuum_all_databases(), vacuum_one_database(), and vacuumlo().

◆ connstr_source

char* connstr_source

Definition at line 56 of file pg_rewind.c.

Referenced by main().

◆ datadir_source

char* datadir_source

◆ datadir_target

◆ dry_run

◆ fetch_done

uint64 fetch_done

Definition at line 69 of file pg_rewind.c.

Referenced by main(), progress_report(), and write_target_range().

◆ fetch_size

uint64 fetch_size

Definition at line 68 of file pg_rewind.c.

Referenced by main(), postgres_fdw_validator(), and progress_report().

◆ showprogress

bool showprogress

Definition at line 59 of file pg_rewind.c.

Referenced by main(), and progress_report().

◆ targetHistory

TimeLineHistoryEntry* targetHistory

Definition at line 64 of file pg_rewind.c.

Referenced by SimpleXLogPageRead().

◆ targetNentries

int targetNentries

◆ WalSegSz