*----------------------
*/
PGconn*
-bdr_establish_connection_and_slot(BdrConnectionConfig *cfg, Name out_slot_name,
- uint64 *out_sysid, TimeLineID* out_timeline, Oid *out_dboid, RepNodeId
- *out_replication_identifier, char **out_snapshot)
+bdr_establish_connection_and_slot(BdrConnectionConfig *cfg,
+ const char *application_name_suffix, Name out_slot_name, uint64 *out_sysid,
+ TimeLineID* out_timeline, Oid *out_dboid,
+ RepNodeId *out_replication_identifier, char **out_snapshot)
{
- char conninfo_repl[MAXCONNINFO + 75];
char remote_ident[256];
PGconn *streamConn;
+ StringInfoData conninfo_repl;
- snprintf(conninfo_repl, sizeof(conninfo_repl),
- "%s replication=database fallback_application_name=bdr",
- cfg->dsn);
+ initStringInfo(&conninfo_repl);
+
+ appendStringInfo(&conninfo_repl,
+ "%s replication=database fallback_application_name='"BDR_LOCALID_FORMAT": %s'",
+ cfg->dsn, BDR_LOCALID_FORMAT_ARGS,
+ application_name_suffix);
/* Establish BDR conn and IDENTIFY_SYSTEM */
streamConn = bdr_connect(
- conninfo_repl,
+ conninfo_repl.data,
remote_ident, sizeof(remote_ident),
out_slot_name, out_sysid, out_timeline, out_dboid
);
elog(DEBUG1, "%s initialized on %s",
MyBgworkerEntry->bgw_name, bdr_apply_config->dbname);
- streamConn = bdr_establish_connection_and_slot(
- bdr_apply_config, &slot_name, &origin_sysid,
- &origin_timeline, &origin_dboid, &replication_identifier, NULL);
+ /* Set our local application_name for our SPI connections */
+ resetStringInfo(&query);
+ appendStringInfo(&query, BDR_LOCALID_FORMAT": %s", BDR_LOCALID_FORMAT_ARGS, "apply");
+ if (bdr_apply_worker->forward_changesets)
+ appendStringInfoString(&query, " catchup");
+
+ if (bdr_apply_worker->replay_stop_lsn != InvalidXLogRecPtr)
+ appendStringInfo(&query, " up to %X/%X",
+ (uint32)(bdr_apply_worker->replay_stop_lsn),
+ (uint32)(bdr_apply_worker->replay_stop_lsn>>32));
+
+ SetConfigOption("application_name", query.data, PGC_USERSET, PGC_S_SESSION);
+
+ /* Form an application_name string to send to the remote end */
+ resetStringInfo(&query);
+ appendStringInfoString(&query, "receive");
+
+ if (bdr_apply_worker->forward_changesets)
+ appendStringInfoString(&query, " catchup");
+
+ if (bdr_apply_worker->replay_stop_lsn != InvalidXLogRecPtr)
+ appendStringInfo(&query, " up to %X/%X",
+ (uint32)(bdr_apply_worker->replay_stop_lsn),
+ (uint32)(bdr_apply_worker->replay_stop_lsn>>32));
+
+ /* Make the replication connection to the remote end */
+ streamConn = bdr_establish_connection_and_slot(bdr_apply_config,
+ query.data, &slot_name, &origin_sysid, &origin_timeline,
+ &origin_dboid, &replication_identifier, NULL);
+
/* initialize stat subsystem, our id won't change further */
bdr_count_set_current_node(replication_identifier);
continue;
snprintf(apply_worker.bgw_name, BGW_MAXLEN,
- "bdr apply: %s", cfg->name);
+ BDR_LOCALID_FORMAT": %s: apply",
+ BDR_LOCALID_FORMAT_ARGS, cfg->name);
apply_worker.bgw_main_arg = Int32GetDatum(i);
if (!RegisterDynamicBackgroundWorker(&apply_worker,
ListCell *c;
BdrPerdbWorker *bdr_perdb_worker;
BdrWorker *bdr_worker_slot;
+ StringInfoData si;
+
+ initStringInfo(&si);
Assert(IsBackgroundWorker);
bdr_worker_init(NameStr(bdr_perdb_worker->dbname));
+ appendStringInfo(&si, BDR_LOCALID_FORMAT": %s", BDR_LOCALID_FORMAT_ARGS, "perdb worker");
+ SetConfigOption("application_name", si.data, PGC_USERSET, PGC_S_SESSION);
+
CurrentResourceOwner = ResourceOwnerCreate(NULL, "bdr seq top-level resource owner");
bdr_saved_resowner = CurrentResourceOwner;
#define BDR_SLOT_NAME_FORMAT "bdr_%u_%s_%u_%u__%s"
#define BDR_NODE_ID_FORMAT "bdr_"UINT64_FORMAT"_%u_%u_%u_%s"
+/* Right now replication_name isn't used; make it easily found for later */
+#define EMPTY_REPLICATION_NAME ""
+
+/*
+ * BDR_LOCALID_FORMAT is used in fallback_application_name. It's distinct from
+ * BDR_NODE_ID_FORMAT in that it doesn't include the remote dboid as that may
+ * not be known yet, just (sysid,tlid,dboid,replication_name) .
+ *
+ * Use BDR_LOCALID_FORMAT_ARGS to sub it in to format strings.
+ */
+#define BDR_LOCALID_FORMAT "bdr ("UINT64_FORMAT",%u,%u,%s)"
+
+#define BDR_LOCALID_FORMAT_ARGS \
+ GetSystemIdentifier(), ThisTimeLineID, MyDatabaseId, EMPTY_REPLICATION_NAME
+
#define BDR_INIT_REPLICA_CMD "bdr_initial_load"
+
/*
* Don't include libpq here, msvc infrastructure requires linking to libpq
* otherwise.
extern struct pg_conn *
bdr_establish_connection_and_slot(BdrConnectionConfig *cfg,
+ const char *application_name_suffix,
Name out_slot_name,
uint64 *out_sysid,
TimeLineID *out_timeline,
#include "replication/replication_identifier.h"
#include "utils/builtins.h"
+#include "utils/guc.h"
#include "utils/syscache.h"
/* GetSysCacheOid equivalent that errors out if nothing is found */
bdr_drop_slot_and_replication_identifier(BdrConnectionConfig *cfg)
{
- char conninfo_repl[MAXCONNINFO + 75];
char remote_ident[256];
PGconn *streamConn;
RepNodeId replication_identifier;
StringInfoData query;
char *sqlstate;
+ initStringInfo(&query);
+
elog(DEBUG1, "bdr %s: Dropping slot and local ident from connection %s",
cfg->dbname, cfg->name);
- snprintf(conninfo_repl, sizeof(conninfo_repl),
- "%s replication=database fallback_application_name=bdr",
- cfg->dsn);
+ appendStringInfo(&query,
+ "%s replication=database fallback_application_name='"BDR_LOCALID_FORMAT": %s: drop slot'",
+ cfg->dsn, BDR_LOCALID_FORMAT_ARGS, cfg->name);
/* Establish BDR conn and IDENTIFY_SYSTEM */
streamConn = bdr_connect(
- conninfo_repl,
+ query.data,
remote_ident, sizeof(remote_ident),
&slot_name, &sysid, &timeline, &dboid
);
* whether it exists or not silently over the replication protocol,
* so we just try it and cope if it's missing.
*/
- initStringInfo(&query);
+ resetStringInfo(&query);
appendStringInfo(&query, "DROP_REPLICATION_SLOT %s", NameStr(slot_name));
res = PQexec(streamConn, query.data);
if (PQresultStatus(res) == PGRES_COMMAND_OK)
char bdr_init_replica_script_path[MAXPGPATH];
const char *envvar;
StringInfoData path;
+ StringInfoData origin_dsn;
+ StringInfoData local_dsn;
int saved_errno;
initStringInfo(&path);
+ initStringInfo(&origin_dsn);
+ initStringInfo(&local_dsn);
bindir = pstrdup(my_exec_path);
get_parent_directory(bindir);
PG_VERSION);
}
+ appendStringInfo(&origin_dsn,
+ "%s fallback_application_name='"BDR_LOCALID_FORMAT": %s: init_replica dump'",
+ cfg->dsn, BDR_LOCALID_FORMAT_ARGS, cfg->name);
+
if (cfg->replica_local_dsn == NULL)
elog(FATAL, "bdr init_replica: no replica_local_dsn specified");
+ appendStringInfo(&local_dsn,
+ "%s fallback_application_name='"BDR_LOCALID_FORMAT": %s: init_replica restore'",
+ cfg->replica_local_dsn, BDR_LOCALID_FORMAT_ARGS, cfg->name);
tmpdir = palloc(strlen(bdr_temp_dump_directory)+32);
sprintf(tmpdir, "%s/postgres-bdr-%s.%d", bdr_temp_dump_directory,
char *const argv[] = {
bdr_init_replica_script_path,
"--snapshot", snapshot,
- "--source", cfg->dsn,
- "--target", cfg->replica_local_dsn,
+ "--source", origin_dsn.data,
+ "--target", local_dsn.data,
"--tmp-directory", tmpdir,
NULL
};
char status;
XLogRecPtr min_remote_lsn;
PGconn *nonrepl_init_conn;
- StringInfoData query;
+ StringInfoData dsn;
BdrWorker *init_replica_worker;
BdrConnectionConfig *init_replica_config;
int spi_ret;
- initStringInfo(&query);
+ initStringInfo(&dsn);
elog(DEBUG2, "bdr %s: bdr_init_replica",
NameStr(*dbname));
elog(DEBUG2, "bdr %s: bdr_init_replica init from connection %s",
NameStr(*dbname), init_replica_config->name);
+ resetStringInfo(&dsn);
+ appendStringInfo(&dsn,
+ "%s fallback_application_name='"BDR_LOCALID_FORMAT": %s: init_replica setup'",
+ init_replica_config->dsn, BDR_LOCALID_FORMAT_ARGS,
+ init_replica_config->name);
+
/*
* Test to see if there's an entry in the remote's bdr.bdr_nodes for our
* system identifier. If there is, that'll tell us what stage of startup
* we are up to and let us resume an incomplete start.
*/
- nonrepl_init_conn = PQconnectdb(init_replica_config->dsn);
+ nonrepl_init_conn = PQconnectdb(dsn.data);
if (PQstatus(nonrepl_init_conn) != CONNECTION_OK)
{
ereport(FATAL,
* are all discarded; they're not needed here, and will be obtained
* again by the apply workers when they're launched after init.
*/
- conn = bdr_establish_connection_and_slot(cfg, &slot_name, &sysid,
- &timeline, &dboid, &replication_identifier, &snapshot);
+ conn = bdr_establish_connection_and_slot(cfg, "create slot",
+ &slot_name, &sysid, &timeline, &dboid, &replication_identifier,
+ &snapshot);
/* Always throws rather than returning failure */
Assert(conn);