Merge pull request #5513 from sysown/v3.0-5497

Phase 3.9: PgSQL monitor health decisions + unit tests
pull/5514/head^2
René Cannaò 2 months ago committed by GitHub
commit ec5a9f9cc5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,44 @@
/**
* @file PgSQLMonitorDecision.h
* @brief Pure decision functions for PgSQL monitor health state.
*
* PgSQL monitor is simpler than MySQL it uses ping failure
* threshold directly with shun_and_killall() (always aggressive).
* Unshunning follows the same time-based recovery as MySQL
* (already covered by MonitorHealthDecision.h can_unshun_server).
*
* @see Phase 3.9 (GitHub issue #5497)
*/
#ifndef PGSQL_MONITOR_DECISION_H
#define PGSQL_MONITOR_DECISION_H
/**
* @brief Determine if a PgSQL server should be shunned based on ping failures.
*
* PgSQL monitor shuns servers when they miss N consecutive heartbeats.
* Unlike MySQL, PgSQL always uses aggressive shunning (kill all connections).
*
* @param missed_heartbeats Number of consecutive missed pings.
* @param max_failures_threshold Config: pgsql-monitor_ping_max_failures.
* @return true if the server should be shunned.
*/
bool pgsql_should_shun_on_ping_failure(
unsigned int missed_heartbeats,
unsigned int max_failures_threshold
);
/**
* @brief Determine if a PgSQL server's read-only status indicates it should
* be taken offline for a writer hostgroup.
*
* @param is_read_only Whether the server reports read_only=true.
* @param is_writer_hg Whether this is a writer hostgroup.
* @return true if the server should be set to OFFLINE_SOFT.
*/
bool pgsql_should_offline_for_readonly(
bool is_read_only,
bool is_writer_hg
);
#endif // PGSQL_MONITOR_DECISION_H

@ -109,6 +109,7 @@ _OBJ_CXX := ProxySQL_GloVars.oo network.oo debug.oo configfile.oo Query_Cache.oo
ServerSelection.oo \
TransactionState.oo \
HostgroupRouting.oo \
PgSQLMonitorDecision.oo \
MySQLErrorClassifier.oo \
BackendSyncDecision.oo \
proxy_sqlite3_symbols.oo

@ -0,0 +1,27 @@
/**
* @file PgSQLMonitorDecision.cpp
* @brief Implementation of PgSQL monitor health decisions.
*
* @see PgSQLMonitorDecision.h
* @see Phase 3.9 (GitHub issue #5497)
*/
#include "PgSQLMonitorDecision.h"
bool pgsql_should_shun_on_ping_failure(
unsigned int missed_heartbeats,
unsigned int max_failures_threshold)
{
if (max_failures_threshold == 0) {
return false; // shunning disabled
}
return (missed_heartbeats >= max_failures_threshold);
}
bool pgsql_should_offline_for_readonly(
bool is_read_only,
bool is_writer_hg)
{
// A read-only server in a writer hostgroup should go OFFLINE_SOFT
return (is_read_only && is_writer_hg);
}

@ -237,6 +237,7 @@ UNIT_TESTS := smoke_test-t query_cache_unit-t query_processor_unit-t \
server_selection_unit-t
hostgroup_routing_unit-t \
transaction_state_unit-t \
pgsql_monitor_unit-t \
mysql_error_classifier_unit-t \
backend_sync_unit-t

@ -0,0 +1,51 @@
/**
* @file pgsql_monitor_unit-t.cpp
* @brief Unit tests for PgSQL monitor health decisions.
*
* @see Phase 3.9 (GitHub issue #5497)
*/
#include "tap.h"
#include "test_globals.h"
#include "test_init.h"
#include "proxysql.h"
#include "PgSQLMonitorDecision.h"
static void test_ping_shunning() {
ok(pgsql_should_shun_on_ping_failure(3, 3) == true,
"shun: failures=3 meets threshold=3");
ok(pgsql_should_shun_on_ping_failure(5, 3) == true,
"shun: failures=5 exceeds threshold=3");
ok(pgsql_should_shun_on_ping_failure(2, 3) == false,
"no shun: failures=2 below threshold=3");
ok(pgsql_should_shun_on_ping_failure(0, 3) == false,
"no shun: zero failures");
ok(pgsql_should_shun_on_ping_failure(1, 1) == true,
"shun: threshold=1, single failure");
ok(pgsql_should_shun_on_ping_failure(10, 0) == false,
"no shun: threshold=0 (disabled)");
}
static void test_readonly_offline() {
ok(pgsql_should_offline_for_readonly(true, true) == true,
"offline: read_only + writer HG");
ok(pgsql_should_offline_for_readonly(true, false) == false,
"not offline: read_only + reader HG");
ok(pgsql_should_offline_for_readonly(false, true) == false,
"not offline: not read_only + writer HG");
ok(pgsql_should_offline_for_readonly(false, false) == false,
"not offline: not read_only + reader HG");
}
int main() {
plan(11);
int rc = test_init_minimal();
ok(rc == 0, "test_init_minimal() succeeds");
test_ping_shunning(); // 6
test_readonly_offline(); // 4
// Total: 1+6+4 = 11
test_cleanup_minimal();
return exit_status();
}
Loading…
Cancel
Save