46 const char *content,
size_t size);
94 printf(
_(
"%s resynchronizes a PostgreSQL cluster with another copy of the cluster.\n\n"),
progname);
97 printf(
_(
" -c, --restore-target-wal use \"restore_command\" in target configuration to\n"
98 " retrieve WAL files from archives\n"));
99 printf(
_(
" -D, --target-pgdata=DIRECTORY existing data directory to modify\n"));
100 printf(
_(
" --source-pgdata=DIRECTORY source data directory to synchronize with\n"));
101 printf(
_(
" --source-server=CONNSTR source server to synchronize with\n"));
102 printf(
_(
" -n, --dry-run stop before modifying anything\n"));
103 printf(
_(
" -N, --no-sync do not wait for changes to be written\n"
104 " safely to disk\n"));
105 printf(
_(
" -P, --progress write progress messages\n"));
106 printf(
_(
" -R, --write-recovery-conf write configuration for replication\n"
107 " (requires --source-server)\n"));
108 printf(
_(
" --config-file=FILENAME use specified main server configuration\n"
109 " file when running target cluster\n"));
110 printf(
_(
" --debug write a lot of debug messages\n"));
111 printf(
_(
" --no-ensure-shutdown do not automatically fix unclean shutdown\n"));
112 printf(
_(
" --sync-method=METHOD set method for syncing files to disk\n"));
113 printf(
_(
" -V, --version output version information, then exit\n"));
114 printf(
_(
" -?, --help show this help, then exit\n"));
165 if (
strcmp(argv[1],
"--help") == 0 ||
strcmp(argv[1],
"-?") == 0)
170 if (
strcmp(argv[1],
"--version") == 0 ||
strcmp(argv[1],
"-V") == 0)
240 pg_log_error(
"no source specified (--source-pgdata or --source-server)");
247 pg_log_error(
"only one of --source-pgdata or --source-server can be specified");
254 pg_log_error(
"no target data directory specified (--target-pgdata)");
261 pg_log_error(
"no source server information (--source-server) specified for --write-recovery-conf");
268 pg_log_error(
"too many command-line arguments (first is \"%s\")",
294 pg_fatal(
"could not read permissions of directory \"%s\": %m",
306 "The target directory will not be modified.");
378 pg_log_info(
"source and target cluster are on the same timeline");
399 pg_log_info(
"servers diverged at WAL location %X/%08X on timeline %u",
473 pg_log_info(
"rewinding from last common checkpoint at %X/%08X on timeline %u",
518 filemap->fetch_size / (1024 * 1024),
519 filemap->total_size / (1024 * 1024));
632 pg_fatal(
"no action decided for file \"%s\"", entry->
path);
664 pg_fatal(
"source system was modified while pg_rewind was running");
668 pg_log_info(
"creating backup label and updating control file");
718 pg_fatal(
"source system was in unexpected state at end of rewind");
750 pg_fatal(
"source and target clusters are from different systems");
758 pg_fatal(
"clusters are not compatible with this version of pg_rewind");
768 pg_fatal(
"target server needs to use either data checksums or \"wal_log_hints = on\"");
779 pg_fatal(
"target server must be shut down cleanly");
789 pg_fatal(
"source data directory must be shut down cleanly");
909 for (
i = 0;
i < *nentries;
i++)
946 for (
i = 0;
i < n;
i++)
962 pg_fatal(
"could not find common ancestor of the source and target cluster's timelines");
993 "START WAL LOCATION: %X/%08X (file %s)\n"
994 "CHECKPOINT LOCATION: %X/%08X\n"
995 "BACKUP METHOD: pg_rewind\n"
996 "BACKUP FROM: standby\n"
1003 pg_fatal(
"backup label buffer too small");
1026 pg_fatal(
"unexpected control file CRC");
1038 pg_fatal(
"unexpected control file size %zu, expected %d",
1049 "invalid WAL segment size in control file (%d bytes)",
1052 pg_log_error_detail(
"The WAL segment size must be a power of two between 1 MB and 1 GB.");
1089 pg_fatal(
"program \"%s\" is needed by %s but was not found in the same directory as \"%s\"",
1092 pg_fatal(
"program \"%s\" was found by \"%s\" but was not the same version as %s",
1121 pg_fatal(
"could not read \"restore_command\" from target cluster");
1126 pg_fatal(
"\"restore_command\" is not set in the target cluster");
1128 pg_log_debug(
"using for rewind \"restore_command = \'%s\'\"",
1157 pg_fatal(
"program \"%s\" is needed by %s but was not found in the same directory as \"%s\"",
1160 pg_fatal(
"program \"%s\" was found by \"%s\" but was not the same version as %s",
1164 pg_log_info(
"executing \"%s\" for target server to complete crash recovery",
1202 pg_log_error(
"postgres single-user mode in target cluster failed");
Datum now(PG_FUNCTION_ARGS)
#define PG_DATA_CHECKSUM_VERSION
#define ngettext(s, p, n)
#define Assert(condition)
#define PG_TEXTDOMAIN(domain)
#define CATALOG_VERSION_NO
int find_my_exec(const char *argv0, char *retpath)
char * pipe_read_line(char *cmd)
void set_pglocale_pgservice(const char *argv0, const char *app)
int find_other_exec(const char *argv0, const char *target, const char *versionstr, char *retpath)
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
#define fprintf(file, fmt, msg)
bool datapagemap_next(datapagemap_iterator_t *iter, BlockNumber *blkno)
datapagemap_iterator_t * datapagemap_iterate(datapagemap_t *map)
PGconn * PQconnectdb(const char *conninfo)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
void traverse_datadir(const char *datadir, process_file_callback_t callback)
char * slurpFile(const char *datadir, const char *path, size_t *filesize)
void close_target_file(void)
void truncate_target_file(const char *path, off_t newsize)
void remove_target(file_entry_t *entry)
void sync_target_dir(void)
void create_target(file_entry_t *entry)
void open_target_file(const char *path, bool trunc)
void write_target_range(char *buf, off_t begin, size_t size)
bool GetDataDirectoryCreatePerm(const char *dataDir)
@ DATA_DIR_SYNC_METHOD_FSYNC
void process_source_file(const char *path, file_type_t type, size_t size, const char *link_target)
void print_filemap(filemap_t *filemap)
void process_target_file(const char *path, file_type_t type, size_t size, const char *link_target)
void calculate_totals(filemap_t *filemap)
filemap_t * decide_file_actions(XLogSegNo last_common_segno)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
rewind_source * init_libpq_source(PGconn *conn)
rewind_source * init_local_source(const char *datadir)
void pg_logging_increase_verbosity(void)
void pg_logging_init(const char *argv0)
#define pg_log_error(...)
#define pg_log_error_hint(...)
#define pg_log_error_detail(...)
#define pg_log_debug(...)
void pfree(void *pointer)
bool parse_sync_method(const char *optarg, DataDirSyncMethod *sync_method)
void extractPageMap(const char *datadir, XLogRecPtr startpoint, int tliIndex, XLogRecPtr endpoint, const char *restoreCommand)
void findLastCheckpoint(const char *datadir, XLogRecPtr forkptr, int tliIndex, XLogRecPtr *lastchkptrec, TimeLineID *lastchkpttli, XLogRecPtr *lastchkptredo, const char *restoreCommand)
XLogRecPtr readOneRecord(const char *datadir, XLogRecPtr ptr, int tliIndex, const char *restoreCommand)
static pg_time_t last_progress_report
static bool writerecoveryconf
#define PG_CONTROL_VERSION
@ DB_SHUTDOWNED_IN_RECOVERY
#define PG_CONTROL_FILE_SIZE
#define COMP_CRC32C(crc, data, len)
#define EQ_CRC32C(c1, c2)
PGDLLIMPORT char * optarg
static ControlFileData ControlFile_source
static void createBackupLabel(XLogRecPtr startpoint, TimeLineID starttli, XLogRecPtr checkpointloc)
static void sanityChecks(void)
static char * datadir_source
static void findCommonAncestorTimeline(TimeLineHistoryEntry *a_history, int a_nentries, TimeLineHistoryEntry *b_history, int b_nentries, XLogRecPtr *recptr, int *tliIndex)
static ControlFileData ControlFile_source_after
static char * restore_command
static XLogRecPtr MinXLogRecPtr(XLogRecPtr a, XLogRecPtr b)
static void ensureCleanShutdown(const char *argv0)
TimeLineHistoryEntry * targetHistory
static rewind_source * source
static ControlFileData ControlFile_target
void progress_report(bool finished)
static TimeLineHistoryEntry * getTimelineHistory(TimeLineID tli, bool is_source, int *nentries)
static void digestControlFile(ControlFileData *ControlFile, const char *content, size_t size)
static char * connstr_source
static void getRestoreCommand(const char *argv0)
static char * config_file
DataDirSyncMethod sync_method
static const char * progname
static void perform_rewind(filemap_t *filemap, rewind_source *source, XLogRecPtr chkptrec, TimeLineID chkpttli, XLogRecPtr chkptredo)
static void disconnect_atexit(void)
TimeLineHistoryEntry * rewind_parseTimeLineHistory(char *buffer, TimeLineID targetTLI, int *nentries)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define PG_BACKEND_VERSIONSTR
const char * get_progname(const char *argv0)
size_t strlcpy(char *dst, const char *src, size_t siz)
static void checkControlFile(void)
PQExpBuffer createPQExpBuffer(void)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void WriteRecoveryConfig(PGconn *pgconn, const char *target_dir, PQExpBuffer contents)
PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, const char *replication_slot, char *dbname)
char * GetDbnameFromConnectionOptions(const char *connstr)
void get_restricted_token(void)
int pg_strip_crlf(char *str)
void appendShellString(PQExpBuffer buf, const char *str)
TimeLineID ThisTimeLineID
uint32 pg_control_version
CheckPoint checkPointCopy
XLogRecPtr minRecoveryPoint
uint32 data_checksum_version
uint32 catalog_version_no
TimeLineID minRecoveryPointTLI
datapagemap_t target_pages_to_overwrite
void(* queue_fetch_file)(struct rewind_source *, const char *path, size_t len)
void(* traverse_files)(struct rewind_source *, process_file_callback_t callback)
void(* finish_fetch)(struct rewind_source *)
XLogRecPtr(* get_current_wal_insert_lsn)(struct rewind_source *)
void(* queue_fetch_range)(struct rewind_source *, const char *path, off_t offset, size_t len)
char *(* fetch_file)(struct rewind_source *, const char *path, size_t *filesize)
void(* destroy)(struct rewind_source *)
static ControlFileData * ControlFile
#define IsValidWalSegSize(size)
#define XLOG_CONTROL_FILE
#define XLByteToSeg(xlrp, logSegNo, wal_segsz_bytes)
static void XLogFileName(char *fname, TimeLineID tli, XLogSegNo logSegNo, int wal_segsz_bytes)
static void TLHistoryFilePath(char *path, TimeLineID tli)
#define XLogRecPtrIsValid(r)
#define LSN_FORMAT_ARGS(lsn)
#define InvalidXLogRecPtr