Files
MaxScale/server/modules/monitor/clustrixmon/clustrixmonitor.hh
Johan Wikman 893059c537 MXS-2424 Use persisted nodes if bootstrap node missing
At runtime the Clustrix monitor will save to an sqlite3
database information about detected nodes and delete that
information if a node disappears.

At startup, if the monitor fails to connect to a bootstrap
node, it will try to connect any of the persisted nodes and
start from there.

This means that in general it is sufficient if the Clustrix
monitor at the very first startup can connect to a bootstrap
node; thereafter it will get by even if the bootstrap node
would disappear for good.
2019-04-12 16:29:21 +03:00

157 lines
4.3 KiB
C++

/*
* Copyright (c) 2018 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2022-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
#pragma once
#include "clustrixmon.hh"
#include <map>
#include <set>
#include <sqlite3.h>
#include <maxscale/monitor.hh>
#include <maxbase/http.hh>
#include "clustrixmembership.hh"
#include "clustrixnode.hh"
class ClustrixMonitor : public maxscale::MonitorWorker,
private ClustrixNode::Persister
{
ClustrixMonitor(const ClustrixMonitor&) = delete;
ClustrixMonitor& operator=(const ClustrixMonitor&) = delete;
public:
class Config
{
public:
Config()
: m_cluster_monitor_interval(DEFAULT_CLUSTER_MONITOR_INTERVAL_VALUE)
, m_health_check_threshold(DEFAULT_HEALTH_CHECK_THRESHOLD_VALUE)
{
};
long cluster_monitor_interval() const
{
return m_cluster_monitor_interval;
}
void set_cluster_monitor_interval(long l)
{
m_cluster_monitor_interval = l;
}
long health_check_threshold() const
{
return m_health_check_threshold;
}
void set_health_check_threshold(long l)
{
m_health_check_threshold = l;
}
private:
long m_cluster_monitor_interval;
long m_health_check_threshold;
};
~ClustrixMonitor();
static ClustrixMonitor* create(const std::string& name, const std::string& module);
bool configure(const MXS_CONFIG_PARAMETER* pParams) override;
bool softfail(SERVER* pServer, json_t** ppError);
bool unsoftfail(SERVER* pServer, json_t** ppError);
protected:
void populate_services() override;
void server_added(SERVER* pServer) override;
void server_removed(SERVER* pServer) override;
private:
ClustrixMonitor(const std::string& name,
const std::string& module,
sqlite3* pDb);
void pre_loop() override;
void post_loop() override;
void tick() override;
void check_cluster(Clustrix::Softfailed softfailed);
void check_hub(Clustrix::Softfailed softfailed);
void choose_hub(Clustrix::Softfailed softfailed);
bool choose_dynamic_hub(Clustrix::Softfailed softfailed, std::set<std::string>& ips_checked);
bool choose_bootstrap_hub(Clustrix::Softfailed softfailed, std::set<std::string>& ips_checked);
bool refresh_using_persisted_nodes(std::set<std::string>& ips_checked);
bool refresh_nodes();
bool refresh_nodes(MYSQL* pHub_con);
bool check_cluster_membership(MYSQL* pHub_con,
std::map<int, ClustrixMembership>* pMemberships);
void update_server_statuses();
void make_health_check();
void initiate_delayed_http_check();
bool check_http(Call::action_t action);
bool perform_softfail(SERVER* pServer, json_t** ppError);
bool perform_unsoftfail(SERVER* pServer, json_t** ppError);
enum class Operation
{
SOFTFAIL,
UNSOFTFAIL,
};
bool perform_operation(Operation operation,
SERVER* pServer,
json_t** ppError);
bool should_check_cluster() const
{
return now() - m_last_cluster_check > m_config.cluster_monitor_interval();
}
void trigger_cluster_check()
{
m_last_cluster_check = 0;
}
void cluster_checked()
{
m_last_cluster_check = now();
}
static long now()
{
return mxb::WorkerLoad::get_time_ms();
}
// ClustrixNode::Persister
void persist(const ClustrixNode& node);
void unpersist(const ClustrixNode& node);
private:
Config m_config;
std::map<int, ClustrixNode> m_nodes;
std::vector<std::string> m_health_urls;
mxb::http::Async m_http;
uint32_t m_delayed_http_check_id { 0 };
long m_last_cluster_check { 0 };
SERVER* m_pHub_server { nullptr };
MYSQL* m_pHub_con { nullptr };
sqlite3* m_pDb { nullptr };
};