diff --git a/dbutils.c b/dbutils.c index a83cb993..4a23a577 100644 --- a/dbutils.c +++ b/dbutils.c @@ -2288,7 +2288,8 @@ get_voting_status(PGconn *conn) return voting_status; } -int request_vote(PGconn *conn, int this_node_id, int this_node_priority, 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) { PQExpBufferData query; PGresult *res; @@ -2298,7 +2299,7 @@ int request_vote(PGconn *conn, int this_node_id, int this_node_priority, XLogRec appendPQExpBuffer(&query, "SELECT repmgr.request_vote(%i, '%X/%X'::pg_lsn)", - this_node_id, + this_node->node_id, (uint32) (last_wal_receive_lsn >> 32), (uint32) last_wal_receive_lsn); @@ -2311,7 +2312,41 @@ int request_vote(PGconn *conn, int this_node_id, int this_node_priority, XLogRec log_debug("XXX lsn_diff %i", lsn_diff); PQclear(res); - return lsn_diff; + + /* we're ahead */ + if (lsn_diff > 0) + { + log_debug("this node is ahead"); + return 1; + } + + /* other node is ahead */ + if (lsn_diff < 0) + { + log_debug("other node is ahead"); + return 0; + } + + /* tiebreak */ + + /* we're higher priority */ + if (this_node->priority > other_node->priority) + { + log_debug("this node has higher priority"); + return 1; + } + + /* still tiebreak - decide by node_id */ + if (this_node->node_id < other_node->node_id) + { + log_debug("this node has lower id"); + return 1; + } + log_debug("other node wins"); + + + /* we lose */ + return 0; } diff --git a/dbutils.h b/dbutils.h index 8b93939e..b0299a91 100644 --- a/dbutils.h +++ b/dbutils.h @@ -246,7 +246,8 @@ bool is_server_available(const char *conninfo); /* node voting functions */ NodeVotingStatus get_voting_status(PGconn *conn); -int request_vote(PGconn *conn, int this_node_id, int this_node_priority, 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); + /* replication status functions */ diff --git a/repmgr.c b/repmgr.c index cc712665..e1a4b022 100644 --- a/repmgr.c +++ b/repmgr.c @@ -165,12 +165,14 @@ request_vote(PG_FUNCTION_ARGS) initStringInfo(&query); appendStringInfo( &query, - "SELECT '%X/%X'::pg_lsn - pg_catalog.pg_last_wal_receive_lsn()::pg_lsn", + "SELECT ('%X/%X'::pg_lsn - pg_catalog.pg_last_wal_receive_lsn()::pg_lsn)::INT", (uint32) (requesting_node_last_lsn >> 32), (uint32) requesting_node_last_lsn); - ret = SPI_execute(query.data, false, 0); + elog(INFO, "query: %s", query.data); + ret = SPI_execute(query.data, true, 0); + // xxx handle errors lsn_diff = DatumGetInt32(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull)); diff --git a/repmgrd.c b/repmgrd.c index fe532317..926e8d06 100644 --- a/repmgrd.c +++ b/repmgrd.c @@ -599,7 +599,7 @@ do_election(void) cell->node_info->is_visible = false; // XXX handle witness-barman - cell->node_info->conn = establish_db_connection(local_node_info.conninfo, false); + cell->node_info->conn = establish_db_connection(cell->node_info->conninfo, false); if (PQstatus(cell->node_info->conn) != CONNECTION_OK) { @@ -628,12 +628,13 @@ do_election(void) for (cell = standby_nodes.head; cell; cell = cell->next) { + log_debug("checking node %i...", cell->node_info->node_id); /* ignore unreachable nodes */ if (cell->node_info->is_visible == false) continue; votes_for_me += request_vote(cell->node_info->conn, - local_node_info.node_id, - local_node_info.priority, + &local_node_info, + cell->node_info, last_wal_receive_lsn); PQfinish(cell->node_info->conn);