poke it around until it works less badly

This commit is contained in:
Ian Barwick
2017-06-29 09:35:09 +09:00
parent fa86fe4ad8
commit 3514e20367
7 changed files with 81 additions and 7 deletions

View File

@@ -16,6 +16,10 @@ static bool config_file_provided = false;
bool config_file_found = false;
static void _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *warning_list);
static bool parse_bool(const char *s,
const char *config_item,
ItemList *error_list);
static void _parse_line(char *buf, char *name, char *value);
static void parse_event_notifications_list(t_configuration_options *options, const char *arg);
static void tablespace_list_append(t_configuration_options *options, const char *arg);
@@ -774,7 +778,7 @@ repmgr_atoi(const char *value, const char *config_item, ItemList *error_list, in
*
* https://www.postgresql.org/docs/current/static/config-setting.html
*/
bool
static bool
parse_bool(const char *s, const char *config_item, ItemList *error_list)
{
PQExpBufferData errors;

View File

@@ -158,9 +158,6 @@ int repmgr_atoi(const char *s,
ItemList *error_list,
int minval);
bool parse_bool(const char *s,
const char *config_item,
ItemList *error_list);
bool parse_pg_basebackup_options(const char *pg_basebackup_options,
t_basebackup_options *backup_options,

View File

@@ -2364,6 +2364,32 @@ set_voting_status_initiated(PGconn *conn)
}
bool
announce_candidature(PGconn *conn, t_node_info *this_node, t_node_info *other_node)
{
PQExpBufferData query;
PGresult *res;
bool retval;
initPQExpBuffer(&query);
appendPQExpBuffer(&query,
"SELECT repmgr.other_node_is_candidate(%i)",
this_node->node_id);
res = PQexec(conn, query.data);
termPQExpBuffer(&query);
retval = (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
? true
: false;
PQclear(res);
return retval;
}
/* ============================ */
/* replication status functions */
/* ============================ */

View File

@@ -248,7 +248,7 @@ bool is_server_available(const char *conninfo);
NodeVotingStatus get_voting_status(PGconn *conn);
int request_vote(PGconn *conn, t_node_info *this_node, t_node_info *other_node, XLogRecPtr last_wal_receive_lsn);
void set_voting_status_initiated(PGconn *conn);
bool announce_candidature(PGconn *conn, t_node_info *this_node, t_node_info *other_node);
/* replication status functions */

View File

@@ -51,3 +51,8 @@ CREATE FUNCTION set_voting_status_initiated()
RETURNS VOID
AS '$libdir/repmgr', 'set_voting_status_initiated'
LANGUAGE C STRICT;
CREATE FUNCTION other_node_is_candidate(INT)
RETURNS BOOL
AS '$libdir/repmgr', 'other_node_is_candidate'
LANGUAGE C STRICT;

View File

@@ -30,6 +30,8 @@
#include "voting.h"
#define UNKNOWN_NODE_ID -1
#define MAXFNAMELEN 64
#define TRANCHE_NAME "repmgrd"
@@ -46,6 +48,7 @@ typedef struct repmgrdSharedState
LWLockId lock; /* protects search/modification */
NodeState node_state;
NodeVotingStatus voting_status;
int candidate_node_id;
} repmgrdSharedState;
static repmgrdSharedState *shared_state = NULL;
@@ -67,6 +70,8 @@ PG_FUNCTION_INFO_V1(get_voting_status);
Datum set_voting_status_initiated(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(set_voting_status_initiated);
Datum other_node_is_candidate(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(other_node_is_candidate);
/*
* Module load callback
*/
@@ -130,7 +135,7 @@ repmgr_shmem_startup(void)
if (!found)
{
/* First time through ... */
/* Initialise shared memory struct */
#if (PG_VERSION_NUM >= 90600)
shared_state->lock = &(GetNamedLWLockTranche(TRANCHE_NAME))->lock;
#else
@@ -138,6 +143,7 @@ repmgr_shmem_startup(void)
#endif
shared_state->voting_status = VS_NO_VOTE;
shared_state->candidate_node_id = UNKNOWN_NODE_ID;
}
LWLockRelease(AddinShmemInitLock);
@@ -225,3 +231,25 @@ set_voting_status_initiated(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
Datum
other_node_is_candidate(PG_FUNCTION_ARGS)
{
int requesting_node_id = PG_GETARG_INT32(0);
LWLockAcquire(shared_state->lock, LW_SHARED);
if (shared_state->candidate_node_id != UNKNOWN_NODE_ID)
{
elog(INFO, "node %i requesting candidature, but node %i already candidate",
requesting_node_id,
shared_state->candidate_node_id);
PG_RETURN_BOOL(false);
}
shared_state->candidate_node_id = requesting_node_id;
LWLockRelease(shared_state->lock);
elog(INFO, "node %i is candidate", requesting_node_id);
PG_RETURN_BOOL(true);
}

View File

@@ -576,7 +576,8 @@ monitor_streaming_standby(void)
}
}
// store lsndiffs, in the event we're not the best node,
// i.e. don't get all the votes, we pass the baton to the best node
static NodeVotingStatus
do_election(void)
{
@@ -598,6 +599,8 @@ do_election(void)
long unsigned rand_wait = (long) ((rand() % 50) + 10) * 10000;
bool other_node_is_candidate = false;
log_debug("do_election(): sleeping %li", rand_wait);
pg_usleep(rand_wait);
@@ -646,10 +649,21 @@ do_election(void)
continue;
}
if (announce_candidature(cell->node_info->conn, &local_node_info, cell->node_info) == false)
{
log_debug("node %i is candidate", cell->node_info->node_id);
other_node_is_candidate = true;
}
cell->node_info->is_visible = true;
visible_nodes ++;
}
if (other_node_is_candidate == true)
{
return VS_NO_VOTE;
}
// XXX check if > 50% visible
/* check again if we've been asked to vote */