34#define DEFAULT_SUB_PORT "50432"
35#define OBJECTTYPE_PUBLICATIONS 0x0001
48#define PG_AUTOCONF_FILENAME "postgresql.auto.conf"
49#define INCLUDED_CONF_FILE "pg_createsubscriber.conf"
50#define INCLUDED_CONF_FILE_DISABLED INCLUDED_CONF_FILE ".disabled"
97static void usage(
void);
104 const char *pub_base_conninfo,
105 const char *sub_base_conninfo);
117 const char *consistent_lsn);
121 const char *slotname);
126 const char *slot_name);
129 bool restricted_access,
130 bool restrict_logical_worker);
148 bool dbnamespecified);
150#define WAIT_INTERVAL 1
224 "You must recreate the physical replica before continuing.");
254 pg_log_warning(
"publication \"%s\" created in database \"%s\" on primary was left behind",
261 pg_log_warning(
"replication slot \"%s\" created in database \"%s\" on primary was left behind",
277 printf(
_(
"%s creates a new logical replica from a standby server.\n\n"),
282 printf(
_(
" -a, --all create subscriptions for all databases except template\n"
283 " databases and databases that don't allow connections\n"));
284 printf(
_(
" -d, --database=DBNAME database in which to create a subscription\n"));
285 printf(
_(
" -D, --pgdata=DATADIR location for the subscriber data directory\n"));
286 printf(
_(
" -n, --dry-run dry run, just show what would be done\n"));
288 printf(
_(
" -P, --publisher-server=CONNSTR publisher connection string\n"));
289 printf(
_(
" -s, --socketdir=DIR socket directory to use (default current dir.)\n"));
290 printf(
_(
" -t, --recovery-timeout=SECS seconds to wait for recovery to end\n"));
291 printf(
_(
" -T, --enable-two-phase enable two-phase commit for all subscriptions\n"));
292 printf(
_(
" -U, --subscriber-username=NAME user name for subscriber connection\n"));
293 printf(
_(
" -v, --verbose output verbose messages\n"));
294 printf(
_(
" --clean=OBJECTTYPE drop all objects of the specified type from specified\n"
295 " databases on the subscriber; accepts: \"%s\"\n"),
"publications");
296 printf(
_(
" --config-file=FILENAME use specified main server configuration\n"
297 " file when running target cluster\n"));
298 printf(
_(
" --publication=NAME publication name\n"));
299 printf(
_(
" --replication-slot=NAME replication slot name\n"));
300 printf(
_(
" --subscription=NAME subscription name\n"));
301 printf(
_(
" -V, --version output version information, then exit\n"));
302 printf(
_(
" -?, --help show this help, then exit\n"));
303 printf(
_(
"\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
304 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
343 if (conn_opts == NULL)
351 for (conn_opt = conn_opts; conn_opt->
keyword != NULL; conn_opt++)
353 if (conn_opt->
val != NULL && conn_opt->
val[0] !=
'\0')
355 if (strcmp(conn_opt->
keyword,
"dbname") == 0)
422 pg_fatal(
"program \"%s\" is needed by %s but was not found in the same directory as \"%s\"",
423 progname,
"pg_createsubscriber", full_path);
425 pg_fatal(
"program \"%s\" was found by \"%s\" but was not the same version as %s",
426 progname, full_path,
"pg_createsubscriber");
446 pg_log_info(
"checking if directory \"%s\" is a cluster data directory",
463 if (major_version != PG_MAJORVERSION_NUM)
466 pg_log_error_detail(
"File \"%s\" contains \"%s\", which is not compatible with this program's version \"%s\".",
467 "PG_VERSION", version_str, PG_MAJORVERSION);
505 const char *pub_base_conninfo,
506 const char *sub_base_conninfo)
550 pg_log_debug(
"publisher(%d): publication: %s ; replication slot: %s ; connection string: %s",
i,
554 pg_log_debug(
"subscriber(%d): subscription: %s ; connection string: %s, two_phase: %s",
i,
560 pubcell = pubcell->
next;
562 subcell = subcell->
next;
564 replslotcell = replslotcell->
next;
638 pg_log_info(
"getting system identifier from publisher");
642 res =
PQexec(
conn,
"SELECT system_identifier FROM pg_catalog.pg_control_system()");
651 pg_log_error(
"could not get system identifier: got %d rows, expected %d row",
656 sysid = strtou64(
PQgetvalue(res, 0, 0), NULL, 10);
658 pg_log_info(
"system identifier is %" PRIu64
" on publisher", sysid);
678 pg_log_info(
"getting system identifier from subscriber");
682 pg_fatal(
"control file appears to be corrupt");
686 pg_log_info(
"system identifier is %" PRIu64
" on subscriber", sysid);
707 pg_log_info(
"modifying system identifier of subscriber");
711 pg_fatal(
"control file appears to be corrupt");
724 pg_log_info(
"dry-run: would set system identifier to %" PRIu64
" on subscriber",
729 pg_log_info(
"system identifier is %" PRIu64
" on subscriber",
734 pg_log_info(
"dry-run: would run pg_resetwal on the subscriber");
736 pg_log_info(
"running pg_resetwal on the subscriber");
745 int rc = system(cmd_str);
748 pg_log_info(
"successfully reset WAL on the subscriber");
770 "SELECT oid FROM pg_catalog.pg_database "
771 "WHERE datname = pg_catalog.current_database()");
781 pg_log_error(
"could not obtain database OID: got %d rows, expected %d row",
787 oid = strtoul(
PQgetvalue(res, 0, 0), NULL, 10);
799 objname =
psprintf(
"pg_createsubscriber_%u_%x", oid, rand);
816 "SELECT 1 FROM pg_catalog.pg_publication "
817 "WHERE pubname = %s",
822 pg_log_error(
"could not find publication \"%s\" in database \"%s\": %s",
853 char *genname = NULL;
876 pg_log_info(
"use existing publication \"%s\" in database \"%s\"",
877 dbinfo[
i].pubname, dbinfo[
i].
dbname);
912 res =
PQexec(
conn,
"SELECT pg_log_standby_snapshot()");
915 pg_log_error(
"could not write an additional WAL record: %s",
937 res =
PQexec(
conn,
"SELECT pg_catalog.pg_is_in_recovery()");
971 int max_prepared_transactions;
972 char *max_slot_wal_keep_size;
1000 "SELECT pg_catalog.current_setting('wal_level'),"
1001 " pg_catalog.current_setting('max_replication_slots'),"
1002 " (SELECT count(*) FROM pg_catalog.pg_replication_slots),"
1003 " pg_catalog.current_setting('max_wal_senders'),"
1004 " (SELECT count(*) FROM pg_catalog.pg_stat_activity WHERE backend_type = 'walsender'),"
1005 " pg_catalog.current_setting('max_prepared_transactions'),"
1006 " pg_catalog.current_setting('max_slot_wal_keep_size')");
1010 pg_log_error(
"could not obtain publisher settings: %s",
1018 max_walsenders = atoi(
PQgetvalue(res, 0, 3));
1019 cur_walsenders = atoi(
PQgetvalue(res, 0, 4));
1020 max_prepared_transactions = atoi(
PQgetvalue(res, 0, 5));
1026 pg_log_debug(
"publisher: max_replication_slots: %d", max_repslots);
1027 pg_log_debug(
"publisher: current replication slots: %d", cur_repslots);
1028 pg_log_debug(
"publisher: max_wal_senders: %d", max_walsenders);
1029 pg_log_debug(
"publisher: current wal senders: %d", cur_walsenders);
1030 pg_log_debug(
"publisher: max_prepared_transactions: %d",
1031 max_prepared_transactions);
1033 max_slot_wal_keep_size);
1039 pg_log_error(
"publisher requires \"wal_level\" >= \"replica\"");
1043 if (max_repslots - cur_repslots <
num_dbs)
1045 pg_log_error(
"publisher requires %d replication slots, but only %d remain",
1046 num_dbs, max_repslots - cur_repslots);
1047 pg_log_error_hint(
"Increase the configuration parameter \"%s\" to at least %d.",
1048 "max_replication_slots", cur_repslots +
num_dbs);
1052 if (max_walsenders - cur_walsenders <
num_dbs)
1054 pg_log_error(
"publisher requires %d WAL sender processes, but only %d remain",
1055 num_dbs, max_walsenders - cur_walsenders);
1056 pg_log_error_hint(
"Increase the configuration parameter \"%s\" to at least %d.",
1057 "max_wal_senders", cur_walsenders +
num_dbs);
1063 pg_log_warning(
"two_phase option will not be enabled for replication slots");
1065 "Prepared transactions will be replicated at COMMIT PREPARED.");
1066 pg_log_warning_hint(
"You can use the command-line option --enable-two-phase to enable two_phase.");
1074 if (
dry_run && (strcmp(max_slot_wal_keep_size,
"-1") != 0))
1076 pg_log_warning(
"required WAL could be removed from the publisher");
1077 pg_log_warning_hint(
"Set the configuration parameter \"%s\" to -1 to ensure that required WAL files are not prematurely removed.",
1078 "max_slot_wal_keep_size");
1103 bool failed =
false;
1131 "SELECT setting FROM pg_catalog.pg_settings WHERE name IN ("
1132 "'max_logical_replication_workers', "
1133 "'max_active_replication_origins', "
1134 "'max_worker_processes', "
1135 "'primary_slot_name') "
1140 pg_log_error(
"could not obtain subscriber settings: %s",
1145 max_reporigins = atoi(
PQgetvalue(res, 0, 0));
1151 pg_log_debug(
"subscriber: max_logical_replication_workers: %d",
1153 pg_log_debug(
"subscriber: max_active_replication_origins: %d", max_reporigins);
1154 pg_log_debug(
"subscriber: max_worker_processes: %d", max_wprocs);
1164 pg_log_error(
"subscriber requires %d active replication origins, but only %d remain",
1166 pg_log_error_hint(
"Increase the configuration parameter \"%s\" to at least %d.",
1167 "max_active_replication_origins",
num_dbs);
1173 pg_log_error(
"subscriber requires %d logical replication workers, but only %d remain",
1175 pg_log_error_hint(
"Increase the configuration parameter \"%s\" to at least %d.",
1176 "max_logical_replication_workers",
num_dbs);
1182 pg_log_error(
"subscriber requires %d worker processes, but only %d remain",
1184 pg_log_error_hint(
"Increase the configuration parameter \"%s\" to at least %d.",
1185 "max_worker_processes",
num_dbs + 1);
1218 pg_log_info(
"dry-run: would drop subscription \"%s\" in database \"%s\"",
1222 pg_log_info(
"dropping subscription \"%s\" in database \"%s\"",
1256 "SELECT s.subname FROM pg_catalog.pg_subscription s "
1257 "INNER JOIN pg_catalog.pg_database d ON (s.subdbid = d.oid) "
1258 "WHERE d.datname = %s",
1264 pg_log_error(
"could not obtain pre-existing subscriptions: %s",
1345 "recovery_target_timeline = 'latest'\n");
1356 "recovery_target_inclusive = false\n");
1358 "recovery_target_action = promote\n");
1367 "recovery_target_lsn = '%X/%08X'\n",
1386 fd = fopen(conf_filename,
"w");
1388 pg_fatal(
"could not open file \"%s\": %m", conf_filename);
1391 pg_fatal(
"could not write to file \"%s\": %m", conf_filename);
1430 pg_log_warning(
"could not drop replication slot \"%s\" on primary",
1454 "SELECT slot_name FROM pg_catalog.pg_replication_slots WHERE failover");
1464 pg_log_warning(
"could not obtain failover replication slot information: %s",
1466 pg_log_warning_hint(
"Drop the failover replication slots on subscriber soon to avoid retention of WAL files.");
1475 pg_log_warning_hint(
"Drop the failover replication slots on subscriber soon to avoid retention of WAL files.");
1491 char *slot_name_esc;
1497 pg_log_info(
"dry-run: would create the replication slot \"%s\" in database \"%s\" on publisher",
1498 slot_name, dbinfo->
dbname);
1500 pg_log_info(
"creating the replication slot \"%s\" in database \"%s\" on publisher",
1501 slot_name, dbinfo->
dbname);
1506 "SELECT lsn FROM pg_catalog.pg_create_logical_replication_slot(%s, 'pgoutput', false, %s, false)",
1519 pg_log_error(
"could not create replication slot \"%s\" in database \"%s\": %s",
1520 slot_name, dbinfo->
dbname,
1541 const char *slot_name)
1544 char *slot_name_esc;
1550 pg_log_info(
"dry-run: would drop the replication slot \"%s\" in database \"%s\"",
1551 slot_name, dbinfo->
dbname);
1553 pg_log_info(
"dropping the replication slot \"%s\" in database \"%s\"",
1554 slot_name, dbinfo->
dbname);
1569 pg_log_error(
"could not drop replication slot \"%s\" in database \"%s\": %s",
1595 pg_log_error(
"pg_ctl was terminated by exception 0x%X",
1597 pg_log_error_detail(
"See C include file \"ntstatus.h\" for a description of the hexadecimal value.");
1605 pg_log_error(
"pg_ctl exited with unrecognized status %d", rc);
1615 bool restrict_logical_worker)
1627 if (restricted_access)
1638 appendPQExpBufferStr(pg_ctl_cmd,
" -o \"-c listen_addresses='' -c unix_socket_permissions=0700");
1650 if (restrict_logical_worker)
1654 rc = system(pg_ctl_cmd->
data);
1670 rc = system(pg_ctl_cmd);
1692 pg_log_info(
"waiting for the target server to reach the consistent state");
1722 pg_fatal(
"server did not end recovery");
1724 pg_log_info(
"target server reached the consistent state");
1725 pg_log_info_hint(
"If pg_createsubscriber fails after this point, you must recreate the physical replica before continuing.");
1746 "SELECT 1 FROM pg_catalog.pg_publication "
1747 "WHERE pubname = %s",
1752 pg_log_error(
"could not obtain publication information: %s",
1775 pg_log_info(
"dry-run: would create publication \"%s\" in database \"%s\"",
1778 pg_log_info(
"creating publication \"%s\" in database \"%s\"",
1791 pg_log_error(
"could not create publication \"%s\" in database \"%s\": %s",
1811 bool *made_publication)
1822 pg_log_info(
"dry-run: would drop publication \"%s\" in database \"%s\"",
1825 pg_log_info(
"dropping publication \"%s\" in database \"%s\"",
1839 pg_log_error(
"could not drop publication \"%s\" in database \"%s\": %s",
1841 *made_publication =
false;
1875 pg_log_info(
"dropping all existing publications in database \"%s\"",
1879 res =
PQexec(
conn,
"SELECT pubname FROM pg_catalog.pg_publication;");
1882 pg_log_error(
"could not obtain publication information: %s",
1906 pg_log_info(
"dry-run: would preserve existing publication \"%s\" in database \"%s\"",
1909 pg_log_info(
"preserve existing publication \"%s\" in database \"%s\"",
1933 char *pubconninfo_esc;
1934 char *replslotname_esc;
1944 pg_log_info(
"dry-run: would create subscription \"%s\" in database \"%s\"",
1947 pg_log_info(
"creating subscription \"%s\" in database \"%s\"",
1951 "CREATE SUBSCRIPTION %s CONNECTION %s PUBLICATION %s "
1952 "WITH (create_slot = false, enabled = false, "
1953 "slot_name = %s, copy_data = false, two_phase = %s)",
1954 subname_esc, pubconninfo_esc, pubname_esc, replslotname_esc,
1969 pg_log_error(
"could not create subscription \"%s\" in database \"%s\": %s",
2006 "SELECT s.oid FROM pg_catalog.pg_subscription s "
2007 "INNER JOIN pg_catalog.pg_database d ON (s.subdbid = d.oid) "
2008 "WHERE s.subname = %s AND d.datname = %s",
2021 pg_log_error(
"could not obtain subscription OID: got %d rows, expected %d row",
2033 suboid = strtoul(
PQgetvalue(res, 0, 0), NULL, 10);
2043 originname =
psprintf(
"pg_%u", suboid);
2046 pg_log_info(
"dry-run: would set the replication progress (node name \"%s\", LSN %s) in database \"%s\"",
2047 originname, lsnstr, dbinfo->
dbname);
2049 pg_log_info(
"setting the replication progress (node name \"%s\", LSN %s) in database \"%s\"",
2050 originname, lsnstr, dbinfo->
dbname);
2054 "SELECT pg_catalog.pg_replication_origin_advance('%s', '%s')",
2055 originname, lsnstr);
2064 pg_log_error(
"could not set replication progress for subscription \"%s\": %s",
2096 pg_log_info(
"dry-run: would enable subscription \"%s\" in database \"%s\"",
2099 pg_log_info(
"enabling subscription \"%s\" in database \"%s\"",
2111 pg_log_error(
"could not enable subscription \"%s\": %s",
2130 bool dbnamespecified)
2136 if (dbnamespecified)
2154 res =
PQexec(
conn,
"SELECT datname FROM pg_database WHERE datistemplate = false AND datallowconn AND datconnlimit <> -2 ORDER BY 1");
2179 static struct option long_options[] =
2207 char *pub_base_conninfo;
2208 char *sub_base_conninfo;
2209 char *dbname_conninfo = NULL;
2213 struct stat statbuf;
2215 char *consistent_lsn;
2226 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
2231 else if (strcmp(argv[1],
"-V") == 0
2232 || strcmp(argv[1],
"--version") == 0)
2234 puts(
"pg_createsubscriber (PostgreSQL) " PG_VERSION);
2270 while ((
c =
getopt_long(argc, argv,
"ad:D:np:P:s:t:TU:v",
2271 long_options, &option_index)) != -1)
2285 pg_fatal(
"database \"%s\" specified more than once for -d/--database",
optarg);
2326 pg_fatal(
"publication \"%s\" specified more than once for --publication",
optarg);
2335 pg_fatal(
"replication slot \"%s\" specified more than once for --replication-slot",
optarg);
2344 pg_fatal(
"subscription \"%s\" specified more than once for --subscription",
optarg);
2350 pg_fatal(
"object type \"%s\" specified more than once for --clean",
optarg);
2362 char *bad_switch = NULL;
2365 bad_switch =
"--database";
2367 bad_switch =
"--publication";
2369 bad_switch =
"--replication-slot";
2371 bad_switch =
"--subscription";
2375 pg_log_error(
"options %s and %s cannot be used together",
2376 bad_switch,
"-a/--all");
2385 pg_log_error(
"too many command-line arguments (first is \"%s\")",
2394 pg_log_error(
"no subscriber data directory specified");
2405 pg_fatal(
"could not determine current directory");
2422 pg_log_error(
"no publisher connection string specified");
2429 "The target directory will not be modified.");
2431 pg_log_info(
"validating publisher connection string");
2434 if (pub_base_conninfo == NULL)
2437 pg_log_info(
"validating subscriber connection string");
2447 bool dbnamespecified = (dbname_conninfo != NULL);
2460 if (dbname_conninfo)
2465 pg_log_info(
"database name \"%s\" was extracted from the publisher connection string",
2480 pg_log_error(
"wrong number of publication names specified");
2481 pg_log_error_detail(
"The number of specified publication names (%d) must match the number of specified database names (%d).",
2487 pg_log_error(
"wrong number of subscription names specified");
2488 pg_log_error_detail(
"The number of specified subscription names (%d) must match the number of specified database names (%d).",
2494 pg_log_error(
"wrong number of replication slot names specified");
2495 pg_log_error_detail(
"The number of specified replication slot names (%d) must match the number of specified database names (%d).",
2507 pg_log_error(
"invalid object type \"%s\" specified for %s",
2508 cell->val,
"--clean");
2539 if (pub_sysid != sub_sysid)
2540 pg_fatal(
"subscriber data directory is not a copy of the source database cluster");
2551 if (
stat(pidfile, &statbuf) == 0)
2563 pg_log_info(
"starting the standby server with command-line options");
#define PG_TEXTDOMAIN(domain)
int find_my_exec(const char *argv0, char *retpath)
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)
#define ALWAYS_SECURE_SEARCH_PATH_SQL
void update_controlfile(const char *DataDir, ControlFileData *ControlFile, bool do_sync)
ControlFileData * get_controlfile(const char *DataDir, bool *crc_ok_p)
int errmsg(const char *fmt,...)
int durable_rename(const char *oldfile, const char *newfile, int elevel)
PGconn * PQconnectdb(const char *conninfo)
void PQconninfoFree(PQconninfoOption *connOptions)
PQconninfoOption * PQconninfoParse(const char *conninfo, char **errmsg)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
void PQfreemem(void *ptr)
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
PGresult * PQexec(PGconn *conn, const char *query)
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
#define pg_malloc_array(type, count)
uint32 get_pg_version(const char *datadir, char **version_str)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
Assert(PointerIsAligned(start, uint64))
#define PQresultErrorMessage
void pg_logging_increase_verbosity(void)
void pg_logging_init(const char *argv0)
void pg_logging_set_level(enum pg_log_level new_level)
#define pg_log_error(...)
#define pg_log_error_hint(...)
#define pg_log_warning_hint(...)
#define pg_log_info_hint(...)
#define pg_log_warning_detail(...)
#define pg_log_error_detail(...)
#define pg_log_debug(...)
static PQExpBuffer recoveryconfcontents
static void pg_ctl_status(const char *pg_ctl_cmd, int rc)
static void create_subscription(PGconn *conn, const struct LogicalRepInfo *dbinfo)
static struct LogicalRepInfo * store_pub_sub_info(const struct CreateSubscriberOptions *opt, const char *pub_base_conninfo, const char *sub_base_conninfo)
static void modify_subscriber_sysid(const struct CreateSubscriberOptions *opt)
static void stop_standby_server(const char *datadir)
static char * pg_ctl_path
static bool server_is_in_recovery(PGconn *conn)
static char * get_exec_path(const char *argv0, const char *progname)
static void appendConnStrItem(PQExpBuffer buf, const char *keyword, const char *val)
static void check_publisher(const struct LogicalRepInfo *dbinfo)
static char * subscriber_dir
static char * create_logical_replication_slot(PGconn *conn, struct LogicalRepInfo *dbinfo)
int main(int argc, char **argv)
static char * primary_slot_name
static void cleanup_objects_atexit(void)
static void check_subscriber(const struct LogicalRepInfo *dbinfo)
static pg_prng_state prng_state
static char * concat_conninfo_dbname(const char *conninfo, const char *dbname)
static void check_data_directory(const char *datadir)
static char * setup_publisher(struct LogicalRepInfo *dbinfo)
#define INCLUDED_CONF_FILE
static void setup_subscriber(struct LogicalRepInfo *dbinfo, const char *consistent_lsn)
static char * get_base_conninfo(const char *conninfo, char **dbname)
static struct LogicalRepInfos dbinfos
static void check_and_drop_publications(PGconn *conn, struct LogicalRepInfo *dbinfo)
static uint64 get_standby_sysid(const char *datadir)
static bool recovery_ended
static void start_standby_server(const struct CreateSubscriberOptions *opt, bool restricted_access, bool restrict_logical_worker)
static void drop_existing_subscription(PGconn *conn, const char *subname, const char *dbname)
static char * get_sub_conninfo(const struct CreateSubscriberOptions *opt)
static void disconnect_database(PGconn *conn, bool exit_on_error)
static void drop_publication(PGconn *conn, const char *pubname, const char *dbname, bool *made_publication)
static void check_and_drop_existing_subscriptions(PGconn *conn, const struct LogicalRepInfo *dbinfo)
static void drop_primary_replication_slot(struct LogicalRepInfo *dbinfo, const char *slotname)
static bool find_publication(PGconn *conn, const char *pubname, const char *dbname)
static void drop_failover_replication_slots(struct LogicalRepInfo *dbinfo)
static void wait_for_end_recovery(const char *conninfo, const struct CreateSubscriberOptions *opt)
static void get_publisher_databases(struct CreateSubscriberOptions *opt, bool dbnamespecified)
static void create_publication(PGconn *conn, struct LogicalRepInfo *dbinfo)
#define OBJECTTYPE_PUBLICATIONS
static void set_replication_progress(PGconn *conn, const struct LogicalRepInfo *dbinfo, const char *lsn)
static char * pg_resetwal_path
static char * generate_object_name(PGconn *conn)
static const char * progname
#define INCLUDED_CONF_FILE_DISABLED
static void drop_replication_slot(PGconn *conn, struct LogicalRepInfo *dbinfo, const char *slot_name)
static bool standby_running
static uint64 get_primary_sysid(const char *conninfo)
static void setup_recovery(const struct LogicalRepInfo *dbinfo, const char *datadir, const char *lsn)
static bool recovery_params_set
static void enable_subscription(PGconn *conn, const struct LogicalRepInfo *dbinfo)
static PGconn * connect_database(const char *conninfo, bool exit_on_error)
PGDLLIMPORT char * optarg
uint32 pg_prng_uint32(pg_prng_state *state)
void pg_prng_seed(pg_prng_state *state, uint64 seed)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define pg_log_warning(...)
int pg_strcasecmp(const char *s1, const char *s2)
const char * pg_strsignal(int signum)
void canonicalize_path(char *path)
const char * get_progname(const char *argv0)
size_t strlcpy(char *dst, const char *src, size_t siz)
PQExpBuffer createPQExpBuffer(void)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
static int fd(const char *x, int i)
char * psprintf(const char *fmt,...)
void WriteRecoveryConfig(PGconn *pgconn, const char *target_dir, PQExpBuffer contents)
PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, const char *replication_slot, char *dbname)
void get_restricted_token(void)
void pg_usleep(long microsec)
bool simple_string_list_member(SimpleStringList *list, const char *val)
void simple_string_list_append(SimpleStringList *list, const char *val)
struct SimpleStringList SimpleStringList
void appendShellString(PQExpBuffer buf, const char *str)
void appendConnStrVal(PQExpBuffer buf, const char *str)
const char * sub_username
SimpleStringList database_names
SimpleStringList objecttypes_to_clean
SimpleStringList sub_names
SimpleStringList replslot_names
SimpleStringList pub_names
struct LogicalRepInfo * dbinfo
bits32 objecttypes_to_clean
char val[FLEXIBLE_ARRAY_MEMBER]
struct SimpleStringListCell * next
SimpleStringListCell * head
#define GET_PG_MAJORVERSION_NUM(v)
char * wait_result_to_str(int exitstatus)
int gettimeofday(struct timeval *tp, void *tzp)
#define LSN_FORMAT_ARGS(lsn)
#define InvalidXLogRecPtr