mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-27 17:06:29 +00:00
poke it around until it works less badly
This commit is contained in:
6
config.c
6
config.c
@@ -16,6 +16,10 @@ static bool config_file_provided = false;
|
|||||||
bool config_file_found = false;
|
bool config_file_found = false;
|
||||||
|
|
||||||
static void _parse_config(t_configuration_options *options, ItemList *error_list, ItemList *warning_list);
|
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_line(char *buf, char *name, char *value);
|
||||||
static void parse_event_notifications_list(t_configuration_options *options, const char *arg);
|
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);
|
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
|
* 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)
|
parse_bool(const char *s, const char *config_item, ItemList *error_list)
|
||||||
{
|
{
|
||||||
PQExpBufferData errors;
|
PQExpBufferData errors;
|
||||||
|
|||||||
3
config.h
3
config.h
@@ -158,9 +158,6 @@ int repmgr_atoi(const char *s,
|
|||||||
ItemList *error_list,
|
ItemList *error_list,
|
||||||
int minval);
|
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,
|
bool parse_pg_basebackup_options(const char *pg_basebackup_options,
|
||||||
t_basebackup_options *backup_options,
|
t_basebackup_options *backup_options,
|
||||||
|
|||||||
26
dbutils.c
26
dbutils.c
@@ -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 */
|
/* replication status functions */
|
||||||
/* ============================ */
|
/* ============================ */
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ bool is_server_available(const char *conninfo);
|
|||||||
NodeVotingStatus get_voting_status(PGconn *conn);
|
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);
|
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);
|
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 */
|
/* replication status functions */
|
||||||
|
|
||||||
|
|||||||
@@ -51,3 +51,8 @@ CREATE FUNCTION set_voting_status_initiated()
|
|||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
AS '$libdir/repmgr', 'set_voting_status_initiated'
|
AS '$libdir/repmgr', 'set_voting_status_initiated'
|
||||||
LANGUAGE C STRICT;
|
LANGUAGE C STRICT;
|
||||||
|
|
||||||
|
CREATE FUNCTION other_node_is_candidate(INT)
|
||||||
|
RETURNS BOOL
|
||||||
|
AS '$libdir/repmgr', 'other_node_is_candidate'
|
||||||
|
LANGUAGE C STRICT;
|
||||||
|
|||||||
30
repmgr.c
30
repmgr.c
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "voting.h"
|
#include "voting.h"
|
||||||
|
|
||||||
|
#define UNKNOWN_NODE_ID -1
|
||||||
|
|
||||||
#define MAXFNAMELEN 64
|
#define MAXFNAMELEN 64
|
||||||
#define TRANCHE_NAME "repmgrd"
|
#define TRANCHE_NAME "repmgrd"
|
||||||
|
|
||||||
@@ -46,6 +48,7 @@ typedef struct repmgrdSharedState
|
|||||||
LWLockId lock; /* protects search/modification */
|
LWLockId lock; /* protects search/modification */
|
||||||
NodeState node_state;
|
NodeState node_state;
|
||||||
NodeVotingStatus voting_status;
|
NodeVotingStatus voting_status;
|
||||||
|
int candidate_node_id;
|
||||||
} repmgrdSharedState;
|
} repmgrdSharedState;
|
||||||
|
|
||||||
static repmgrdSharedState *shared_state = NULL;
|
static repmgrdSharedState *shared_state = NULL;
|
||||||
@@ -67,6 +70,8 @@ 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);
|
||||||
|
PG_FUNCTION_INFO_V1(other_node_is_candidate);
|
||||||
/*
|
/*
|
||||||
* Module load callback
|
* Module load callback
|
||||||
*/
|
*/
|
||||||
@@ -130,7 +135,7 @@ repmgr_shmem_startup(void)
|
|||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
/* First time through ... */
|
/* Initialise shared memory struct */
|
||||||
#if (PG_VERSION_NUM >= 90600)
|
#if (PG_VERSION_NUM >= 90600)
|
||||||
shared_state->lock = &(GetNamedLWLockTranche(TRANCHE_NAME))->lock;
|
shared_state->lock = &(GetNamedLWLockTranche(TRANCHE_NAME))->lock;
|
||||||
#else
|
#else
|
||||||
@@ -138,6 +143,7 @@ repmgr_shmem_startup(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
shared_state->voting_status = VS_NO_VOTE;
|
shared_state->voting_status = VS_NO_VOTE;
|
||||||
|
shared_state->candidate_node_id = UNKNOWN_NODE_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWLockRelease(AddinShmemInitLock);
|
LWLockRelease(AddinShmemInitLock);
|
||||||
@@ -225,3 +231,25 @@ set_voting_status_initiated(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
PG_RETURN_VOID();
|
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);
|
||||||
|
}
|
||||||
|
|||||||
16
repmgrd.c
16
repmgrd.c
@@ -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
|
static NodeVotingStatus
|
||||||
do_election(void)
|
do_election(void)
|
||||||
{
|
{
|
||||||
@@ -598,6 +599,8 @@ do_election(void)
|
|||||||
|
|
||||||
long unsigned rand_wait = (long) ((rand() % 50) + 10) * 10000;
|
long unsigned rand_wait = (long) ((rand() % 50) + 10) * 10000;
|
||||||
|
|
||||||
|
bool other_node_is_candidate = false;
|
||||||
|
|
||||||
log_debug("do_election(): sleeping %li", rand_wait);
|
log_debug("do_election(): sleeping %li", rand_wait);
|
||||||
|
|
||||||
pg_usleep(rand_wait);
|
pg_usleep(rand_wait);
|
||||||
@@ -646,10 +649,21 @@ do_election(void)
|
|||||||
continue;
|
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;
|
cell->node_info->is_visible = true;
|
||||||
visible_nodes ++;
|
visible_nodes ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (other_node_is_candidate == true)
|
||||||
|
{
|
||||||
|
return VS_NO_VOTE;
|
||||||
|
}
|
||||||
|
|
||||||
// XXX check if > 50% visible
|
// XXX check if > 50% visible
|
||||||
|
|
||||||
/* check again if we've been asked to vote */
|
/* check again if we've been asked to vote */
|
||||||
|
|||||||
Reference in New Issue
Block a user