mirror of
https://github.com/EnterpriseDB/repmgr.git
synced 2026-03-25 16:16:29 +00:00
Add some sanity checks for calls to repmgrd functions
This commit is contained in:
193
repmgr.c
193
repmgr.c
@@ -233,7 +233,13 @@ set_local_node_id(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
LWLockAcquire(shared_state->lock, LW_SHARED);
|
LWLockAcquire(shared_state->lock, LW_SHARED);
|
||||||
shared_state->local_node_id = local_node_id;
|
|
||||||
|
/* only set local_node_id once, as it should never change */
|
||||||
|
if (shared_state->local_node_id == UNKNOWN_NODE_ID)
|
||||||
|
{
|
||||||
|
shared_state->local_node_id = local_node_id;
|
||||||
|
}
|
||||||
|
|
||||||
LWLockRelease(shared_state->lock);
|
LWLockRelease(shared_state->lock);
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
@@ -300,81 +306,82 @@ request_vote(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!shared_state)
|
if (!shared_state)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
LWLockAcquire(shared_state->lock, LW_SHARED);
|
LWLockAcquire(shared_state->lock, LW_SHARED);
|
||||||
|
|
||||||
/* this node has initiated voting or already responded to another node */
|
/* only do something if local_node_id is initialised */
|
||||||
if (shared_state->voting_status != VS_NO_VOTE)
|
if (shared_state->local_node_id != UNKNOWN_NODE_ID)
|
||||||
{
|
{
|
||||||
LWLockRelease(shared_state->lock);
|
/* this node has initiated voting or already responded to another node */
|
||||||
|
if (shared_state->voting_status != VS_NO_VOTE)
|
||||||
|
{
|
||||||
|
LWLockRelease(shared_state->lock);
|
||||||
|
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
elog(INFO, "node %i has received request from node %i for electoral term %i (our term: %i)",
|
elog(INFO, "node %i has received request from node %i for electoral term %i (our term: %i)",
|
||||||
shared_state->local_node_id,
|
shared_state->local_node_id,
|
||||||
requesting_node_id, current_electoral_term,
|
requesting_node_id, current_electoral_term,
|
||||||
shared_state->current_electoral_term);
|
shared_state->current_electoral_term);
|
||||||
|
|
||||||
SPI_connect();
|
SPI_connect();
|
||||||
|
|
||||||
initStringInfo(&query);
|
initStringInfo(&query);
|
||||||
|
|
||||||
appendStringInfo(
|
appendStringInfo(
|
||||||
&query,
|
&query,
|
||||||
#if (PG_VERSION_NUM >= 100000)
|
#if (PG_VERSION_NUM >= 100000)
|
||||||
"SELECT pg_catalog.pg_last_wal_receive_lsn()");
|
"SELECT pg_catalog.pg_last_wal_receive_lsn()");
|
||||||
#else
|
#else
|
||||||
"SELECT pg_catalog.pg_last_xlog_receive_location()");
|
"SELECT pg_catalog.pg_last_xlog_receive_location()");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
elog(DEBUG1, "query: %s", query.data);
|
elog(DEBUG1, "query: %s", query.data);
|
||||||
ret = SPI_execute(query.data, true, 0);
|
ret = SPI_execute(query.data, true, 0);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
SPI_finish();
|
||||||
|
elog(WARNING, "unable to retrieve last received LSN");
|
||||||
|
LWLockRelease(shared_state->lock);
|
||||||
|
|
||||||
|
#if (PG_VERSION_NUM >= 90400)
|
||||||
|
PG_RETURN_LSN(InvalidOid);
|
||||||
|
#else
|
||||||
|
PG_RETURN_TEXT_P(cstring_to_text("0/0"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (PG_VERSION_NUM >= 90400)
|
||||||
|
our_lsn = DatumGetLSN(SPI_getbinval(SPI_tuptable->vals[0],
|
||||||
|
SPI_tuptable->tupdesc,
|
||||||
|
1, &isnull));
|
||||||
|
|
||||||
|
elog(DEBUG1, "our LSN is %X/%X",
|
||||||
|
(uint32) (our_lsn >> 32),
|
||||||
|
(uint32) our_lsn);
|
||||||
|
#else
|
||||||
|
value = SPI_getvalue(SPI_tuptable->vals[0],
|
||||||
|
SPI_tuptable->tupdesc,
|
||||||
|
1);
|
||||||
|
strncpy(lsn_text, value, 64);
|
||||||
|
pfree(value);
|
||||||
|
elog(DEBUG1, "our LSN is %s", lsn_text);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* indicate this node has responded to a vote request */
|
||||||
|
shared_state->voting_status = VS_VOTE_REQUEST_RECEIVED;
|
||||||
|
shared_state->current_electoral_term = current_electoral_term;
|
||||||
|
|
||||||
|
/* should we free "query" here? */
|
||||||
SPI_finish();
|
SPI_finish();
|
||||||
elog(WARNING, "unable to retrieve last received LSN");
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= 90400)
|
|
||||||
PG_RETURN_LSN(InvalidOid);
|
|
||||||
#else
|
|
||||||
PG_RETURN_TEXT_P(cstring_to_text("0/0"));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= 90400)
|
|
||||||
our_lsn = DatumGetLSN(SPI_getbinval(SPI_tuptable->vals[0],
|
|
||||||
SPI_tuptable->tupdesc,
|
|
||||||
1, &isnull));
|
|
||||||
|
|
||||||
elog(DEBUG1, "our LSN is %X/%X",
|
|
||||||
(uint32) (our_lsn >> 32),
|
|
||||||
(uint32) our_lsn);
|
|
||||||
#else
|
|
||||||
value = SPI_getvalue(SPI_tuptable->vals[0],
|
|
||||||
SPI_tuptable->tupdesc,
|
|
||||||
1);
|
|
||||||
strncpy(lsn_text, value, 64);
|
|
||||||
pfree(value);
|
|
||||||
elog(DEBUG1, "our LSN is %s", lsn_text);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* indicate this node has responded to a vote request */
|
|
||||||
shared_state->voting_status = VS_VOTE_REQUEST_RECEIVED;
|
|
||||||
shared_state->current_electoral_term = current_electoral_term;
|
|
||||||
|
|
||||||
LWLockRelease(shared_state->lock);
|
LWLockRelease(shared_state->lock);
|
||||||
|
|
||||||
/* should we free "query" here? */
|
|
||||||
SPI_finish();
|
|
||||||
|
|
||||||
#if (PG_VERSION_NUM >= 90400)
|
#if (PG_VERSION_NUM >= 90400)
|
||||||
PG_RETURN_LSN(our_lsn);
|
PG_RETURN_LSN(our_lsn);
|
||||||
#else
|
#else
|
||||||
@@ -410,17 +417,23 @@ Datum
|
|||||||
set_voting_status_initiated(PG_FUNCTION_ARGS)
|
set_voting_status_initiated(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
#ifndef BDR_ONLY
|
#ifndef BDR_ONLY
|
||||||
int electoral_term;
|
int electoral_term = -1;
|
||||||
|
|
||||||
LWLockAcquire(shared_state->lock, LW_SHARED);
|
LWLockAcquire(shared_state->lock, LW_SHARED);
|
||||||
shared_state->voting_status = VS_VOTE_INITIATED;
|
|
||||||
shared_state->current_electoral_term += 1;
|
|
||||||
|
|
||||||
electoral_term = shared_state->current_electoral_term;
|
/* only do something if local_node_id is initialised */
|
||||||
|
if (shared_state->local_node_id != UNKNOWN_NODE_ID)
|
||||||
|
{
|
||||||
|
shared_state->voting_status = VS_VOTE_INITIATED;
|
||||||
|
shared_state->current_electoral_term += 1;
|
||||||
|
|
||||||
|
electoral_term = shared_state->current_electoral_term;
|
||||||
|
|
||||||
|
elog(INFO, "setting voting term to %i", electoral_term);
|
||||||
|
}
|
||||||
|
|
||||||
LWLockRelease(shared_state->lock);
|
LWLockRelease(shared_state->lock);
|
||||||
|
|
||||||
elog(INFO, "setting voting term to %i", electoral_term);
|
|
||||||
|
|
||||||
PG_RETURN_INT32(electoral_term);
|
PG_RETURN_INT32(electoral_term);
|
||||||
#else
|
#else
|
||||||
PG_RETURN_INT32(-1);
|
PG_RETURN_INT32(-1);
|
||||||
@@ -439,21 +452,26 @@ other_node_is_candidate(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
LWLockAcquire(shared_state->lock, LW_SHARED);
|
LWLockAcquire(shared_state->lock, LW_SHARED);
|
||||||
|
|
||||||
if (shared_state->current_electoral_term == electoral_term)
|
/* only do something if local_node_id is initialised */
|
||||||
|
if (shared_state->local_node_id != UNKNOWN_NODE_ID)
|
||||||
{
|
{
|
||||||
if (shared_state->candidate_node_id != UNKNOWN_NODE_ID)
|
if (shared_state->current_electoral_term == electoral_term)
|
||||||
{
|
{
|
||||||
elog(INFO, "node %i requesting candidature, but node %i already candidate",
|
if (shared_state->candidate_node_id != UNKNOWN_NODE_ID)
|
||||||
requesting_node_id,
|
{
|
||||||
shared_state->candidate_node_id);
|
elog(INFO, "node %i requesting candidature, but node %i already candidate",
|
||||||
PG_RETURN_BOOL(false);
|
requesting_node_id,
|
||||||
|
shared_state->candidate_node_id);
|
||||||
|
PG_RETURN_BOOL(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shared_state->candidate_node_id = requesting_node_id;
|
||||||
|
elog(INFO, "node %i is candidate", requesting_node_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_state->candidate_node_id = requesting_node_id;
|
|
||||||
LWLockRelease(shared_state->lock);
|
LWLockRelease(shared_state->lock);
|
||||||
|
|
||||||
elog(INFO, "node %i is candidate", requesting_node_id);
|
|
||||||
PG_RETURN_BOOL(true);
|
PG_RETURN_BOOL(true);
|
||||||
#else
|
#else
|
||||||
PG_RETURN_BOOL(false);
|
PG_RETURN_BOOL(false);
|
||||||
@@ -471,13 +489,18 @@ notify_follow_primary(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
LWLockAcquire(shared_state->lock, LW_SHARED);
|
LWLockAcquire(shared_state->lock, LW_SHARED);
|
||||||
|
|
||||||
elog(INFO, "node %i received notification to follow node %i",
|
/* only do something if local_node_id is initialised */
|
||||||
shared_state->local_node_id,
|
if (shared_state->local_node_id != UNKNOWN_NODE_ID)
|
||||||
primary_node_id);
|
{
|
||||||
|
elog(INFO, "node %i received notification to follow node %i",
|
||||||
|
shared_state->local_node_id,
|
||||||
|
primary_node_id);
|
||||||
|
|
||||||
|
/* Explicitly set the primary node id */
|
||||||
|
shared_state->candidate_node_id = primary_node_id;
|
||||||
|
shared_state->follow_new_primary = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Explicitly set the primary node id */
|
|
||||||
shared_state->candidate_node_id = primary_node_id;
|
|
||||||
shared_state->follow_new_primary = true;
|
|
||||||
LWLockRelease(shared_state->lock);
|
LWLockRelease(shared_state->lock);
|
||||||
#endif
|
#endif
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
@@ -513,9 +536,13 @@ reset_voting_status(PG_FUNCTION_ARGS)
|
|||||||
|
|
||||||
LWLockAcquire(shared_state->lock, LW_SHARED);
|
LWLockAcquire(shared_state->lock, LW_SHARED);
|
||||||
|
|
||||||
shared_state->voting_status = VS_NO_VOTE;
|
/* only do something if local_node_id is initialised */
|
||||||
shared_state->candidate_node_id = UNKNOWN_NODE_ID;
|
if (shared_state->local_node_id != UNKNOWN_NODE_ID)
|
||||||
shared_state->follow_new_primary = false;
|
{
|
||||||
|
shared_state->voting_status = VS_NO_VOTE;
|
||||||
|
shared_state->candidate_node_id = UNKNOWN_NODE_ID;
|
||||||
|
shared_state->follow_new_primary = false;
|
||||||
|
}
|
||||||
|
|
||||||
LWLockRelease(shared_state->lock);
|
LWLockRelease(shared_state->lock);
|
||||||
#endif
|
#endif
|
||||||
@@ -556,9 +583,13 @@ unset_bdr_failover_handler(PG_FUNCTION_ARGS)
|
|||||||
if (!shared_state)
|
if (!shared_state)
|
||||||
PG_RETURN_NULL();
|
PG_RETURN_NULL();
|
||||||
|
|
||||||
LWLockAcquire(shared_state->lock, LW_SHARED);
|
/* only do something if local_node_id is initialised */
|
||||||
shared_state->bdr_failover_handler = UNKNOWN_NODE_ID;
|
if (shared_state->local_node_id != UNKNOWN_NODE_ID)
|
||||||
LWLockRelease(shared_state->lock);
|
{
|
||||||
|
LWLockAcquire(shared_state->lock, LW_SHARED);
|
||||||
|
shared_state->bdr_failover_handler = UNKNOWN_NODE_ID;
|
||||||
|
LWLockRelease(shared_state->lock);
|
||||||
|
}
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user