pgindent run

This commit is contained in:
Ian Barwick
2017-09-11 11:14:13 +09:00
parent 0e6699ecb6
commit a9f4a027a7
36 changed files with 3523 additions and 3288 deletions

View File

@@ -104,4 +104,3 @@ appendShellString(PQExpBuffer buf, const char *str)
appendPQExpBufferChar(buf, '\''); appendPQExpBufferChar(buf, '\'');
} }

View File

@@ -23,10 +23,8 @@
#ifndef _COMPAT_H_ #ifndef _COMPAT_H_
#define _COMPAT_H_ #define _COMPAT_H_
extern void extern void appendConnStrVal(PQExpBuffer buf, const char *str);
appendConnStrVal(PQExpBuffer buf, const char *str);
extern void extern void appendShellString(PQExpBuffer buf, const char *str);
appendShellString(PQExpBuffer buf, const char *str);
#endif #endif

View File

@@ -63,10 +63,10 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
struct stat stat_config; struct stat stat_config;
/* /*
* If a configuration file was provided, check it exists, otherwise * If a configuration file was provided, check it exists, otherwise emit
* emit an error and terminate. We assume that if a user explicitly * an error and terminate. We assume that if a user explicitly provides a
* provides a configuration file, they'll want to make sure it's * configuration file, they'll want to make sure it's used and not fall
* used and not fall back to any of the defaults. * back to any of the defaults.
*/ */
if (config_file != NULL && config_file[0] != '\0') if (config_file != NULL && config_file[0] != '\0')
{ {
@@ -92,18 +92,19 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
} }
/* /*-----------
* If no configuration file was provided, attempt to find a default file * If no configuration file was provided, attempt to find a default file
* in this order: * in this order:
* - current directory * - current directory
* - /etc/repmgr.conf * - /etc/repmgr.conf
* - default sysconfdir * - default sysconfdir
* *
* here we just check for the existence of the file; parse_config() * here we just check for the existence of the file; parse_config() will
* will handle read errors etc. * handle read errors etc.
* *
* XXX modify this section so package maintainers can provide a patch * XXX modify this section so package maintainers can provide a patch
* specifying location of a distribution-specific configuration file * specifying location of a distribution-specific configuration file
*-----------
*/ */
if (config_file_provided == false) if (config_file_provided == false)
{ {
@@ -159,7 +160,7 @@ load_config(const char *config_file, bool verbose, bool terse, t_configuration_o
goto end_search; goto end_search;
} }
end_search: end_search:
if (config_file_found == true) if (config_file_found == true)
{ {
if (verbose == true) if (verbose == true)
@@ -186,8 +187,8 @@ void
parse_config(t_configuration_options *options, bool terse) parse_config(t_configuration_options *options, bool terse)
{ {
/* Collate configuration file errors here for friendlier reporting */ /* Collate configuration file errors here for friendlier reporting */
static ItemList config_errors = { NULL, NULL }; static ItemList config_errors = {NULL, NULL};
static ItemList config_warnings = { NULL, NULL }; static ItemList config_warnings = {NULL, NULL};
_parse_config(options, &config_errors, &config_warnings); _parse_config(options, &config_errors, &config_warnings);
@@ -273,7 +274,8 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
/* default to 6 reconnection attempts at intervals of 10 seconds */ /* default to 6 reconnection attempts at intervals of 10 seconds */
options->reconnect_attempts = DEFAULT_RECONNECTION_ATTEMPTS; options->reconnect_attempts = DEFAULT_RECONNECTION_ATTEMPTS;
options->reconnect_interval = DEFAULT_RECONNECTION_INTERVAL; options->reconnect_interval = DEFAULT_RECONNECTION_INTERVAL;
options->monitoring_history = false; /* new in 4.0, replaces --monitoring-history */ options->monitoring_history = false; /* new in 4.0, replaces
* --monitoring-history */
options->degraded_monitoring_timeout = -1; options->degraded_monitoring_timeout = -1;
options->async_query_timeout = DEFAULT_ASYNC_QUERY_TIMEOUT; options->async_query_timeout = DEFAULT_ASYNC_QUERY_TIMEOUT;
options->primary_notification_timeout = DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT; options->primary_notification_timeout = DEFAULT_PRIMARY_NOTIFICATION_TIMEOUT;
@@ -333,9 +335,9 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
fp = fopen(config_file_path, "r"); fp = fopen(config_file_path, "r");
/* /*
* A configuration file has been found, either provided by the user * A configuration file has been found, either provided by the user or
* or found in one of the default locations. If we can't open it, * found in one of the default locations. If we can't open it, fail with
* fail with an error. * an error.
*/ */
if (fp == NULL) if (fp == NULL)
{ {
@@ -387,7 +389,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
strncpy(options->replication_user, value, NAMEDATALEN); strncpy(options->replication_user, value, NAMEDATALEN);
else else
item_list_append(error_list, item_list_append(error_list,
_( "value for \"replication_user\" must contain fewer than " STR(NAMEDATALEN) " characters")); _("value for \"replication_user\" must contain fewer than " STR(NAMEDATALEN) " characters"));
} }
else if (strcmp(name, "pg_bindir") == 0) else if (strcmp(name, "pg_bindir") == 0)
strncpy(options->pg_bindir, value, MAXPGPATH); strncpy(options->pg_bindir, value, MAXPGPATH);
@@ -524,7 +526,10 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
else if (strcmp(name, "promote_delay") == 0) else if (strcmp(name, "promote_delay") == 0)
options->promote_delay = repmgr_atoi(value, name, error_list, 1); options->promote_delay = repmgr_atoi(value, name, error_list, 1);
/* Following parameters have been deprecated or renamed from 3.x - issue a warning */ /*
* Following parameters have been deprecated or renamed from 3.x -
* issue a warning
*/
else if (strcmp(name, "cluster") == 0) else if (strcmp(name, "cluster") == 0)
{ {
item_list_append(warning_list, item_list_append(warning_list,
@@ -578,14 +583,18 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
known_parameter = false; known_parameter = false;
log_warning(_("%s/%s: unknown name/value pair provided; ignoring"), name, value); log_warning(_("%s/%s: unknown name/value pair provided; ignoring"), name, value);
} }
/* /*
* Raise an error if a known parameter is provided with an empty value. * Raise an error if a known parameter is provided with an empty
* Currently there's no reason why empty parameters are needed; if * value. Currently there's no reason why empty parameters are needed;
* we want to accept those, we'd need to add stricter default checking, * if we want to accept those, we'd need to add stricter default
* as currently e.g. an empty `node` value will be converted to '0'. * checking, as currently e.g. an empty `node` value will be converted
* to '0'.
*/ */
if (known_parameter == true && !strlen(value)) { if (known_parameter == true && !strlen(value))
{
char error_message_buf[MAXLEN] = ""; char error_message_buf[MAXLEN] = "";
maxlen_snprintf(error_message_buf, maxlen_snprintf(error_message_buf,
_("\"%s\": no value provided"), _("\"%s\": no value provided"),
name); name);
@@ -618,10 +627,11 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
} }
else else
{ {
/* Sanity check the provided conninfo string /*
* Sanity check the provided conninfo string
* *
* NOTE: PQconninfoParse() verifies the string format and checks for valid options * NOTE: PQconninfoParse() verifies the string format and checks for
* but does not sanity check values * valid options but does not sanity check values
*/ */
PQconninfoOption *conninfo_options = NULL; PQconninfoOption *conninfo_options = NULL;
@@ -631,6 +641,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
if (conninfo_options == NULL) if (conninfo_options == NULL)
{ {
char error_message_buf[MAXLEN] = ""; char error_message_buf[MAXLEN] = "";
snprintf(error_message_buf, snprintf(error_message_buf,
MAXLEN, MAXLEN,
_("\"conninfo\": %s (provided: \"%s\")"), _("\"conninfo\": %s (provided: \"%s\")"),
@@ -662,7 +673,7 @@ _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *
_("\archive_ready_critical\" must be greater than \"archive_ready_warning\"")); _("\archive_ready_critical\" must be greater than \"archive_ready_warning\""));
} }
if( options->replication_lag_warning >= options->replication_lag_critical) if (options->replication_lag_warning >= options->replication_lag_critical)
{ {
item_list_append(error_list, item_list_append(error_list,
_("\replication_lag_critical\" must be greater than \"replication_lag_warning\"")); _("\replication_lag_critical\" must be greater than \"replication_lag_warning\""));
@@ -780,7 +791,7 @@ _parse_line(char *buf, char *name, char *value)
if (buf[i] == '=') if (buf[i] == '=')
break; break;
switch(buf[i]) switch (buf[i])
{ {
/* Ignore whitespace */ /* Ignore whitespace */
case ' ': case ' ':
@@ -799,9 +810,9 @@ _parse_line(char *buf, char *name, char *value)
*/ */
for (; i < MAXLEN; ++i) for (; i < MAXLEN; ++i)
{ {
if (buf[i+1] == ' ') if (buf[i + 1] == ' ')
continue; continue;
if (buf[i+1] == '\t') if (buf[i + 1] == '\t')
continue; continue;
break; break;
@@ -912,8 +923,8 @@ reload_config(t_configuration_options *orig_options)
bool config_changed = false; bool config_changed = false;
bool log_config_changed = false; bool log_config_changed = false;
static ItemList config_errors = { NULL, NULL }; static ItemList config_errors = {NULL, NULL};
static ItemList config_warnings = { NULL, NULL }; static ItemList config_warnings = {NULL, NULL};
log_info(_("reloading configuration file")); log_info(_("reloading configuration file"));
@@ -980,7 +991,7 @@ reload_config(t_configuration_options *orig_options)
/* conninfo */ /* conninfo */
if (strcmp(orig_options->conninfo, new_options.conninfo) != 0) if (strcmp(orig_options->conninfo, new_options.conninfo) != 0)
{ {
/* Test conninfo string works*/ /* Test conninfo string works */
conn = establish_db_connection(new_options.conninfo, false); conn = establish_db_connection(new_options.conninfo, false);
if (!conn || (PQstatus(conn) != CONNECTION_OK)) if (!conn || (PQstatus(conn) != CONNECTION_OK))
{ {
@@ -1234,7 +1245,8 @@ repmgr_atoi(const char *value, const char *config_item, ItemList *error_list, in
initPQExpBuffer(&errors); initPQExpBuffer(&errors);
/* It's possible that some versions of strtol() don't treat an empty /*
* It's possible that some versions of strtol() don't treat an empty
* string as an error. * string as an error.
*/ */
if (*value == '\0') if (*value == '\0')
@@ -1253,14 +1265,14 @@ repmgr_atoi(const char *value, const char *config_item, ItemList *error_list, in
_("\"%s\": invalid value (provided: \"%s\")"), _("\"%s\": invalid value (provided: \"%s\")"),
config_item, value); config_item, value);
} }
else if ((int32)longval < longval) else if ((int32) longval < longval)
{ {
appendPQExpBuffer(&errors, appendPQExpBuffer(&errors,
_("\"%s\": must be a positive signed 32 bit integer, i.e. 2147483647 or less (provided: \"%s\")"), _("\"%s\": must be a positive signed 32 bit integer, i.e. 2147483647 or less (provided: \"%s\")"),
config_item, config_item,
value); value);
} }
else if ((int32)longval < minval) else if ((int32) longval < minval)
/* Disallow negative values for most parameters */ /* Disallow negative values for most parameters */
{ {
appendPQExpBuffer(&errors, appendPQExpBuffer(&errors,
@@ -1510,13 +1522,14 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
char *options_string_ptr = NULL; char *options_string_ptr = NULL;
/* /*
* Add parsed options to this list, then copy to an array * Add parsed options to this list, then copy to an array to pass to
* to pass to getopt * getopt
*/ */
static ItemList option_argv = { NULL, NULL }; static ItemList option_argv = {NULL, NULL};
char *argv_item = NULL; char *argv_item = NULL;
int c, argc_item = 1; int c,
argc_item = 1;
char **argv_array = NULL; char **argv_array = NULL;
ItemListCell *cell = NULL; ItemListCell *cell = NULL;
@@ -1536,8 +1549,8 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
}; };
/* /*
* From PostgreSQL 10, --xlog-method is renamed --wal-method * From PostgreSQL 10, --xlog-method is renamed --wal-method and there's
* and there's also --no-slot, which we'll want to consider. * also --no-slot, which we'll want to consider.
*/ */
static struct option long_options_10[] = static struct option long_options_10[] =
{ {
@@ -1576,8 +1589,8 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
/* /*
* Array of argument values to pass to getopt_long - this will need to * Array of argument values to pass to getopt_long - this will need to
* include an empty string as the first value (normally this would be * include an empty string as the first value (normally this would be the
* the program name) * program name)
*/ */
argv_array = pg_malloc0(sizeof(char *) * (argc_item + 2)); argv_array = pg_malloc0(sizeof(char *) * (argc_item + 2));
@@ -1648,7 +1661,8 @@ parse_pg_basebackup_options(const char *pg_basebackup_options, t_basebackup_opti
{ {
int i; int i;
for (i = 0; i < argc_item + 2; i ++)
for (i = 0; i < argc_item + 2; i++)
pfree(argv_array[i]); pfree(argv_array[i]);
} }
pfree(argv_array); pfree(argv_array);

View File

@@ -31,7 +31,8 @@
extern bool config_file_found; extern bool config_file_found;
extern char config_file_path[MAXPGPATH]; extern char config_file_path[MAXPGPATH];
typedef enum { typedef enum
{
FAILOVER_MANUAL, FAILOVER_MANUAL,
FAILOVER_AUTOMATIC FAILOVER_AUTOMATIC
} failover_mode_opt; } failover_mode_opt;
@@ -186,7 +187,8 @@ typedef struct
#define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "", false } #define T_BASEBACKUP_OPTIONS_INITIALIZER { "", "", false }
typedef enum { typedef enum
{
RTA_PAUSE, RTA_PAUSE,
RTA_PROMOTE, RTA_PROMOTE,
RTA_SHUTDOWN RTA_SHUTDOWN

View File

@@ -104,7 +104,7 @@ get_data_checksum_version(const char *data_directory)
} }
else else
{ {
data_checksum_version = (int)control_file_info->control_file->data_checksum_version; data_checksum_version = (int) control_file_info->control_file->data_checksum_version;
} }
pfree(control_file_info->control_file); pfree(control_file_info->control_file);

View File

@@ -19,7 +19,7 @@ typedef struct
} ControlFileInfo; } ControlFileInfo;
extern DBState get_db_state(const char *data_directory); extern DBState get_db_state(const char *data_directory);
extern const char * describe_db_state(DBState state); extern const char *describe_db_state(DBState state);
extern int get_data_checksum_version(const char *data_directory); extern int get_data_checksum_version(const char *data_directory);
extern uint64 get_system_identifier(const char *data_directory); extern uint64 get_system_identifier(const char *data_directory);
extern XLogRecPtr get_latest_checkpoint_location(const char *data_directory); extern XLogRecPtr get_latest_checkpoint_location(const char *data_directory);

236
dbutils.c
View File

@@ -62,10 +62,11 @@ XLogRecPtr
parse_lsn(const char *str) parse_lsn(const char *str)
{ {
XLogRecPtr ptr = InvalidXLogRecPtr; XLogRecPtr ptr = InvalidXLogRecPtr;
uint32 high, low; uint32 high,
low;
if (sscanf(str, "%x/%x", &high, &low) == 2) if (sscanf(str, "%x/%x", &high, &low) == 2)
ptr = (((XLogRecPtr)high) << 32) + (XLogRecPtr)low; ptr = (((XLogRecPtr) high) << 32) + (XLogRecPtr) low;
return ptr; return ptr;
} }
@@ -75,7 +76,7 @@ parse_lsn(const char *str)
* Wrap query with appropriate DDL function, if required. * Wrap query with appropriate DDL function, if required.
*/ */
void void
wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt, ...) wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt,...)
{ {
va_list arglist; va_list arglist;
char buf[MAXLEN]; char buf[MAXLEN];
@@ -175,7 +176,8 @@ _establish_db_connection(const char *conninfo, const bool exit_on_error, const b
} }
/* /*
* set "synchronous_commit" to "local" in case synchronous replication is in use * set "synchronous_commit" to "local" in case synchronous replication is
* in use
* *
* XXX set this explicitly before any write operations * XXX set this explicitly before any write operations
*/ */
@@ -218,7 +220,8 @@ establish_db_connection_quiet(const char *conninfo)
PGconn PGconn
*establish_primary_db_connection(PGconn *conn, *
establish_primary_db_connection(PGconn *conn,
const bool exit_on_error) const bool exit_on_error)
{ {
t_node_info primary_node_info = T_NODE_INFO_INITIALIZER; t_node_info primary_node_info = T_NODE_INFO_INITIALIZER;
@@ -275,7 +278,7 @@ establish_db_connection_by_params(t_conninfo_param_list *param_list,
param_set_ine(param_list, "fallback_application_name", "repmgr"); param_set_ine(param_list, "fallback_application_name", "repmgr");
/* Connect to the database using the provided parameters */ /* Connect to the database using the provided parameters */
conn = PQconnectdbParams((const char**)param_list->keywords, (const char**)param_list->values, true); conn = PQconnectdbParams((const char **) param_list->keywords, (const char **) param_list->values, true);
/* Check to see that the backend connection was successfully made */ /* Check to see that the backend connection was successfully made */
if ((PQstatus(conn) != CONNECTION_OK)) if ((PQstatus(conn) != CONNECTION_OK))
@@ -294,8 +297,8 @@ establish_db_connection_by_params(t_conninfo_param_list *param_list,
int i; int i;
/* /*
* set "synchronous_commit" to "local" in case synchronous replication is in * set "synchronous_commit" to "local" in case synchronous replication
* use (provided this is not a replication connection) * is in use (provided this is not a replication connection)
*/ */
for (i = 0; param_list->keywords[i]; i++) for (i = 0; param_list->keywords[i]; i++)
@@ -398,7 +401,7 @@ initialize_conninfo_params(t_conninfo_param_list *param_list, bool set_defaults)
/* Count maximum number of parameters */ /* Count maximum number of parameters */
for (def = defs; def->keyword; def++) for (def = defs; def->keyword; def++)
param_list->size ++; param_list->size++;
/* Initialize our internal parameter list */ /* Initialize our internal parameter list */
param_list->keywords = pg_malloc0(sizeof(char *) * (param_list->size + 1)); param_list->keywords = pg_malloc0(sizeof(char *) * (param_list->size + 1));
@@ -451,6 +454,7 @@ void
copy_conninfo_params(t_conninfo_param_list *dest_list, t_conninfo_param_list *source_list) copy_conninfo_params(t_conninfo_param_list *dest_list, t_conninfo_param_list *source_list)
{ {
int c; int c;
for (c = 0; c < source_list->size && source_list->keywords[c] != NULL; c++) for (c = 0; c < source_list->size && source_list->keywords[c] != NULL; c++)
{ {
if (source_list->values[c] != NULL && source_list->values[c][0] != '\0') if (source_list->values[c] != NULL && source_list->values[c][0] != '\0')
@@ -489,6 +493,7 @@ param_set(t_conninfo_param_list *param_list, const char *param, const char *valu
if (c < param_list->size) if (c < param_list->size)
{ {
int param_len = strlen(param) + 1; int param_len = strlen(param) + 1;
param_list->keywords[c] = pg_malloc0(param_len); param_list->keywords[c] = pg_malloc0(param_len);
param_list->values[c] = pg_malloc0(value_len); param_list->values[c] = pg_malloc0(value_len);
@@ -497,9 +502,9 @@ param_set(t_conninfo_param_list *param_list, const char *param, const char *valu
} }
/* /*
* It's theoretically possible a parameter couldn't be added as * It's theoretically possible a parameter couldn't be added as the array
* the array is full, but it's highly improbable so we won't * is full, but it's highly improbable so we won't handle it at the
* handle it at the moment. * moment.
*/ */
} }
@@ -531,6 +536,7 @@ param_set_ine(t_conninfo_param_list *param_list, const char *param, const char *
if (c < param_list->size) if (c < param_list->size)
{ {
int param_len = strlen(param) + 1; int param_len = strlen(param) + 1;
param_list->keywords[c] = pg_malloc0(param_len); param_list->keywords[c] = pg_malloc0(param_len);
param_list->values[c] = pg_malloc0(value_len); param_list->values[c] = pg_malloc0(value_len);
@@ -1261,8 +1267,7 @@ get_replication_info(PGconn *conn, ReplInfo *replication_info)
server_version_num = get_server_version(conn, NULL); server_version_num = get_server_version(conn, NULL);
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT ts, " " SELECT ts, "
" last_wal_receive_lsn, " " last_wal_receive_lsn, "
" last_wal_replay_lsn, " " last_wal_replay_lsn, "
@@ -1277,8 +1282,7 @@ get_replication_info(PGconn *conn, ReplInfo *replication_info)
if (server_version_num >= 100000) if (server_version_num >= 100000)
{ {
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT CURRENT_TIMESTAMP AS ts, " " SELECT CURRENT_TIMESTAMP AS ts, "
" pg_catalog.pg_last_wal_receive_lsn() AS last_wal_receive_lsn, " " pg_catalog.pg_last_wal_receive_lsn() AS last_wal_receive_lsn, "
" pg_catalog.pg_last_wal_replay_lsn() AS last_wal_replay_lsn, " " pg_catalog.pg_last_wal_replay_lsn() AS last_wal_replay_lsn, "
@@ -1286,16 +1290,14 @@ get_replication_info(PGconn *conn, ReplInfo *replication_info)
} }
else else
{ {
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT CURRENT_TIMESTAMP AS ts, " " SELECT CURRENT_TIMESTAMP AS ts, "
" pg_catalog.pg_last_xlog_receive_location() AS last_wal_receive_lsn, " " pg_catalog.pg_last_xlog_receive_location() AS last_wal_receive_lsn, "
" pg_catalog.pg_last_xlog_replay_location() AS last_wal_replay_lsn, " " pg_catalog.pg_last_xlog_replay_location() AS last_wal_replay_lsn, "
" pg_catalog.pg_last_xact_replay_timestamp() AS last_xact_replay_timestamp "); " pg_catalog.pg_last_xact_replay_timestamp() AS last_xact_replay_timestamp ");
} }
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" ) q "); " ) q ");
log_verbose(LOG_DEBUG, "get_replication_info():\n%s", query.data); log_verbose(LOG_DEBUG, "get_replication_info():\n%s", query.data);
@@ -1318,6 +1320,7 @@ get_replication_info(PGconn *conn, ReplInfo *replication_info)
strncpy(replication_info->last_xact_replay_timestamp, PQgetvalue(res, 0, 3), MAXLEN); strncpy(replication_info->last_xact_replay_timestamp, PQgetvalue(res, 0, 3), MAXLEN);
replication_info->replication_lag_time = atoi(PQgetvalue(res, 0, 4)); replication_info->replication_lag_time = atoi(PQgetvalue(res, 0, 4));
replication_info->receiving_streamed_wal = atobool(PQgetvalue(res, 0, 5)); replication_info->receiving_streamed_wal = atobool(PQgetvalue(res, 0, 5));
PQclear(res); PQclear(res);
return true; return true;
@@ -1334,8 +1337,7 @@ can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *rea
if (server_version_num < 90500) if (server_version_num < 90500)
{ {
appendPQExpBuffer( appendPQExpBuffer(reason,
reason,
_("pg_rewind available from PostgreSQL 9.5")); _("pg_rewind available from PostgreSQL 9.5"));
return false; return false;
} }
@@ -1345,18 +1347,17 @@ can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *rea
if (can_use == false) if (can_use == false)
appendPQExpBuffer(reason, "; "); appendPQExpBuffer(reason, "; ");
appendPQExpBuffer( appendPQExpBuffer(reason,
reason,
_("\"full_page_writes\" must be set to \"on\"")); _("\"full_page_writes\" must be set to \"on\""));
can_use = false; can_use = false;
} }
/* /*
* "wal_log_hints" off - are data checksums available? * "wal_log_hints" off - are data checksums available? Note: we're
* Note: we're checking the local pg_control file here as the value will * checking the local pg_control file here as the value will be the same
* be the same throughout the cluster and saves a round-trip to the * throughout the cluster and saves a round-trip to the demotion
* demotion candidate. * candidate.
*/ */
if (guc_set(conn, "wal_log_hints", "=", "on") == false) if (guc_set(conn, "wal_log_hints", "=", "on") == false)
{ {
@@ -1367,8 +1368,7 @@ can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *rea
if (can_use == false) if (can_use == false)
appendPQExpBuffer(reason, "; "); appendPQExpBuffer(reason, "; ");
appendPQExpBuffer( appendPQExpBuffer(reason,
reason,
_("\"wal_log_hints\" is set to \"off\" but unable to determine checksum version")); _("\"wal_log_hints\" is set to \"off\" but unable to determine checksum version"));
can_use = false; can_use = false;
} }
@@ -1377,8 +1377,7 @@ can_use_pg_rewind(PGconn *conn, const char *data_directory, PQExpBufferData *rea
if (can_use == false) if (can_use == false)
appendPQExpBuffer(reason, "; "); appendPQExpBuffer(reason, "; ");
appendPQExpBuffer( appendPQExpBuffer(reason,
reason,
_("\"wal_log_hints\" is set to \"off\" and checksums are disabled")); _("\"wal_log_hints\" is set to \"off\" and checksums are disabled"));
can_use = false; can_use = false;
@@ -1421,7 +1420,7 @@ get_ready_archive_files(PGconn *conn, const char *data_directory)
log_error(_("unable to access archive_status directory \"%s\""), log_error(_("unable to access archive_status directory \"%s\""),
archive_status_dir); archive_status_dir);
log_detail("%s", strerror(errno)); log_detail("%s", strerror(errno));
/* XXX magic number*/ /* XXX magic number */
return -1; return -1;
} }
@@ -1432,7 +1431,7 @@ get_ready_archive_files(PGconn *conn, const char *data_directory)
log_error(_("unable to open archive directory \"%s\""), log_error(_("unable to open archive directory \"%s\""),
archive_status_dir); archive_status_dir);
log_detail("%s", strerror(errno)); log_detail("%s", strerror(errno));
/* XXX magic number*/ /* XXX magic number */
return -1; return -1;
} }
@@ -1456,11 +1455,11 @@ get_ready_archive_files(PGconn *conn, const char *data_directory)
basenamelen = (int) strlen(arcdir_ent->d_name) - 6; basenamelen = (int) strlen(arcdir_ent->d_name) - 6;
/* /*
* count anything ending in ".ready"; for a more precise implementation * count anything ending in ".ready"; for a more precise
* see: src/backend/postmaster/pgarch.c * implementation see: src/backend/postmaster/pgarch.c
*/ */
if (strcmp(arcdir_ent->d_name + basenamelen, ".ready") == 0) if (strcmp(arcdir_ent->d_name + basenamelen, ".ready") == 0)
ready_count ++; ready_count++;
} }
closedir(arcdir); closedir(arcdir);
@@ -1483,20 +1482,17 @@ get_replication_lag_seconds(PGconn *conn)
if (server_version_num >= 100000) if (server_version_num >= 100000)
{ {
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT CASE WHEN (pg_catalog.pg_last_wal_receive_lsn() = pg_catalog.pg_last_wal_replay_lsn()) "); " SELECT CASE WHEN (pg_catalog.pg_last_wal_receive_lsn() = pg_catalog.pg_last_wal_replay_lsn()) ");
} }
else else
{ {
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT CASE WHEN (pg_catalog.pg_last_xlog_receive_location() = pg_catalog.pg_last_xlog_replay_location()) "); " SELECT CASE WHEN (pg_catalog.pg_last_xlog_receive_location() = pg_catalog.pg_last_xlog_replay_location()) ");
} }
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" THEN 0 " " THEN 0 "
" ELSE EXTRACT(epoch FROM (pg_catalog.clock_timestamp() - pg_catalog.pg_last_xact_replay_timestamp()))::INT " " ELSE EXTRACT(epoch FROM (pg_catalog.clock_timestamp() - pg_catalog.pg_last_xact_replay_timestamp()))::INT "
" END " " END "
@@ -1557,8 +1553,7 @@ repmgrd_set_local_node_id(PGconn *conn, int local_node_id)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT repmgr.set_local_node_id(%i)", " SELECT repmgr.set_local_node_id(%i)",
local_node_id); local_node_id);
@@ -1581,7 +1576,8 @@ repmgrd_set_local_node_id(PGconn *conn, int local_node_id)
/* result functions */ /* result functions */
/* ================ */ /* ================ */
bool atobool(const char *value) bool
atobool(const char *value)
{ {
return (strcmp(value, "t") == 0) return (strcmp(value, "t") == 0)
? true ? true
@@ -1760,7 +1756,7 @@ parse_node_type(const char *type)
const char * const char *
get_node_type_string(t_server_type type) get_node_type_string(t_server_type type)
{ {
switch(type) switch (type)
{ {
case PRIMARY: case PRIMARY:
return "primary"; return "primary";
@@ -1895,7 +1891,8 @@ get_local_node_record(PGconn *conn, int node_id, t_node_info *node_info)
static static
void _populate_node_records(PGresult *res, NodeInfoList *node_list) void
_populate_node_records(PGresult *res, NodeInfoList *node_list)
{ {
int i; int i;
@@ -1909,6 +1906,7 @@ void _populate_node_records(PGresult *res, NodeInfoList *node_list)
for (i = 0; i < PQntuples(res); i++) for (i = 0; i < PQntuples(res); i++)
{ {
NodeInfoListCell *cell; NodeInfoListCell *cell;
cell = (NodeInfoListCell *) pg_malloc0(sizeof(NodeInfoListCell)); cell = (NodeInfoListCell *) pg_malloc0(sizeof(NodeInfoListCell));
cell->node_info = pg_malloc0(sizeof(t_node_info)); cell->node_info = pg_malloc0(sizeof(t_node_info));
@@ -1936,8 +1934,7 @@ get_all_node_records(PGconn *conn, NodeInfoList *node_list)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT " REPMGR_NODES_COLUMNS " SELECT " REPMGR_NODES_COLUMNS
" FROM repmgr.nodes " " FROM repmgr.nodes "
"ORDER BY node_id "); "ORDER BY node_id ");
@@ -1963,8 +1960,7 @@ get_downstream_node_records(PGconn *conn, int node_id, NodeInfoList *node_list)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT " REPMGR_NODES_COLUMNS " SELECT " REPMGR_NODES_COLUMNS
" FROM repmgr.nodes " " FROM repmgr.nodes "
" WHERE upstream_node_id = %i " " WHERE upstream_node_id = %i "
@@ -1993,8 +1989,7 @@ get_active_sibling_node_records(PGconn *conn, int node_id, int upstream_node_id,
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT " REPMGR_NODES_COLUMNS " SELECT " REPMGR_NODES_COLUMNS
" FROM repmgr.nodes " " FROM repmgr.nodes "
" WHERE upstream_node_id = %i " " WHERE upstream_node_id = %i "
@@ -2026,8 +2021,7 @@ get_node_records_by_priority(PGconn *conn, NodeInfoList *node_list)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT " REPMGR_NODES_COLUMNS " SELECT " REPMGR_NODES_COLUMNS
" FROM repmgr.nodes " " FROM repmgr.nodes "
"ORDER BY priority DESC, node_name "); "ORDER BY priority DESC, node_name ");
@@ -2053,8 +2047,7 @@ get_all_node_records_with_upstream(PGconn *conn, NodeInfoList *node_list)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT n.node_id, n.type, n.upstream_node_id, n.node_name, n.conninfo, n.repluser, " " SELECT n.node_id, n.type, n.upstream_node_id, n.node_name, n.conninfo, n.repluser, "
" n.slot_name, n.location, n.priority, n.active, un.node_name AS upstream_node_name " " n.slot_name, n.location, n.priority, n.active, un.node_name AS upstream_node_name "
" FROM repmgr.nodes n " " FROM repmgr.nodes n "
@@ -2120,10 +2113,11 @@ _create_update_node_record(PGconn *conn, char *action, t_node_info *node_info)
if (node_info->upstream_node_id == NO_UPSTREAM_NODE && node_info->type == STANDBY) if (node_info->upstream_node_id == NO_UPSTREAM_NODE && node_info->type == STANDBY)
{ {
/* /*
* No explicit upstream node id provided for standby - attempt to * No explicit upstream node id provided for standby - attempt to get
* get primary node id * primary node id
*/ */
int primary_node_id = get_primary_node_id(conn); int primary_node_id = get_primary_node_id(conn);
maxlen_snprintf(upstream_node_id, "%i", primary_node_id); maxlen_snprintf(upstream_node_id, "%i", primary_node_id);
upstream_node_id_ptr = upstream_node_id; upstream_node_id_ptr = upstream_node_id;
} }
@@ -2394,8 +2388,7 @@ update_node_record_conn_priority(PGconn *conn, t_configuration_options *options)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"UPDATE repmgr.nodes " "UPDATE repmgr.nodes "
" SET conninfo = '%s', " " SET conninfo = '%s', "
" priority = %d " " priority = %d "
@@ -2459,8 +2452,7 @@ get_node_replication_stats(PGconn *conn, t_node_info *node_info)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT current_setting('max_wal_senders')::INT AS max_wal_senders, " " SELECT current_setting('max_wal_senders')::INT AS max_wal_senders, "
" (SELECT COUNT(*) FROM pg_catalog.pg_stat_replication) AS attached_wal_receivers, " " (SELECT COUNT(*) FROM pg_catalog.pg_stat_replication) AS attached_wal_receivers, "
" current_setting('max_replication_slots')::INT AS max_replication_slots, " " current_setting('max_replication_slots')::INT AS max_replication_slots, "
@@ -2503,8 +2495,7 @@ is_downstream_node_attached(PGconn *conn, char *node_name)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT COUNT(*) FROM pg_catalog.pg_stat_replication " " SELECT COUNT(*) FROM pg_catalog.pg_stat_replication "
" WHERE application_name = '%s'", " WHERE application_name = '%s'",
node_name); node_name);
@@ -2592,8 +2583,7 @@ get_datadir_configuration_files(PGconn *conn, KeyValueList *list)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"WITH files AS ( " "WITH files AS ( "
" WITH dd AS ( " " WITH dd AS ( "
" SELECT setting " " SELECT setting "
@@ -2647,8 +2637,7 @@ get_configuration_file_locations(PGconn *conn, t_configfile_list *list)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" WITH dd AS ( " " WITH dd AS ( "
" SELECT setting AS data_directory" " SELECT setting AS data_directory"
" FROM pg_catalog.pg_settings " " FROM pg_catalog.pg_settings "
@@ -2697,8 +2686,7 @@ get_configuration_file_locations(PGconn *conn, t_configfile_list *list)
/* Fetch locations of pg_hba.conf and pg_ident.conf */ /* Fetch locations of pg_hba.conf and pg_ident.conf */
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" WITH dd AS ( " " WITH dd AS ( "
" SELECT setting AS data_directory" " SELECT setting AS data_directory"
" FROM pg_catalog.pg_settings " " FROM pg_catalog.pg_settings "
@@ -2781,7 +2769,7 @@ config_file_list_add(t_configfile_list *list, const char *file, const char *file
strncpy(list->files[list->entries]->filename, filename, MAXPGPATH); strncpy(list->files[list->entries]->filename, filename, MAXPGPATH);
list->files[list->entries]->in_data_directory = in_data_dir; list->files[list->entries]->in_data_directory = in_data_dir;
list->entries ++; list->entries++;
} }
@@ -2860,20 +2848,21 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char
* Only attempt to write a record if a connection handle was provided. * Only attempt to write a record if a connection handle was provided.
* Also check that the repmgr schema has been properly initialised - if * Also check that the repmgr schema has been properly initialised - if
* not it means no configuration file was provided, which can happen with * not it means no configuration file was provided, which can happen with
* e.g. `repmgr standby clone`, and we won't know which schema to write to. * e.g. `repmgr standby clone`, and we won't know which schema to write
* to.
*/ */
if (conn != NULL && PQstatus(conn) == CONNECTION_OK) if (conn != NULL && PQstatus(conn) == CONNECTION_OK)
{ {
int n_node_id = htonl(node_id); int n_node_id = htonl(node_id);
char *t_successful = successful ? "TRUE" : "FALSE"; char *t_successful = successful ? "TRUE" : "FALSE";
const char *values[4] = { (char *)&n_node_id, const char *values[4] = {(char *) &n_node_id,
event, event,
t_successful, t_successful,
details details
}; };
int lengths[4] = { sizeof(n_node_id), int lengths[4] = {sizeof(n_node_id),
0, 0,
0, 0,
0 0
@@ -2924,8 +2913,8 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char
/* /*
* If no database connection provided, or the query failed, generate a * If no database connection provided, or the query failed, generate a
* current timestamp ourselves. This isn't quite the same * current timestamp ourselves. This isn't quite the same format as
* format as PostgreSQL, but is close enough for diagnostic use. * PostgreSQL, but is close enough for diagnostic use.
*/ */
if (!strlen(event_timestamp)) if (!strlen(event_timestamp))
{ {
@@ -2949,9 +2938,9 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char
int r = 0; int r = 0;
/* /*
* If configuration option 'event_notifications' was provided, * If configuration option 'event_notifications' was provided, check
* check if this event is one of the ones listed; if not listed, * if this event is one of the ones listed; if not listed, don't
* don't execute the notification script. * execute the notification script.
* *
* (If 'event_notifications' was not provided, we assume the script * (If 'event_notifications' was not provided, we assume the script
* should be executed for all events). * should be executed for all events).
@@ -2971,7 +2960,8 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char
} }
/* /*
* Event type not found in the 'event_notifications' list - return early * Event type not found in the 'event_notifications' list - return
* early
*/ */
if (notify_ok == false) if (notify_ok == false)
{ {
@@ -2984,7 +2974,7 @@ _create_event(PGconn *conn, t_configuration_options *options, int node_id, char
end_ptr = parsed_command + MAXPGPATH - 1; end_ptr = parsed_command + MAXPGPATH - 1;
*end_ptr = '\0'; *end_ptr = '\0';
for(src_ptr = options->event_notification_command; *src_ptr; src_ptr++) for (src_ptr = options->event_notification_command; *src_ptr; src_ptr++)
{ {
if (*src_ptr == '%') if (*src_ptr == '%')
{ {
@@ -3099,8 +3089,8 @@ create_replication_slot(PGconn *conn, char *slot_name, int server_version_num, P
/* /*
* Check whether slot exists already; if it exists and is active, that * Check whether slot exists already; if it exists and is active, that
* means another active standby is using it, which creates an error situation; * means another active standby is using it, which creates an error
* if not we can reuse it as-is * situation; if not we can reuse it as-is
*/ */
record_status = get_slot_record(conn, slot_name, &slot_info); record_status = get_slot_record(conn, slot_name, &slot_info);
@@ -3117,7 +3107,7 @@ create_replication_slot(PGconn *conn, char *slot_name, int server_version_num, P
if (slot_info.active == false) if (slot_info.active == false)
{ {
// XXX is this a good idea? /* XXX is this a good idea? */
log_debug("replication slot \"%s\" exists but is inactive; reusing", log_debug("replication slot \"%s\" exists but is inactive; reusing",
slot_name); slot_name);
@@ -3429,14 +3419,13 @@ add_monitoring_record(
char *last_xact_replay_timestamp, char *last_xact_replay_timestamp,
long long unsigned int replication_lag_bytes, long long unsigned int replication_lag_bytes,
long long unsigned int apply_lag_bytes long long unsigned int apply_lag_bytes
) )
{ {
PQExpBufferData query; PQExpBufferData query;
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"INSERT INTO repmgr.monitoring_history " "INSERT INTO repmgr.monitoring_history "
" (primary_node_id, " " (primary_node_id, "
" standby_node_id, " " standby_node_id, "
@@ -3476,7 +3465,7 @@ add_monitoring_record(
res = PQexec(local_conn, "SELECT repmgr.standby_set_last_updated()"); res = PQexec(local_conn, "SELECT repmgr.standby_set_last_updated()");
/* not critical if the above query fails*/ /* not critical if the above query fails */
if (PQresultStatus(res) != PGRES_TUPLES_OK) if (PQresultStatus(res) != PGRES_TUPLES_OK)
log_warning(_("unable to set last_updated:\n %s"), PQerrorMessage(local_conn)); log_warning(_("unable to set last_updated:\n %s"), PQerrorMessage(local_conn));
@@ -3549,22 +3538,20 @@ request_vote(PGconn *conn, t_node_info *this_node, t_node_info *other_node, int
log_debug("NULL returned by repmgr.request_vote()"); log_debug("NULL returned by repmgr.request_vote()");
/* /*
* get the node's last receive location anyway * get the node's last receive location anyway TODO: have
* TODO: have repmgr.request_vote() return two values * repmgr.request_vote() return two values
*/ */
initPQExpBuffer(&query); initPQExpBuffer(&query);
if (server_version_num >= 100000) if (server_version_num >= 100000)
{ {
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT pg_catalog.pg_last_wal_receive_lsn()"); "SELECT pg_catalog.pg_last_wal_receive_lsn()");
} }
else else
{ {
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT pg_catalog.pg_last_xlog_receive_location()"); "SELECT pg_catalog.pg_last_xlog_receive_location()");
} }
@@ -3676,7 +3663,7 @@ notify_follow_primary(PGconn *conn, int primary_node_id)
primary_node_id); primary_node_id);
log_verbose(LOG_DEBUG, "notify_follow_primary():\n %s", query.data); log_verbose(LOG_DEBUG, "notify_follow_primary():\n %s", query.data);
// XXX handle failure /* XXX handle failure */
res = PQexec(conn, query.data); res = PQexec(conn, query.data);
termPQExpBuffer(&query); termPQExpBuffer(&query);
@@ -3706,7 +3693,7 @@ get_new_primary(PGconn *conn, int *primary_node_id)
res = PQexec(conn, query.data); res = PQexec(conn, query.data);
termPQExpBuffer(&query); termPQExpBuffer(&query);
// XXX handle error /* XXX handle error */
new_primary_node_id = atoi(PQgetvalue(res, 0, 0)); new_primary_node_id = atoi(PQgetvalue(res, 0, 0));
@@ -3738,7 +3725,7 @@ reset_voting_status(PGconn *conn)
res = PQexec(conn, query.data); res = PQexec(conn, query.data);
termPQExpBuffer(&query); termPQExpBuffer(&query);
// COMMAND_OK? /* COMMAND_OK? */
if (PQresultStatus(res) != PGRES_TUPLES_OK) if (PQresultStatus(res) != PGRES_TUPLES_OK)
{ {
log_error(_("unable to execute repmgr.reset_voting_status():\n %s"), log_error(_("unable to execute repmgr.reset_voting_status():\n %s"),
@@ -3820,8 +3807,7 @@ is_bdr_db(PGconn *conn, PQExpBufferData *output)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT COUNT(*) FROM pg_catalog.pg_extension WHERE extname='bdr'"); "SELECT COUNT(*) FROM pg_catalog.pg_extension WHERE extname='bdr'");
res = PQexec(conn, query.data); res = PQexec(conn, query.data);
@@ -3852,8 +3838,7 @@ is_bdr_db(PGconn *conn, PQExpBufferData *output)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT bdr.bdr_is_active_in_db()"); "SELECT bdr.bdr_is_active_in_db()");
res = PQexec(conn, query.data); res = PQexec(conn, query.data);
termPQExpBuffer(&query); termPQExpBuffer(&query);
@@ -3884,8 +3869,7 @@ is_active_bdr_node(PGconn *conn, const char *node_name)
bool is_active_bdr_node = false; bool is_active_bdr_node = false;
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT COALESCE(s.active, TRUE) AS active" " SELECT COALESCE(s.active, TRUE) AS active"
" FROM bdr.bdr_nodes n " " FROM bdr.bdr_nodes n "
" LEFT JOIN pg_replication_slots s " " LEFT JOIN pg_replication_slots s "
@@ -3920,8 +3904,7 @@ is_bdr_repmgr(PGconn *conn)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT COUNT(*)" "SELECT COUNT(*)"
" FROM repmgr.nodes" " FROM repmgr.nodes"
" WHERE type != 'bdr' "); " WHERE type != 'bdr' ");
@@ -3952,8 +3935,7 @@ is_table_in_bdr_replication_set(PGconn *conn, const char *tablename, const char
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT COUNT(*) " "SELECT COUNT(*) "
" FROM UNNEST(bdr.table_get_replication_sets('repmgr.%s')) AS repset " " FROM UNNEST(bdr.table_get_replication_sets('repmgr.%s')) AS repset "
" WHERE repset='%s' ", " WHERE repset='%s' ",
@@ -3987,8 +3969,7 @@ add_table_to_bdr_replication_set(PGconn *conn, const char *tablename, const char
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT bdr.table_set_replication_sets('repmgr.%s', '{%s}')", "SELECT bdr.table_set_replication_sets('repmgr.%s', '{%s}')",
tablename, tablename,
set); set);
@@ -4023,8 +4004,7 @@ bdr_node_exists(PGconn *conn, const char *node_name)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT COUNT(*)" "SELECT COUNT(*)"
" FROM bdr.bdr_nodes" " FROM bdr.bdr_nodes"
" WHERE node_name = '%s'", " WHERE node_name = '%s'",
@@ -4057,8 +4037,7 @@ get_bdr_node_replication_slot_status(PGconn *conn, const char *node_name)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT s.active " " SELECT s.active "
" FROM pg_catalog.pg_replication_slots s " " FROM pg_catalog.pg_replication_slots s "
" WHERE slot_name = " " WHERE slot_name = "
@@ -4097,8 +4076,7 @@ get_bdr_other_node_name(PGconn *conn, int node_id, char *node_name)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT node_name " " SELECT node_name "
" FROM repmgr.nodes " " FROM repmgr.nodes "
" WHERE node_id != %i", " WHERE node_id != %i",
@@ -4109,7 +4087,7 @@ get_bdr_other_node_name(PGconn *conn, int node_id, char *node_name)
res = PQexec(conn, query.data); res = PQexec(conn, query.data);
termPQExpBuffer(&query); termPQExpBuffer(&query);
if(PQresultStatus(res) == PGRES_TUPLES_OK) if (PQresultStatus(res) == PGRES_TUPLES_OK)
{ {
strncpy(node_name, PQgetvalue(res, 0, 0), MAXLEN); strncpy(node_name, PQgetvalue(res, 0, 0), MAXLEN);
} }
@@ -4132,8 +4110,7 @@ add_extension_tables_to_bdr_replication_set(PGconn *conn)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT c.relname " " SELECT c.relname "
" FROM pg_class c " " FROM pg_class c "
"INNER JOIN pg_namespace n " "INNER JOIN pg_namespace n "
@@ -4146,7 +4123,7 @@ add_extension_tables_to_bdr_replication_set(PGconn *conn)
if (PQresultStatus(res) != PGRES_TUPLES_OK) if (PQresultStatus(res) != PGRES_TUPLES_OK)
{ {
// /* */
} }
else else
{ {
@@ -4174,8 +4151,7 @@ get_all_bdr_node_records(PGconn *conn, BdrNodeInfoList *node_list)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT " BDR_NODES_COLUMNS " SELECT " BDR_NODES_COLUMNS
" FROM bdr.bdr_nodes " " FROM bdr.bdr_nodes "
"ORDER BY node_seq_id "); "ORDER BY node_seq_id ");
@@ -4199,8 +4175,7 @@ get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
" SELECT " BDR_NODES_COLUMNS " SELECT " BDR_NODES_COLUMNS
" FROM bdr.bdr_nodes " " FROM bdr.bdr_nodes "
" WHERE node_name = '%s'", " WHERE node_name = '%s'",
@@ -4236,11 +4211,12 @@ get_bdr_node_record_by_name(PGconn *conn, const char *node_name, t_bdr_node_info
static static
void _populate_bdr_node_records(PGresult *res, BdrNodeInfoList *node_list) void
_populate_bdr_node_records(PGresult *res, BdrNodeInfoList *node_list)
{ {
int i; int i;
clear_node_info_list((NodeInfoList *)node_list); clear_node_info_list((NodeInfoList *) node_list);
if (PQresultStatus(res) != PGRES_TUPLES_OK) if (PQresultStatus(res) != PGRES_TUPLES_OK)
{ {
@@ -4250,6 +4226,7 @@ void _populate_bdr_node_records(PGresult *res, BdrNodeInfoList *node_list)
for (i = 0; i < PQntuples(res); i++) for (i = 0; i < PQntuples(res); i++)
{ {
BdrNodeInfoListCell *cell; BdrNodeInfoListCell *cell;
cell = (BdrNodeInfoListCell *) pg_malloc0(sizeof(BdrNodeInfoListCell)); cell = (BdrNodeInfoListCell *) pg_malloc0(sizeof(BdrNodeInfoListCell));
cell->node_info = pg_malloc0(sizeof(t_bdr_node_info)); cell->node_info = pg_malloc0(sizeof(t_bdr_node_info));
@@ -4294,8 +4271,7 @@ am_bdr_failover_handler(PGconn *conn, int node_id)
initPQExpBuffer(&query); initPQExpBuffer(&query);
appendPQExpBuffer( appendPQExpBuffer(&query,
&query,
"SELECT repmgr.am_bdr_failover_handler(%i)", "SELECT repmgr.am_bdr_failover_handler(%i)",
node_id); node_id);
@@ -4322,9 +4298,9 @@ void
unset_bdr_failover_handler(PGconn *conn) unset_bdr_failover_handler(PGconn *conn)
{ {
PGresult *res = NULL; PGresult *res = NULL;
res = PQexec(conn, "SELECT repmgr.unset_bdr_failover_handler()"); res = PQexec(conn, "SELECT repmgr.unset_bdr_failover_handler()");
PQclear(res); PQclear(res);
return; return;
} }

View File

@@ -33,52 +33,60 @@
#define ERRBUFF_SIZE 512 #define ERRBUFF_SIZE 512
typedef enum { typedef enum
{
UNKNOWN = 0, UNKNOWN = 0,
PRIMARY, PRIMARY,
STANDBY, STANDBY,
BDR BDR
} t_server_type; } t_server_type;
typedef enum { typedef enum
{
REPMGR_INSTALLED = 0, REPMGR_INSTALLED = 0,
REPMGR_AVAILABLE, REPMGR_AVAILABLE,
REPMGR_UNAVAILABLE, REPMGR_UNAVAILABLE,
REPMGR_UNKNOWN REPMGR_UNKNOWN
} ExtensionStatus; } ExtensionStatus;
typedef enum { typedef enum
{
RECTYPE_UNKNOWN = -1, RECTYPE_UNKNOWN = -1,
RECTYPE_PRIMARY, RECTYPE_PRIMARY,
RECTYPE_STANDBY RECTYPE_STANDBY
} RecoveryType; } RecoveryType;
typedef enum { typedef enum
{
RECORD_ERROR = -1, RECORD_ERROR = -1,
RECORD_FOUND, RECORD_FOUND,
RECORD_NOT_FOUND RECORD_NOT_FOUND
} RecordStatus; } RecordStatus;
typedef enum { typedef enum
{
MS_NORMAL = 0, MS_NORMAL = 0,
MS_DEGRADED = 1 MS_DEGRADED = 1
} MonitoringState; } MonitoringState;
typedef enum { typedef enum
{
NODE_STATUS_UNKNOWN = -1, NODE_STATUS_UNKNOWN = -1,
NODE_STATUS_UP, NODE_STATUS_UP,
NODE_STATUS_DOWN, NODE_STATUS_DOWN,
NODE_STATUS_UNCLEAN_SHUTDOWN NODE_STATUS_UNCLEAN_SHUTDOWN
} NodeStatus; } NodeStatus;
typedef enum { typedef enum
{
VR_VOTE_REFUSED = -1, VR_VOTE_REFUSED = -1,
VR_POSITIVE_VOTE, VR_POSITIVE_VOTE,
VR_NEGATIVE_VOTE VR_NEGATIVE_VOTE
} VoteRequestResult; } VoteRequestResult;
typedef enum { typedef enum
{
SLOT_UNKNOWN = -1, SLOT_UNKNOWN = -1,
SLOT_INACTIVE, SLOT_INACTIVE,
SLOT_ACTIVE SLOT_ACTIVE
@@ -260,7 +268,8 @@ typedef struct BdrNodeInfoList
0 \ 0 \
} }
typedef struct { typedef struct
{
char current_timestamp[MAXLEN]; char current_timestamp[MAXLEN];
uint64 last_wal_receive_lsn; uint64 last_wal_receive_lsn;
uint64 last_wal_replay_lsn; uint64 last_wal_replay_lsn;
@@ -321,7 +330,8 @@ extern int server_version_num;
XLogRecPtr parse_lsn(const char *str); XLogRecPtr parse_lsn(const char *str);
extern void wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt, ...) extern void
wrap_ddl_query(PQExpBufferData *query_buf, int replication_type, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
bool atobool(const char *value); bool atobool(const char *value);
@@ -445,7 +455,8 @@ int wait_connection_availability(PGconn *conn, long long timeout);
bool is_server_available(const char *conninfo); bool is_server_available(const char *conninfo);
/* monitoring functions */ /* monitoring functions */
void add_monitoring_record( void
add_monitoring_record(
PGconn *primary_conn, PGconn *primary_conn,
PGconn *local_conn, PGconn *local_conn,
int primary_node_id, int primary_node_id,
@@ -456,7 +467,7 @@ void add_monitoring_record(
char *last_xact_replay_timestamp, char *last_xact_replay_timestamp,
long long unsigned int replication_lag_bytes, long long unsigned int replication_lag_bytes,
long long unsigned int apply_lag_bytes long long unsigned int apply_lag_bytes
); );
/* node voting functions */ /* node voting functions */
@@ -494,4 +505,3 @@ bool am_bdr_failover_handler(PGconn *conn, int node_id);
void unset_bdr_failover_handler(PGconn *conn); void unset_bdr_failover_handler(PGconn *conn);
#endif /* _REPMGR_DBUTILS_H_ */ #endif /* _REPMGR_DBUTILS_H_ */

View File

@@ -321,4 +321,3 @@ unlink_dir_callback(const char *fpath, const struct stat *sb, int typeflag, stru
return rv; return rv;
} }

View File

@@ -45,4 +45,3 @@
#define ERR_OUT_OF_MEMORY 21 #define ERR_OUT_OF_MEMORY 21
#endif /* _ERRCODE_H_ */ #endif /* _ERRCODE_H_ */

39
log.c
View File

@@ -37,7 +37,8 @@
/* #define REPMGR_DEBUG */ /* #define REPMGR_DEBUG */
static int detect_log_facility(const char *facility); static int detect_log_facility(const char *facility);
static void _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_list ap) static void
_stderr_log_with_level(const char *level_name, int level, const char *fmt, va_list ap)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 0)));
int log_type = REPMGR_STDERR; int log_type = REPMGR_STDERR;
@@ -45,6 +46,7 @@ int log_level = LOG_NOTICE;
int last_log_level = LOG_INFO; int last_log_level = LOG_INFO;
int verbose_logging = false; int verbose_logging = false;
int terse_logging = false; int terse_logging = false;
/* /*
* Global variable to be set by the main application to ensure any log output * Global variable to be set by the main application to ensure any log output
* emitted before logger_init is called, is output in the correct format * emitted before logger_init is called, is output in the correct format
@@ -52,7 +54,7 @@ int terse_logging = false;
int logger_output_mode = OM_DAEMON; int logger_output_mode = OM_DAEMON;
extern void extern void
stderr_log_with_level(const char *level_name, int level, const char *fmt, ...) stderr_log_with_level(const char *level_name, int level, const char *fmt,...)
{ {
va_list arglist; va_list arglist;
@@ -67,8 +69,8 @@ _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_li
char buf[100]; char buf[100];
/* /*
* Store the requested level so that if there's a subsequent * Store the requested level so that if there's a subsequent log_hint() or
* log_hint() or log_detail(), we can suppress that if appropriate. * log_detail(), we can suppress that if appropriate.
*/ */
last_log_level = level; last_log_level = level;
@@ -80,6 +82,7 @@ _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_li
{ {
time_t t; time_t t;
struct tm *tm; struct tm *tm;
time(&t); time(&t);
tm = localtime(&t); tm = localtime(&t);
strftime(buf, 100, "[%Y-%m-%d %H:%M:%S]", tm); strftime(buf, 100, "[%Y-%m-%d %H:%M:%S]", tm);
@@ -97,7 +100,7 @@ _stderr_log_with_level(const char *level_name, int level, const char *fmt, va_li
} }
void void
log_hint(const char *fmt, ...) log_hint(const char *fmt,...)
{ {
va_list ap; va_list ap;
@@ -111,7 +114,7 @@ log_hint(const char *fmt, ...)
void void
log_detail(const char *fmt, ...) log_detail(const char *fmt,...)
{ {
va_list ap; va_list ap;
@@ -125,7 +128,7 @@ log_detail(const char *fmt, ...)
void void
log_verbose(int level, const char *fmt, ...) log_verbose(int level, const char *fmt,...)
{ {
va_list ap; va_list ap;
@@ -133,7 +136,7 @@ log_verbose(int level, const char *fmt, ...)
if (verbose_logging == true) if (verbose_logging == true)
{ {
switch(level) switch (level)
{ {
case LOG_EMERG: case LOG_EMERG:
_stderr_log_with_level("EMERG", level, fmt, ap); _stderr_log_with_level("EMERG", level, fmt, ap);
@@ -202,8 +205,8 @@ logger_init(t_configuration_options *opts, const char *ident)
} }
/* /*
* STDERR only logging requested - finish here without setting up any further * STDERR only logging requested - finish here without setting up any
* logging facility. * further logging facility.
*/ */
if (logger_output_mode == OM_COMMAND_LINE) if (logger_output_mode == OM_COMMAND_LINE)
return true; return true;
@@ -251,9 +254,10 @@ logger_init(t_configuration_options *opts, const char *ident)
{ {
FILE *fd; FILE *fd;
/* Check if we can write to the specified file before redirecting /*
* stderr - if freopen() fails, stderr output will vanish into * Check if we can write to the specified file before redirecting
* the ether and the user won't know what's going on. * stderr - if freopen() fails, stderr output will vanish into the
* ether and the user won't know what's going on.
*/ */
fd = fopen(opts->log_file, "a"); fd = fopen(opts->log_file, "a");
@@ -270,9 +274,9 @@ logger_init(t_configuration_options *opts, const char *ident)
fd = freopen(opts->log_file, "a", stderr); fd = freopen(opts->log_file, "a", stderr);
/* /*
* It's possible freopen() may still fail due to e.g. a race condition; * It's possible freopen() may still fail due to e.g. a race
* as it's not feasible to restore stderr after a failed freopen(), * condition; as it's not feasible to restore stderr after a failed
* we'll write to stdout as a last resort. * freopen(), we'll write to stdout as a last resort.
*/ */
if (fd == NULL) if (fd == NULL)
{ {
@@ -318,7 +322,8 @@ logger_set_verbose(void)
* options and hints. * options and hints.
*/ */
void logger_set_terse(void) void
logger_set_terse(void)
{ {
terse_logging = true; terse_logging = true;
} }

11
log.h
View File

@@ -122,18 +122,21 @@ int detect_log_level(const char *level);
/* Logger initialisation and shutdown */ /* Logger initialisation and shutdown */
bool logger_init(t_configuration_options * opts, const char *ident); bool logger_init(t_configuration_options *opts, const char *ident);
bool logger_shutdown(void); bool logger_shutdown(void);
void logger_set_verbose(void); void logger_set_verbose(void);
void logger_set_terse(void); void logger_set_terse(void);
void log_detail(const char *fmt, ...) void
log_detail(const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
void log_hint(const char *fmt, ...) void
log_hint(const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
void log_verbose(int level, const char *fmt, ...) void
log_verbose(int level, const char *fmt,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern int log_type; extern int log_type;

View File

@@ -136,15 +136,15 @@ do_bdr_register(void)
} }
/* /*
* before adding the extension tables to the replication set, * before adding the extension tables to the replication set, if any other
* if any other BDR nodes exist, populate repmgr.nodes with a copy * BDR nodes exist, populate repmgr.nodes with a copy of existing entries
* of existing entries
* *
* currently we won't copy the contents of any other tables * currently we won't copy the contents of any other tables
* *
*/ */
{ {
NodeInfoList local_node_records = T_NODE_INFO_LIST_INITIALIZER; NodeInfoList local_node_records = T_NODE_INFO_LIST_INITIALIZER;
get_all_node_records(conn, &local_node_records); get_all_node_records(conn, &local_node_records);
if (local_node_records.node_count == 0) if (local_node_records.node_count == 0)
@@ -236,9 +236,10 @@ do_bdr_register(void)
if (record_status == RECORD_FOUND) if (record_status == RECORD_FOUND)
{ {
bool node_updated = false; bool node_updated = false;
/* /*
* At this point we will have established there are no non-BDR records, * At this point we will have established there are no non-BDR
* so no need to verify the node type * records, so no need to verify the node type
*/ */
if (!runtime_options.force) if (!runtime_options.force)
{ {
@@ -250,8 +251,8 @@ do_bdr_register(void)
} }
/* /*
* don't permit changing the node name - this must match the * don't permit changing the node name - this must match the BDR node
* BDR node name set when the node was registered. * name set when the node was registered.
*/ */
if (strncmp(node_info.node_name, config_file_options.node_name, MAXLEN) != 0) if (strncmp(node_info.node_name, config_file_options.node_name, MAXLEN) != 0)

View File

@@ -27,7 +27,8 @@
#define SHOW_HEADER_COUNT 7 #define SHOW_HEADER_COUNT 7
typedef enum { typedef enum
{
SHOW_ID = 0, SHOW_ID = 0,
SHOW_NAME, SHOW_NAME,
SHOW_ROLE, SHOW_ROLE,
@@ -39,7 +40,8 @@ typedef enum {
#define EVENT_HEADER_COUNT 6 #define EVENT_HEADER_COUNT 6
typedef enum { typedef enum
{
EV_NODE_ID = 0, EV_NODE_ID = 0,
EV_NODE_NAME, EV_NODE_NAME,
EV_EVENT, EV_EVENT,
@@ -50,7 +52,8 @@ typedef enum {
struct ColHeader { struct ColHeader
{
char title[MAXLEN]; char title[MAXLEN];
int max_length; int max_length;
int cur_length; int cur_length;
@@ -78,7 +81,7 @@ do_cluster_show(void)
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER; NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
NodeInfoListCell *cell = NULL; NodeInfoListCell *cell = NULL;
int i = 0; int i = 0;
ItemList warnings = { NULL, NULL }; ItemList warnings = {NULL, NULL};
/* Connect to local database to obtain cluster connection data */ /* Connect to local database to obtain cluster connection data */
log_verbose(LOG_INFO, _("connecting to database\n")); log_verbose(LOG_INFO, _("connecting to database\n"));
@@ -106,8 +109,8 @@ do_cluster_show(void)
strncpy(headers_show[SHOW_CONNINFO].title, _("Connection string"), MAXLEN); strncpy(headers_show[SHOW_CONNINFO].title, _("Connection string"), MAXLEN);
/* /*
* NOTE: if repmgr is ever localized into non-ASCII locales, * NOTE: if repmgr is ever localized into non-ASCII locales, use
* use pg_wcssize() or similar to establish printed column length * pg_wcssize() or similar to establish printed column length
*/ */
for (i = 0; i < SHOW_HEADER_COUNT; i++) for (i = 0; i < SHOW_HEADER_COUNT; i++)
@@ -136,7 +139,8 @@ do_cluster_show(void)
/* /*
* TODO: count nodes marked as "? unreachable" and add a hint about * TODO: count nodes marked as "? unreachable" and add a hint about
* the other cluster commands for better determining whether unreachable. * the other cluster commands for better determining whether
* unreachable.
*/ */
switch (cell->node_info->type) switch (cell->node_info->type)
{ {
@@ -191,7 +195,7 @@ do_cluster_show(void)
/* node is unreachable */ /* node is unreachable */
else else
{ {
/* node is unreachable but marked active*/ /* node is unreachable but marked active */
if (cell->node_info->active == true) if (cell->node_info->active == true)
{ {
appendPQExpBuffer(&details, "? unreachable"); appendPQExpBuffer(&details, "? unreachable");
@@ -259,7 +263,7 @@ do_cluster_show(void)
/* node is unreachable */ /* node is unreachable */
else else
{ {
/* node is unreachable but marked active*/ /* node is unreachable but marked active */
if (cell->node_info->active == true) if (cell->node_info->active == true)
{ {
appendPQExpBuffer(&details, "? unreachable"); appendPQExpBuffer(&details, "? unreachable");
@@ -345,6 +349,7 @@ do_cluster_show(void)
for (i = 0; i < SHOW_HEADER_COUNT; i++) for (i = 0; i < SHOW_HEADER_COUNT; i++)
{ {
int j; int j;
for (j = 0; j < headers_show[i].max_length; j++) for (j = 0; j < headers_show[i].max_length; j++)
printf("-"); printf("-");
@@ -365,8 +370,8 @@ do_cluster_show(void)
int recovery_type = RECTYPE_UNKNOWN; int recovery_type = RECTYPE_UNKNOWN;
/* /*
* here we explicitly convert the RecoveryType to integer values to * here we explicitly convert the RecoveryType to integer values
* avoid implicit dependency on the values in the enum * to avoid implicit dependency on the values in the enum
*/ */
switch (cell->node_info->recovery_type) switch (cell->node_info->recovery_type)
{ {
@@ -388,12 +393,12 @@ do_cluster_show(void)
} }
else else
{ {
printf( " %-*i ", headers_show[SHOW_ID].max_length, cell->node_info->node_id); printf(" %-*i ", headers_show[SHOW_ID].max_length, cell->node_info->node_id);
printf("| %-*s ", headers_show[SHOW_NAME].max_length, cell->node_info->node_name); printf("| %-*s ", headers_show[SHOW_NAME].max_length, cell->node_info->node_name);
printf("| %-*s ", headers_show[SHOW_ROLE].max_length, get_node_type_string(cell->node_info->type)); printf("| %-*s ", headers_show[SHOW_ROLE].max_length, get_node_type_string(cell->node_info->type));
printf("| %-*s ", headers_show[SHOW_STATUS].max_length, cell->node_info->details); printf("| %-*s ", headers_show[SHOW_STATUS].max_length, cell->node_info->details);
printf("| %-*s ", headers_show[SHOW_UPSTREAM_NAME].max_length , cell->node_info->upstream_node_name); printf("| %-*s ", headers_show[SHOW_UPSTREAM_NAME].max_length, cell->node_info->upstream_node_name);
printf("| %-*s ", headers_show[SHOW_LOCATION].max_length , cell->node_info->location); printf("| %-*s ", headers_show[SHOW_LOCATION].max_length, cell->node_info->location);
printf("| %-*s\n", headers_show[SHOW_CONNINFO].max_length, cell->node_info->conninfo); printf("| %-*s\n", headers_show[SHOW_CONNINFO].max_length, cell->node_info->conninfo);
} }
} }
@@ -516,7 +521,8 @@ do_cluster_event(void)
exit(ERR_DB_QUERY); exit(ERR_DB_QUERY);
} }
if (PQntuples(res) == 0) { if (PQntuples(res) == 0)
{
/* print this message directly, rather than as a log line */ /* print this message directly, rather than as a log line */
printf(_("no matching events found\n")); printf(_("no matching events found\n"));
PQclear(res); PQclear(res);
@@ -536,14 +542,14 @@ do_cluster_event(void)
headers_event[i].max_length = strlen(headers_event[i].title); headers_event[i].max_length = strlen(headers_event[i].title);
} }
for(i = 0; i < PQntuples(res); i++) for (i = 0; i < PQntuples(res); i++)
{ {
int j; int j;
for (j = 0; j < EVENT_HEADER_COUNT; j++) for (j = 0; j < EVENT_HEADER_COUNT; j++)
{ {
headers_event[j].cur_length = strlen(PQgetvalue(res, i, j)); headers_event[j].cur_length = strlen(PQgetvalue(res, i, j));
if(headers_event[j].cur_length > headers_event[j].max_length) if (headers_event[j].cur_length > headers_event[j].max_length)
{ {
headers_event[j].max_length = headers_event[j].cur_length; headers_event[j].max_length = headers_event[j].cur_length;
} }
@@ -567,6 +573,7 @@ do_cluster_event(void)
for (i = 0; i < EVENT_HEADER_COUNT; i++) for (i = 0; i < EVENT_HEADER_COUNT; i++)
{ {
int j; int j;
for (j = 0; j < headers_event[i].max_length; j++) for (j = 0; j < headers_event[i].max_length; j++)
printf("-"); printf("-");
@@ -578,7 +585,7 @@ do_cluster_event(void)
printf("\n"); printf("\n");
for(i = 0; i < PQntuples(res); i++) for (i = 0; i < PQntuples(res); i++)
{ {
int j; int j;
@@ -607,7 +614,8 @@ do_cluster_event(void)
void void
do_cluster_crosscheck(void) do_cluster_crosscheck(void)
{ {
int i = 0, n = 0; int i = 0,
n = 0;
char c; char c;
const char *node_header = "Name"; const char *node_header = "Name";
int name_length = strlen(node_header); int name_length = strlen(node_header);
@@ -642,22 +650,23 @@ do_cluster_crosscheck(void)
int node_ix = 0; int node_ix = 0;
/* /*
* The value of entry (i,j) is equal to the * The value of entry (i,j) is equal to the maximum value of all
* maximum value of all the (i,j,k). Indeed: * the (i,j,k). Indeed:
* *
* - if one of the (i,j,k) is 0 (node up), then 0 * - if one of the (i,j,k) is 0 (node up), then 0 (the node is
* (the node is up); * up);
* *
* - if the (i,j,k) are either -1 (down) or -2 * - if the (i,j,k) are either -1 (down) or -2 (unknown), then -1
* (unknown), then -1 (the node is down); * (the node is down);
* *
* - if all the (i,j,k) are -2 (unknown), then -2 * - if all the (i,j,k) are -2 (unknown), then -2 (the node is in
* (the node is in an unknown state). * an unknown state).
*/ */
for(node_ix = 0; node_ix < n; node_ix ++) for (node_ix = 0; node_ix < n; node_ix++)
{ {
int node_status = cube[node_ix]->matrix_list_rec[i]->node_status_list[column_node_ix]->node_status; int node_status = cube[node_ix]->matrix_list_rec[i]->node_status_list[column_node_ix]->node_status;
if (node_status > max_node_status) if (node_status > max_node_status)
max_node_status = node_status; max_node_status = node_status;
} }
@@ -685,7 +694,9 @@ do_cluster_crosscheck(void)
/* clean up allocated cube array */ /* clean up allocated cube array */
{ {
int h, j; int h,
j;
for (h = 0; h < n; h++) for (h = 0; h < n; h++)
{ {
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
@@ -710,7 +721,9 @@ do_cluster_crosscheck(void)
void void
do_cluster_matrix() do_cluster_matrix()
{ {
int i = 0, j = 0, n = 0; int i = 0,
j = 0,
n = 0;
const char *node_header = "Name"; const char *node_header = "Name";
int name_length = strlen(node_header); int name_length = strlen(node_header);
@@ -789,7 +802,8 @@ do_cluster_matrix()
static void static void
matrix_set_node_status(t_node_matrix_rec **matrix_rec_list, int n, int node_id, int connection_node_id, int connection_status) matrix_set_node_status(t_node_matrix_rec **matrix_rec_list, int n, int node_id, int connection_node_id, int connection_status)
{ {
int i, j; int i,
j;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
@@ -813,7 +827,8 @@ static int
build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length) build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
{ {
PGconn *conn = NULL; PGconn *conn = NULL;
int i = 0, j = 0; int i = 0,
j = 0;
int local_node_id = UNKNOWN_NODE_ID; int local_node_id = UNKNOWN_NODE_ID;
int node_count = 0; int node_count = 0;
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER; NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
@@ -852,9 +867,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
/* /*
* Allocate an empty matrix record list * Allocate an empty matrix record list
* *
* -2 == NULL ? * -2 == NULL ? -1 == Error x 0 == OK *
* -1 == Error x
* 0 == OK *
*/ */
matrix_rec_list = (t_node_matrix_rec **) pg_malloc0(sizeof(t_node_matrix_rec) * nodes.node_count); matrix_rec_list = (t_node_matrix_rec **) pg_malloc0(sizeof(t_node_matrix_rec) * nodes.node_count);
@@ -902,9 +915,11 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
{ {
int connection_status = 0; int connection_status = 0;
t_conninfo_param_list remote_conninfo = T_CONNINFO_PARAM_LIST_INITIALIZER; t_conninfo_param_list remote_conninfo = T_CONNINFO_PARAM_LIST_INITIALIZER;
char *host = NULL, *p = NULL; char *host = NULL,
*p = NULL;
int connection_node_id = cell->node_info->node_id; int connection_node_id = cell->node_info->node_id;
int x, y; int x,
y;
PGconn *node_conn = NULL; PGconn *node_conn = NULL;
initialize_conninfo_params(&remote_conninfo, false); initialize_conninfo_params(&remote_conninfo, false);
@@ -948,9 +963,9 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
initPQExpBuffer(&command); initPQExpBuffer(&command);
/* /*
* We'll pass cluster name and database connection string to the remote * We'll pass cluster name and database connection string to the
* repmgr - those are the only values it needs to work, and saves us * remote repmgr - those are the only values it needs to work, and
* making assumptions about the location of repmgr.conf * saves us making assumptions about the location of repmgr.conf
*/ */
appendPQExpBuffer(&command, appendPQExpBuffer(&command,
"\"%s -d '%s' ", "\"%s -d '%s' ",
@@ -975,7 +990,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
initPQExpBuffer(&command_output); initPQExpBuffer(&command_output);
(void)remote_command( (void) remote_command(
host, host,
runtime_options.remote_user, runtime_options.remote_user,
command.data, command.data,
@@ -998,7 +1013,7 @@ build_cluster_matrix(t_node_matrix_rec ***matrix_rec_dest, int *name_length)
nodes.node_count, nodes.node_count,
connection_node_id, connection_node_id,
x, x,
(y == -1) ? -1 : 0 ); (y == -1) ? -1 : 0);
while (*p && (*p != '\n')) while (*p && (*p != '\n'))
p++; p++;
@@ -1026,7 +1041,9 @@ static int
build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length) build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
{ {
PGconn *conn = NULL; PGconn *conn = NULL;
int h, i, j; int h,
i,
j;
NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER; NodeInfoList nodes = T_NODE_INFO_LIST_INITIALIZER;
NodeInfoListCell *cell = NULL; NodeInfoListCell *cell = NULL;
@@ -1056,9 +1073,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
/* /*
* Allocate an empty cube matrix structure * Allocate an empty cube matrix structure
* *
* -2 == NULL * -2 == NULL -1 == Error 0 == OK
* -1 == Error
* 0 == OK
*/ */
cube = (t_node_status_cube **) pg_malloc(sizeof(t_node_status_cube *) * nodes.node_count); cube = (t_node_status_cube **) pg_malloc(sizeof(t_node_status_cube *) * nodes.node_count);
@@ -1155,7 +1170,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
/* fix to work with --node-id */ /* fix to work with --node-id */
if (cube[i]->node_id == config_file_options.node_id) if (cube[i]->node_id == config_file_options.node_id)
{ {
(void)local_command( (void) local_command(
command.data, command.data,
&command_output); &command_output);
} }
@@ -1181,7 +1196,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
log_verbose(LOG_DEBUG, "build_cluster_crosscheck(): executing\n %s", quoted_command.data); log_verbose(LOG_DEBUG, "build_cluster_crosscheck(): executing\n %s", quoted_command.data);
(void)remote_command( (void) remote_command(
host, host,
runtime_options.remote_user, runtime_options.remote_user,
quoted_command.data, quoted_command.data,
@@ -1195,7 +1210,7 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
p = command_output.data; p = command_output.data;
if(!strlen(command_output.data)) if (!strlen(command_output.data))
{ {
termPQExpBuffer(&command_output); termPQExpBuffer(&command_output);
continue; continue;
@@ -1243,7 +1258,9 @@ build_cluster_crosscheck(t_node_status_cube ***dest_cube, int *name_length)
static void static void
cube_set_node_status(t_node_status_cube **cube, int n, int execute_node_id, int matrix_node_id, int connection_node_id, int connection_status) cube_set_node_status(t_node_status_cube **cube, int n, int execute_node_id, int matrix_node_id, int connection_node_id, int connection_status)
{ {
int h, i, j; int h,
i,
j;
for (h = 0; h < n; h++) for (h = 0; h < n; h++)

View File

@@ -69,10 +69,10 @@ do_node_status(void)
char cluster_size[MAXLEN]; char cluster_size[MAXLEN];
PQExpBufferData output; PQExpBufferData output;
KeyValueList node_status = { NULL, NULL }; KeyValueList node_status = {NULL, NULL};
KeyValueListCell *cell = NULL; KeyValueListCell *cell = NULL;
ItemList warnings = { NULL, NULL }; ItemList warnings = {NULL, NULL};
RecoveryType recovery_type = RECTYPE_UNKNOWN; RecoveryType recovery_type = RECTYPE_UNKNOWN;
ReplInfo replication_info = T_REPLINFO_INTIALIZER; ReplInfo replication_info = T_REPLINFO_INTIALIZER;
t_recovery_conf recovery_conf = T_RECOVERY_CONF_INITIALIZER; t_recovery_conf recovery_conf = T_RECOVERY_CONF_INITIALIZER;
@@ -268,6 +268,7 @@ do_node_status(void)
if (node_info.max_replication_slots > 0) if (node_info.max_replication_slots > 0)
{ {
PQExpBufferData slotinfo; PQExpBufferData slotinfo;
initPQExpBuffer(&slotinfo); initPQExpBuffer(&slotinfo);
appendPQExpBuffer( appendPQExpBuffer(
@@ -456,7 +457,8 @@ do_node_status(void)
*/ */
static static
void _do_node_status_is_shutdown_cleanly(void) void
_do_node_status_is_shutdown_cleanly(void)
{ {
PGPing ping_status; PGPing ping_status;
PQExpBufferData output; PQExpBufferData output;
@@ -503,7 +505,10 @@ void _do_node_status_is_shutdown_cleanly(void)
if (db_state != DB_SHUTDOWNED && db_state != DB_SHUTDOWNED_IN_RECOVERY) if (db_state != DB_SHUTDOWNED && db_state != DB_SHUTDOWNED_IN_RECOVERY)
{ {
/* node is not running, but pg_controldata says it is - unclean shutdown */ /*
* node is not running, but pg_controldata says it is - unclean
* shutdown
*/
if (node_status != NODE_STATUS_UP) if (node_status != NODE_STATUS_UP)
{ {
node_status = NODE_STATUS_UNCLEAN_SHUTDOWN; node_status = NODE_STATUS_UNCLEAN_SHUTDOWN;
@@ -517,7 +522,11 @@ void _do_node_status_is_shutdown_cleanly(void)
{ {
node_status = NODE_STATUS_UNKNOWN; node_status = NODE_STATUS_UNKNOWN;
} }
/* if still "UNKNOWN" at this point, then the node must be cleanly shut down */
/*
* if still "UNKNOWN" at this point, then the node must be cleanly shut
* down
*/
else if (node_status == NODE_STATUS_UNKNOWN) else if (node_status == NODE_STATUS_UNKNOWN)
{ {
node_status = NODE_STATUS_DOWN; node_status = NODE_STATUS_DOWN;
@@ -557,7 +566,7 @@ do_node_check(void)
t_node_info node_info = T_NODE_INFO_INITIALIZER; t_node_info node_info = T_NODE_INFO_INITIALIZER;
CheckStatusList status_list = { NULL, NULL }; CheckStatusList status_list = {NULL, NULL};
CheckStatusListCell *cell = NULL; CheckStatusListCell *cell = NULL;
@@ -576,8 +585,9 @@ do_node_check(void)
/* add replication statistics to node record */ /* add replication statistics to node record */
get_node_replication_stats(conn, &node_info); get_node_replication_stats(conn, &node_info);
/* handle specific checks /*
* ====================== */ * handle specific checks ======================
*/
if (runtime_options.archive_ready == true) if (runtime_options.archive_ready == true)
{ {
(void) do_node_check_archive_ready(conn, runtime_options.output_mode, NULL); (void) do_node_check_archive_ready(conn, runtime_options.output_mode, NULL);
@@ -1225,8 +1235,8 @@ do_node_check_downstream(PGconn *conn, OutputMode mode, CheckStatusList *list_ou
NodeInfoListCell *cell = NULL; NodeInfoListCell *cell = NULL;
int missing_nodes_count = 0; int missing_nodes_count = 0;
CheckStatus status = CHECK_STATUS_OK; CheckStatus status = CHECK_STATUS_OK;
ItemList missing_nodes = { NULL, NULL }; ItemList missing_nodes = {NULL, NULL};
ItemList attached_nodes = { NULL, NULL }; ItemList attached_nodes = {NULL, NULL};
PQExpBufferData details; PQExpBufferData details;
initPQExpBuffer(&details); initPQExpBuffer(&details);
@@ -1237,7 +1247,7 @@ do_node_check_downstream(PGconn *conn, OutputMode mode, CheckStatusList *list_ou
{ {
if (is_downstream_node_attached(conn, cell->node_info->node_name) == false) if (is_downstream_node_attached(conn, cell->node_info->node_name) == false)
{ {
missing_nodes_count ++; missing_nodes_count++;
item_list_append_format(&missing_nodes, item_list_append_format(&missing_nodes,
"%s (ID: %i)", "%s (ID: %i)",
cell->node_info->node_name, cell->node_info->node_name,
@@ -1269,6 +1279,7 @@ do_node_check_downstream(PGconn *conn, OutputMode mode, CheckStatusList *list_ou
{ {
ItemListCell *missing_cell = NULL; ItemListCell *missing_cell = NULL;
bool first = true; bool first = true;
status = CHECK_STATUS_CRITICAL; status = CHECK_STATUS_CRITICAL;
appendPQExpBuffer( appendPQExpBuffer(
@@ -1330,6 +1341,7 @@ do_node_check_downstream(PGconn *conn, OutputMode mode, CheckStatusList *list_ou
{ {
ItemListCell *attached_cell = NULL; ItemListCell *attached_cell = NULL;
bool first = true; bool first = true;
if (missing_nodes_count) if (missing_nodes_count)
printf("; "); printf("; ");
printf("attached: "); printf("attached: ");
@@ -1433,7 +1445,7 @@ do_node_service(void)
log_notice(_("issuing CHECKPOINT")); log_notice(_("issuing CHECKPOINT"));
// check superuser conn! /* check superuser conn! */
checkpoint(conn); checkpoint(conn);
PQfinish(conn); PQfinish(conn);
@@ -1661,8 +1673,8 @@ do_node_rejoin(void)
} }
/* /*
* Forcibly rewind node if requested (this is mainly for use when * Forcibly rewind node if requested (this is mainly for use when this
* this action is being executed by "repmgr standby switchover") * action is being executed by "repmgr standby switchover")
*/ */
if (runtime_options.force_rewind == true) if (runtime_options.force_rewind == true)
{ {
@@ -1783,7 +1795,7 @@ _do_node_archive_config(void)
DIR *arcdir; DIR *arcdir;
KeyValueList config_files = { NULL, NULL }; KeyValueList config_files = {NULL, NULL};
KeyValueListCell *cell = NULL; KeyValueListCell *cell = NULL;
int copied_count = 0; int copied_count = 0;
@@ -1811,7 +1823,7 @@ _do_node_archive_config(void)
} }
else if(!S_ISDIR(statbuf.st_mode)) else if (!S_ISDIR(statbuf.st_mode))
{ {
log_error(_("\"%s\" exists but is not a directory"), log_error(_("\"%s\" exists but is not a directory"),
archive_dir); archive_dir);
@@ -1830,8 +1842,8 @@ _do_node_archive_config(void)
} }
/* /*
* attempt to remove any existing files in the directory * attempt to remove any existing files in the directory TODO: collate
* TODO: collate problem files into list * problem files into list
*/ */
while ((arcdir_ent = readdir(arcdir)) != NULL) while ((arcdir_ent = readdir(arcdir)) != NULL)
{ {
@@ -2027,8 +2039,9 @@ _do_node_restore_config(void)
} }
/* /*
* Finally, delete directory - it should be empty unless it's been interfered * Finally, delete directory - it should be empty unless it's been
* with for some reason, in which case manual intervention is required * interfered with for some reason, in which case manual intervention is
* required
*/ */
if (rmdir(archive_dir) != 0 && errno != EEXIST) if (rmdir(archive_dir) != 0 && errno != EEXIST)
{ {
@@ -2063,7 +2076,8 @@ format_archive_dir(char *archive_dir)
static bool static bool
copy_file(const char *src_file, const char *dest_file) copy_file(const char *src_file, const char *dest_file)
{ {
FILE *ptr_old, *ptr_new; FILE *ptr_old,
*ptr_new;
int a = 0; int a = 0;
ptr_old = fopen(src_file, "r"); ptr_old = fopen(src_file, "r");
@@ -2080,7 +2094,7 @@ copy_file(const char *src_file, const char *dest_file)
chmod(dest_file, S_IRUSR | S_IWUSR); chmod(dest_file, S_IRUSR | S_IWUSR);
while(1) while (1)
{ {
a = fgetc(ptr_old); a = fgetc(ptr_old);

View File

@@ -83,8 +83,8 @@ do_primary_register(void)
/* /*
* In --dry-run mode we can't proceed any further as the following code * In --dry-run mode we can't proceed any further as the following code
* attempts to query the repmgr metadata, which won't exist until * attempts to query the repmgr metadata, which won't exist until the
* the extension is installed * extension is installed
*/ */
if (runtime_options.dry_run == true) if (runtime_options.dry_run == true)
{ {
@@ -100,7 +100,10 @@ do_primary_register(void)
{ {
if (current_primary_id != config_file_options.node_id) if (current_primary_id != config_file_options.node_id)
{ {
/* it's impossible to add a second primary to a streaming replication cluster */ /*
* it's impossible to add a second primary to a streaming
* replication cluster
*/
log_error(_("there is already an active registered primary (node ID: %i) in this cluster"), current_primary_id); log_error(_("there is already an active registered primary (node ID: %i) in this cluster"), current_primary_id);
PQfinish(primary_conn); PQfinish(primary_conn);
PQfinish(conn); PQfinish(conn);
@@ -115,8 +118,9 @@ do_primary_register(void)
begin_transaction(conn); begin_transaction(conn);
/* /*
* Check for an active primary node record with a different ID. This shouldn't * Check for an active primary node record with a different ID. This
* happen, but could do if an existing primary was shut down without being unregistered. * shouldn't happen, but could do if an existing primary was shut down
* without being unregistered.
*/ */
current_primary_id = get_primary_node_id(conn); current_primary_id = get_primary_node_id(conn);
if (current_primary_id != NODE_NOT_FOUND && current_primary_id != config_file_options.node_id) if (current_primary_id != NODE_NOT_FOUND && current_primary_id != config_file_options.node_id)
@@ -130,8 +134,8 @@ do_primary_register(void)
} }
/* /*
* Check whether there's an existing record for this node, and * Check whether there's an existing record for this node, and update it
* update it if --force set * if --force set
*/ */
record_status = get_node_record(conn, config_file_options.node_id, &node_info); record_status = get_node_record(conn, config_file_options.node_id, &node_info);
@@ -257,8 +261,8 @@ do_primary_unregister(void)
get_local_node_record(local_conn, config_file_options.node_id, &local_node_info); get_local_node_record(local_conn, config_file_options.node_id, &local_node_info);
/* /*
* Obtain a connection to the current primary node - if this isn't possible, * Obtain a connection to the current primary node - if this isn't
* abort as we won't be able to update the "nodes" table anyway. * possible, abort as we won't be able to update the "nodes" table anyway.
*/ */
primary_conn = establish_primary_db_connection(local_conn, false); primary_conn = establish_primary_db_connection(local_conn, false);
@@ -367,7 +371,10 @@ do_primary_unregister(void)
/* Node appears to be a standby */ /* Node appears to be a standby */
if (recovery_type == RECTYPE_STANDBY) if (recovery_type == RECTYPE_STANDBY)
{ {
/* We'll refuse to do anything unless the node record shows it as a primary */ /*
* We'll refuse to do anything unless the node record shows it as
* a primary
*/
if (target_node_info_ptr->type != PRIMARY) if (target_node_info_ptr->type != PRIMARY)
{ {
log_error(_("node %s (ID: %i) is a %s, unable to unregister"), log_error(_("node %s (ID: %i) is a %s, unable to unregister"),
@@ -376,9 +383,11 @@ do_primary_unregister(void)
get_node_type_string(target_node_info_ptr->type)); get_node_type_string(target_node_info_ptr->type));
can_unregister = false; can_unregister = false;
} }
/* /*
* If --F/--force not set, hint that it might be appropriate to * If --F/--force not set, hint that it might be appropriate to
* register the node as a standby rather than unregister as primary * register the node as a standby rather than unregister as
* primary
*/ */
else if (!runtime_options.force) else if (!runtime_options.force)
{ {
@@ -415,8 +424,10 @@ do_primary_unregister(void)
PQfinish(primary_conn); PQfinish(primary_conn);
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
/* This appears to be the cluster primary - cowardly refuse
* to delete the record /*
* This appears to be the cluster primary - cowardly refuse to
* delete the record
*/ */
if (primary_node_info.node_id == target_node_info_ptr->node_id) if (primary_node_info.node_id == target_node_info_ptr->node_id)
{ {

File diff suppressed because it is too large Load Diff

View File

@@ -160,12 +160,14 @@ typedef struct
} }
typedef enum { typedef enum
{
barman, barman,
pg_basebackup pg_basebackup
} standy_clone_mode; } standy_clone_mode;
typedef enum { typedef enum
{
ACTION_UNKNOWN = -1, ACTION_UNKNOWN = -1,
ACTION_NONE, ACTION_NONE,
ACTION_START, ACTION_START,

View File

@@ -86,8 +86,8 @@ t_node_info target_node_info = T_NODE_INFO_INITIALIZER;
/* Collate command line errors and warnings here for friendlier reporting */ /* Collate command line errors and warnings here for friendlier reporting */
static ItemList cli_errors = { NULL, NULL }; static ItemList cli_errors = {NULL, NULL};
static ItemList cli_warnings = { NULL, NULL }; static ItemList cli_warnings = {NULL, NULL};
int int
@@ -109,9 +109,9 @@ main(int argc, char **argv)
set_progname(argv[0]); set_progname(argv[0]);
/* /*
* Tell the logger we're a command-line program - this will * Tell the logger we're a command-line program - this will ensure any
* ensure any output logged before the logger is initialized * output logged before the logger is initialized will be formatted
* will be formatted correctly. Can be overriden with "--log-to-file". * correctly. Can be overriden with "--log-to-file".
*/ */
logger_output_mode = OM_COMMAND_LINE; logger_output_mode = OM_COMMAND_LINE;
@@ -119,14 +119,13 @@ main(int argc, char **argv)
* Initialize and pre-populate conninfo parameters; these will be * Initialize and pre-populate conninfo parameters; these will be
* overwritten if matching command line parameters are provided. * overwritten if matching command line parameters are provided.
* *
* Only some actions will need these, but we need to do this before * Only some actions will need these, but we need to do this before the
* the command line is parsed. * command line is parsed.
* *
* Note: PQconndefaults() does not provide a default value for * Note: PQconndefaults() does not provide a default value for "dbname",
* "dbname", but if none is provided will default to "username" * but if none is provided will default to "username" when the connection
* when the connection is made. We won't set "dbname" here if no * is made. We won't set "dbname" here if no default available, as that
* default available, as that would break the libpq behaviour if * would break the libpq behaviour if non-default username is provided.
* non-default username is provided.
*/ */
initialize_conninfo_params(&default_conninfo, true); initialize_conninfo_params(&default_conninfo, true);
@@ -180,16 +179,16 @@ main(int argc, char **argv)
&optindex)) != -1) &optindex)) != -1)
{ {
/* /*
* NOTE: some integer parameters (e.g. -p/--port) are stored internally * NOTE: some integer parameters (e.g. -p/--port) are stored
* as strings. We use repmgr_atoi() to check these but discard the * internally as strings. We use repmgr_atoi() to check these but
* returned integer; repmgr_atoi() will append the error message to the * discard the returned integer; repmgr_atoi() will append the error
* provided list. * message to the provided list.
*/ */
switch (c) switch (c)
{ {
/* /*
* Options which cause repmgr to exit in this block; * Options which cause repmgr to exit in this block; these are
* these are the only ones which can be executed as root user * the only ones which can be executed as root user
*/ */
case OPT_HELP: /* --help */ case OPT_HELP: /* --help */
help_option = true; help_option = true;
@@ -202,9 +201,11 @@ main(int argc, char **argv)
} }
break; break;
case 'V': case 'V':
/* /*
* in contrast to repmgr3 and earlier, we only display the repmgr version * in contrast to repmgr3 and earlier, we only display the
* as it's not specific to a particular PostgreSQL version * repmgr version as it's not specific to a particular
* PostgreSQL version
*/ */
printf("%s %s\n", progname(), REPMGR_VERSION); printf("%s %s\n", progname(), REPMGR_VERSION);
exit(SUCCESS); exit(SUCCESS);
@@ -250,16 +251,20 @@ main(int argc, char **argv)
*/ */
/* /*
* These are the standard database connection options; with the * These are the standard database connection options; with
* exception of -d/--dbname (which could be a conninfo string) * the exception of -d/--dbname (which could be a conninfo
* we'll also set these values in "source_conninfo" (overwriting * string) we'll also set these values in "source_conninfo"
* preset values from environment variables). * (overwriting preset values from environment variables). XXX
* XXX check this is same as psql * check this is same as psql
*/ */
/* -d/--dbname */ /* -d/--dbname */
case 'd': case 'd':
strncpy(runtime_options.dbname, optarg, MAXLEN); strncpy(runtime_options.dbname, optarg, MAXLEN);
/* dbname will be set in source_conninfo later after checking if it's a conninfo string */
/*
* dbname will be set in source_conninfo later after checking
* if it's a conninfo string
*/
runtime_options.connection_param_provided = true; runtime_options.connection_param_provided = true;
break; break;
@@ -322,8 +327,9 @@ main(int argc, char **argv)
strncpy(runtime_options.node_name, optarg, MAXLEN); strncpy(runtime_options.node_name, optarg, MAXLEN);
break; break;
/* standby options * /*
* --------------- */ * standby options * ---------------
*/
/* --upstream-node-id */ /* --upstream-node-id */
case OPT_UPSTREAM_NODE_ID: case OPT_UPSTREAM_NODE_ID:
@@ -502,6 +508,7 @@ main(int argc, char **argv)
case 'L': case 'L':
{ {
int detected_log_level = detect_log_level(optarg); int detected_log_level = detect_log_level(optarg);
if (detected_log_level != -1) if (detected_log_level != -1)
{ {
strncpy(runtime_options.log_level, optarg, MAXLEN); strncpy(runtime_options.log_level, optarg, MAXLEN);
@@ -509,6 +516,7 @@ main(int argc, char **argv)
else else
{ {
PQExpBufferData invalid_log_level; PQExpBufferData invalid_log_level;
initPQExpBuffer(&invalid_log_level); initPQExpBuffer(&invalid_log_level);
appendPQExpBuffer(&invalid_log_level, _("invalid log level \"%s\" provided"), optarg); appendPQExpBuffer(&invalid_log_level, _("invalid log level \"%s\" provided"), optarg);
item_list_append(&cli_errors, invalid_log_level.data); item_list_append(&cli_errors, invalid_log_level.data);
@@ -597,6 +605,7 @@ main(int argc, char **argv)
if (opts == NULL) if (opts == NULL)
{ {
PQExpBufferData conninfo_error; PQExpBufferData conninfo_error;
initPQExpBuffer(&conninfo_error); initPQExpBuffer(&conninfo_error);
appendPQExpBuffer(&conninfo_error, _("error parsing conninfo:\n%s"), errmsg); appendPQExpBuffer(&conninfo_error, _("error parsing conninfo:\n%s"), errmsg);
item_list_append(&cli_errors, conninfo_error.data); item_list_append(&cli_errors, conninfo_error.data);
@@ -613,6 +622,7 @@ main(int argc, char **argv)
* settings take priority * settings take priority
*/ */
PQconninfoOption *opt; PQconninfoOption *opt;
for (opt = opts; opt->keyword != NULL; opt++) for (opt = opts; opt->keyword != NULL; opt++)
{ {
if (opt->val != NULL && opt->val[0] != '\0') if (opt->val != NULL && opt->val[0] != '\0')
@@ -654,9 +664,9 @@ main(int argc, char **argv)
} }
/* /*
* Disallow further running as root to prevent directory ownership problems. * Disallow further running as root to prevent directory ownership
* We check this here to give the root user a chance to execute --help/--version * problems. We check this here to give the root user a chance to execute
* options. * --help/--version options.
*/ */
if (geteuid() == 0 && help_option == false) if (geteuid() == 0 && help_option == false)
{ {
@@ -681,13 +691,14 @@ main(int argc, char **argv)
/* /*
* Determine the node type and action; following are valid: * Determine the node type and action; following are valid:
* *
* { PRIMARY | MASTER } REGISTER | * { PRIMARY | MASTER } REGISTER | STANDBY {REGISTER | UNREGISTER | CLONE
* STANDBY {REGISTER | UNREGISTER | CLONE [node] | PROMOTE | FOLLOW [node] | SWITCHOVER | REWIND} | * [node] | PROMOTE | FOLLOW [node] | SWITCHOVER | REWIND} | BDR {
* BDR { REGISTER | UNREGISTER } | * REGISTER | UNREGISTER } | NODE { STATUS | CHECK | REJOIN |
* NODE { STATUS | CHECK | REJOIN | ARCHIVE-CONFIG | RESTORE-CONFIG | SERVICE } | * ARCHIVE-CONFIG | RESTORE-CONFIG | SERVICE } | CLUSTER { CROSSCHECK |
* CLUSTER { CROSSCHECK | MATRIX | SHOW | CLEANUP | EVENT } * MATRIX | SHOW | CLEANUP | EVENT }
* *
* [node] is an optional hostname, provided instead of the -h/--host option * [node] is an optional hostname, provided instead of the -h/--host
* option
*/ */
if (optind < argc) if (optind < argc)
{ {
@@ -706,7 +717,7 @@ main(int argc, char **argv)
if (repmgr_command != NULL) if (repmgr_command != NULL)
{ {
#ifndef BDR_ONLY #ifndef BDR_ONLY
if (strcasecmp(repmgr_command, "PRIMARY") == 0 || strcasecmp(repmgr_command, "MASTER") == 0 ) if (strcasecmp(repmgr_command, "PRIMARY") == 0 || strcasecmp(repmgr_command, "MASTER") == 0)
{ {
if (help_option == true) if (help_option == true)
{ {
@@ -823,6 +834,7 @@ main(int argc, char **argv)
if (action == NO_ACTION) if (action == NO_ACTION)
{ {
PQExpBufferData command_error; PQExpBufferData command_error;
initPQExpBuffer(&command_error); initPQExpBuffer(&command_error);
if (repmgr_command == NULL) if (repmgr_command == NULL)
@@ -853,7 +865,10 @@ main(int argc, char **argv)
item_list_append(&cli_errors, command_error.data); item_list_append(&cli_errors, command_error.data);
} }
/* STANDBY CLONE historically accepts the upstream hostname as an additional argument */ /*
* STANDBY CLONE historically accepts the upstream hostname as an
* additional argument
*/
if (action == STANDBY_CLONE) if (action == STANDBY_CLONE)
{ {
if (optind < argc) if (optind < argc)
@@ -861,6 +876,7 @@ main(int argc, char **argv)
if (runtime_options.host_param_provided == true) if (runtime_options.host_param_provided == true)
{ {
PQExpBufferData additional_host_arg; PQExpBufferData additional_host_arg;
initPQExpBuffer(&additional_host_arg); initPQExpBuffer(&additional_host_arg);
appendPQExpBuffer(&additional_host_arg, appendPQExpBuffer(&additional_host_arg,
_("host name provided both with %s and as an extra parameter"), _("host name provided both with %s and as an extra parameter"),
@@ -879,6 +895,7 @@ main(int argc, char **argv)
if (optind < argc) if (optind < argc)
{ {
PQExpBufferData too_many_args; PQExpBufferData too_many_args;
initPQExpBuffer(&too_many_args); initPQExpBuffer(&too_many_args);
appendPQExpBuffer(&too_many_args, _("too many command-line arguments (first extra is \"%s\")"), argv[optind]); appendPQExpBuffer(&too_many_args, _("too many command-line arguments (first extra is \"%s\")"), argv[optind]);
item_list_append(&cli_errors, too_many_args.data); item_list_append(&cli_errors, too_many_args.data);
@@ -886,9 +903,9 @@ main(int argc, char **argv)
/* /*
* The configuration file is not required for some actions (e.g. 'standby clone'), * The configuration file is not required for some actions (e.g. 'standby
* however if available we'll parse it anyway for options like 'log_level', * clone'), however if available we'll parse it anyway for options like
* 'use_replication_slots' etc. * 'log_level', 'use_replication_slots' etc.
*/ */
load_config(runtime_options.config_file, load_config(runtime_options.config_file,
runtime_options.verbose, runtime_options.verbose,
@@ -899,8 +916,8 @@ main(int argc, char **argv)
check_cli_parameters(action); check_cli_parameters(action);
/* /*
* Sanity checks for command line parameters completed by now; * Sanity checks for command line parameters completed by now; any further
* any further errors will be runtime ones * errors will be runtime ones
*/ */
if (cli_errors.head != NULL) if (cli_errors.head != NULL)
{ {
@@ -909,8 +926,8 @@ main(int argc, char **argv)
} }
/* /*
* Print any warnings about inappropriate command line options, * Print any warnings about inappropriate command line options, unless
* unless -t/--terse set * -t/--terse set
*/ */
if (cli_warnings.head != NULL && runtime_options.terse == false) if (cli_warnings.head != NULL && runtime_options.terse == false)
{ {
@@ -918,8 +935,10 @@ main(int argc, char **argv)
print_item_list(&cli_warnings); print_item_list(&cli_warnings);
} }
/* post-processing following command line parameter checks /*
* ======================================================= */ * post-processing following command line parameter checks
* =======================================================
*/
if (runtime_options.csv == true) if (runtime_options.csv == true)
{ {
@@ -953,18 +972,27 @@ main(int argc, char **argv)
} }
/* Check for configuration file items which can be overriden by runtime options */ /*
/* ============================================================================ */ * Check for configuration file items which can be overriden by runtime
* options
*/
/* Command-line parameter -L/--log-level overrides any setting in config file*/ /*
* ============================================================================
*/
/*
* Command-line parameter -L/--log-level overrides any setting in config
* file
*/
if (*runtime_options.log_level != '\0') if (*runtime_options.log_level != '\0')
{ {
strncpy(config_file_options.log_level, runtime_options.log_level, MAXLEN); strncpy(config_file_options.log_level, runtime_options.log_level, MAXLEN);
} }
/* /*
* Initialise pg_bindir - command line parameter will override * Initialise pg_bindir - command line parameter will override any setting
* any setting in the configuration file * in the configuration file
*/ */
if (!strlen(runtime_options.pg_bindir)) if (!strlen(runtime_options.pg_bindir))
{ {
@@ -975,6 +1003,7 @@ main(int argc, char **argv)
if (strlen(runtime_options.pg_bindir)) if (strlen(runtime_options.pg_bindir))
{ {
int len = strlen(runtime_options.pg_bindir); int len = strlen(runtime_options.pg_bindir);
if (runtime_options.pg_bindir[len - 1] != '/') if (runtime_options.pg_bindir[len - 1] != '/')
{ {
maxlen_snprintf(pg_bindir, "%s/", runtime_options.pg_bindir); maxlen_snprintf(pg_bindir, "%s/", runtime_options.pg_bindir);
@@ -987,11 +1016,12 @@ main(int argc, char **argv)
/* /*
* Initialize the logger. We've previously requested STDERR logging only * Initialize the logger. We've previously requested STDERR logging only
* to ensure the repmgr command doesn't have its output diverted to a logging * to ensure the repmgr command doesn't have its output diverted to a
* facility (which usually doesn't make sense for a command line program). * logging facility (which usually doesn't make sense for a command line
* program).
* *
* If required (e.g. when calling repmgr from repmgrd), this behaviour can be * If required (e.g. when calling repmgr from repmgrd), this behaviour can
* overridden with "--log-to-file". * be overridden with "--log-to-file".
*/ */
logger_init(&config_file_options, progname()); logger_init(&config_file_options, progname());
@@ -1025,11 +1055,11 @@ main(int argc, char **argv)
* If a node was specified (by --node-id or --node-name), check it exists * If a node was specified (by --node-id or --node-name), check it exists
* (and pre-populate a record for later use). * (and pre-populate a record for later use).
* *
* At this point check_cli_parameters() will already have determined * At this point check_cli_parameters() will already have determined if
* if provision of these is valid for the action, otherwise it unsets them. * provision of these is valid for the action, otherwise it unsets them.
* *
* We need to check this much later than other command line parameters * We need to check this much later than other command line parameters as
* as we need to wait until the configuration file is parsed and we can * we need to wait until the configuration file is parsed and we can
* obtain the conninfo string. * obtain the conninfo string.
*/ */
@@ -1062,6 +1092,7 @@ main(int argc, char **argv)
else if (runtime_options.node_name[0] != '\0') else if (runtime_options.node_name[0] != '\0')
{ {
char *escaped = escape_string(conn, runtime_options.node_name); char *escaped = escape_string(conn, runtime_options.node_name);
if (escaped == NULL) if (escaped == NULL)
{ {
log_error(_("unable to escape value provided for --node-name")); log_error(_("unable to escape value provided for --node-name"));
@@ -1196,7 +1227,8 @@ main(int argc, char **argv)
static void static void
check_cli_parameters(const int action) check_cli_parameters(const int action)
{ {
/* ======================================================================== /*
* ========================================================================
* check all parameters required for an action are provided, and warn * check all parameters required for an action are provided, and warn
* about ineffective actions * about ineffective actions
* ======================================================================== * ========================================================================
@@ -1244,7 +1276,11 @@ check_cli_parameters(const int action)
action_name(action)); action_name(action));
} }
// XXX if -D/--pgdata provided, and also config_file_options.pgdaga, warn -D/--pgdata will be ignored /*
* XXX if -D/--pgdata provided, and also
* config_file_options.pgdaga, warn -D/--pgdata will be
* ignored
*/
if (*runtime_options.upstream_conninfo) if (*runtime_options.upstream_conninfo)
{ {
@@ -1267,8 +1303,8 @@ check_cli_parameters(const int action)
case STANDBY_FOLLOW: case STANDBY_FOLLOW:
{ {
/* /*
* if `repmgr standby follow` executed with host params, ensure data * if `repmgr standby follow` executed with host params,
* directory was provided * ensure data directory was provided
*/ */
} }
break; break;
@@ -1306,12 +1342,13 @@ check_cli_parameters(const int action)
} }
/* ======================================================================== /*
* ========================================================================
* warn if parameters provided for an action where they're not relevant * warn if parameters provided for an action where they're not relevant
* ======================================================================== * ========================================================================
*/ */
/* --host etc.*/ /* --host etc. */
if (runtime_options.connection_param_provided) if (runtime_options.connection_param_provided)
{ {
switch (action) switch (action)
@@ -1573,13 +1610,13 @@ check_cli_parameters(const int action)
int used_options = 0; int used_options = 0;
if (runtime_options.csv == true) if (runtime_options.csv == true)
used_options ++; used_options++;
if (runtime_options.nagios == true) if (runtime_options.nagios == true)
used_options ++; used_options++;
if (runtime_options.optformat == true) if (runtime_options.optformat == true)
used_options ++; used_options++;
if (used_options > 1) if (used_options > 1)
{ {
@@ -1592,10 +1629,10 @@ check_cli_parameters(const int action)
} }
static const char* static const char *
action_name(const int action) action_name(const int action)
{ {
switch(action) switch (action)
{ {
case PRIMARY_REGISTER: case PRIMARY_REGISTER:
return "PRIMARY REGISTER"; return "PRIMARY REGISTER";
@@ -1648,7 +1685,7 @@ print_error_list(ItemList *error_list, int log_level)
for (cell = error_list->head; cell; cell = cell->next) for (cell = error_list->head; cell; cell = cell->next)
{ {
switch(log_level) switch (log_level)
{ {
/* Currently we only need errors and warnings */ /* Currently we only need errors and warnings */
case LOG_ERROR: case LOG_ERROR:
@@ -1772,7 +1809,7 @@ create_repmgr_extension(PGconn *conn)
extension_status = get_repmgr_extension_status(conn); extension_status = get_repmgr_extension_status(conn);
switch(extension_status) switch (extension_status)
{ {
case REPMGR_UNKNOWN: case REPMGR_UNKNOWN:
log_error(_("unable to determine status of \"repmgr\" extension")); log_error(_("unable to determine status of \"repmgr\" extension"));
@@ -1948,12 +1985,13 @@ int
test_ssh_connection(char *host, char *remote_user) test_ssh_connection(char *host, char *remote_user)
{ {
char script[MAXLEN] = ""; char script[MAXLEN] = "";
int r = 1, i; int r = 1,
i;
/* On some OS, true is located in a different place than in Linux /*
* we have to try them all until all alternatives are gone or we * On some OS, true is located in a different place than in Linux we have
* found `true' because the target OS may differ from the source * to try them all until all alternatives are gone or we found `true'
* OS * because the target OS may differ from the source OS
*/ */
const char *bin_true_paths[] = { const char *bin_true_paths[] = {
"/bin/true", "/bin/true",
@@ -2142,12 +2180,12 @@ copy_remote_files(char *host, char *remote_user, char *remote_path,
} }
/* /*
* When copying the main PGDATA directory, certain files and contents * When copying the main PGDATA directory, certain files and contents of
* of certain directories need to be excluded. * certain directories need to be excluded.
* *
* See function 'sendDir()' in 'src/backend/replication/basebackup.c' - * See function 'sendDir()' in 'src/backend/replication/basebackup.c' -
* we're basically simulating what pg_basebackup does, but with rsync rather * we're basically simulating what pg_basebackup does, but with rsync
* than the BASEBACKUP replication protocol command. * rather than the BASEBACKUP replication protocol command.
* *
* *However* currently we'll always copy the contents of the 'pg_replslot' * *However* currently we'll always copy the contents of the 'pg_replslot'
* directory and delete later if appropriate. * directory and delete later if appropriate.
@@ -2268,13 +2306,15 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *recovery_c
if (strlen(runtime_options.upstream_conninfo)) if (strlen(runtime_options.upstream_conninfo))
{ {
char *escaped = escape_recovery_conf_value(runtime_options.upstream_conninfo); char *escaped = escape_recovery_conf_value(runtime_options.upstream_conninfo);
maxlen_snprintf(line, "primary_conninfo = '%s'\n", maxlen_snprintf(line, "primary_conninfo = '%s'\n",
escaped); escaped);
free(escaped); free(escaped);
} }
/* /*
* otherwise use the conninfo inferred from the upstream connection * otherwise use the conninfo inferred from the upstream connection and/or
* and/or node record * node record
*/ */
else else
{ {
@@ -2320,7 +2360,10 @@ create_recovery_file(t_node_info *node_record, t_conninfo_param_list *recovery_c
log_debug("recovery.conf: %s", line); log_debug("recovery.conf: %s", line);
} }
/* If restore_command is set, we use it as restore_command in recovery.conf */ /*
* If restore_command is set, we use it as restore_command in
* recovery.conf
*/
if (strcmp(config_file_options.restore_command, "") != 0) if (strcmp(config_file_options.restore_command, "") != 0)
{ {
maxlen_snprintf(line, "restore_command = '%s'\n", maxlen_snprintf(line, "restore_command = '%s'\n",
@@ -2523,7 +2566,7 @@ get_server_action(t_server_action action, char *script, char *data_dir)
if (data_dir == NULL || data_dir[0] == '\0') if (data_dir == NULL || data_dir[0] == '\0')
data_dir = "(none provided)"; data_dir = "(none provided)";
switch(action) switch (action)
{ {
case ACTION_NONE: case ACTION_NONE:
script[0] = '\0'; script[0] = '\0';
@@ -2698,7 +2741,7 @@ get_server_action(t_server_action action, char *script, char *data_dir)
bool bool
data_dir_required_for_action(t_server_action action) data_dir_required_for_action(t_server_action action)
{ {
switch(action) switch (action)
{ {
case ACTION_NONE: case ACTION_NONE:
return false; return false;
@@ -2750,8 +2793,8 @@ void
get_node_data_directory(char *data_dir_buf) get_node_data_directory(char *data_dir_buf)
{ {
/* /*
* the configuration file setting has priority, and will always be * the configuration file setting has priority, and will always be set
* set when a configuration file was provided * when a configuration file was provided
*/ */
if (config_file_options.data_directory[0] != '\0') if (config_file_options.data_directory[0] != '\0')
{ {
@@ -2802,7 +2845,7 @@ init_node_record(t_node_info *node_record)
/* use the "user" value from "conninfo" */ /* use the "user" value from "conninfo" */
char repluser[MAXLEN] = ""; char repluser[MAXLEN] = "";
(void)get_conninfo_value(config_file_options.conninfo, "user", repluser); (void) get_conninfo_value(config_file_options.conninfo, "user", repluser);
strncpy(node_record->repluser, repluser, NAMEDATALEN); strncpy(node_record->repluser, repluser, NAMEDATALEN);
} }

View File

@@ -141,22 +141,22 @@ static struct option long_options[] =
/* "standby switchover" options */ /* "standby switchover" options */
{"remote-config-file", required_argument, NULL, 'C'}, {"remote-config-file", required_argument, NULL, 'C'},
{"always-promote", no_argument, NULL, OPT_ALWAYS_PROMOTE }, {"always-promote", no_argument, NULL, OPT_ALWAYS_PROMOTE},
{"force-rewind", no_argument, NULL, OPT_FORCE_REWIND }, {"force-rewind", no_argument, NULL, OPT_FORCE_REWIND},
{"siblings-follow", no_argument, NULL, OPT_SIBLINGS_FOLLOW }, {"siblings-follow", no_argument, NULL, OPT_SIBLINGS_FOLLOW},
/* "node status" options */ /* "node status" options */
{"is-shutdown-cleanly", no_argument, NULL, OPT_IS_SHUTDOWN_CLEANLY }, {"is-shutdown-cleanly", no_argument, NULL, OPT_IS_SHUTDOWN_CLEANLY},
/* "node check" options */ /* "node check" options */
{"archive-ready", no_argument, NULL, OPT_ARCHIVE_READY }, {"archive-ready", no_argument, NULL, OPT_ARCHIVE_READY},
{"downstream", no_argument, NULL, OPT_DOWNSTREAM }, {"downstream", no_argument, NULL, OPT_DOWNSTREAM},
{"replication-lag", no_argument, NULL, OPT_REPLICATION_LAG }, {"replication-lag", no_argument, NULL, OPT_REPLICATION_LAG},
{"role", no_argument, NULL, OPT_ROLE }, {"role", no_argument, NULL, OPT_ROLE},
{"slots", no_argument, NULL, OPT_SLOTS }, {"slots", no_argument, NULL, OPT_SLOTS},
/* "node join" options */ /* "node join" options */
{"config-files", required_argument, NULL, OPT_CONFIG_FILES }, {"config-files", required_argument, NULL, OPT_CONFIG_FILES},
/* "node service" options */ /* "node service" options */
{"action", required_argument, NULL, OPT_ACTION}, {"action", required_argument, NULL, OPT_ACTION},
@@ -165,16 +165,16 @@ static struct option long_options[] =
{"checkpoint", no_argument, NULL, OPT_CHECKPOINT}, {"checkpoint", no_argument, NULL, OPT_CHECKPOINT},
/* "cluster event" options */ /* "cluster event" options */
{"all", no_argument, NULL, OPT_ALL }, {"all", no_argument, NULL, OPT_ALL},
{"event", required_argument, NULL, OPT_EVENT }, {"event", required_argument, NULL, OPT_EVENT},
{"limit", required_argument, NULL, OPT_LIMIT }, {"limit", required_argument, NULL, OPT_LIMIT},
/* Following options for internal use */ /* Following options for internal use */
{"config-archive-dir", required_argument, NULL, OPT_CONFIG_ARCHIVE_DIR}, {"config-archive-dir", required_argument, NULL, OPT_CONFIG_ARCHIVE_DIR},
/* deprecated */ /* deprecated */
{"no-conninfo-password", no_argument, NULL, OPT_NO_CONNINFO_PASSWORD}, {"no-conninfo-password", no_argument, NULL, OPT_NO_CONNINFO_PASSWORD},
/* legacy alias for -D/--pgdata*/ /* legacy alias for -D/--pgdata */
{"data-dir", required_argument, NULL, OPT_DATA_DIR}, {"data-dir", required_argument, NULL, OPT_DATA_DIR},
/* --node-id */ /* --node-id */
{"node", required_argument, NULL, OPT_NODE}, {"node", required_argument, NULL, OPT_NODE},

View File

@@ -49,7 +49,8 @@
PG_MODULE_MAGIC; PG_MODULE_MAGIC;
typedef enum { typedef enum
{
LEADER_NODE, LEADER_NODE,
FOLLOWER_NODE, FOLLOWER_NODE,
CANDIDATE_NODE CANDIDATE_NODE
@@ -81,40 +82,52 @@ void _PG_fini(void);
static void repmgr_shmem_startup(void); static void repmgr_shmem_startup(void);
Datum set_local_node_id(PG_FUNCTION_ARGS); Datum set_local_node_id(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_local_node_id); PG_FUNCTION_INFO_V1(set_local_node_id);
Datum standby_set_last_updated(PG_FUNCTION_ARGS); Datum standby_set_last_updated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(standby_set_last_updated); PG_FUNCTION_INFO_V1(standby_set_last_updated);
Datum standby_get_last_updated(PG_FUNCTION_ARGS); Datum standby_get_last_updated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(standby_get_last_updated); PG_FUNCTION_INFO_V1(standby_get_last_updated);
Datum request_vote(PG_FUNCTION_ARGS); Datum request_vote(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(request_vote); PG_FUNCTION_INFO_V1(request_vote);
Datum get_voting_status(PG_FUNCTION_ARGS); Datum get_voting_status(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_voting_status); PG_FUNCTION_INFO_V1(get_voting_status);
Datum set_voting_status_initiated(PG_FUNCTION_ARGS); Datum set_voting_status_initiated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_voting_status_initiated); PG_FUNCTION_INFO_V1(set_voting_status_initiated);
Datum other_node_is_candidate(PG_FUNCTION_ARGS); Datum other_node_is_candidate(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(other_node_is_candidate); PG_FUNCTION_INFO_V1(other_node_is_candidate);
Datum notify_follow_primary(PG_FUNCTION_ARGS); Datum notify_follow_primary(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(notify_follow_primary); PG_FUNCTION_INFO_V1(notify_follow_primary);
Datum get_new_primary(PG_FUNCTION_ARGS); Datum get_new_primary(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(get_new_primary); PG_FUNCTION_INFO_V1(get_new_primary);
Datum reset_voting_status(PG_FUNCTION_ARGS); Datum reset_voting_status(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(reset_voting_status); PG_FUNCTION_INFO_V1(reset_voting_status);
Datum am_bdr_failover_handler(PG_FUNCTION_ARGS); Datum am_bdr_failover_handler(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(am_bdr_failover_handler); PG_FUNCTION_INFO_V1(am_bdr_failover_handler);
Datum unset_bdr_failover_handler(PG_FUNCTION_ARGS); Datum unset_bdr_failover_handler(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(unset_bdr_failover_handler); PG_FUNCTION_INFO_V1(unset_bdr_failover_handler);
@@ -331,7 +344,7 @@ request_vote(PG_FUNCTION_ARGS)
LWLockRelease(shared_state->lock); LWLockRelease(shared_state->lock);
// should we free "query" here? /* should we free "query" here? */
SPI_finish(); SPI_finish();
PG_RETURN_LSN(our_lsn); PG_RETURN_LSN(our_lsn);

View File

@@ -65,8 +65,7 @@ monitor_bdr(void)
} }
/* /*
* Verify that database is a BDR one * Verify that database is a BDR one TODO: check if supported BDR version?
* TODO: check if supported BDR version?
*/ */
log_info(_("connected to database, checking for BDR")); log_info(_("connected to database, checking for BDR"));
@@ -81,7 +80,10 @@ monitor_bdr(void)
log_error(_("repmgr metadata table 'repmgr.%s' is not in the 'repmgr' replication set"), log_error(_("repmgr metadata table 'repmgr.%s' is not in the 'repmgr' replication set"),
"nodes"); "nodes");
/* TODO: add `repmgr bdr sync` or similar for this situation, and hint here */ /*
* TODO: add `repmgr bdr sync` or similar for this situation, and hint
* here
*/
exit(ERR_BAD_CONFIG); exit(ERR_BAD_CONFIG);
} }
@@ -100,8 +102,8 @@ monitor_bdr(void)
record_status = get_node_record(local_conn, config_file_options.node_id, &local_node_info); record_status = get_node_record(local_conn, config_file_options.node_id, &local_node_info);
/* /*
* Terminate if we can't find the local node record. This is a "fix-the-config" * Terminate if we can't find the local node record. This is a
* situation, not a lot else we can do. * "fix-the-config" situation, not a lot else we can do.
*/ */
if (record_status != RECORD_FOUND) if (record_status != RECORD_FOUND)
{ {
@@ -139,7 +141,8 @@ monitor_bdr(void)
NULL); NULL);
/* /*
* retrieve list of all nodes - we'll need these if the DB connection goes away * retrieve list of all nodes - we'll need these if the DB connection goes
* away
*/ */
get_all_node_records(local_conn, &nodes); get_all_node_records(local_conn, &nodes);
@@ -191,6 +194,7 @@ monitor_bdr(void)
if (cell->node_info->node_status == NODE_STATUS_UP) if (cell->node_info->node_status == NODE_STATUS_UP)
{ {
instr_time node_unreachable_start; instr_time node_unreachable_start;
INSTR_TIME_SET_CURRENT(node_unreachable_start); INSTR_TIME_SET_CURRENT(node_unreachable_start);
cell->node_info->node_status = NODE_STATUS_DOWN; cell->node_info->node_status = NODE_STATUS_DOWN;
@@ -252,7 +256,7 @@ monitor_bdr(void)
} }
} }
loop: loop:
/* emit "still alive" log message at regular intervals, if requested */ /* emit "still alive" log message at regular intervals, if requested */
if (config_file_options.log_status_interval > 0) if (config_file_options.log_status_interval > 0)
@@ -282,8 +286,7 @@ monitor_bdr(void)
if (got_SIGHUP) if (got_SIGHUP)
{ {
/* /*
* if we can reload, then could need to change * if we can reload, then could need to change local_conn
* local_conn
*/ */
if (reload_config(&config_file_options)) if (reload_config(&config_file_options))
{ {
@@ -372,7 +375,10 @@ do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node)
{ {
log_debug("do_bdr_failover() %s", cell->node_info->node_name); log_debug("do_bdr_failover() %s", cell->node_info->node_name);
/* don't attempt to connect to the current monitored node, as that's the one which has failed */ /*
* don't attempt to connect to the current monitored node, as that's
* the one which has failed
*/
if (cell->node_info->node_id == monitored_node->node_id) if (cell->node_info->node_id == monitored_node->node_id)
continue; continue;
@@ -459,11 +465,11 @@ do_bdr_failover(NodeInfoList *nodes, t_node_info *monitored_node)
/* /*
* Create an event record * Create an event record
* *
* If we were able to connect to another node, we'll update the * If we were able to connect to another node, we'll update the event log
* event log there. * there.
* *
* In any case the event notification command will be triggered * In any case the event notification command will be triggered with the
* with the event "bdr_failover" * event "bdr_failover"
*/ */
create_event_notification_extended( create_event_notification_extended(

View File

@@ -24,7 +24,8 @@
#include "repmgrd-physical.h" #include "repmgrd-physical.h"
typedef enum { typedef enum
{
FAILOVER_STATE_UNKNOWN = -1, FAILOVER_STATE_UNKNOWN = -1,
FAILOVER_STATE_NONE, FAILOVER_STATE_NONE,
FAILOVER_STATE_PROMOTED, FAILOVER_STATE_PROMOTED,
@@ -41,7 +42,8 @@ typedef enum {
} FailoverState; } FailoverState;
typedef enum { typedef enum
{
ELECTION_NOT_CANDIDATE = -1, ELECTION_NOT_CANDIDATE = -1,
ELECTION_WON, ELECTION_WON,
ELECTION_LOST, ELECTION_LOST,
@@ -91,14 +93,14 @@ do_physical_node_check(void)
{ {
#ifndef BDR_ONLY #ifndef BDR_ONLY
/* /*
* Check if node record is active - if not, and `failover=automatic`, the node * Check if node record is active - if not, and `failover=automatic`, the
* won't be considered as a promotion candidate; this often happens when * node won't be considered as a promotion candidate; this often happens
* a failed primary is recloned and the node was not re-registered, giving * when a failed primary is recloned and the node was not re-registered,
* the impression failover capability is there when it's not. In this case * giving the impression failover capability is there when it's not. In
* abort with an error and a hint about registering. * this case abort with an error and a hint about registering.
* *
* If `failover=manual`, repmgrd can continue to passively monitor the node, but * If `failover=manual`, repmgrd can continue to passively monitor the
* we should nevertheless issue a warning and the same hint. * node, but we should nevertheless issue a warning and the same hint.
*/ */
if (local_node_info.active == false) if (local_node_info.active == false)
@@ -138,8 +140,8 @@ do_physical_node_check(void)
if (config_file_options.service_promote_command[0] != '\0') if (config_file_options.service_promote_command[0] != '\0')
{ {
/* /*
* if repmgrd executes "service_promote_command" directly, repmgr metadata * if repmgrd executes "service_promote_command" directly,
* won't get updated * repmgr metadata won't get updated
*/ */
log_hint(_("\"service_promote_command\" is set, but can only be executed by \"repmgr standby promote\"")); log_hint(_("\"service_promote_command\" is set, but can only be executed by \"repmgr standby promote\""));
} }
@@ -242,8 +244,8 @@ monitor_streaming_primary(void)
PQfinish(local_conn); PQfinish(local_conn);
/* /*
* as we're monitoring the primary, no point in trying to write * as we're monitoring the primary, no point in trying to
* the event to the database * write the event to the database
* *
* XXX possible pre-action event * XXX possible pre-action event
*/ */
@@ -346,12 +348,12 @@ monitor_streaming_primary(void)
/* /*
* possibly attempt to find another node from cached list * possibly attempt to find another node from cached list check if
* check if there's a new primary - if so add hook for fencing? * there's a new primary - if so add hook for fencing? loop, if
* loop, if starts up check status, switch monitoring mode * starts up check status, switch monitoring mode
*/ */
} }
loop: loop:
/* emit "still alive" log message at regular intervals, if requested */ /* emit "still alive" log message at regular intervals, if requested */
if (config_file_options.log_status_interval > 0) if (config_file_options.log_status_interval > 0)
{ {
@@ -421,9 +423,9 @@ monitor_streaming_standby(void)
log_debug("monitor_streaming_standby()"); log_debug("monitor_streaming_standby()");
/* /*
* If no upstream node id is specified in the metadata, we'll try * If no upstream node id is specified in the metadata, we'll try and
* and determine the current cluster primary in the assumption we * determine the current cluster primary in the assumption we should
* should connect to that by default. * connect to that by default.
*/ */
if (local_node_info.upstream_node_id == UNKNOWN_NODE_ID) if (local_node_info.upstream_node_id == UNKNOWN_NODE_ID)
{ {
@@ -431,9 +433,9 @@ monitor_streaming_standby(void)
/* /*
* Terminate if there doesn't appear to be an active cluster primary. * Terminate if there doesn't appear to be an active cluster primary.
* There could be one or more nodes marked as inactive primaries, and one * There could be one or more nodes marked as inactive primaries, and
* of them could actually be a primary, but we can't sensibly monitor * one of them could actually be a primary, but we can't sensibly
* in that state. * monitor in that state.
*/ */
if (local_node_info.upstream_node_id == NODE_NOT_FOUND) if (local_node_info.upstream_node_id == NODE_NOT_FOUND)
{ {
@@ -446,9 +448,9 @@ monitor_streaming_standby(void)
record_status = get_node_record(local_conn, local_node_info.upstream_node_id, &upstream_node_info); record_status = get_node_record(local_conn, local_node_info.upstream_node_id, &upstream_node_info);
/* /*
* Terminate if we can't find the record for the node we're supposed * Terminate if we can't find the record for the node we're supposed to
* to monitor. This is a "fix-the-config" situation, not a lot else we * monitor. This is a "fix-the-config" situation, not a lot else we can
* can do. * do.
*/ */
if (record_status == RECORD_NOT_FOUND) if (record_status == RECORD_NOT_FOUND)
{ {
@@ -473,8 +475,8 @@ monitor_streaming_standby(void)
/* /*
* Upstream node must be running at repmgrd startup. * Upstream node must be running at repmgrd startup.
* *
* We could possibly have repmgrd skip to degraded monitoring mode until it * We could possibly have repmgrd skip to degraded monitoring mode until
* comes up, but there doesn't seem to be much point in doing that. * it comes up, but there doesn't seem to be much point in doing that.
*/ */
if (PQstatus(upstream_conn) != CONNECTION_OK) if (PQstatus(upstream_conn) != CONNECTION_OK)
{ {
@@ -486,15 +488,18 @@ monitor_streaming_standby(void)
exit(ERR_DB_CONN); exit(ERR_DB_CONN);
} }
/* refresh upstream node record from upstream node, so it's as up-to-date as possible */ /*
* refresh upstream node record from upstream node, so it's as up-to-date
* as possible
*/
record_status = get_node_record(upstream_conn, upstream_node_info.node_id, &upstream_node_info); record_status = get_node_record(upstream_conn, upstream_node_info.node_id, &upstream_node_info);
if (upstream_node_info.type == STANDBY) if (upstream_node_info.type == STANDBY)
{ {
/* /*
* Currently cascaded standbys need to be able to connect to the primary. * Currently cascaded standbys need to be able to connect to the
* We could possibly add a limited connection mode for cases where this isn't * primary. We could possibly add a limited connection mode for cases
* possible. * where this isn't possible.
*/ */
primary_conn = establish_primary_db_connection(upstream_conn, false); primary_conn = establish_primary_db_connection(upstream_conn, false);
@@ -518,6 +523,7 @@ monitor_streaming_standby(void)
if (startup_event_logged == false) if (startup_event_logged == false)
{ {
PQExpBufferData event_details; PQExpBufferData event_details;
initPQExpBuffer(&event_details); initPQExpBuffer(&event_details);
appendPQExpBuffer(&event_details, appendPQExpBuffer(&event_details,
@@ -617,7 +623,10 @@ monitor_streaming_standby(void)
failover_done = do_upstream_standby_failover(); failover_done = do_upstream_standby_failover();
} }
/* XXX it's possible it will make sense to return in all cases to restart monitoring */ /*
* XXX it's possible it will make sense to return in all
* cases to restart monitoring
*/
if (failover_done == true) if (failover_done == true)
{ {
primary_node_id = get_primary_node_id(local_conn); primary_node_id = get_primary_node_id(local_conn);
@@ -641,10 +650,13 @@ monitor_streaming_standby(void)
if (PQstatus(upstream_conn) == CONNECTION_OK) if (PQstatus(upstream_conn) == CONNECTION_OK)
{ {
// XXX check here if upstream is still primary /* XXX check here if upstream is still primary */
// -> will be a problem if another node was promoted in the meantime /*
// and upstream is now former primary * -> will be a problem if another node was promoted in
// XXX scan other nodes to see if any has become primary * the meantime
*/
/* and upstream is now former primary */
/* XXX scan other nodes to see if any has become primary */
upstream_node_info.node_status = NODE_STATUS_UP; upstream_node_info.node_status = NODE_STATUS_UP;
monitoring_state = MS_NORMAL; monitoring_state = MS_NORMAL;
@@ -684,8 +696,8 @@ monitor_streaming_standby(void)
else else
{ {
/* /*
* unable to connect to former primary - check if another node has * unable to connect to former primary - check if another node
* been promoted * has been promoted
*/ */
NodeInfoListCell *cell; NodeInfoListCell *cell;
@@ -697,12 +709,13 @@ monitor_streaming_standby(void)
log_notice(_("local node is primary, checking local node record")); log_notice(_("local node is primary, checking local node record"));
/* /*
* There may be a delay between the node being promoted and the local * There may be a delay between the node being promoted
* record being updated, so if the node record still shows it as a * and the local record being updated, so if the node
* standby, do nothing, we'll catch the update during the next loop. * record still shows it as a standby, do nothing, we'll
* (e.g. node was manually * catch the update during the next loop. (e.g. node was
* promoted) we'll do nothing, as the repmgr metadata is now out-of-sync. * manually promoted) we'll do nothing, as the repmgr
* If it does get fixed, we'll catch it here on a future iteration. * metadata is now out-of-sync. If it does get fixed,
* we'll catch it here on a future iteration.
*/ */
/* refresh own internal node record */ /* refresh own internal node record */
@@ -769,7 +782,7 @@ monitor_streaming_standby(void)
} }
} }
loop: loop:
/* emit "still alive" log message at regular intervals, if requested */ /* emit "still alive" log message at regular intervals, if requested */
if (config_file_options.log_status_interval > 0) if (config_file_options.log_status_interval > 0)
@@ -779,6 +792,7 @@ monitor_streaming_standby(void)
if (log_status_interval_elapsed >= config_file_options.log_status_interval) if (log_status_interval_elapsed >= config_file_options.log_status_interval)
{ {
PQExpBufferData monitoring_summary; PQExpBufferData monitoring_summary;
initPQExpBuffer(&monitoring_summary); initPQExpBuffer(&monitoring_summary);
appendPQExpBuffer( appendPQExpBuffer(
@@ -827,6 +841,7 @@ monitor_streaming_standby(void)
if (update_node_record_set_active(primary_conn, local_node_info.node_id, false) == true) if (update_node_record_set_active(primary_conn, local_node_info.node_id, false) == true)
{ {
PQExpBufferData event_details; PQExpBufferData event_details;
initPQExpBuffer(&event_details); initPQExpBuffer(&event_details);
local_node_info.active = false; local_node_info.active = false;
@@ -853,7 +868,8 @@ monitor_streaming_standby(void)
} }
} }
} }
else { else
{
if (local_node_info.active == false) if (local_node_info.active == false)
{ {
if (PQstatus(primary_conn) == CONNECTION_OK) if (PQstatus(primary_conn) == CONNECTION_OK)
@@ -861,6 +877,7 @@ monitor_streaming_standby(void)
if (update_node_record_set_active(primary_conn, local_node_info.node_id, true) == true) if (update_node_record_set_active(primary_conn, local_node_info.node_id, true) == true)
{ {
PQExpBufferData event_details; PQExpBufferData event_details;
initPQExpBuffer(&event_details); initPQExpBuffer(&event_details);
local_node_info.active = true; local_node_info.active = true;
@@ -954,8 +971,8 @@ do_primary_failover(void)
best_candidate = poll_best_candidate(&standby_nodes); best_candidate = poll_best_candidate(&standby_nodes);
/* /*
* this can occur in a tie-break situation, where this node establishes * this can occur in a tie-break situation, where this node
* it is the best candidate * establishes it is the best candidate
*/ */
if (best_candidate->node_id == local_node_info.node_id) if (best_candidate->node_id == local_node_info.node_id)
{ {
@@ -1012,8 +1029,8 @@ do_primary_failover(void)
/* /*
* node has decided it is a follower, so will await notification * node has decided it is a follower, so will await notification from the
* from the candidate that it has promoted itself and can be followed * candidate that it has promoted itself and can be followed
*/ */
if (failover_state == FAILOVER_STATE_WAITING_NEW_PRIMARY) if (failover_state == FAILOVER_STATE_WAITING_NEW_PRIMARY)
{ {
@@ -1060,6 +1077,7 @@ do_primary_failover(void)
else else
{ {
PQExpBufferData event_details; PQExpBufferData event_details;
initPQExpBuffer(&event_details); initPQExpBuffer(&event_details);
appendPQExpBuffer(&event_details, appendPQExpBuffer(&event_details,
_("node %i is in manual failover mode and is now disconnected from streaming replication"), _("node %i is in manual failover mode and is now disconnected from streaming replication"),
@@ -1072,7 +1090,11 @@ do_primary_failover(void)
&config_file_options, &config_file_options,
local_node_info.node_id, local_node_info.node_id,
"standby_disconnect_manual", "standby_disconnect_manual",
/* here "true" indicates the action has occurred as expected */
/*
* here "true" indicates the action has occurred as
* expected
*/
true, true,
event_details.data); event_details.data);
PQfinish(new_primary_conn); PQfinish(new_primary_conn);
@@ -1092,7 +1114,7 @@ do_primary_failover(void)
} }
} }
switch(failover_state) switch (failover_state)
{ {
case FAILOVER_STATE_PROMOTED: case FAILOVER_STATE_PROMOTED:
log_debug("failover state is PROMOTED"); log_debug("failover state is PROMOTED");
@@ -1112,7 +1134,10 @@ do_primary_failover(void)
case FAILOVER_STATE_PRIMARY_REAPPEARED: case FAILOVER_STATE_PRIMARY_REAPPEARED:
log_debug("failover state is PRIMARY_REAPPEARED"); log_debug("failover state is PRIMARY_REAPPEARED");
/* notify siblings that they should resume following the original primary */ /*
* notify siblings that they should resume following the original
* primary
*/
notify_followers(&standby_nodes, upstream_node_info.node_id); notify_followers(&standby_nodes, upstream_node_info.node_id);
/* we no longer care about our former siblings */ /* we no longer care about our former siblings */
@@ -1151,6 +1176,7 @@ do_primary_failover(void)
return false; return false;
case FAILOVER_STATE_FOLLOW_FAIL: case FAILOVER_STATE_FOLLOW_FAIL:
/* /*
* for whatever reason we were unable to follow the new primary - * for whatever reason we were unable to follow the new primary -
* continue monitoring in degraded state * continue monitoring in degraded state
@@ -1229,11 +1255,14 @@ update_monitoring_history(void)
if (primary_last_wal_location >= replication_info.last_wal_receive_lsn) if (primary_last_wal_location >= replication_info.last_wal_receive_lsn)
{ {
replication_lag_bytes = (long long unsigned int)(primary_last_wal_location - replication_info.last_wal_receive_lsn); replication_lag_bytes = (long long unsigned int) (primary_last_wal_location - replication_info.last_wal_receive_lsn);
} }
else else
{ {
/* This should never happen, but in case it does set replication lag to zero */ /*
* This should never happen, but in case it does set replication lag
* to zero
*/
log_warning("primary xlog (%X/%X) location appears less than standby receive location (%X/%X)", log_warning("primary xlog (%X/%X) location appears less than standby receive location (%X/%X)",
format_lsn(primary_last_wal_location), format_lsn(primary_last_wal_location),
format_lsn(replication_info.last_wal_receive_lsn)); format_lsn(replication_info.last_wal_receive_lsn));
@@ -1286,9 +1315,10 @@ do_upstream_standby_failover(void)
log_error(_("unable to retrieve primary node record")); log_error(_("unable to retrieve primary node record"));
return false; return false;
} }
/* /*
* Verify that we can still talk to the cluster primary, even though * Verify that we can still talk to the cluster primary, even though the
* the node's upstream is not available * node's upstream is not available
*/ */
check_connection(&primary_node_info, &primary_conn); check_connection(&primary_node_info, &primary_conn);
@@ -1344,9 +1374,9 @@ do_upstream_standby_failover(void)
log_error("%s", event_details.data); log_error("%s", event_details.data);
/* It may not possible to write to the event notification /*
* table but we should be able to generate an external notification * It may not possible to write to the event notification table but we
* if required. * should be able to generate an external notification if required.
*/ */
create_event_notification( create_event_notification(
primary_conn, primary_conn,
@@ -1390,8 +1420,9 @@ do_upstream_standby_failover(void)
record_status = get_node_record(primary_conn, local_node_info.node_id, &local_node_info); record_status = get_node_record(primary_conn, local_node_info.node_id, &local_node_info);
/* /*
* highly improbable this will happen, but in case we're unable to retrieve * highly improbable this will happen, but in case we're unable to
* our node record from the primary, update it ourselves, and hope for the best * retrieve our node record from the primary, update it ourselves, and
* hope for the best
*/ */
if (record_status != RECORD_FOUND) if (record_status != RECORD_FOUND)
{ {
@@ -1434,8 +1465,8 @@ promote_self(void)
/* /*
* optionally add a delay before promoting the standby; this is mainly * optionally add a delay before promoting the standby; this is mainly
* useful for testing (e.g. for reappearance of the original primary) * useful for testing (e.g. for reappearance of the original primary) and
* and is not documented. * is not documented.
*/ */
if (config_file_options.promote_delay > 0) if (config_file_options.promote_delay > 0)
{ {
@@ -1467,15 +1498,15 @@ promote_self(void)
r = system(promote_command); r = system(promote_command);
/* connection should stay up, but check just in case */ /* connection should stay up, but check just in case */
if(PQstatus(local_conn) != CONNECTION_OK) if (PQstatus(local_conn) != CONNECTION_OK)
{ {
local_conn = establish_db_connection(local_node_info.conninfo, true); local_conn = establish_db_connection(local_node_info.conninfo, true);
/* assume node failed */ /* assume node failed */
if(PQstatus(local_conn) != CONNECTION_OK) if (PQstatus(local_conn) != CONNECTION_OK)
{ {
log_error(_("unable to reconnect to local node")); log_error(_("unable to reconnect to local node"));
// XXX handle this /* XXX handle this */
return FAILOVER_STATE_LOCAL_NODE_FAILURE; return FAILOVER_STATE_LOCAL_NODE_FAILURE;
} }
} }
@@ -1507,10 +1538,10 @@ promote_self(void)
termPQExpBuffer(&event_details); termPQExpBuffer(&event_details);
//primary_conn = NULL; /* primary_conn = NULL; */
// XXX handle this! /* XXX handle this! */
// -> we'll need to let the other nodes know too.... /* -> we'll need to let the other nodes know too.... */
/* no failover occurred but we'll want to restart connections */ /* no failover occurred but we'll want to restart connections */
return FAILOVER_STATE_PRIMARY_REAPPEARED; return FAILOVER_STATE_PRIMARY_REAPPEARED;
@@ -1610,8 +1641,7 @@ poll_best_candidate(NodeInfoList *standby_nodes)
* cases we could end up with two candidate nodes, so they should each * cases we could end up with two candidate nodes, so they should each
* come to the same conclusion. * come to the same conclusion.
* *
* XXX check there are no cases where the standby node's LSN is * XXX check there are no cases where the standby node's LSN is not set
* not set
*/ */
for (cell = standby_nodes->head; cell; cell = cell->next) for (cell = standby_nodes->head; cell; cell = cell->next)
{ {
@@ -1709,7 +1739,7 @@ follow_new_primary(int new_primary_id)
return FAILOVER_STATE_FOLLOW_FAIL; return FAILOVER_STATE_FOLLOW_FAIL;
} }
// XXX check if new_primary_id == failed_primary.node_id? /* XXX check if new_primary_id == failed_primary.node_id? */
if (log_type == REPMGR_STDERR && *config_file_options.log_file) if (log_type == REPMGR_STDERR && *config_file_options.log_file)
{ {
@@ -1721,6 +1751,7 @@ follow_new_primary(int new_primary_id)
if (PQstatus(upstream_conn) == CONNECTION_OK) if (PQstatus(upstream_conn) == CONNECTION_OK)
{ {
RecoveryType primary_recovery_type = get_recovery_type(upstream_conn); RecoveryType primary_recovery_type = get_recovery_type(upstream_conn);
if (primary_recovery_type == RECTYPE_PRIMARY) if (primary_recovery_type == RECTYPE_PRIMARY)
{ {
new_primary_ok = true; new_primary_ok = true;
@@ -1739,8 +1770,8 @@ follow_new_primary(int new_primary_id)
} }
/* /*
* disconnect from local node, as follow operation will result in * disconnect from local node, as follow operation will result in a server
* a server restart * restart
*/ */
PQfinish(local_conn); PQfinish(local_conn);
@@ -1762,24 +1793,27 @@ follow_new_primary(int new_primary_id)
if (r != 0) if (r != 0)
{ {
PGconn *old_primary_conn; PGconn *old_primary_conn;
/* /*
* The follow action could still fail due to the original primary reappearing * The follow action could still fail due to the original primary
* before the candidate could promote itself ("repmgr standby follow" will * reappearing before the candidate could promote itself ("repmgr
* refuse to promote another node if the primary is available). However * standby follow" will refuse to promote another node if the primary
* the new primary will only instruct use to follow it after it's successfully * is available). However the new primary will only instruct use to
* promoted itself, so that very likely won't be the reason for the failure. * follow it after it's successfully promoted itself, so that very
* likely won't be the reason for the failure.
* *
* *
* TODO: check the new primary too - we could have a split-brain * TODO: check the new primary too - we could have a split-brain
* situation where the old primary reappeared just after the new * situation where the old primary reappeared just after the new one
* one promoted itself. * promoted itself.
*/ */
old_primary_conn = establish_db_connection(failed_primary.conninfo, false); old_primary_conn = establish_db_connection(failed_primary.conninfo, false);
if (PQstatus(old_primary_conn) == CONNECTION_OK) if (PQstatus(old_primary_conn) == CONNECTION_OK)
{ {
// XXX add event notifications /* XXX add event notifications */
RecoveryType upstream_recovery_type = get_recovery_type(old_primary_conn); RecoveryType upstream_recovery_type = get_recovery_type(old_primary_conn);
PQfinish(old_primary_conn); PQfinish(old_primary_conn);
if (upstream_recovery_type == RECTYPE_PRIMARY) if (upstream_recovery_type == RECTYPE_PRIMARY)
@@ -1842,7 +1876,7 @@ follow_new_primary(int new_primary_id)
static const char * static const char *
_print_voting_status(NodeVotingStatus voting_status) _print_voting_status(NodeVotingStatus voting_status)
{ {
switch(voting_status) switch (voting_status)
{ {
case VS_NO_VOTE: case VS_NO_VOTE:
return "NO VOTE"; return "NO VOTE";
@@ -1863,7 +1897,7 @@ _print_voting_status(NodeVotingStatus voting_status)
static const char * static const char *
_print_election_result(ElectionResult result) _print_election_result(ElectionResult result)
{ {
switch(result) switch (result)
{ {
case ELECTION_NOT_CANDIDATE: case ELECTION_NOT_CANDIDATE:
return "NOT CANDIDATE"; return "NOT CANDIDATE";
@@ -1898,8 +1932,8 @@ do_election(void)
int visible_nodes = 1; int visible_nodes = 1;
/* /*
* get voting status from shared memory - should be one of "VS_NO_VOTE" * get voting status from shared memory - should be one of "VS_NO_VOTE" or
* or "VS_VOTE_REQUEST_RECEIVED". If VS_NO_VOTE, we declare ourselves as * "VS_VOTE_REQUEST_RECEIVED". If VS_NO_VOTE, we declare ourselves as
* candidate and initiate the voting process. * candidate and initiate the voting process.
*/ */
NodeVotingStatus voting_status; NodeVotingStatus voting_status;
@@ -1910,13 +1944,13 @@ do_election(void)
bool other_node_is_ahead = false; bool other_node_is_ahead = false;
/* /*
* Check if at least one server in the primary's location is visible; * Check if at least one server in the primary's location is visible; if
* if not we'll assume a network split between this node and the primary * not we'll assume a network split between this node and the primary
* location, and not promote any standby. * location, and not promote any standby.
* *
* NOTE: this function is only ever called by standbys attached to the current * NOTE: this function is only ever called by standbys attached to the
* (unreachable) primary, so "upstream_node_info" will always contain the * current (unreachable) primary, so "upstream_node_info" will always
* primary node record. * contain the primary node record.
*/ */
bool primary_location_seen = false; bool primary_location_seen = false;
@@ -1968,10 +2002,10 @@ do_election(void)
} }
/* /*
* Here we mark ourselves as candidate, so any further vote requests * Here we mark ourselves as candidate, so any further vote requests are
* are rejected. However it's possible another node has done the * rejected. However it's possible another node has done the same thing,
* same thing, so when announcing ourselves as candidate to the other * so when announcing ourselves as candidate to the other nodes, we'll
* nodes, we'll check for that and withdraw our candidature. * check for that and withdraw our candidature.
*/ */
electoral_term = set_voting_status_initiated(local_conn); electoral_term = set_voting_status_initiated(local_conn);
@@ -2007,15 +2041,17 @@ do_election(void)
} }
/* /*
* tell the other node we're candidate - if the node has already declared * tell the other node we're candidate - if the node has already
* itself, we withdraw * declared itself, we withdraw
* *
* XXX check for situations where more than one node could end up as candidate? * XXX check for situations where more than one node could end up as
* candidate?
* *
* XXX note it's possible some nodes accepted our candidature before we * XXX note it's possible some nodes accepted our candidature before
* found out about the other candidate, check what happens in that situation * we found out about the other candidate, check what happens in that
* -> other node will have info from all the nodes, even if not the vote, * situation -> other node will have info from all the nodes, even if
* so it should be able to determine the best node anyway * not the vote, so it should be able to determine the best node
* anyway
*/ */
if (announce_candidature(cell->node_info->conn, &local_node_info, cell->node_info, electoral_term) == false) if (announce_candidature(cell->node_info->conn, &local_node_info, cell->node_info, electoral_term) == false)
@@ -2028,8 +2064,8 @@ do_election(void)
} }
/* /*
* see if the node is in the primary's location (but skip the check * see if the node is in the primary's location (but skip the check if
* if we've seen * we've seen
*/ */
if (primary_location_seen == false) if (primary_location_seen == false)
{ {
@@ -2040,7 +2076,7 @@ do_election(void)
} }
cell->node_info->node_status = NODE_STATUS_UP; cell->node_info->node_status = NODE_STATUS_UP;
visible_nodes ++; visible_nodes++;
} }
if (other_node_is_candidate == true) if (other_node_is_candidate == true)

View File

@@ -46,7 +46,7 @@ PGconn *local_conn = NULL;
/* Collate command line errors here for friendlier reporting */ /* Collate command line errors here for friendlier reporting */
static ItemList cli_errors = { NULL, NULL }; static ItemList cli_errors = {NULL, NULL};
bool startup_event_logged = false; bool startup_event_logged = false;
@@ -54,7 +54,7 @@ MonitoringState monitoring_state = MS_NORMAL;
instr_time degraded_monitoring_start; instr_time degraded_monitoring_start;
static void close_connections(void); static void close_connections(void);
void (*_close_connections)(void) = NULL; void (*_close_connections) (void) = NULL;
/* /*
* Record receipt of SIGHUP; will cause configuration file to be reread * Record receipt of SIGHUP; will cause configuration file to be reread
@@ -116,7 +116,7 @@ main(int argc, char **argv)
set_progname(argv[0]); set_progname(argv[0]);
srand ( time(NULL) ); srand(time(NULL));
/* Disallow running as root */ /* Disallow running as root */
if (geteuid() == 0) if (geteuid() == 0)
@@ -154,9 +154,11 @@ main(int argc, char **argv)
exit(SUCCESS); exit(SUCCESS);
case 'V': case 'V':
/* /*
* in contrast to repmgr3 and earlier, we only display the repmgr version * in contrast to repmgr3 and earlier, we only display the
* as it's not specific to a particular PostgreSQL version * repmgr version as it's not specific to a particular
* PostgreSQL version
*/ */
printf("%s %s\n", progname(), REPMGR_VERSION); printf("%s %s\n", progname(), REPMGR_VERSION);
exit(SUCCESS); exit(SUCCESS);
@@ -183,6 +185,7 @@ main(int argc, char **argv)
case 'L': case 'L':
{ {
int detected_cli_log_level = detect_log_level(optarg); int detected_cli_log_level = detect_log_level(optarg);
if (detected_cli_log_level != -1) if (detected_cli_log_level != -1)
{ {
strncpy(cli_log_level, optarg, MAXLEN); strncpy(cli_log_level, optarg, MAXLEN);
@@ -190,6 +193,7 @@ main(int argc, char **argv)
else else
{ {
PQExpBufferData invalid_log_level; PQExpBufferData invalid_log_level;
initPQExpBuffer(&invalid_log_level); initPQExpBuffer(&invalid_log_level);
appendPQExpBuffer(&invalid_log_level, appendPQExpBuffer(&invalid_log_level,
_("invalid log level \"%s\" provided"), _("invalid log level \"%s\" provided"),
@@ -223,6 +227,7 @@ main(int argc, char **argv)
} }
startup_event_logged = false; startup_event_logged = false;
/* /*
* Tell the logger we're a daemon - this will ensure any output logged * Tell the logger we're a daemon - this will ensure any output logged
* before the logger is initialized will be formatted correctly * before the logger is initialized will be formatted correctly
@@ -230,15 +235,19 @@ main(int argc, char **argv)
logger_output_mode = OM_DAEMON; logger_output_mode = OM_DAEMON;
/* /*
* Parse the configuration file, if provided. If no configuration file * Parse the configuration file, if provided. If no configuration file was
* was provided, or one was but was incomplete, parse_config() will * provided, or one was but was incomplete, parse_config() will abort
* abort anyway, with an appropriate message. * anyway, with an appropriate message.
*/ */
load_config(config_file, verbose, false, &config_file_options, argv[0]); load_config(config_file, verbose, false, &config_file_options, argv[0]);
/* Some configuration file items can be overriden by command line options */ /* Some configuration file items can be overriden by command line options */
/* Command-line parameter -L/--log-level overrides any setting in config file*/
/*
* Command-line parameter -L/--log-level overrides any setting in config
* file
*/
if (*cli_log_level != '\0') if (*cli_log_level != '\0')
{ {
strncpy(config_file_options.log_level, cli_log_level, MAXLEN); strncpy(config_file_options.log_level, cli_log_level, MAXLEN);
@@ -304,8 +313,8 @@ main(int argc, char **argv)
* point, but we'll skip that and assume the presence of a node record * point, but we'll skip that and assume the presence of a node record
* means we're dealing with a supported installation. * means we're dealing with a supported installation.
* *
* The absence of a node record will also indicate that either the node * The absence of a node record will also indicate that either the node or
* or repmgr has not been properly configured. * repmgr has not been properly configured.
*/ */
/* Retrieve record for this node from the local database */ /* Retrieve record for this node from the local database */
@@ -368,7 +377,7 @@ start_monitoring(void)
local_node_info.node_name, local_node_info.node_name,
local_node_info.node_id); local_node_info.node_id);
while(true) while (true)
{ {
switch (local_node_info.type) switch (local_node_info.type)
{ {
@@ -400,11 +409,13 @@ update_registration(PGconn *conn)
{ {
bool success = update_node_record_conn_priority(local_conn, bool success = update_node_record_conn_priority(local_conn,
&config_file_options); &config_file_options);
// check values have actually changed
/* check values have actually changed */
if (success == false) if (success == false)
{ {
PQExpBufferData errmsg; PQExpBufferData errmsg;
initPQExpBuffer(&errmsg); initPQExpBuffer(&errmsg);
appendPQExpBuffer(&errmsg, appendPQExpBuffer(&errmsg,
@@ -635,10 +646,9 @@ try_reconnect(t_node_info *node_info)
log_notice(_("node has recovered, reconnecting")); log_notice(_("node has recovered, reconnecting"));
/* /*
* XXX we should also handle the case where node is pingable * XXX we should also handle the case where node is pingable but
* but connection denied due to connection exhaustion * connection denied due to connection exhaustion - fall back to
* - fall back to degraded monitoring? * degraded monitoring? - make that configurable
* - make that configurable
*/ */
conn = establish_db_connection(node_info->conninfo, false); conn = establish_db_connection(node_info->conninfo, false);
if (PQstatus(conn) == CONNECTION_OK) if (PQstatus(conn) == CONNECTION_OK)
@@ -680,14 +690,14 @@ calculate_elapsed(instr_time start_time)
INSTR_TIME_SUBTRACT(current_time, start_time); INSTR_TIME_SUBTRACT(current_time, start_time);
return (int)INSTR_TIME_GET_DOUBLE(current_time); return (int) INSTR_TIME_GET_DOUBLE(current_time);
} }
const char * const char *
print_monitoring_state(MonitoringState monitoring_state) print_monitoring_state(MonitoringState monitoring_state)
{ {
switch(monitoring_state) switch (monitoring_state)
{ {
case MS_NORMAL: case MS_NORMAL:
return "normal"; return "normal";
@@ -730,5 +740,3 @@ terminate(int retval)
exit(retval); exit(retval);
} }

View File

@@ -76,7 +76,7 @@ maxpath_snprintf(char *str, const char *format,...)
void void
append_where_clause(PQExpBufferData *where_clause, const char *format, ...) append_where_clause(PQExpBufferData *where_clause, const char *format,...)
{ {
va_list arglist; va_list arglist;
char stringbuf[MAXLEN]; char stringbuf[MAXLEN];
@@ -85,7 +85,7 @@ append_where_clause(PQExpBufferData *where_clause, const char *format, ...)
(void) xvsnprintf(stringbuf, MAXLEN, format, arglist); (void) xvsnprintf(stringbuf, MAXLEN, format, arglist);
va_end(arglist); va_end(arglist);
if(where_clause->data[0] == '\0') if (where_clause->data[0] == '\0')
{ {
appendPQExpBuffer(where_clause, appendPQExpBuffer(where_clause,
" WHERE "); " WHERE ");
@@ -110,7 +110,7 @@ item_list_append(ItemList *item_list, const char *message)
void void
item_list_append_format(ItemList *item_list, const char *format, ...) item_list_append_format(ItemList *item_list, const char *format,...)
{ {
ItemListCell *cell; ItemListCell *cell;
va_list arglist; va_list arglist;
@@ -166,7 +166,7 @@ key_value_list_set(KeyValueList *item_list, const char *key, const char *value)
} }
void void
key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value, ...) key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value,...)
{ {
KeyValueListCell *cell = NULL; KeyValueListCell *cell = NULL;
va_list arglist; va_list arglist;
@@ -205,7 +205,7 @@ key_value_list_set_format(KeyValueList *item_list, const char *key, const char *
void void
key_value_list_set_output_mode (KeyValueList *item_list, const char *key, OutputMode mode) key_value_list_set_output_mode(KeyValueList *item_list, const char *key, OutputMode mode)
{ {
KeyValueListCell *cell = NULL; KeyValueListCell *cell = NULL;
@@ -250,7 +250,7 @@ check_status_list_set(CheckStatusList *list, const char *item, CheckStatus statu
void void
check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details, ...) check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details,...)
{ {
CheckStatusListCell *cell; CheckStatusListCell *cell;
va_list arglist; va_list arglist;
@@ -436,7 +436,7 @@ parse_follow_command(char *parsed_command, char *template, int node_id)
end_ptr = parsed_command + MAXPGPATH - 1; end_ptr = parsed_command + MAXPGPATH - 1;
*end_ptr = '\0'; *end_ptr = '\0';
for(src_ptr = template; *src_ptr; src_ptr++) for (src_ptr = template; *src_ptr; src_ptr++)
{ {
if (*src_ptr == '%') if (*src_ptr == '%')
{ {

View File

@@ -33,14 +33,16 @@
#define MAXLEN_STR STR(MAXLEN) #define MAXLEN_STR STR(MAXLEN)
typedef enum { typedef enum
{
CHECK_STATUS_OK = 0, CHECK_STATUS_OK = 0,
CHECK_STATUS_WARNING, CHECK_STATUS_WARNING,
CHECK_STATUS_CRITICAL, CHECK_STATUS_CRITICAL,
CHECK_STATUS_UNKNOWN CHECK_STATUS_UNKNOWN
} CheckStatus; } CheckStatus;
typedef enum { typedef enum
{
OM_NOT_SET = -1, OM_NOT_SET = -1,
OM_TEXT, OM_TEXT,
OM_CSV, OM_CSV,
@@ -100,62 +102,58 @@ maxpath_snprintf(char *str, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern void extern void
item_list_append(ItemList *item_list, const char *message); item_list_append(ItemList *item_list, const char *message);
extern void extern void
item_list_append_format(ItemList *item_list, const char *format, ...) item_list_append_format(ItemList *item_list, const char *format,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern void extern void
item_list_free(ItemList *item_list); item_list_free(ItemList *item_list);
extern void extern void
key_value_list_set(KeyValueList *item_list, const char *key, const char *value); key_value_list_set(KeyValueList *item_list, const char *key, const char *value);
extern void extern void
key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value, ...) key_value_list_set_format(KeyValueList *item_list, const char *key, const char *value,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 3, 4)));
extern void extern void
key_value_list_set_output_mode(KeyValueList *item_list, const char *key, OutputMode mode); key_value_list_set_output_mode(KeyValueList *item_list, const char *key, OutputMode mode);
extern const char * extern const char *key_value_list_get(KeyValueList *item_list, const char *key);
key_value_list_get(KeyValueList *item_list, const char *key);
extern void extern void
key_value_list_free(KeyValueList *item_list); key_value_list_free(KeyValueList *item_list);
extern void extern void
check_status_list_set(CheckStatusList *list, const char *item, CheckStatus status, const char *details); check_status_list_set(CheckStatusList *list, const char *item, CheckStatus status, const char *details);
extern void extern void
check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details, ...) check_status_list_set_format(CheckStatusList *list, const char *item, CheckStatus status, const char *details,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 4, 5)));
extern void extern void
check_status_list_free(CheckStatusList *list); check_status_list_free(CheckStatusList *list);
extern const char * output_check_status(CheckStatus status); extern const char *output_check_status(CheckStatus status);
extern char * extern char *escape_recovery_conf_value(const char *src);
escape_recovery_conf_value(const char *src);
extern char * extern char *escape_string(PGconn *conn, const char *string);
escape_string(PGconn *conn, const char *string);
extern void extern void
append_where_clause(PQExpBufferData *where_clause, const char *clause, ...) append_where_clause(PQExpBufferData *where_clause, const char *clause,...)
__attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3))); __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
extern char * extern char *string_skip_prefix(const char *prefix, char *string);
string_skip_prefix(const char *prefix, char *string);
extern char extern char
*string_remove_trailing_newlines(char *string); *string_remove_trailing_newlines(char *string);
extern char *trim(char *s); extern char *trim(char *s);
extern void extern void
parse_follow_command(char *parsed_command, char *template, int node_id); parse_follow_command(char *parsed_command, char *template, int node_id);
#endif /* _STRUTIL_H_ */ #endif /* _STRUTIL_H_ */

View File

@@ -18,7 +18,8 @@
#ifndef _VOTING_H_ #ifndef _VOTING_H_
#define _VOTING_H_ #define _VOTING_H_
typedef enum { typedef enum
{
VS_UNKNOWN = -1, VS_UNKNOWN = -1,
VS_NO_VOTE, VS_NO_VOTE,
VS_VOTE_REQUEST_RECEIVED, VS_VOTE_REQUEST_RECEIVED,