We agreed to add a parameter called sync_standbys http://archives.postgresql.org/message-id/4d1dcf5a.7070...@enterprisedb.com. that required the concept of a server name.
I've written this patch to add a server name parameter and to send an info message which returns the server name, attached. For now, Sync Rep will be written to match sync_standbys against the application_name instead. It may be possible we agree it is the right way to go, so I've not rushed to apply the patch given here after all. This patch now has a lower priority than the main sync rep patch. -- Simon Riggs http://www.2ndQuadrant.com/books/ PostgreSQL Development, 24x7 Support, Training and Services
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index c7f5bd5..46096e6 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -125,6 +125,7 @@ static void XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr); static void XLogWalRcvFlush(bool dying); static void XLogWalRcvSendReply(void); static void XLogWalRcvSendHSFeedback(void); +static void XLogWalRcvSendInfo(void); /* Signal handlers */ static void WalRcvSigHupHandler(SIGNAL_ARGS); @@ -276,6 +277,9 @@ WalReceiverMain(void) walrcv_connect(conninfo, startpoint); DisableWalRcvImmediateExit(); + /* Give the primary our identification and configuration information */ + XLogWalRcvSendInfo(); + /* Loop until end-of-streaming or error */ for (;;) { @@ -305,6 +309,7 @@ WalReceiverMain(void) { got_SIGHUP = false; ProcessConfigFile(PGC_SIGHUP); + XLogWalRcvSendInfo(); } /* Wait a while for data to arrive */ @@ -702,3 +707,26 @@ XLogWalRcvSendHSFeedback(void) memcpy(&buf[1], &feedback_message, sizeof(StandbyHSFeedbackMessage)); walrcv_send(buf, sizeof(StandbyHSFeedbackMessage) + 1); } + +/* + * Send info message to primary. + */ +static void +XLogWalRcvSendInfo(void) +{ + char buf[sizeof(StandbyInfoMessage) + 1]; + StandbyInfoMessage info_message; + + /* Get current timestamp. */ + info_message.sendTime = GetCurrentTimestamp(); + strncpy(info_message.servername, ServerName, strlen(ServerName)); + info_message.servername[strlen(ServerName)] = '\0'; + + elog(DEBUG2, "sending standby info servername \"%s\"", + info_message.servername); + + /* Prepend with the message type and send it. */ + buf[0] = 'i'; + memcpy(&buf[1], &info_message, sizeof(StandbyInfoMessage)); + walrcv_send(buf, sizeof(StandbyInfoMessage) + 1); +} diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index e04d59e..43e47d9 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -119,6 +119,7 @@ static void StartReplication(StartReplicationCmd * cmd); static void ProcessStandbyMessage(void); static void ProcessStandbyReplyMessage(void); static void ProcessStandbyHSFeedbackMessage(void); +static void ProcessStandbyInfoMessage(void); static void ProcessRepliesIfAny(void); @@ -537,6 +538,10 @@ ProcessStandbyMessage(void) ProcessStandbyHSFeedbackMessage(); break; + case 'i': + ProcessStandbyInfoMessage(); + break; + default: ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), @@ -655,6 +660,16 @@ ProcessStandbyHSFeedbackMessage(void) } } +static void +ProcessStandbyInfoMessage(void) +{ + StandbyInfoMessage info; + + pq_copymsgbytes(&reply_message, (char *) &info, sizeof(StandbyInfoMessage)); + + elog(DEBUG2, "server name %s", info.servername); +} + /* Main loop of walsender process */ static int WalSndLoop(void) diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 55cbf75..fd733e0 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -186,6 +186,7 @@ static const char *assign_pgstat_temp_directory(const char *newval, bool doit, G static const char *assign_application_name(const char *newval, bool doit, GucSource source); static const char *show_unix_socket_permissions(void); static const char *show_log_file_mode(void); +static const char *assign_server_name(const char *newval, bool doit, GucSource source); static char *config_enum_get_options(struct config_enum * record, const char *prefix, const char *suffix, @@ -405,6 +406,9 @@ int tcp_keepalives_idle; int tcp_keepalives_interval; int tcp_keepalives_count; +char *ServerName = NULL; + + /* * These variables are all dummies that don't do anything, except in some * cases provide the value for SHOW to display. The real state is elsewhere @@ -2365,6 +2369,15 @@ static struct config_string ConfigureNamesString[] = }, { + {"server_name", PGC_POSTMASTER, CLIENT_CONN_STATEMENT, + gettext_noop("Allows setting of a unique name for this server."), + NULL + }, + &ServerName, + "", assign_server_name, NULL + }, + + { {"temp_tablespaces", PGC_USERSET, CLIENT_CONN_STATEMENT, gettext_noop("Sets the tablespace(s) to use for temporary tables and sort files."), NULL, @@ -8184,4 +8197,29 @@ show_log_file_mode(void) return buf; } +static const char * +assign_server_name(const char *newval, bool doit, GucSource source) +{ + char *p; + +#define MAX_LEN_SERVERNAME 64 + /* Limit the maximum length of the server name */ + if (strlen(newval) > MAX_LEN_SERVERNAME) + ereport(GUC_complaint_elevel(source), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("\"server_name\" maximum length is %d characters", + MAX_LEN_SERVERNAME))); + + /* Only allow clean ASCII chars in the application name */ + for (p = (char *) newval; *p; p++) + { + if (*p < 32 || *p > 126) + ereport(GUC_complaint_elevel(source), + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("\"server_name\" must only contain ASCII characters"))); + } + + return newval; +} + #include "guc-file.c" diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 6726733..cbe6fb2 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -56,6 +56,7 @@ # - Connection Settings - +#server_name = '' # optional server name for use when clustering servers #listen_addresses = 'localhost' # what IP address(es) to listen on; # comma-separated list of addresses; # defaults to 'localhost', '*' = all diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index aa8cce5..bf6c262 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -218,6 +218,7 @@ extern int CTimeZone; #define MAXTZLEN 10 /* max TZ name len, not counting tr. null */ +extern char *ServerName; extern bool enableFsync; extern bool allowSystemTableMods; extern PGDLLIMPORT int work_mem; diff --git a/src/include/replication/walprotocol.h b/src/include/replication/walprotocol.h index 9baca94..5f16371 100644 --- a/src/include/replication/walprotocol.h +++ b/src/include/replication/walprotocol.h @@ -81,6 +81,20 @@ typedef struct } StandbyHSFeedbackMessage; /* + * Info message from standby (message type 'i'). This is wrapped within + * a CopyData message at the FE/BE protocol level. + * + * Note that the data length is not specified here. + */ +typedef struct +{ + char servername[65]; /* Must match MAX_LEN_SERVERNAME + 1*/ + + /* Sender's system clock at the time of transmission */ + TimestampTz sendTime; +} StandbyInfoMessage; + +/* * Maximum data payload in a WAL data message. Must be >= XLOG_BLCKSZ. * * We don't have a good idea of what a good value would be; there's some
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers