If 'dynamic_node_detection' has been set to false, then the
Clustrix monitor will not dynamically figure out what nodes are
available, but instead use the bootstrap nodes as such.
With 'dynamic_node_detection' being false, the Clustrix monitor
will do no cluster checks, but simply ping the health port of
each server.
'dynamic_node_detection' specifies whether the Clustrix monitor
should dynamically figure out what nodes there are, or just rely
upon static information.
'health_check_port' specifies the port to be used when perforing
the health check ping.
Added core functionality for UNIX domain sockets in servers. Currently the
address parameter accepts them both but a separate `socket` parameter is
needed.
If the monitor setting "replication_master_ssl" is set to on, any CHANGE MASTER TO-command
will have MASTER_SSL=1. If set to off or unset, MASTER_SSL is left unchanged to match existing
behaviour.
If case of MDBCI_VM_PATH variable does not have trailing slash full names of _network_config
and _lables files are defined in the wrong way: MDBCI_VM_PATH is interpreted as a part of file name
instead of direcoty name
If normal authentication fails and a PAM service is defined, PAM authentication
is attempted. Separate services can be set for read-only users and admin-level
users.
In case when nodes/servers/replication/etc in backend are broken test can not
get proper version information and exits without doing anything.
To avoid it, test first checks backend, call fix_replication() if needed
and only after that tris to check if backend version is ok for this test
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.
Information about the detected Clustrix nodes is now stored to
a Clustrix monitor specific sqlite-database. This will be used
for bootstrapping the Clustrix monitor, in case a statically
defined bootstrap server is unavailable.
The configuration mechanism consists of the following concepts:
Specification
Specifies the available configuration parameters of a module,
their names and their types.
Param
Specifies a parameter, its name and its type.
Type
Specifies the type of a configuration parameters; Bool, Size,
Count, etc.
Configuration
Specifies the configuration values of a particular instance of
the module. Configuration walks hand in hand with Specification,
the latter specifies what the former should contain.
A Specification is capable of configuring a Configuration from a
MXS_CONFIG_PARAMETER, checking in the process that all parameters
are of the correct type and that the required parameters are present.
A Specification is capable of persisting itself so that it later
can be read back.
The mechanism is closed for modification but open for extension in
the sense that if a module requires a custom parameter, all it needs
to do is to derive one class from Param and another from Type.
The canonical way for using this mechanism is as follows. Consider
a module xyx that has three parameters; a parameter called
"enabled" that is of boolean type, a parameter called "period"
that is of duration type, and a parameter "cache" that is of
size type. That would be declared as follows:
// xyz.hh
class XYZSession;
class XYZ : public maxscale::Filter<XYZ, XYZSession>
{
public:
static XYZ* create(const char* zName, MXS_CONFIG_PARAMETER* pParams);
private:
XYZ();
static config::Specification s_specification;
static config::ParamBool s_enabled;
static config::ParamDuration<std::chrono::seconds> s_period;
static config::ParamSize s_cache;
config::Configuration m_configuration;
config::Bool m_enabled;
config::Duration<std::chrono::seconds> m_period;
config::Size m_cache;
};
// xyz.cc
config::Specification XYZ::s_specification(MXS_MODULE_NAME);
config::ParamBool XYZ::s_enabled(
&s_specification,
"enabled",
"Specifies whether ... should be enabled or not."
);
config::ParamDuration<std::chrono::seconds> XYZ::s_period(
&s_specification,
"period",
"Specifies the period. Rounded to the nearest second."
);
config::ParamSize XYZ::s_cache(
&s_specification,
"cache",
"Specifies the size of the internal cache."
);
XYZ::XYZ()
: m_configuration(&s_specification)
, m_enabled(&m_configuration, &s_enabled)
, m_period(&m_configuration, &s_period)
, m_cache(&m_configuration, &s_cache)
{
}
XYZ* XYZ::create(const char* zName, MXS_CONFIG_PARAMETER* pParams)
{
XYZ* pXyz = new XYZ;
if (!s_specification.configure(pXyz->m_configuration, pParams))
{
delete pXyz;
pXyz = nullptr;
}
return pXyz;
}
RESET QUERY CACHE is reported to be a session command, which will
cause it to be sent to all servers. RESET [MASTER|SLAVE] are
classified as write, which will cause them to be sent to the master.
It could be argued that RESET [MASTER|SLAVE] should cause an error
to be sent to the client.
RESET is neither parsed not tokenized, so RESET statements ends
up being sent to the master. That is fine for all but RESET QUERY
CACHE that should be sent to all servers.
Recognize the XA keyword and classify the statement as write.
Needs to be dealt with explicitly as sqlite3 assumes there are
no keywords starting with the letter X.
The largest part of the code deals with the start of a response. Moving
this into a subfunction makes the function clearer as the switch statement
inside a switch statement is removed.
By processing the packets one at a time, the reply state is updated
correctly regardless of how many packets are received. This removes the
need for the clunky code that used modutil_count_signal_packets to detect
the end of the result set.