Merge branch '2.4' of github.com:mariadb-corporation/MaxScale into 2.4
This commit is contained in:
@ -49,8 +49,8 @@ These tutorials are for specific use cases and module combinations.
|
|||||||
- [Filter Tutorial](Tutorials/Filter-Tutorial.md)
|
- [Filter Tutorial](Tutorials/Filter-Tutorial.md)
|
||||||
- [RabbitMQ and Tee Filter Data Archiving Tutorial](Tutorials/RabbitMQ-And-Tee-Archiving.md)
|
- [RabbitMQ and Tee Filter Data Archiving Tutorial](Tutorials/RabbitMQ-And-Tee-Archiving.md)
|
||||||
- [RabbitMQ Setup and MariaDB MaxScale Integration Tutorial](Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md)
|
- [RabbitMQ Setup and MariaDB MaxScale Integration Tutorial](Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md)
|
||||||
- [Clustrix Monitor Tutorial](Tutorials/Configuring-Clustrix-Monitor.md)
|
- [Xpand Monitor Tutorial](Tutorials/Configuring-Xpand-Monitor.md)
|
||||||
- [MaxScale Clustrix Tutorial](Tutorials/MaxScale-Clustrix-Tutorial.md)
|
- [MaxScale Xpand Tutorial](Tutorials/MaxScale-Xpand-Tutorial.md)
|
||||||
|
|
||||||
Here are tutorials on monitoring and managing MariaDB MaxScale in cluster environments.
|
Here are tutorials on monitoring and managing MariaDB MaxScale in cluster environments.
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ Module specific documentation.
|
|||||||
- [Galera Monitor](Monitors/Galera-Monitor.md)
|
- [Galera Monitor](Monitors/Galera-Monitor.md)
|
||||||
- [ColumnStore Monitor](Monitors/ColumnStore-Monitor.md)
|
- [ColumnStore Monitor](Monitors/ColumnStore-Monitor.md)
|
||||||
- [Aurora Monitor](Monitors/Aurora-Monitor.md)
|
- [Aurora Monitor](Monitors/Aurora-Monitor.md)
|
||||||
- [Clustrix Monitor](Monitors/Clustrix-Monitor.md)
|
- [Xpand Monitor](Monitors/Xpand-Monitor.md)
|
||||||
|
|
||||||
## Protocols
|
## Protocols
|
||||||
|
|
||||||
|
@ -1,29 +1,32 @@
|
|||||||
# Clustrix Monitor
|
# Xpand Monitor
|
||||||
|
|
||||||
|
**NOTE** The Xpand monitor is intended for use with a native Xpand
|
||||||
|
cluster, not with the Xpand storage engine.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The Clustrix Monitor is a monitor that monitors a Clustrix cluster. It is
|
The Xpand Monitor is a monitor that monitors a Xpand cluster. It is
|
||||||
capable of detecting the cluster setup and creating corresponding server
|
capable of detecting the cluster setup and creating corresponding server
|
||||||
instances within MaxScale.
|
instances within MaxScale.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
A minimal configuration for a monitor requires one server in the Clustrix
|
A minimal configuration for a monitor requires one server in the Xpand
|
||||||
cluster, and a username and a password to connect to the server. Note that
|
cluster, and a username and a password to connect to the server. Note that
|
||||||
by default the Clustrix monitor will only use that server in order to
|
by default the Xpand monitor will only use that server in order to
|
||||||
dynamically find out the configuration of the cluster; after startup it
|
dynamically find out the configuration of the cluster; after startup it
|
||||||
will completely rely upon information obtained at runtime. To change the
|
will completely rely upon information obtained at runtime. To change the
|
||||||
default behaviour, please see the parameter
|
default behaviour, please see the parameter
|
||||||
[dynamic_node_detection](#dynamic_node_detection).
|
[dynamic_node_detection](#dynamic_node_detection).
|
||||||
|
|
||||||
To ensure that the Clustrix monitor will be able to start, it is adviseable
|
To ensure that the Xpand monitor will be able to start, it is adviseable
|
||||||
to provide _more_ than one server to cater for the case that not all nodes
|
to provide _more_ than one server to cater for the case that not all nodes
|
||||||
are always up when MaxScale starts.
|
are always up when MaxScale starts.
|
||||||
|
|
||||||
```
|
```
|
||||||
[TheClustrixMonitor]
|
[TheXpandMonitor]
|
||||||
type=monitor
|
type=monitor
|
||||||
module=clustrixmon
|
module=xpandmon
|
||||||
servers=server1,server2,server3
|
servers=server1,server2,server3
|
||||||
user=myuser
|
user=myuser
|
||||||
password=mypwd
|
password=mypwd
|
||||||
@ -32,22 +35,22 @@ password=mypwd
|
|||||||
|
|
||||||
## Dynamic Servers
|
## Dynamic Servers
|
||||||
|
|
||||||
The server objects the Clustrix monitor creates for each detected
|
The server objects the Xpand monitor creates for each detected
|
||||||
Clustrix node will be named like
|
Xpand node will be named like
|
||||||
```
|
```
|
||||||
@@<name-of-clustrix-monitor>:node-<id>
|
@@<name-of-xpand-monitor>:node-<id>
|
||||||
```
|
```
|
||||||
where `<name-of-clustrix-monitor>` is the name of the Clustrix monitor
|
where `<name-of-xpand-monitor>` is the name of the Xpand monitor
|
||||||
instance, as defined in the MaxScale configuration file, and `<id>` is the
|
instance, as defined in the MaxScale configuration file, and `<id>` is the
|
||||||
id of the Clustrix node.
|
id of the Xpand node.
|
||||||
|
|
||||||
For instance, with the Clustrix monitor defined as above and a Clustrix
|
For instance, with the Xpand monitor defined as above and a Xpand
|
||||||
cluster consisting of 3 nodes whose ids are `1`, `2` and `3` respectively,
|
cluster consisting of 3 nodes whose ids are `1`, `2` and `3` respectively,
|
||||||
the names of the created server objects will be:
|
the names of the created server objects will be:
|
||||||
```
|
```
|
||||||
@@TheClustrixMonitor:node-1
|
@@TheXpandMonitor:node-1
|
||||||
@@TheClustrixMonitor:node-2
|
@@TheXpandMonitor:node-2
|
||||||
@@TheClustrixMonitor:node-3
|
@@TheXpandMonitor:node-3
|
||||||
```
|
```
|
||||||
|
|
||||||
### Grants
|
### Grants
|
||||||
@ -76,9 +79,9 @@ The user name must be changed to the one actually being used.
|
|||||||
For a list of optional parameters that all monitors support, read the
|
For a list of optional parameters that all monitors support, read the
|
||||||
[Monitor Common](Monitor-Common.md) document.
|
[Monitor Common](Monitor-Common.md) document.
|
||||||
|
|
||||||
## Clustrix Monitor optional parameters
|
## Xpand Monitor optional parameters
|
||||||
|
|
||||||
These are optional parameters specific to the Clustrix Monitor.
|
These are optional parameters specific to the Xpand Monitor.
|
||||||
|
|
||||||
### `cluster_monitor_interval`
|
### `cluster_monitor_interval`
|
||||||
|
|
||||||
@ -105,12 +108,12 @@ health_check_threshold=3
|
|||||||
|
|
||||||
### `dynamic_node_detection`
|
### `dynamic_node_detection`
|
||||||
|
|
||||||
By default, the Clustrix monitor will only use the bootstrap nodes
|
By default, the Xpand monitor will only use the bootstrap nodes
|
||||||
in order to connect to the Clustrix cluster and then find out the
|
in order to connect to the Xpand cluster and then find out the
|
||||||
cluster configuration dynamically at runtime.
|
cluster configuration dynamically at runtime.
|
||||||
|
|
||||||
That behaviour can be turned off with this optional parameter, in
|
That behaviour can be turned off with this optional parameter, in
|
||||||
which case all Clustrix nodes must manually be defined as shown below.
|
which case all Xpand nodes must manually be defined as shown below.
|
||||||
|
|
||||||
```
|
```
|
||||||
[Node-1]
|
[Node-1]
|
||||||
@ -125,9 +128,9 @@ port=3306
|
|||||||
[Node-3]
|
[Node-3]
|
||||||
...
|
...
|
||||||
|
|
||||||
[Clustrix-Monitor]
|
[TheXpandMonitor]
|
||||||
type=monitor
|
type=monitor
|
||||||
module=clustrixmon
|
module=xpandmon
|
||||||
servers=Node-1, Node-2, Node-3
|
servers=Node-1, Node-2, Node-3
|
||||||
dynamic_node_detection=false
|
dynamic_node_detection=false
|
||||||
```
|
```
|
||||||
@ -151,26 +154,26 @@ is `false`. Note also that the port must be the same for all nodes.
|
|||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
The Clustrix monitor supports the following module commands.
|
The Xpand monitor supports the following module commands.
|
||||||
|
|
||||||
### `softfail`
|
### `softfail`
|
||||||
|
|
||||||
With the `softfail` module command, a node can be _softfailed_ via
|
With the `softfail` module command, a node can be _softfailed_ via
|
||||||
MaxScale. The command requires as argument the name of the Clustrix
|
MaxScale. The command requires as argument the name of the Xpand
|
||||||
monitor instance (as defined in the configuration file) and the name
|
monitor instance (as defined in the configuration file) and the name
|
||||||
of the node to be softfailed.
|
of the node to be softfailed.
|
||||||
|
|
||||||
For instance, with a configuration file like
|
For instance, with a configuration file like
|
||||||
```
|
```
|
||||||
[TheClustrixMonitor]
|
[TheXpandMonitor]
|
||||||
type=monitor
|
type=monitor
|
||||||
module=clustrixmon
|
module=xpandmon
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
then the node whose server name is `@@TheClustrixMonitor:node-1` can
|
then the node whose server name is `@@TheXpandMonitor:node-1` can
|
||||||
be softfailed like
|
be softfailed like
|
||||||
```
|
```
|
||||||
$ maxctrl call command clustrixmon softfail TheClustrixMonitor @@TheClustrixMonitor:node-1
|
$ maxctrl call command xpandmon softfail TheXpandMonitor @@TheXpandMonitor:node-1
|
||||||
```
|
```
|
||||||
If the softfailing of a node is successfully initiated, then the status
|
If the softfailing of a node is successfully initiated, then the status
|
||||||
of the corresponding MaxScale server object will be set to `Draining`,
|
of the corresponding MaxScale server object will be set to `Draining`,
|
||||||
@ -184,14 +187,14 @@ of the softfailing operation is.
|
|||||||
### `unsoftfail`
|
### `unsoftfail`
|
||||||
|
|
||||||
With the `unsoftfail` module command, a node can be _unsoftfailed_ via
|
With the `unsoftfail` module command, a node can be _unsoftfailed_ via
|
||||||
MaxScale. The command requires as argument the name of the Clustrix
|
MaxScale. The command requires as argument the name of the Xpand
|
||||||
monitor instance (as defined in the configuration file) and the name
|
monitor instance (as defined in the configuration file) and the name
|
||||||
of the node to be unsoftfailed.
|
of the node to be unsoftfailed.
|
||||||
|
|
||||||
With a setup similar to the `softfail` case, a node can be unsoftfailed
|
With a setup similar to the `softfail` case, a node can be unsoftfailed
|
||||||
like:
|
like:
|
||||||
```
|
```
|
||||||
$ maxctrl call command clustrixmon unsoftfail TheClustrixMonitor @@TheClustrixMonitor:node-1
|
$ maxctrl call command xpandmon unsoftfail TheXpandMonitor @@TheXpandMonitor:node-1
|
||||||
```
|
```
|
||||||
If a node is successfully softfailed, then a `Draining` status of
|
If a node is successfully softfailed, then a `Draining` status of
|
||||||
the corresponding MaxScale server object will be cleared.
|
the corresponding MaxScale server object will be cleared.
|
||||||
@ -213,6 +216,6 @@ If a node that was softfailed is UNSOFTFAILed then the `Draining`
|
|||||||
status will be cleared.
|
status will be cleared.
|
||||||
|
|
||||||
If the softfailing and unsoftfailing is initiated using the `softfail`
|
If the softfailing and unsoftfailing is initiated using the `softfail`
|
||||||
and `unsoftfail` commands of the Clustrix monitor, then there will be
|
and `unsoftfail` commands of the Xpand monitor, then there will be
|
||||||
no delay between the softfailing or unsoftfailing being initated and the
|
no delay between the softfailing or unsoftfailing being initated and the
|
||||||
`Draining` status being turned on/off.
|
`Draining` status being turned on/off.
|
@ -120,22 +120,20 @@ value of `threads`.
|
|||||||
"type": "threads",
|
"type": "threads",
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"stats": {
|
"stats": {
|
||||||
"reads": 2,
|
"reads": 2, // Number of EPOLLIN events
|
||||||
"writes": 0,
|
"writes": 0, // number of EPOLLOUT events
|
||||||
"errors": 0,
|
"errors": 0, // Number of EPOLLERR events
|
||||||
"hangups": 0,
|
"hangups": 0, // Number of EPOLLHUP or EPOLLRDHUP events
|
||||||
"accepts": 0,
|
"accepts": 0, // Number of EPOLLIN events for listeners
|
||||||
"blocking_polls": 180,
|
"max_event_queue_length": 1, // Maximum number of events returned by epoll
|
||||||
"event_queue_length": 1,
|
"max_exec_time": 0, // Maximum number of internal ticks (100ms per tick) an event took to execute
|
||||||
"max_event_queue_length": 1,
|
"max_queue_time": 0, // Maximum number of internal ticks that an event waited in the queue
|
||||||
"max_exec_time": 0,
|
"current_descriptors": 1, // How many file descriptors this thread is handling
|
||||||
"max_queue_time": 0,
|
"total_descriptors": 1, // Total number of file descriptors added to this thread
|
||||||
"current_descriptors": 1,
|
"load": { // Thread load in percentages i.e. 100 is 100%
|
||||||
"total_descriptors": 1,
|
"last_second": 0, // Load over the past second
|
||||||
"load": {
|
"last_minute": 0, // Load over the past minute
|
||||||
"last_second": 0,
|
"last_hour": 0 // Load over the past hour
|
||||||
"last_minute": 0,
|
|
||||||
"last_hour": 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
# Configuring the Clustrix Monitor
|
# Configuring the Xpand Monitor
|
||||||
|
|
||||||
This document describes how to configure the Clustrix monitor for use
|
**NOTE** The Xpand monitor is intended for use with a native Xpand
|
||||||
with a Clustrix cluster.
|
cluster, not with the Xpand storage engine.
|
||||||
|
|
||||||
|
This document describes how to configure the Xpand monitor for use
|
||||||
|
with a Xpand cluster.
|
||||||
|
|
||||||
## Configuring the Monitor
|
## Configuring the Monitor
|
||||||
|
|
||||||
Contrary to the other monitors of MaxScale, the Clustrix monitor will
|
Contrary to the other monitors of MaxScale, the Xpand monitor will
|
||||||
autonomously figure out the cluster configuration and for each Clustrix
|
autonomously figure out the cluster configuration and for each Xpand
|
||||||
node create the corresponding MaxScale server object.
|
node create the corresponding MaxScale server object.
|
||||||
|
|
||||||
In order to do that, a _sufficient_ number of "bootstrap" server instances
|
In order to do that, a _sufficient_ number of "bootstrap" server instances
|
||||||
must be specified in the MaxScale configuration file for the Clustrix
|
must be specified in the MaxScale configuration file for the Xpand
|
||||||
monitor to start with. One server instance is in principle sufficient, but
|
monitor to start with. One server instance is in principle sufficient, but
|
||||||
if the corresponding node happens to be down when MaxScale starts, the
|
if the corresponding node happens to be down when MaxScale starts, the
|
||||||
monitor will not be able to function.
|
monitor will not be able to function.
|
||||||
@ -30,14 +33,14 @@ protocol=mariadbbackend
|
|||||||
```
|
```
|
||||||
|
|
||||||
The server configuration is identical with that of any other server, but since
|
The server configuration is identical with that of any other server, but since
|
||||||
these servers are _only_ used for bootstrapping the Clustrix monitor it is
|
these servers are _only_ used for bootstrapping the Xpand monitor it is
|
||||||
adviceable to use names that clearly will identify them as such.
|
adviceable to use names that clearly will identify them as such.
|
||||||
|
|
||||||
The actual Clustrix monitor configuration looks as follows:
|
The actual Xpand monitor configuration looks as follows:
|
||||||
```
|
```
|
||||||
[Clustrix]
|
[Xpand]
|
||||||
type=monitor
|
type=monitor
|
||||||
module=clustrixmon
|
module=xpandmon
|
||||||
servers=Bootstrap1, Bootstrap2
|
servers=Bootstrap1, Bootstrap2
|
||||||
user=monitor_user
|
user=monitor_user
|
||||||
password=monitor_password
|
password=monitor_password
|
||||||
@ -56,19 +59,19 @@ is, access the `system` tables of the Cluster for checking the Cluster
|
|||||||
configuration. The default values are `2000` and `60000`, that is, 2 seconds
|
configuration. The default values are `2000` and `60000`, that is, 2 seconds
|
||||||
and 1 minute, respectively.
|
and 1 minute, respectively.
|
||||||
|
|
||||||
For each detected Clustrix node a corresponding MaxScale server object will be
|
For each detected Xpand node a corresponding MaxScale server object will be
|
||||||
created, whose name is `@@<Monitor-Name>:node-<id>, where _Monitor-Name_
|
created, whose name is `@@<Monitor-Name>:node-<id>, where _Monitor-Name_
|
||||||
is the name of the monitor, in this example `Clustrix` and _id_ is the node id
|
is the name of the monitor, in this example `Xpand` and _id_ is the node id
|
||||||
of the Clustrix node. So, with a cluster of three nodes, the created servers
|
of the Xpand node. So, with a cluster of three nodes, the created servers
|
||||||
might be named like.
|
might be named like.
|
||||||
|
|
||||||
```
|
```
|
||||||
@@Clustrix:node-2`
|
@@Xpand:node-2`
|
||||||
@@Clustrix:node-3`
|
@@Xpand:node-3`
|
||||||
@@Clustrix:node-7`
|
@@Xpand:node-7`
|
||||||
```
|
```
|
||||||
Note that as these are created at runtime and may disappear at any moment,
|
Note that as these are created at runtime and may disappear at any moment,
|
||||||
depending on changes happening in and made to the Clustrix cluster, they
|
depending on changes happening in and made to the Xpand cluster, they
|
||||||
should never be referred to directly from service configurations. Instead,
|
should never be referred to directly from service configurations. Instead,
|
||||||
services should refer to the monitor, as shown in the following:
|
services should refer to the monitor, as shown in the following:
|
||||||
```
|
```
|
||||||
@ -77,12 +80,12 @@ type=service
|
|||||||
router=readconnroute
|
router=readconnroute
|
||||||
user=service_user
|
user=service_user
|
||||||
password=service_password
|
password=service_password
|
||||||
cluster=Clustrix
|
cluster=Xpand
|
||||||
```
|
```
|
||||||
Instead of listing the servers of the service explicitly using the `servers`
|
Instead of listing the servers of the service explicitly using the `servers`
|
||||||
parameter as usually is the case, the service refers to the Clustrix monitor
|
parameter as usually is the case, the service refers to the Xpand monitor
|
||||||
using the `cluster` parameter. This will cause the service to use the Clustrix
|
using the `cluster` parameter. This will cause the service to use the Xpand
|
||||||
nodes that the Clustrix monitor discovers at runtime.
|
nodes that the Xpand monitor discovers at runtime.
|
||||||
|
|
||||||
For additional details, please consult the monitor
|
For additional details, please consult the monitor
|
||||||
[documentation](../Monitors/Clustrix-Monitor.md).
|
[documentation](../Monitors/Xpand-Monitor.md).
|
@ -1,28 +1,31 @@
|
|||||||
# MaxScale and Clustrix Tutorial
|
# MaxScale and Xpand Tutorial
|
||||||
|
|
||||||
Since version 2.4, MaxScale has built-in support for Clustrix. This
|
**NOTE** The Xpand monitor is intended for use with a native Xpand
|
||||||
tutorial explains how to setup MaxScale in front of a Clustrix
|
cluster, not with the Xpand storage engine.
|
||||||
|
|
||||||
|
Since version 2.4, MaxScale has built-in support for Xpand. This
|
||||||
|
tutorial explains how to setup MaxScale in front of a Xpand
|
||||||
cluster.
|
cluster.
|
||||||
|
|
||||||
There is no Clustrix specific router, but both the
|
There is no Xpand specific router, but both the
|
||||||
[readconnroute](../Routers/ReadConnRoute.md) and
|
[readconnroute](../Routers/ReadConnRoute.md) and
|
||||||
the [readwritesplit](../Routers/ReadWriteSplit.md) routers can be
|
the [readwritesplit](../Routers/ReadWriteSplit.md) routers can be
|
||||||
used.
|
used.
|
||||||
|
|
||||||
## Clustrix and Readconnroute
|
## Xpand and Readconnroute
|
||||||
|
|
||||||
With _readconnroute_ you get simple connection based routing, where
|
With _readconnroute_ you get simple connection based routing, where
|
||||||
each new connection is created (by default) to the Clustrix node with
|
each new connection is created (by default) to the Xpand node with
|
||||||
the least amount of existing connections. That is, with readconnroute
|
the least amount of existing connections. That is, with readconnroute
|
||||||
the behaviour will be very similar to the behaviour when
|
the behaviour will be very similar to the behaviour when
|
||||||
[HAProxy](http://www.haproxy.org) is used as the Clustrix load
|
[HAProxy](http://www.haproxy.org) is used as the Xpand load
|
||||||
balancer.
|
balancer.
|
||||||
|
|
||||||
### Bootstrap servers
|
### Bootstrap servers
|
||||||
|
|
||||||
The Clustrix monitor is capable of autonomously figuring out the cluster
|
The Xpand monitor is capable of autonomously figuring out the cluster
|
||||||
configuration, but in order to get going there must be at least one
|
configuration, but in order to get going there must be at least one
|
||||||
_server_-section referring to a node in the Clustrix cluster.
|
_server_-section referring to a node in the Xpand cluster.
|
||||||
```
|
```
|
||||||
[Bootstrap-1]
|
[Bootstrap-1]
|
||||||
type=server
|
type=server
|
||||||
@ -31,31 +34,31 @@ port=3306
|
|||||||
protocol=MySQLBackend
|
protocol=MySQLBackend
|
||||||
```
|
```
|
||||||
That server defintion will be used by the monitor in order to connect
|
That server defintion will be used by the monitor in order to connect
|
||||||
to the Clustrix cluster. There can be more than one such "bootstrap"
|
to the Xpand cluster. There can be more than one such "bootstrap"
|
||||||
definition to cater for the case that the node used as a bootstrap
|
definition to cater for the case that the node used as a bootstrap
|
||||||
server is down when MaxScale starts.
|
server is down when MaxScale starts.
|
||||||
|
|
||||||
**NOTE** These bootstrap servers should _only_ be referred to from the
|
**NOTE** These bootstrap servers should _only_ be referred to from the
|
||||||
Clustrix monitor configuration, but _never_ from a service.
|
Xpand monitor configuration, but _never_ from a service.
|
||||||
|
|
||||||
### Monitor
|
### Monitor
|
||||||
|
|
||||||
In the Clustrix monitor section, the bootstrap servers are referred to
|
In the Xpand monitor section, the bootstrap servers are referred to
|
||||||
in the same way as "ordinary" servers are referred to in other monitors.
|
in the same way as "ordinary" servers are referred to in other monitors.
|
||||||
```
|
```
|
||||||
[Clustrix]
|
[Xpand]
|
||||||
type=monitor
|
type=monitor
|
||||||
module=clustrixmon
|
module=xpandmon
|
||||||
servers=Bootstrap-1
|
servers=Bootstrap-1
|
||||||
user=USER
|
user=USER
|
||||||
password=PASSWORD
|
password=PASSWORD
|
||||||
```
|
```
|
||||||
The bootstrap servers are only used for connecting to the Clustrix
|
The bootstrap servers are only used for connecting to the Xpand
|
||||||
cluster; thereafter the Clustrix monitor will dynamically find out the
|
cluster; thereafter the Xpand monitor will dynamically find out the
|
||||||
cluster configuration.
|
cluster configuration.
|
||||||
|
|
||||||
The discovered cluster configuration will be stored (the ips and ports
|
The discovered cluster configuration will be stored (the ips and ports
|
||||||
of the Clustrix nodes) and upon subsequent restarts the Clustrix
|
of the Xpand nodes) and upon subsequent restarts the Xpand
|
||||||
monitor will use that information if the bootstrap servers happen to
|
monitor will use that information if the bootstrap servers happen to
|
||||||
be unavailable.
|
be unavailable.
|
||||||
|
|
||||||
@ -65,11 +68,11 @@ the following:
|
|||||||
┌───────────────────┬──────────────┬──────┬─────────────┬─────────────────┬──────┐
|
┌───────────────────┬──────────────┬──────┬─────────────┬─────────────────┬──────┐
|
||||||
│ Server │ Address │ Port │ Connections │ State │ GTID │
|
│ Server │ Address │ Port │ Connections │ State │ GTID │
|
||||||
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
||||||
│ @@Clustrix:node-7 │ 10.2.224.102 │ 3306 │ 0 │ Master, Running │ │
|
│ @@Xpand:node-7 │ 10.2.224.102 │ 3306 │ 0 │ Master, Running │ │
|
||||||
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
||||||
│ @@Clustrix:node-8 │ 10.2.224.103 │ 3306 │ 0 │ Master, Running │ │
|
│ @@Xpand:node-8 │ 10.2.224.103 │ 3306 │ 0 │ Master, Running │ │
|
||||||
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
||||||
│ @@Clustrix:node-6 │ 10.2.224.101 │ 3306 │ 0 │ Master, Running │ │
|
│ @@Xpand:node-6 │ 10.2.224.101 │ 3306 │ 0 │ Master, Running │ │
|
||||||
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
├───────────────────┼──────────────┼──────┼─────────────┼─────────────────┼──────┤
|
||||||
│ Bootstrap-1 │ 10.2.224.101 │ 3306 │ 0 │ Master, Running │ │
|
│ Bootstrap-1 │ 10.2.224.101 │ 3306 │ 0 │ Master, Running │ │
|
||||||
└───────────────────┴──────────────┴──────┴─────────────┴─────────────────┴──────┘
|
└───────────────────┴──────────────┴──────┴─────────────┴─────────────────┴──────┘
|
||||||
@ -77,29 +80,29 @@ the following:
|
|||||||
All servers whose name start with `@@` have been detected dynamically.
|
All servers whose name start with `@@` have been detected dynamically.
|
||||||
|
|
||||||
Note that the address `10.2.224.101` appears twice; once for
|
Note that the address `10.2.224.101` appears twice; once for
|
||||||
`Bootstrap-1` and another time for `@@Clustrix:node-6`. The Clustrix
|
`Bootstrap-1` and another time for `@@Xpand:node-6`. The Xpand
|
||||||
monitor will create a dynamic server instance for _all_ nodes in the
|
monitor will create a dynamic server instance for _all_ nodes in the
|
||||||
Clustrix cluster; also for the ones used in bootstrap server sections.
|
Xpand cluster; also for the ones used in bootstrap server sections.
|
||||||
|
|
||||||
### Service
|
### Service
|
||||||
|
|
||||||
The service is specified as follows:
|
The service is specified as follows:
|
||||||
```
|
```
|
||||||
[Clustrix-Service]
|
[Xpand-Service]
|
||||||
type=service
|
type=service
|
||||||
router=readconnroute
|
router=readconnroute
|
||||||
user=USER
|
user=USER
|
||||||
password=PASSWORD
|
password=PASSWORD
|
||||||
cluster=Clustrix
|
cluster=Xpand
|
||||||
```
|
```
|
||||||
Note that the service does *not* list any specific servers, but
|
Note that the service does *not* list any specific servers, but
|
||||||
instead refers, using the argument `cluster`, to the Clustrix monitor.
|
instead refers, using the argument `cluster`, to the Xpand monitor.
|
||||||
|
|
||||||
In practice this means that the service will use the servers of the
|
In practice this means that the service will use the servers of the
|
||||||
monitor named `Clustrix` and in the case of a Clustrix monitor those
|
monitor named `Xpand` and in the case of a Xpand monitor those
|
||||||
servers will be the ones that the monitor has detected
|
servers will be the ones that the monitor has detected
|
||||||
dynamically. That is, when setup like this, the service will
|
dynamically. That is, when setup like this, the service will
|
||||||
automatically adjust to any changes taking place in the Clustrix
|
automatically adjust to any changes taking place in the Xpand
|
||||||
cluster.
|
cluster.
|
||||||
|
|
||||||
**NOTE** There is no need to specify any `router_options`, but the
|
**NOTE** There is no need to specify any `router_options`, but the
|
||||||
@ -111,25 +114,25 @@ cause only a _single_ node to be used.
|
|||||||
|
|
||||||
To complete the configuration, a listener must be specified.
|
To complete the configuration, a listener must be specified.
|
||||||
```
|
```
|
||||||
[Clustrix-Service-Listener]
|
[Xpand-Service-Listener]
|
||||||
type=listener
|
type=listener
|
||||||
service=Clustrix-Service
|
service=Xpand-Service
|
||||||
protocol=MariaDBClient
|
protocol=MariaDBClient
|
||||||
port=4008
|
port=4008
|
||||||
```
|
```
|
||||||
|
|
||||||
## Clustrix and Readwritesplit
|
## Xpand and Readwritesplit
|
||||||
|
|
||||||
The primary purpose of the router _readwritesplit_ is to split
|
The primary purpose of the router _readwritesplit_ is to split
|
||||||
statements between one master and multiple slaves. In the case of
|
statements between one master and multiple slaves. In the case of
|
||||||
Clustrix, all servers will be masters, but _readwritesplit_ may still
|
Xpand, all servers will be masters, but _readwritesplit_ may still
|
||||||
be the right choise.
|
be the right choise.
|
||||||
|
|
||||||
Namely, as _readwritesplit_ is transaction aware and capable of
|
Namely, as _readwritesplit_ is transaction aware and capable of
|
||||||
replaying transactions, it can be used for hiding certain events
|
replaying transactions, it can be used for hiding certain events
|
||||||
taking place in Clustrix from the clients that use it.
|
taking place in Xpand from the clients that use it.
|
||||||
|
|
||||||
For instance, whenever a node is removed from or added to a Clustrix
|
For instance, whenever a node is removed from or added to a Xpand
|
||||||
cluster there will be a _group change_, which is visible to a client
|
cluster there will be a _group change_, which is visible to a client
|
||||||
as a transaction rollback. However, if _readwritesplit_ is used and
|
as a transaction rollback. However, if _readwritesplit_ is used and
|
||||||
transaction replay is enabled, then MaxScale may be able to hide the
|
transaction replay is enabled, then MaxScale may be able to hide the
|
||||||
@ -143,12 +146,12 @@ described above.
|
|||||||
|
|
||||||
The service is specified as follows:
|
The service is specified as follows:
|
||||||
```
|
```
|
||||||
[Clustrix-Service]
|
[Xpand-Service]
|
||||||
type=service
|
type=service
|
||||||
router=readwritesplit
|
router=readwritesplit
|
||||||
user=maxscale
|
user=maxscale
|
||||||
password=maxscale
|
password=maxscale
|
||||||
cluster=Clustrix
|
cluster=Xpand
|
||||||
transaction_replay=true
|
transaction_replay=true
|
||||||
slave_selection_criteria=LEAST_GLOBAL_CONNECTIONS
|
slave_selection_criteria=LEAST_GLOBAL_CONNECTIONS
|
||||||
```
|
```
|
||||||
@ -163,7 +166,7 @@ to the _readwritesplit_
|
|||||||
|
|
||||||
**NOTE** It is vital to have
|
**NOTE** It is vital to have
|
||||||
`slave_selection_criteria=LEAST_GLOBAL_CONNECTIONS`, as otherwise
|
`slave_selection_criteria=LEAST_GLOBAL_CONNECTIONS`, as otherwise
|
||||||
connections will **not** be distributed evenly across all Clustrix
|
connections will **not** be distributed evenly across all Xpand
|
||||||
nodes.
|
nodes.
|
||||||
|
|
||||||
As a rule of thumb, use _readwritesplit_ if it is important that
|
As a rule of thumb, use _readwritesplit_ if it is important that
|
@ -65,6 +65,7 @@ struct NAME_MAPPING
|
|||||||
|
|
||||||
static NAME_MAPPING name_mappings[] =
|
static NAME_MAPPING name_mappings[] =
|
||||||
{
|
{
|
||||||
|
{MODULE_MONITOR, "clustrixmon", "xpandmon", false},
|
||||||
{MODULE_MONITOR, "mysqlmon", "mariadbmon", false},
|
{MODULE_MONITOR, "mysqlmon", "mariadbmon", false},
|
||||||
{MODULE_PROTOCOL, "mysqlclient", "mariadbclient", false},
|
{MODULE_PROTOCOL, "mysqlclient", "mariadbclient", false},
|
||||||
{MODULE_PROTOCOL, "mysqlbackend", "mariadbbackend", false},
|
{MODULE_PROTOCOL, "mysqlbackend", "mariadbbackend", false},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
add_subdirectory(auroramon)
|
add_subdirectory(auroramon)
|
||||||
add_subdirectory(clustrixmon)
|
|
||||||
add_subdirectory(csmon)
|
add_subdirectory(csmon)
|
||||||
add_subdirectory(galeramon)
|
add_subdirectory(galeramon)
|
||||||
add_subdirectory(grmon)
|
add_subdirectory(grmon)
|
||||||
add_subdirectory(mariadbmon)
|
add_subdirectory(mariadbmon)
|
||||||
|
add_subdirectory(xpandmon)
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
add_library(clustrixmon SHARED
|
|
||||||
clustrix.cc
|
|
||||||
clustrixmon.cc
|
|
||||||
clustrixmonitor.cc
|
|
||||||
clustrixnode.cc
|
|
||||||
)
|
|
||||||
target_link_libraries(clustrixmon maxscale-common)
|
|
||||||
set_target_properties(clustrixmon PROPERTIES VERSION "1.0.0" LINK_FLAGS -Wl,-z,defs)
|
|
||||||
install_module(clustrixmon core)
|
|
9
server/modules/monitor/xpandmon/CMakeLists.txt
Normal file
9
server/modules/monitor/xpandmon/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
add_library(xpandmon SHARED
|
||||||
|
xpand.cc
|
||||||
|
xpandmon.cc
|
||||||
|
xpandmonitor.cc
|
||||||
|
xpandnode.cc
|
||||||
|
)
|
||||||
|
target_link_libraries(xpandmon maxscale-common)
|
||||||
|
set_target_properties(xpandmon PROPERTIES VERSION "1.0.0" LINK_FLAGS -Wl,-z,defs)
|
||||||
|
install_module(xpandmon core)
|
@ -11,7 +11,7 @@
|
|||||||
* Public License.
|
* Public License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clustrix.hh"
|
#include "xpand.hh"
|
||||||
#include <maxbase/assert.h>
|
#include <maxbase/assert.h>
|
||||||
|
|
||||||
using maxscale::Monitor;
|
using maxscale::Monitor;
|
||||||
@ -27,7 +27,7 @@ const char CN_STATIC[] = "static";
|
|||||||
const char CN_UNKNOWN[] = "unknown";
|
const char CN_UNKNOWN[] = "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Clustrix::to_string(Clustrix::Status status)
|
std::string xpand::to_string(xpand::Status status)
|
||||||
{
|
{
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
@ -48,7 +48,7 @@ std::string Clustrix::to_string(Clustrix::Status status)
|
|||||||
return CN_UNKNOWN;
|
return CN_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clustrix::Status Clustrix::status_from_string(const std::string& status)
|
xpand::Status xpand::status_from_string(const std::string& status)
|
||||||
{
|
{
|
||||||
if (status == CN_QUORUM)
|
if (status == CN_QUORUM)
|
||||||
{
|
{
|
||||||
@ -64,12 +64,12 @@ Clustrix::Status Clustrix::status_from_string(const std::string& status)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MXB_WARNING("'%s' is an unknown status for a Clustrix node.", status.c_str());
|
MXB_WARNING("'%s' is an unknown status for a Xpand node.", status.c_str());
|
||||||
return Status::UNKNOWN;
|
return Status::UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Clustrix::to_string(Clustrix::SubState substate)
|
std::string xpand::to_string(xpand::SubState substate)
|
||||||
{
|
{
|
||||||
switch (substate)
|
switch (substate)
|
||||||
{
|
{
|
||||||
@ -84,7 +84,7 @@ std::string Clustrix::to_string(Clustrix::SubState substate)
|
|||||||
return CN_UNKNOWN;
|
return CN_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clustrix::SubState Clustrix::substate_from_string(const std::string& substate)
|
xpand::SubState xpand::substate_from_string(const std::string& substate)
|
||||||
{
|
{
|
||||||
if (substate == CN_NORMAL)
|
if (substate == CN_NORMAL)
|
||||||
{
|
{
|
||||||
@ -92,12 +92,12 @@ Clustrix::SubState Clustrix::substate_from_string(const std::string& substate)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MXB_WARNING("'%s' is an unknown sub-state for a Clustrix node.", substate.c_str());
|
MXB_WARNING("'%s' is an unknown sub-state for a Xpand node.", substate.c_str());
|
||||||
return SubState::UNKNOWN;
|
return SubState::UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Clustrix::is_part_of_the_quorum(const char* zName, MYSQL* pCon)
|
bool xpand::is_part_of_the_quorum(const char* zName, MYSQL* pCon)
|
||||||
{
|
{
|
||||||
bool rv = false;
|
bool rv = false;
|
||||||
|
|
||||||
@ -114,27 +114,27 @@ bool Clustrix::is_part_of_the_quorum(const char* zName, MYSQL* pCon)
|
|||||||
MYSQL_ROW row = mysql_fetch_row(pResult);
|
MYSQL_ROW row = mysql_fetch_row(pResult);
|
||||||
if (row && row[0])
|
if (row && row[0])
|
||||||
{
|
{
|
||||||
Clustrix::Status status = Clustrix::status_from_string(row[0]);
|
xpand::Status status = xpand::status_from_string(row[0]);
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case Clustrix::Status::QUORUM:
|
case xpand::Status::QUORUM:
|
||||||
rv = true;
|
rv = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Clustrix::Status::STATIC:
|
case xpand::Status::STATIC:
|
||||||
MXS_NOTICE("%s: Node %s is not part of the quorum (static), switching to "
|
MXS_NOTICE("%s: Node %s is not part of the quorum (static), switching to "
|
||||||
"other node for monitoring.",
|
"other node for monitoring.",
|
||||||
zName, mysql_get_host_info(pCon));
|
zName, mysql_get_host_info(pCon));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Clustrix::Status::DYNAMIC:
|
case xpand::Status::DYNAMIC:
|
||||||
MXS_NOTICE("%s: Node %s is not part of the quorum (dynamic), switching to "
|
MXS_NOTICE("%s: Node %s is not part of the quorum (dynamic), switching to "
|
||||||
"other node for monitoring.",
|
"other node for monitoring.",
|
||||||
zName, mysql_get_host_info(pCon));
|
zName, mysql_get_host_info(pCon));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Clustrix::Status::UNKNOWN:
|
case xpand::Status::UNKNOWN:
|
||||||
MXS_WARNING("%s: Do not know how to interpret '%s'. Assuming node %s "
|
MXS_WARNING("%s: Do not know how to interpret '%s'. Assuming node %s "
|
||||||
"is not part of the quorum.",
|
"is not part of the quorum.",
|
||||||
zName, row[0], mysql_get_host_info(pCon));
|
zName, row[0], mysql_get_host_info(pCon));
|
||||||
@ -163,7 +163,7 @@ bool Clustrix::is_part_of_the_quorum(const char* zName, MYSQL* pCon)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Clustrix::is_being_softfailed(const char* zName, MYSQL* pCon)
|
bool xpand::is_being_softfailed(const char* zName, MYSQL* pCon)
|
||||||
{
|
{
|
||||||
bool rv = false;
|
bool rv = false;
|
||||||
|
|
||||||
@ -201,22 +201,22 @@ bool Clustrix::is_being_softfailed(const char* zName, MYSQL* pCon)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Clustrix::ping_or_connect_to_hub(const char* zName,
|
bool xpand::ping_or_connect_to_hub(const char* zName,
|
||||||
const MonitorServer::ConnectionSettings& settings,
|
const MonitorServer::ConnectionSettings& settings,
|
||||||
Softfailed softfailed,
|
Softfailed softfailed,
|
||||||
SERVER& server,
|
SERVER& server,
|
||||||
MYSQL** ppCon)
|
MYSQL** ppCon)
|
||||||
{
|
{
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
MonitorServer::ConnectResult rv = Monitor::ping_or_connect_to_db(settings, server, ppCon);
|
MonitorServer::ConnectResult rv = Monitor::ping_or_connect_to_db(settings, server, ppCon);
|
||||||
|
|
||||||
if (Monitor::connection_is_ok(rv))
|
if (Monitor::connection_is_ok(rv))
|
||||||
{
|
{
|
||||||
if (Clustrix::is_part_of_the_quorum(zName, *ppCon))
|
if (xpand::is_part_of_the_quorum(zName, *ppCon))
|
||||||
{
|
{
|
||||||
if ((softfailed == Softfailed::REJECT) && Clustrix::is_being_softfailed(zName, *ppCon))
|
if ((softfailed == Softfailed::REJECT) && xpand::is_being_softfailed(zName, *ppCon))
|
||||||
{
|
{
|
||||||
MXS_NOTICE("%s: The Clustrix node %s used as hub is part of the quorum, "
|
MXS_NOTICE("%s: The Xpand node %s used as hub is part of the quorum, "
|
||||||
"but it is being softfailed. Switching to another node.",
|
"but it is being softfailed. Switching to another node.",
|
||||||
zName, server.address);
|
zName, server.address);
|
||||||
}
|
}
|
@ -12,12 +12,12 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "clustrixmon.hh"
|
#include "xpandmon.hh"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <maxscale/monitor.hh>
|
#include <maxscale/monitor.hh>
|
||||||
#include <maxscale/server.hh>
|
#include <maxscale/server.hh>
|
||||||
|
|
||||||
namespace Clustrix
|
namespace xpand
|
||||||
{
|
{
|
||||||
|
|
||||||
enum class Status
|
enum class Status
|
||||||
@ -47,9 +47,9 @@ enum class Softfailed
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is a particular Clustrix node part of the quorum.
|
* Is a particular Xpand node part of the quorum.
|
||||||
*
|
*
|
||||||
* @param zName The name of the Clustrix monitor instance.
|
* @param zName The name of the Xpand monitor instance.
|
||||||
* @param pCon Valid MYSQL handle to the server.
|
* @param pCon Valid MYSQL handle to the server.
|
||||||
*
|
*
|
||||||
* @return True, if the node is part of the quorum, false otherwise.
|
* @return True, if the node is part of the quorum, false otherwise.
|
||||||
@ -57,10 +57,10 @@ enum class Softfailed
|
|||||||
bool is_part_of_the_quorum(const char* zName, MYSQL* pCon);
|
bool is_part_of_the_quorum(const char* zName, MYSQL* pCon);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is a particular Clustrix node part of the quorum.
|
* Is a particular Xpand node part of the quorum.
|
||||||
*
|
*
|
||||||
* @param zName The name of the Clustrix monitor instance.
|
* @param zName The name of the Xpand monitor instance.
|
||||||
* @param ms The monitored server object of a Clustrix node.
|
* @param ms The monitored server object of a Xpand node.
|
||||||
*
|
*
|
||||||
* @return True, if the node is part of the quorum, false otherwise.
|
* @return True, if the node is part of the quorum, false otherwise.
|
||||||
*/
|
*/
|
||||||
@ -72,9 +72,9 @@ inline bool is_part_of_the_quorum(const char* zName, mxs::MonitorServer& ms)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is a particular Clustrix node being softfailed.
|
* Is a particular Xpand node being softfailed.
|
||||||
*
|
*
|
||||||
* @param zName The name of the Clustrix monitor instance.
|
* @param zName The name of the Xpand monitor instance.
|
||||||
* @param pCon Valid MYSQL handle to the server.
|
* @param pCon Valid MYSQL handle to the server.
|
||||||
*
|
*
|
||||||
* @return True, if the node is being softfailed, false otherwise.
|
* @return True, if the node is being softfailed, false otherwise.
|
||||||
@ -85,10 +85,10 @@ bool is_being_softfailed(const char* zName, MYSQL* pCon);
|
|||||||
* Ping or create connection to server and check whether it can be used
|
* Ping or create connection to server and check whether it can be used
|
||||||
* as hub.
|
* as hub.
|
||||||
*
|
*
|
||||||
* @param zName The name of the Clustrix monitor instance.
|
* @param zName The name of the Xpand monitor instance.
|
||||||
* @param settings Connection settings
|
* @param settings Connection settings
|
||||||
* @param softfailed Whether a softfailed node is considered ok or not.
|
* @param softfailed Whether a softfailed node is considered ok or not.
|
||||||
* @param server Server object referring to a Clustrix node.
|
* @param server Server object referring to a Xpand node.
|
||||||
* @param ppCon Address of pointer to MYSQL object referring to @server
|
* @param ppCon Address of pointer to MYSQL object referring to @server
|
||||||
* (@c *ppCon may also be NULL).
|
* (@c *ppCon may also be NULL).
|
||||||
*
|
*
|
||||||
@ -106,7 +106,7 @@ bool ping_or_connect_to_hub(const char* zName,
|
|||||||
* Ping or create connection to server and check whether it can be used
|
* Ping or create connection to server and check whether it can be used
|
||||||
* as hub.
|
* as hub.
|
||||||
*
|
*
|
||||||
* @param zName The name of the Clustrix monitor instance.
|
* @param zName The name of the Xpand monitor instance.
|
||||||
* @param settings Connection settings
|
* @param settings Connection settings
|
||||||
* @param softfailed Whether a softfailed node is considered ok or not.
|
* @param softfailed Whether a softfailed node is considered ok or not.
|
||||||
* @param ms The monitored server.
|
* @param ms The monitored server.
|
@ -12,19 +12,19 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "clustrixmon.hh"
|
#include "xpandmon.hh"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "clustrix.hh"
|
#include "xpand.hh"
|
||||||
|
|
||||||
class ClustrixMembership
|
class XpandMembership
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ClustrixMembership(int id,
|
XpandMembership(int id,
|
||||||
Clustrix::Status status,
|
xpand::Status status,
|
||||||
Clustrix::SubState substate,
|
xpand::SubState substate,
|
||||||
int instance)
|
int instance)
|
||||||
: m_id(id)
|
: m_id(id)
|
||||||
, m_status(status)
|
, m_status(status)
|
||||||
, m_substate(substate)
|
, m_substate(substate)
|
||||||
@ -37,12 +37,12 @@ public:
|
|||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clustrix::Status status() const
|
xpand::Status status() const
|
||||||
{
|
{
|
||||||
return m_status;
|
return m_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clustrix::SubState substate() const
|
xpand::SubState substate() const
|
||||||
{
|
{
|
||||||
return m_substate;
|
return m_substate;
|
||||||
}
|
}
|
||||||
@ -57,8 +57,8 @@ public:
|
|||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "{"
|
ss << "{"
|
||||||
<< m_id << ", "
|
<< m_id << ", "
|
||||||
<< Clustrix::to_string(m_status) << ", "
|
<< xpand::to_string(m_status) << ", "
|
||||||
<< Clustrix::to_string(m_substate) << ", "
|
<< xpand::to_string(m_substate) << ", "
|
||||||
<< m_instance
|
<< m_instance
|
||||||
<< "}";
|
<< "}";
|
||||||
return ss.str();
|
return ss.str();
|
||||||
@ -70,13 +70,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_id;
|
int m_id;
|
||||||
Clustrix::Status m_status;
|
xpand::Status m_status;
|
||||||
Clustrix::SubState m_substate;
|
xpand::SubState m_substate;
|
||||||
int m_instance;
|
int m_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const ClustrixMembership& x)
|
inline std::ostream& operator<<(std::ostream& out, const XpandMembership& x)
|
||||||
{
|
{
|
||||||
x.print(out);
|
x.print(out);
|
||||||
return out;
|
return out;
|
@ -11,10 +11,10 @@
|
|||||||
* Public License.
|
* Public License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clustrixmon.hh"
|
#include "xpandmon.hh"
|
||||||
#include <maxscale/modinfo.h>
|
#include <maxscale/modinfo.h>
|
||||||
#include <maxscale/modulecmd.hh>
|
#include <maxscale/modulecmd.hh>
|
||||||
#include "clustrixmonitor.hh"
|
#include "xpandmonitor.hh"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -25,7 +25,7 @@ bool handle_softfail(const MODULECMD_ARG* args, json_t** error_out)
|
|||||||
mxb_assert(MODULECMD_GET_TYPE(&args->argv[0].type) == MODULECMD_ARG_MONITOR);
|
mxb_assert(MODULECMD_GET_TYPE(&args->argv[0].type) == MODULECMD_ARG_MONITOR);
|
||||||
mxb_assert(MODULECMD_GET_TYPE(&args->argv[1].type) == MODULECMD_ARG_SERVER);
|
mxb_assert(MODULECMD_GET_TYPE(&args->argv[1].type) == MODULECMD_ARG_SERVER);
|
||||||
|
|
||||||
ClustrixMonitor* pMon = static_cast<ClustrixMonitor*>(args->argv[0].value.monitor);
|
XpandMonitor* pMon = static_cast<XpandMonitor*>(args->argv[0].value.monitor);
|
||||||
SERVER* pServer = args->argv[1].value.server;
|
SERVER* pServer = args->argv[1].value.server;
|
||||||
|
|
||||||
return pMon->softfail(pServer, error_out);
|
return pMon->softfail(pServer, error_out);
|
||||||
@ -37,7 +37,7 @@ bool handle_unsoftfail(const MODULECMD_ARG* args, json_t** error_out)
|
|||||||
mxb_assert(MODULECMD_GET_TYPE(&args->argv[0].type) == MODULECMD_ARG_MONITOR);
|
mxb_assert(MODULECMD_GET_TYPE(&args->argv[0].type) == MODULECMD_ARG_MONITOR);
|
||||||
mxb_assert(MODULECMD_GET_TYPE(&args->argv[1].type) == MODULECMD_ARG_SERVER);
|
mxb_assert(MODULECMD_GET_TYPE(&args->argv[1].type) == MODULECMD_ARG_SERVER);
|
||||||
|
|
||||||
ClustrixMonitor* pMon = static_cast<ClustrixMonitor*>(args->argv[0].value.monitor);
|
XpandMonitor* pMon = static_cast<XpandMonitor*>(args->argv[0].value.monitor);
|
||||||
SERVER* pServer = args->argv[1].value.server;
|
SERVER* pServer = args->argv[1].value.server;
|
||||||
|
|
||||||
return pMon->unsoftfail(pServer, error_out);
|
return pMon->unsoftfail(pServer, error_out);
|
||||||
@ -54,7 +54,7 @@ bool handle_unsoftfail(const MODULECMD_ARG* args, json_t** error_out)
|
|||||||
*/
|
*/
|
||||||
extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||||
{
|
{
|
||||||
MXS_NOTICE("Initialise the MariaDB Clustrix Monitor module.");
|
MXS_NOTICE("Initialise the MariaDB Xpand Monitor module.");
|
||||||
|
|
||||||
static modulecmd_arg_type_t softfail_argv[] =
|
static modulecmd_arg_type_t softfail_argv[] =
|
||||||
{
|
{
|
||||||
@ -91,17 +91,17 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
|||||||
MXS_MODULE_API_MONITOR,
|
MXS_MODULE_API_MONITOR,
|
||||||
MXS_MODULE_GA,
|
MXS_MODULE_GA,
|
||||||
MXS_MONITOR_VERSION,
|
MXS_MONITOR_VERSION,
|
||||||
"A Clustrix cluster monitor",
|
"A Xpand cluster monitor",
|
||||||
"V1.0.0",
|
"V1.0.0",
|
||||||
MXS_NO_MODULE_CAPABILITIES,
|
MXS_NO_MODULE_CAPABILITIES,
|
||||||
&maxscale::MonitorApi<ClustrixMonitor>::s_api,
|
&maxscale::MonitorApi<XpandMonitor>::s_api,
|
||||||
NULL, /* Process init. */
|
NULL, /* Process init. */
|
||||||
NULL, /* Process finish. */
|
NULL, /* Process finish. */
|
||||||
NULL, /* Thread init. */
|
NULL, /* Thread init. */
|
||||||
NULL, /* Thread finish. */
|
NULL, /* Thread finish. */
|
||||||
};
|
};
|
||||||
|
|
||||||
ClustrixMonitor::Config::populate(info);
|
XpandMonitor::Config::populate(info);
|
||||||
|
|
||||||
return &info;
|
return &info;
|
||||||
}
|
}
|
@ -12,7 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define MXS_MODULE_NAME "clustrixmon"
|
#define MXS_MODULE_NAME "xpandmon"
|
||||||
|
|
||||||
#include <maxscale/ccdefs.hh>
|
#include <maxscale/ccdefs.hh>
|
||||||
#include <maxbase/log.hh>
|
#include <maxbase/log.hh>
|
@ -11,7 +11,7 @@
|
|||||||
* Public License.
|
* Public License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clustrixmonitor.hh"
|
#include "xpandmonitor.hh"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <maxbase/string.hh>
|
#include <maxbase/string.hh>
|
||||||
@ -26,19 +26,19 @@ namespace http = mxb::http;
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using maxscale::MonitorServer;
|
using maxscale::MonitorServer;
|
||||||
|
|
||||||
#define LOG_JSON_ERROR(ppJson, format, ...) \
|
#define LOG_JSON_ERROR(ppJson, format, ...) \
|
||||||
do { \
|
do { \
|
||||||
MXS_ERROR(format, ##__VA_ARGS__); \
|
MXS_ERROR(format, ##__VA_ARGS__); \
|
||||||
if (ppJson) \
|
if (ppJson) \
|
||||||
{ \
|
{ \
|
||||||
*ppJson = mxs_json_error_append(*ppJson, format, ##__VA_ARGS__); \
|
*ppJson = mxs_json_error_append(*ppJson, format, ##__VA_ARGS__); \
|
||||||
} \
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace clustrixmon
|
namespace xpandmon
|
||||||
{
|
{
|
||||||
|
|
||||||
config::Specification specification(MXS_MODULE_NAME, config::Specification::MONITOR);
|
config::Specification specification(MXS_MODULE_NAME, config::Specification::MONITOR);
|
||||||
@ -46,7 +46,7 @@ config::Specification specification(MXS_MODULE_NAME, config::Specification::MONI
|
|||||||
config::ParamDuration<std::chrono::milliseconds>
|
config::ParamDuration<std::chrono::milliseconds>
|
||||||
cluster_monitor_interval(&specification,
|
cluster_monitor_interval(&specification,
|
||||||
"cluster_monitor_interval",
|
"cluster_monitor_interval",
|
||||||
"How frequently the Clustrix monitor should perform a cluster check.",
|
"How frequently the Xpand monitor should perform a cluster check.",
|
||||||
mxs::config::INTERPRET_AS_MILLISECONDS,
|
mxs::config::INTERPRET_AS_MILLISECONDS,
|
||||||
std::chrono::milliseconds(DEFAULT_CLUSTER_MONITOR_INTERVAL));
|
std::chrono::milliseconds(DEFAULT_CLUSTER_MONITOR_INTERVAL));
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ dynamic_node_detection(&specification,
|
|||||||
config::ParamInteger
|
config::ParamInteger
|
||||||
health_check_port(&specification,
|
health_check_port(&specification,
|
||||||
"health_check_port",
|
"health_check_port",
|
||||||
"Port number for Clustrix health check.",
|
"Port number for Xpand health check.",
|
||||||
DEFAULT_HEALTH_CHECK_PORT,
|
DEFAULT_HEALTH_CHECK_PORT,
|
||||||
0, std::numeric_limits<uint16_t>::max()); // min, max
|
0, std::numeric_limits<uint16_t>::max()); // min, max
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ sqlite3* open_or_create_db(const std::string& path)
|
|||||||
path.c_str(), sqlite3_errmsg(pDb));
|
path.c_str(), sqlite3_errmsg(pDb));
|
||||||
}
|
}
|
||||||
MXS_ERROR("Could not open sqlite3 database for storing information "
|
MXS_ERROR("Could not open sqlite3 database for storing information "
|
||||||
"about dynamically detected Clustrix nodes. The Clustrix "
|
"about dynamically detected Xpand nodes. The Xpand "
|
||||||
"monitor will remain dependent upon statically defined "
|
"monitor will remain dependent upon statically defined "
|
||||||
"bootstrap nodes.");
|
"bootstrap nodes.");
|
||||||
}
|
}
|
||||||
@ -195,40 +195,40 @@ sqlite3* open_or_create_db(const std::string& path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClustrixMonitor::Config::Config(const std::string& name)
|
XpandMonitor::Config::Config(const std::string& name)
|
||||||
: m_configuration(name, &clustrixmon::specification)
|
: m_configuration(name, &xpandmon::specification)
|
||||||
, m_cluster_monitor_interval(&m_configuration, &clustrixmon::cluster_monitor_interval)
|
, m_cluster_monitor_interval(&m_configuration, &xpandmon::cluster_monitor_interval)
|
||||||
, m_health_check_threshold(&m_configuration, &clustrixmon::health_check_threshold)
|
, m_health_check_threshold(&m_configuration, &xpandmon::health_check_threshold)
|
||||||
, m_dynamic_node_detection(&m_configuration, &clustrixmon::dynamic_node_detection)
|
, m_dynamic_node_detection(&m_configuration, &xpandmon::dynamic_node_detection)
|
||||||
, m_health_check_port(&m_configuration, &clustrixmon::health_check_port)
|
, m_health_check_port(&m_configuration, &xpandmon::health_check_port)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
//static
|
||||||
void ClustrixMonitor::Config::populate(MXS_MODULE& module)
|
void XpandMonitor::Config::populate(MXS_MODULE& module)
|
||||||
{
|
{
|
||||||
clustrixmon::specification.populate(module);
|
xpandmon::specification.populate(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::Config::configure(const MXS_CONFIG_PARAMETER& params)
|
bool XpandMonitor::Config::configure(const MXS_CONFIG_PARAMETER& params)
|
||||||
{
|
{
|
||||||
return clustrixmon::specification.configure(m_configuration, params);
|
return xpandmon::specification.configure(m_configuration, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClustrixMonitor::ClustrixMonitor(const string& name, const string& module, sqlite3* pDb)
|
XpandMonitor::XpandMonitor(const string& name, const string& module, sqlite3* pDb)
|
||||||
: MonitorWorker(name, module)
|
: MonitorWorker(name, module)
|
||||||
, m_config(name)
|
, m_config(name)
|
||||||
, m_pDb(pDb)
|
, m_pDb(pDb)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ClustrixMonitor::~ClustrixMonitor()
|
XpandMonitor::~XpandMonitor()
|
||||||
{
|
{
|
||||||
sqlite3_close_v2(m_pDb);
|
sqlite3_close_v2(m_pDb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ClustrixMonitor* ClustrixMonitor::create(const string& name, const string& module)
|
XpandMonitor* XpandMonitor::create(const string& name, const string& module)
|
||||||
{
|
{
|
||||||
string path = get_datadir();
|
string path = get_datadir();
|
||||||
|
|
||||||
@ -239,29 +239,29 @@ ClustrixMonitor* ClustrixMonitor::create(const string& name, const string& modul
|
|||||||
{
|
{
|
||||||
MXS_ERROR("Could not create the directory %s, MaxScale will not be "
|
MXS_ERROR("Could not create the directory %s, MaxScale will not be "
|
||||||
"able to create database for persisting connection "
|
"able to create database for persisting connection "
|
||||||
"information of dynamically detected Clustrix nodes.",
|
"information of dynamically detected Xpand nodes.",
|
||||||
path.c_str());
|
path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
path += "/clustrix_nodes-v";
|
path += "/xpand_nodes-v";
|
||||||
path += std::to_string(SCHEMA_VERSION);
|
path += std::to_string(SCHEMA_VERSION);
|
||||||
path += ".db";
|
path += ".db";
|
||||||
|
|
||||||
sqlite3* pDb = open_or_create_db(path);
|
sqlite3* pDb = open_or_create_db(path);
|
||||||
|
|
||||||
ClustrixMonitor* pThis = nullptr;
|
XpandMonitor* pThis = nullptr;
|
||||||
|
|
||||||
if (pDb)
|
if (pDb)
|
||||||
{
|
{
|
||||||
// Even if the creation/opening of the sqlite3 database fails, we will still
|
// Even if the creation/opening of the sqlite3 database fails, we will still
|
||||||
// get a valid database handle.
|
// get a valid database handle.
|
||||||
pThis = new ClustrixMonitor(name, module, pDb);
|
pThis = new XpandMonitor(name, module, pDb);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The handle will be null, *only* if the opening fails due to a memory
|
// The handle will be null, *only* if the opening fails due to a memory
|
||||||
// allocation error.
|
// allocation error.
|
||||||
MXS_ALERT("sqlite3 memory allocation failed, the Clustrix monitor "
|
MXS_ALERT("sqlite3 memory allocation failed, the Xpand monitor "
|
||||||
"cannot continue.");
|
"cannot continue.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,9 +270,9 @@ ClustrixMonitor* ClustrixMonitor::create(const string& name, const string& modul
|
|||||||
|
|
||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
|
|
||||||
bool ClustrixMonitor::configure(const MXS_CONFIG_PARAMETER* pParams)
|
bool XpandMonitor::configure(const MXS_CONFIG_PARAMETER* pParams)
|
||||||
{
|
{
|
||||||
if (!clustrixmon::specification.validate(*pParams))
|
if (!xpandmon::specification.validate(*pParams))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -294,25 +294,25 @@ bool ClustrixMonitor::configure(const MXS_CONFIG_PARAMETER* pParams)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::populate_services()
|
void XpandMonitor::populate_services()
|
||||||
{
|
{
|
||||||
mxb_assert(!is_running());
|
mxb_assert(!is_running());
|
||||||
|
|
||||||
// The servers that the Clustrix monitor has been configured with are
|
// The servers that the Xpand monitor has been configured with are
|
||||||
// only used for bootstrapping and services will not be populated
|
// only used for bootstrapping and services will not be populated
|
||||||
// with them.
|
// with them.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::softfail(SERVER* pServer, json_t** ppError)
|
bool XpandMonitor::softfail(SERVER* pServer, json_t** ppError)
|
||||||
{
|
{
|
||||||
bool rv = false;
|
bool rv = false;
|
||||||
|
|
||||||
if (is_running())
|
if (is_running())
|
||||||
{
|
{
|
||||||
call([this, pServer, ppError, &rv]() {
|
call([this, pServer, ppError, &rv]() {
|
||||||
rv = perform_softfail(pServer, ppError);
|
rv = perform_softfail(pServer, ppError);
|
||||||
},
|
},
|
||||||
EXECUTE_QUEUED);
|
EXECUTE_QUEUED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -325,16 +325,16 @@ bool ClustrixMonitor::softfail(SERVER* pServer, json_t** ppError)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::unsoftfail(SERVER* pServer, json_t** ppError)
|
bool XpandMonitor::unsoftfail(SERVER* pServer, json_t** ppError)
|
||||||
{
|
{
|
||||||
bool rv = false;
|
bool rv = false;
|
||||||
|
|
||||||
if (is_running())
|
if (is_running())
|
||||||
{
|
{
|
||||||
call([this, pServer, ppError, &rv]() {
|
call([this, pServer, ppError, &rv]() {
|
||||||
rv = perform_unsoftfail(pServer, ppError);
|
rv = perform_unsoftfail(pServer, ppError);
|
||||||
},
|
},
|
||||||
EXECUTE_QUEUED);
|
EXECUTE_QUEUED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -347,26 +347,26 @@ bool ClustrixMonitor::unsoftfail(SERVER* pServer, json_t** ppError)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::server_added(SERVER* pServer)
|
void XpandMonitor::server_added(SERVER* pServer)
|
||||||
{
|
{
|
||||||
// The servers explicitly added to the Cluster monitor are only used
|
// The servers explicitly added to the Cluster monitor are only used
|
||||||
// as bootstrap servers, so they are not added to any services.
|
// as bootstrap servers, so they are not added to any services.
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::server_removed(SERVER* pServer)
|
void XpandMonitor::server_removed(SERVER* pServer)
|
||||||
{
|
{
|
||||||
// @see server_added(), no action is needed.
|
// @see server_added(), no action is needed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ClustrixMonitor::pre_loop()
|
void XpandMonitor::pre_loop()
|
||||||
{
|
{
|
||||||
load_server_journal(nullptr);
|
load_server_journal(nullptr);
|
||||||
if (m_config.dynamic_node_detection())
|
if (m_config.dynamic_node_detection())
|
||||||
{
|
{
|
||||||
// At startup we accept softfailed nodes in an attempt to be able to
|
// At startup we accept softfailed nodes in an attempt to be able to
|
||||||
// connect at any cost. It'll be replaced once there is an alternative.
|
// connect at any cost. It'll be replaced once there is an alternative.
|
||||||
check_cluster(Clustrix::Softfailed::ACCEPT);
|
check_cluster(xpand::Softfailed::ACCEPT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -376,7 +376,7 @@ void ClustrixMonitor::pre_loop()
|
|||||||
make_health_check();
|
make_health_check();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::post_loop()
|
void XpandMonitor::post_loop()
|
||||||
{
|
{
|
||||||
if (m_pHub_con)
|
if (m_pHub_con)
|
||||||
{
|
{
|
||||||
@ -387,12 +387,12 @@ void ClustrixMonitor::post_loop()
|
|||||||
m_pHub_server = nullptr;
|
m_pHub_server = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::tick()
|
void XpandMonitor::tick()
|
||||||
{
|
{
|
||||||
check_maintenance_requests();
|
check_maintenance_requests();
|
||||||
if (m_config.dynamic_node_detection() && should_check_cluster())
|
if (m_config.dynamic_node_detection() && should_check_cluster())
|
||||||
{
|
{
|
||||||
check_cluster(Clustrix::Softfailed::REJECT);
|
check_cluster(xpand::Softfailed::REJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_http.status())
|
switch (m_http.status())
|
||||||
@ -418,7 +418,7 @@ void ClustrixMonitor::tick()
|
|||||||
store_server_journal(nullptr);
|
store_server_journal(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::choose_hub(Clustrix::Softfailed softfailed)
|
void XpandMonitor::choose_hub(xpand::Softfailed softfailed)
|
||||||
{
|
{
|
||||||
mxb_assert(!m_pHub_con);
|
mxb_assert(!m_pHub_con);
|
||||||
|
|
||||||
@ -443,7 +443,7 @@ void ClustrixMonitor::choose_hub(Clustrix::Softfailed softfailed)
|
|||||||
|
|
||||||
if (m_pHub_con)
|
if (m_pHub_con)
|
||||||
{
|
{
|
||||||
MXS_NOTICE("%s: Monitoring Clustrix cluster state using node %s:%d.",
|
MXS_NOTICE("%s: Monitoring Xpand cluster state using node %s:%d.",
|
||||||
name(), m_pHub_server->address, m_pHub_server->port);
|
name(), m_pHub_server->address, m_pHub_server->port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -453,11 +453,11 @@ void ClustrixMonitor::choose_hub(Clustrix::Softfailed softfailed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::choose_dynamic_hub(Clustrix::Softfailed softfailed, std::set<string>& ips_checked)
|
bool XpandMonitor::choose_dynamic_hub(xpand::Softfailed softfailed, std::set<string>& ips_checked)
|
||||||
{
|
{
|
||||||
for (auto& kv : m_nodes_by_id)
|
for (auto& kv : m_nodes_by_id)
|
||||||
{
|
{
|
||||||
ClustrixNode& node = kv.second;
|
XpandNode& node = kv.second;
|
||||||
|
|
||||||
if (node.can_be_used_as_hub(name(), settings().conn_settings, softfailed))
|
if (node.can_be_used_as_hub(name(), settings().conn_settings, softfailed))
|
||||||
{
|
{
|
||||||
@ -476,13 +476,13 @@ bool ClustrixMonitor::choose_dynamic_hub(Clustrix::Softfailed softfailed, std::s
|
|||||||
return m_pHub_con != nullptr;
|
return m_pHub_con != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::choose_bootstrap_hub(Clustrix::Softfailed softfailed, std::set<string>& ips_checked)
|
bool XpandMonitor::choose_bootstrap_hub(xpand::Softfailed softfailed, std::set<string>& ips_checked)
|
||||||
{
|
{
|
||||||
for (auto* pMs : servers())
|
for (auto* pMs : servers())
|
||||||
{
|
{
|
||||||
if (ips_checked.find(pMs->server->address) == ips_checked.end())
|
if (ips_checked.find(pMs->server->address) == ips_checked.end())
|
||||||
{
|
{
|
||||||
if (Clustrix::ping_or_connect_to_hub(name(), settings().conn_settings, softfailed, *pMs))
|
if (xpand::ping_or_connect_to_hub(name(), settings().conn_settings, softfailed, *pMs))
|
||||||
{
|
{
|
||||||
m_pHub_con = pMs->con;
|
m_pHub_con = pMs->con;
|
||||||
m_pHub_server = pMs->server;
|
m_pHub_server = pMs->server;
|
||||||
@ -504,9 +504,9 @@ bool ClustrixMonitor::choose_bootstrap_hub(Clustrix::Softfailed softfailed, std:
|
|||||||
return m_pHub_con != nullptr;
|
return m_pHub_con != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::refresh_using_persisted_nodes(std::set<string>& ips_checked)
|
bool XpandMonitor::refresh_using_persisted_nodes(std::set<string>& ips_checked)
|
||||||
{
|
{
|
||||||
MXS_NOTICE("Attempting to find a Clustrix bootstrap node from one of the nodes "
|
MXS_NOTICE("Attempting to find a Xpand bootstrap node from one of the nodes "
|
||||||
"used during the previous run of MaxScale.");
|
"used during the previous run of MaxScale.");
|
||||||
|
|
||||||
bool refreshed = false;
|
bool refreshed = false;
|
||||||
@ -543,7 +543,7 @@ bool ClustrixMonitor::refresh_using_persisted_nodes(std::set<string>& ips_checke
|
|||||||
nullptr,
|
nullptr,
|
||||||
port, nullptr, 0))
|
port, nullptr, 0))
|
||||||
{
|
{
|
||||||
if (Clustrix::is_part_of_the_quorum(name(), pHub_con))
|
if (xpand::is_part_of_the_quorum(name(), pHub_con))
|
||||||
{
|
{
|
||||||
if (refresh_nodes(pHub_con))
|
if (refresh_nodes(pHub_con))
|
||||||
{
|
{
|
||||||
@ -577,18 +577,18 @@ bool ClustrixMonitor::refresh_using_persisted_nodes(std::set<string>& ips_checke
|
|||||||
return refreshed;
|
return refreshed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::refresh_nodes()
|
bool XpandMonitor::refresh_nodes()
|
||||||
{
|
{
|
||||||
mxb_assert(m_pHub_con);
|
mxb_assert(m_pHub_con);
|
||||||
|
|
||||||
return refresh_nodes(m_pHub_con);
|
return refresh_nodes(m_pHub_con);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::refresh_nodes(MYSQL* pHub_con)
|
bool XpandMonitor::refresh_nodes(MYSQL* pHub_con)
|
||||||
{
|
{
|
||||||
mxb_assert(pHub_con);
|
mxb_assert(pHub_con);
|
||||||
|
|
||||||
map<int, ClustrixMembership> memberships;
|
map<int, XpandMembership> memberships;
|
||||||
|
|
||||||
bool refreshed = check_cluster_membership(pHub_con, &memberships);
|
bool refreshed = check_cluster_membership(pHub_con, &memberships);
|
||||||
|
|
||||||
@ -610,7 +610,7 @@ bool ClustrixMonitor::refresh_nodes(MYSQL* pHub_con)
|
|||||||
set<int> nids;
|
set<int> nids;
|
||||||
for (const auto& kv : m_nodes_by_id)
|
for (const auto& kv : m_nodes_by_id)
|
||||||
{
|
{
|
||||||
const ClustrixNode& node = kv.second;
|
const XpandNode& node = kv.second;
|
||||||
nids.insert(node.id());
|
nids.insert(node.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +626,7 @@ bool ClustrixMonitor::refresh_nodes(MYSQL* pHub_con)
|
|||||||
bool softfailed = row[4] ? true : false;
|
bool softfailed = row[4] ? true : false;
|
||||||
|
|
||||||
// '@@' ensures no clash with user created servers.
|
// '@@' ensures no clash with user created servers.
|
||||||
// Monitor name ensures no clash with other Clustrix monitor instances.
|
// Monitor name ensures no clash with other Xpand monitor instances.
|
||||||
string server_name = string("@@") + m_name + ":node-" + std::to_string(id);
|
string server_name = string("@@") + m_name + ":node-" + std::to_string(id);
|
||||||
|
|
||||||
auto nit = m_nodes_by_id.find(id);
|
auto nit = m_nodes_by_id.find(id);
|
||||||
@ -637,7 +637,7 @@ bool ClustrixMonitor::refresh_nodes(MYSQL* pHub_con)
|
|||||||
// Existing node.
|
// Existing node.
|
||||||
mxb_assert(SERVER::find_by_unique_name(server_name));
|
mxb_assert(SERVER::find_by_unique_name(server_name));
|
||||||
|
|
||||||
ClustrixNode& node = nit->second;
|
XpandNode& node = nit->second;
|
||||||
|
|
||||||
node.update(ip, mysql_port, health_port);
|
node.update(ip, mysql_port, health_port);
|
||||||
|
|
||||||
@ -684,11 +684,11 @@ bool ClustrixMonitor::refresh_nodes(MYSQL* pHub_con)
|
|||||||
pServer->set_status(SERVER_DRAINING);
|
pServer->set_status(SERVER_DRAINING);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ClustrixMembership& membership = mit->second;
|
const XpandMembership& membership = mit->second;
|
||||||
int health_check_threshold = m_config.health_check_threshold();
|
int health_check_threshold = m_config.health_check_threshold();
|
||||||
|
|
||||||
ClustrixNode node(this, membership, ip, mysql_port, health_port,
|
XpandNode node(this, membership, ip, mysql_port, health_port,
|
||||||
health_check_threshold, pServer);
|
health_check_threshold, pServer);
|
||||||
|
|
||||||
m_nodes_by_id.insert(make_pair(id, node));
|
m_nodes_by_id.insert(make_pair(id, node));
|
||||||
|
|
||||||
@ -735,8 +735,8 @@ bool ClustrixMonitor::refresh_nodes(MYSQL* pHub_con)
|
|||||||
auto it = m_nodes_by_id.find(nid);
|
auto it = m_nodes_by_id.find(nid);
|
||||||
mxb_assert(it != m_nodes_by_id.end());
|
mxb_assert(it != m_nodes_by_id.end());
|
||||||
|
|
||||||
ClustrixNode& node = it->second;
|
XpandNode& node = it->second;
|
||||||
node.set_running(false, ClustrixNode::APPROACH_OVERRIDE);
|
node.set_running(false, XpandNode::APPROACH_OVERRIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster_checked();
|
cluster_checked();
|
||||||
@ -762,7 +762,7 @@ bool ClustrixMonitor::refresh_nodes(MYSQL* pHub_con)
|
|||||||
return refreshed;
|
return refreshed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::check_bootstrap_servers()
|
void XpandMonitor::check_bootstrap_servers()
|
||||||
{
|
{
|
||||||
HostPortPairs nodes;
|
HostPortPairs nodes;
|
||||||
char* pError = nullptr;
|
char* pError = nullptr;
|
||||||
@ -813,7 +813,7 @@ void ClustrixMonitor::check_bootstrap_servers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::remove_persisted_information()
|
bool XpandMonitor::remove_persisted_information()
|
||||||
{
|
{
|
||||||
char* pError = nullptr;
|
char* pError = nullptr;
|
||||||
int rv;
|
int rv;
|
||||||
@ -833,7 +833,7 @@ bool ClustrixMonitor::remove_persisted_information()
|
|||||||
return rv1 == SQLITE_OK && rv2 == SQLITE_OK;
|
return rv1 == SQLITE_OK && rv2 == SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::persist_bootstrap_servers()
|
void XpandMonitor::persist_bootstrap_servers()
|
||||||
{
|
{
|
||||||
string values;
|
string values;
|
||||||
|
|
||||||
@ -871,7 +871,7 @@ void ClustrixMonitor::persist_bootstrap_servers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::check_cluster(Clustrix::Softfailed softfailed)
|
void XpandMonitor::check_cluster(xpand::Softfailed softfailed)
|
||||||
{
|
{
|
||||||
if (m_pHub_con)
|
if (m_pHub_con)
|
||||||
{
|
{
|
||||||
@ -889,21 +889,21 @@ void ClustrixMonitor::check_cluster(Clustrix::Softfailed softfailed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::check_hub(Clustrix::Softfailed softfailed)
|
void XpandMonitor::check_hub(xpand::Softfailed softfailed)
|
||||||
{
|
{
|
||||||
mxb_assert(m_pHub_con);
|
mxb_assert(m_pHub_con);
|
||||||
mxb_assert(m_pHub_server);
|
mxb_assert(m_pHub_server);
|
||||||
|
|
||||||
if (!Clustrix::ping_or_connect_to_hub(name(), settings().conn_settings, softfailed,
|
if (!xpand::ping_or_connect_to_hub(name(), settings().conn_settings, softfailed,
|
||||||
*m_pHub_server, &m_pHub_con))
|
*m_pHub_server, &m_pHub_con))
|
||||||
{
|
{
|
||||||
mysql_close(m_pHub_con);
|
mysql_close(m_pHub_con);
|
||||||
m_pHub_con = nullptr;
|
m_pHub_con = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::check_cluster_membership(MYSQL* pHub_con,
|
bool XpandMonitor::check_cluster_membership(MYSQL* pHub_con,
|
||||||
std::map<int, ClustrixMembership>* pMemberships)
|
std::map<int, XpandMembership>* pMemberships)
|
||||||
{
|
{
|
||||||
mxb_assert(pHub_con);
|
mxb_assert(pHub_con);
|
||||||
mxb_assert(pMemberships);
|
mxb_assert(pMemberships);
|
||||||
@ -923,7 +923,7 @@ bool ClustrixMonitor::check_cluster_membership(MYSQL* pHub_con,
|
|||||||
set<int> nids;
|
set<int> nids;
|
||||||
for (const auto& kv : m_nodes_by_id)
|
for (const auto& kv : m_nodes_by_id)
|
||||||
{
|
{
|
||||||
const ClustrixNode& node = kv.second;
|
const XpandNode& node = kv.second;
|
||||||
nids.insert(node.id());
|
nids.insert(node.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,20 +941,20 @@ bool ClustrixMonitor::check_cluster_membership(MYSQL* pHub_con,
|
|||||||
|
|
||||||
if (it != m_nodes_by_id.end())
|
if (it != m_nodes_by_id.end())
|
||||||
{
|
{
|
||||||
ClustrixNode& node = it->second;
|
XpandNode& node = it->second;
|
||||||
|
|
||||||
node.update(Clustrix::status_from_string(status),
|
node.update(xpand::status_from_string(status),
|
||||||
Clustrix::substate_from_string(substate),
|
xpand::substate_from_string(substate),
|
||||||
instance);
|
instance);
|
||||||
|
|
||||||
nids.erase(node.id());
|
nids.erase(node.id());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClustrixMembership membership(nid,
|
XpandMembership membership(nid,
|
||||||
Clustrix::status_from_string(status),
|
xpand::status_from_string(status),
|
||||||
Clustrix::substate_from_string(substate),
|
xpand::substate_from_string(substate),
|
||||||
instance);
|
instance);
|
||||||
|
|
||||||
pMemberships->insert(make_pair(nid, membership));
|
pMemberships->insert(make_pair(nid, membership));
|
||||||
}
|
}
|
||||||
@ -974,7 +974,7 @@ bool ClustrixMonitor::check_cluster_membership(MYSQL* pHub_con,
|
|||||||
auto it = m_nodes_by_id.find(nid);
|
auto it = m_nodes_by_id.find(nid);
|
||||||
mxb_assert(it != m_nodes_by_id.end());
|
mxb_assert(it != m_nodes_by_id.end());
|
||||||
|
|
||||||
ClustrixNode& node = it->second;
|
XpandNode& node = it->second;
|
||||||
node.deactivate_server();
|
node.deactivate_server();
|
||||||
m_nodes_by_id.erase(it);
|
m_nodes_by_id.erase(it);
|
||||||
}
|
}
|
||||||
@ -995,7 +995,7 @@ bool ClustrixMonitor::check_cluster_membership(MYSQL* pHub_con,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::populate_from_bootstrap_servers()
|
void XpandMonitor::populate_from_bootstrap_servers()
|
||||||
{
|
{
|
||||||
int id = 1;
|
int id = 1;
|
||||||
|
|
||||||
@ -1003,17 +1003,17 @@ void ClustrixMonitor::populate_from_bootstrap_servers()
|
|||||||
{
|
{
|
||||||
SERVER* pServer = ms->server;
|
SERVER* pServer = ms->server;
|
||||||
|
|
||||||
Clustrix::Status status = Clustrix::Status::UNKNOWN;
|
xpand::Status status = xpand::Status::UNKNOWN;
|
||||||
Clustrix::SubState substate = Clustrix::SubState::UNKNOWN;
|
xpand::SubState substate = xpand::SubState::UNKNOWN;
|
||||||
int instance = 1;
|
int instance = 1;
|
||||||
ClustrixMembership membership(id, status, substate, instance);
|
XpandMembership membership(id, status, substate, instance);
|
||||||
|
|
||||||
std::string ip = pServer->address;
|
std::string ip = pServer->address;
|
||||||
int mysql_port = pServer->port;
|
int mysql_port = pServer->port;
|
||||||
int health_port = m_config.health_check_port();
|
int health_port = m_config.health_check_port();
|
||||||
int health_check_threshold = m_config.health_check_threshold();
|
int health_check_threshold = m_config.health_check_threshold();
|
||||||
|
|
||||||
ClustrixNode node(this, membership, ip, mysql_port, health_port, health_check_threshold, pServer);
|
XpandNode node(this, membership, ip, mysql_port, health_port, health_check_threshold, pServer);
|
||||||
|
|
||||||
m_nodes_by_id.insert(make_pair(id, node));
|
m_nodes_by_id.insert(make_pair(id, node));
|
||||||
++id;
|
++id;
|
||||||
@ -1026,7 +1026,7 @@ void ClustrixMonitor::populate_from_bootstrap_servers()
|
|||||||
update_http_urls();
|
update_http_urls();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::update_server_statuses()
|
void XpandMonitor::update_server_statuses()
|
||||||
{
|
{
|
||||||
mxb_assert(!servers().empty());
|
mxb_assert(!servers().empty());
|
||||||
|
|
||||||
@ -1035,14 +1035,14 @@ void ClustrixMonitor::update_server_statuses()
|
|||||||
pMs->stash_current_status();
|
pMs->stash_current_status();
|
||||||
|
|
||||||
auto it = find_if(m_nodes_by_id.begin(), m_nodes_by_id.end(),
|
auto it = find_if(m_nodes_by_id.begin(), m_nodes_by_id.end(),
|
||||||
[pMs](const std::pair<int, ClustrixNode>& element) -> bool {
|
[pMs](const std::pair<int, XpandNode>& element) -> bool {
|
||||||
const ClustrixNode& info = element.second;
|
const XpandNode& info = element.second;
|
||||||
return pMs->server->address == info.ip();
|
return pMs->server->address == info.ip();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it != m_nodes_by_id.end())
|
if (it != m_nodes_by_id.end())
|
||||||
{
|
{
|
||||||
const ClustrixNode& info = it->second;
|
const XpandNode& info = it->second;
|
||||||
|
|
||||||
if (info.is_running())
|
if (info.is_running())
|
||||||
{
|
{
|
||||||
@ -1060,7 +1060,7 @@ void ClustrixMonitor::update_server_statuses()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::make_health_check()
|
void XpandMonitor::make_health_check()
|
||||||
{
|
{
|
||||||
mxb_assert(m_http.status() != http::Async::PENDING);
|
mxb_assert(m_http.status() != http::Async::PENDING);
|
||||||
|
|
||||||
@ -1082,7 +1082,7 @@ void ClustrixMonitor::make_health_check()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::initiate_delayed_http_check()
|
void XpandMonitor::initiate_delayed_http_check()
|
||||||
{
|
{
|
||||||
mxb_assert(m_delayed_http_check_id == 0);
|
mxb_assert(m_delayed_http_check_id == 0);
|
||||||
|
|
||||||
@ -1095,10 +1095,10 @@ void ClustrixMonitor::initiate_delayed_http_check()
|
|||||||
ms = max_delay_ms;
|
ms = max_delay_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_delayed_http_check_id = delayed_call(ms, &ClustrixMonitor::check_http, this);
|
m_delayed_http_check_id = delayed_call(ms, &XpandMonitor::check_http, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::check_http(Call::action_t action)
|
bool XpandMonitor::check_http(Call::action_t action)
|
||||||
{
|
{
|
||||||
m_delayed_http_check_id = 0;
|
m_delayed_http_check_id = 0;
|
||||||
|
|
||||||
@ -1124,7 +1124,7 @@ bool ClustrixMonitor::check_http(Call::action_t action)
|
|||||||
{
|
{
|
||||||
bool running = (result.code == 200); // HTTP OK
|
bool running = (result.code == 200); // HTTP OK
|
||||||
|
|
||||||
ClustrixNode& node = it->second;
|
XpandNode& node = it->second;
|
||||||
|
|
||||||
node.set_running(running);
|
node.set_running(running);
|
||||||
|
|
||||||
@ -1153,12 +1153,12 @@ bool ClustrixMonitor::check_http(Call::action_t action)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::update_http_urls()
|
void XpandMonitor::update_http_urls()
|
||||||
{
|
{
|
||||||
vector<string> health_urls;
|
vector<string> health_urls;
|
||||||
for (const auto& kv : m_nodes_by_id)
|
for (const auto& kv : m_nodes_by_id)
|
||||||
{
|
{
|
||||||
const ClustrixNode& node = kv.second;
|
const XpandNode& node = kv.second;
|
||||||
string url = "http://" + node.ip() + ":" + std::to_string(node.health_port());
|
string url = "http://" + node.ip() + ":" + std::to_string(node.health_port());
|
||||||
|
|
||||||
health_urls.push_back(url);
|
health_urls.push_back(url);
|
||||||
@ -1178,7 +1178,7 @@ void ClustrixMonitor::update_http_urls()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::perform_softfail(SERVER* pServer, json_t** ppError)
|
bool XpandMonitor::perform_softfail(SERVER* pServer, json_t** ppError)
|
||||||
{
|
{
|
||||||
bool rv = perform_operation(Operation::SOFTFAIL, pServer, ppError);
|
bool rv = perform_operation(Operation::SOFTFAIL, pServer, ppError);
|
||||||
|
|
||||||
@ -1189,14 +1189,14 @@ bool ClustrixMonitor::perform_softfail(SERVER* pServer, json_t** ppError)
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::perform_unsoftfail(SERVER* pServer, json_t** ppError)
|
bool XpandMonitor::perform_unsoftfail(SERVER* pServer, json_t** ppError)
|
||||||
{
|
{
|
||||||
return perform_operation(Operation::UNSOFTFAIL, pServer, ppError);
|
return perform_operation(Operation::UNSOFTFAIL, pServer, ppError);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClustrixMonitor::perform_operation(Operation operation,
|
bool XpandMonitor::perform_operation(Operation operation,
|
||||||
SERVER* pServer,
|
SERVER* pServer,
|
||||||
json_t** ppError)
|
json_t** ppError)
|
||||||
{
|
{
|
||||||
bool performed = false;
|
bool performed = false;
|
||||||
|
|
||||||
@ -1207,19 +1207,19 @@ bool ClustrixMonitor::perform_operation(Operation operation,
|
|||||||
|
|
||||||
if (!m_pHub_con)
|
if (!m_pHub_con)
|
||||||
{
|
{
|
||||||
check_cluster(Clustrix::Softfailed::ACCEPT);
|
check_cluster(xpand::Softfailed::ACCEPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pHub_con)
|
if (m_pHub_con)
|
||||||
{
|
{
|
||||||
auto it = find_if(m_nodes_by_id.begin(), m_nodes_by_id.end(),
|
auto it = find_if(m_nodes_by_id.begin(), m_nodes_by_id.end(),
|
||||||
[pServer](const std::pair<int, ClustrixNode>& element) {
|
[pServer](const std::pair<int, XpandNode>& element) {
|
||||||
return element.second.server() == pServer;
|
return element.second.server() == pServer;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it != m_nodes_by_id.end())
|
if (it != m_nodes_by_id.end())
|
||||||
{
|
{
|
||||||
ClustrixNode& node = it->second;
|
XpandNode& node = it->second;
|
||||||
|
|
||||||
const char ZQUERY_FORMAT[] = "ALTER CLUSTER %s %d";
|
const char ZQUERY_FORMAT[] = "ALTER CLUSTER %s %d";
|
||||||
|
|
||||||
@ -1267,7 +1267,7 @@ bool ClustrixMonitor::perform_operation(Operation operation,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_JSON_ERROR(ppError,
|
LOG_JSON_ERROR(ppError,
|
||||||
"%s: Could not could not connect to any Clustrix node, "
|
"%s: Could not could not connect to any Xpand node, "
|
||||||
"cannot perform %s of %s.",
|
"cannot perform %s of %s.",
|
||||||
name(), zOperation, pServer->address);
|
name(), zOperation, pServer->address);
|
||||||
}
|
}
|
||||||
@ -1275,7 +1275,7 @@ bool ClustrixMonitor::perform_operation(Operation operation,
|
|||||||
return performed;
|
return performed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::persist(const ClustrixNode& node)
|
void XpandMonitor::persist(const XpandNode& node)
|
||||||
{
|
{
|
||||||
if (!m_pDb)
|
if (!m_pDb)
|
||||||
{
|
{
|
||||||
@ -1294,7 +1294,7 @@ void ClustrixMonitor::persist(const ClustrixNode& node)
|
|||||||
char* pError = nullptr;
|
char* pError = nullptr;
|
||||||
if (sqlite3_exec(m_pDb, sql_upsert, nullptr, nullptr, &pError) == SQLITE_OK)
|
if (sqlite3_exec(m_pDb, sql_upsert, nullptr, nullptr, &pError) == SQLITE_OK)
|
||||||
{
|
{
|
||||||
MXS_INFO("Updated Clustrix node in bookkeeping: %d, '%s', %d, %d.",
|
MXS_INFO("Updated Xpand node in bookkeeping: %d, '%s', %d, %d.",
|
||||||
id, zIp, mysql_port, health_port);
|
id, zIp, mysql_port, health_port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1304,7 +1304,7 @@ void ClustrixMonitor::persist(const ClustrixNode& node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClustrixMonitor::unpersist(const ClustrixNode& node)
|
void XpandMonitor::unpersist(const XpandNode& node)
|
||||||
{
|
{
|
||||||
if (!m_pDb)
|
if (!m_pDb)
|
||||||
{
|
{
|
||||||
@ -1320,7 +1320,7 @@ void ClustrixMonitor::unpersist(const ClustrixNode& node)
|
|||||||
char* pError = nullptr;
|
char* pError = nullptr;
|
||||||
if (sqlite3_exec(m_pDb, sql_delete, nullptr, nullptr, &pError) == SQLITE_OK)
|
if (sqlite3_exec(m_pDb, sql_delete, nullptr, nullptr, &pError) == SQLITE_OK)
|
||||||
{
|
{
|
||||||
MXS_INFO("Deleted Clustrix node %d from bookkeeping.", id);
|
MXS_INFO("Deleted Xpand node %d from bookkeeping.", id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
@ -12,21 +12,21 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "clustrixmon.hh"
|
#include "xpandmon.hh"
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include <maxscale/config2.hh>
|
#include <maxscale/config2.hh>
|
||||||
#include <maxscale/monitor.hh>
|
#include <maxscale/monitor.hh>
|
||||||
#include <maxbase/http.hh>
|
#include <maxbase/http.hh>
|
||||||
#include "clustrixmembership.hh"
|
#include "xpandmembership.hh"
|
||||||
#include "clustrixnode.hh"
|
#include "xpandnode.hh"
|
||||||
|
|
||||||
class ClustrixMonitor : public maxscale::MonitorWorker
|
class XpandMonitor : public maxscale::MonitorWorker
|
||||||
, private ClustrixNode::Persister
|
, private XpandNode::Persister
|
||||||
{
|
{
|
||||||
ClustrixMonitor(const ClustrixMonitor&) = delete;
|
XpandMonitor(const XpandMonitor&) = delete;
|
||||||
ClustrixMonitor& operator=(const ClustrixMonitor&) = delete;
|
XpandMonitor& operator=(const XpandMonitor&) = delete;
|
||||||
public:
|
public:
|
||||||
class Config
|
class Config
|
||||||
{
|
{
|
||||||
@ -65,9 +65,9 @@ public:
|
|||||||
config::Integer m_health_check_port;
|
config::Integer m_health_check_port;
|
||||||
};
|
};
|
||||||
|
|
||||||
~ClustrixMonitor();
|
~XpandMonitor();
|
||||||
|
|
||||||
static ClustrixMonitor* create(const std::string& name, const std::string& module);
|
static XpandMonitor* create(const std::string& name, const std::string& module);
|
||||||
|
|
||||||
bool configure(const MXS_CONFIG_PARAMETER* pParams) override;
|
bool configure(const MXS_CONFIG_PARAMETER* pParams) override;
|
||||||
|
|
||||||
@ -81,9 +81,9 @@ protected:
|
|||||||
void server_removed(SERVER* pServer) override;
|
void server_removed(SERVER* pServer) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClustrixMonitor(const std::string& name,
|
XpandMonitor(const std::string& name,
|
||||||
const std::string& module,
|
const std::string& module,
|
||||||
sqlite3* pDb);
|
sqlite3* pDb);
|
||||||
|
|
||||||
void pre_loop() override;
|
void pre_loop() override;
|
||||||
void post_loop() override;
|
void post_loop() override;
|
||||||
@ -94,18 +94,18 @@ private:
|
|||||||
bool remove_persisted_information();
|
bool remove_persisted_information();
|
||||||
void persist_bootstrap_servers();
|
void persist_bootstrap_servers();
|
||||||
|
|
||||||
void check_cluster(Clustrix::Softfailed softfailed);
|
void check_cluster(xpand::Softfailed softfailed);
|
||||||
void check_hub(Clustrix::Softfailed softfailed);
|
void check_hub(xpand::Softfailed softfailed);
|
||||||
void choose_hub(Clustrix::Softfailed softfailed);
|
void choose_hub(xpand::Softfailed softfailed);
|
||||||
|
|
||||||
bool choose_dynamic_hub(Clustrix::Softfailed softfailed, std::set<std::string>& ips_checked);
|
bool choose_dynamic_hub(xpand::Softfailed softfailed, std::set<std::string>& ips_checked);
|
||||||
bool choose_bootstrap_hub(Clustrix::Softfailed softfailed, std::set<std::string>& ips_checked);
|
bool choose_bootstrap_hub(xpand::Softfailed softfailed, std::set<std::string>& ips_checked);
|
||||||
bool refresh_using_persisted_nodes(std::set<std::string>& ips_checked);
|
bool refresh_using_persisted_nodes(std::set<std::string>& ips_checked);
|
||||||
|
|
||||||
bool refresh_nodes();
|
bool refresh_nodes();
|
||||||
bool refresh_nodes(MYSQL* pHub_con);
|
bool refresh_nodes(MYSQL* pHub_con);
|
||||||
bool check_cluster_membership(MYSQL* pHub_con,
|
bool check_cluster_membership(MYSQL* pHub_con,
|
||||||
std::map<int, ClustrixMembership>* pMemberships);
|
std::map<int, XpandMembership>* pMemberships);
|
||||||
|
|
||||||
void populate_from_bootstrap_servers();
|
void populate_from_bootstrap_servers();
|
||||||
|
|
||||||
@ -150,18 +150,18 @@ private:
|
|||||||
return mxb::WorkerLoad::get_time_ms();
|
return mxb::WorkerLoad::get_time_ms();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClustrixNode::Persister
|
// XpandNode::Persister
|
||||||
void persist(const ClustrixNode& node);
|
void persist(const XpandNode& node);
|
||||||
void unpersist(const ClustrixNode& node);
|
void unpersist(const XpandNode& node);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Config m_config;
|
Config m_config;
|
||||||
std::map<int, ClustrixNode> m_nodes_by_id;
|
std::map<int, XpandNode> m_nodes_by_id;
|
||||||
std::vector<std::string> m_health_urls;
|
std::vector<std::string> m_health_urls;
|
||||||
mxb::http::Async m_http;
|
mxb::http::Async m_http;
|
||||||
uint32_t m_delayed_http_check_id {0};
|
uint32_t m_delayed_http_check_id {0};
|
||||||
long m_last_cluster_check {0};
|
long m_last_cluster_check {0};
|
||||||
SERVER* m_pHub_server {nullptr};
|
SERVER* m_pHub_server {nullptr};
|
||||||
MYSQL* m_pHub_con {nullptr};
|
MYSQL* m_pHub_con {nullptr};
|
||||||
sqlite3* m_pDb {nullptr};
|
sqlite3* m_pDb {nullptr};
|
||||||
};
|
};
|
@ -11,15 +11,15 @@
|
|||||||
* Public License.
|
* Public License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clustrixnode.hh"
|
#include "xpandnode.hh"
|
||||||
#include "clustrix.hh"
|
#include "xpand.hh"
|
||||||
|
|
||||||
bool ClustrixNode::can_be_used_as_hub(const char* zName,
|
bool XpandNode::can_be_used_as_hub(const char* zName,
|
||||||
const mxs::MonitorServer::ConnectionSettings& settings,
|
const mxs::MonitorServer::ConnectionSettings& settings,
|
||||||
Clustrix::Softfailed softfailed)
|
xpand::Softfailed softfailed)
|
||||||
{
|
{
|
||||||
mxb_assert(m_pServer);
|
mxb_assert(m_pServer);
|
||||||
bool rv = Clustrix::ping_or_connect_to_hub(zName, settings, softfailed, *m_pServer, &m_pCon);
|
bool rv = xpand::ping_or_connect_to_hub(zName, settings, softfailed, *m_pServer, &m_pCon);
|
||||||
|
|
||||||
if (!rv)
|
if (!rv)
|
||||||
{
|
{
|
@ -12,21 +12,21 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "clustrixmon.hh"
|
#include "xpandmon.hh"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "clustrix.hh"
|
#include "xpand.hh"
|
||||||
#include "clustrixmembership.hh"
|
#include "xpandmembership.hh"
|
||||||
|
|
||||||
class ClustrixNode
|
class XpandNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class Persister
|
class Persister
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void persist(const ClustrixNode& node) = 0;
|
virtual void persist(const XpandNode& node) = 0;
|
||||||
virtual void unpersist(const ClustrixNode& node) = 0;
|
virtual void unpersist(const XpandNode& node) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
@ -41,13 +41,13 @@ public:
|
|||||||
APPROACH_DEFAULT
|
APPROACH_DEFAULT
|
||||||
};
|
};
|
||||||
|
|
||||||
ClustrixNode(Persister* pPersister,
|
XpandNode(Persister* pPersister,
|
||||||
const ClustrixMembership& membership,
|
const XpandMembership& membership,
|
||||||
const std::string& ip,
|
const std::string& ip,
|
||||||
int mysql_port,
|
int mysql_port,
|
||||||
int health_port,
|
int health_port,
|
||||||
int health_check_threshold,
|
int health_check_threshold,
|
||||||
SERVER* pServer)
|
SERVER* pServer)
|
||||||
: m_persister(*pPersister)
|
: m_persister(*pPersister)
|
||||||
, m_id(membership.id())
|
, m_id(membership.id())
|
||||||
, m_status(membership.status())
|
, m_status(membership.status())
|
||||||
@ -65,7 +65,7 @@ public:
|
|||||||
m_persister.persist(*this);
|
m_persister.persist(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ClustrixNode()
|
~XpandNode()
|
||||||
{
|
{
|
||||||
if (m_pCon)
|
if (m_pCon)
|
||||||
{
|
{
|
||||||
@ -78,12 +78,12 @@ public:
|
|||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clustrix::Status status() const
|
xpand::Status status() const
|
||||||
{
|
{
|
||||||
return m_status;
|
return m_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Clustrix::SubState substate() const
|
xpand::SubState substate() const
|
||||||
{
|
{
|
||||||
return m_substate;
|
return m_substate;
|
||||||
}
|
}
|
||||||
@ -178,7 +178,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(Clustrix::Status status, Clustrix::SubState substate, int instance)
|
void update(xpand::Status status, xpand::SubState substate, int instance)
|
||||||
{
|
{
|
||||||
m_status = status;
|
m_status = status;
|
||||||
m_substate = substate;
|
m_substate = substate;
|
||||||
@ -193,7 +193,7 @@ public:
|
|||||||
|
|
||||||
bool can_be_used_as_hub(const char* zName,
|
bool can_be_used_as_hub(const char* zName,
|
||||||
const mxs::MonitorServer::ConnectionSettings& settings,
|
const mxs::MonitorServer::ConnectionSettings& settings,
|
||||||
Clustrix::Softfailed softfailed);
|
xpand::Softfailed softfailed);
|
||||||
|
|
||||||
SERVER* server() const
|
SERVER* server() const
|
||||||
{
|
{
|
||||||
@ -225,21 +225,21 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Persister& m_persister;
|
Persister& m_persister;
|
||||||
int m_id;
|
int m_id;
|
||||||
Clustrix::Status m_status;
|
xpand::Status m_status;
|
||||||
Clustrix::SubState m_substate;
|
xpand::SubState m_substate;
|
||||||
int m_instance;
|
int m_instance;
|
||||||
std::string m_ip;
|
std::string m_ip;
|
||||||
int m_mysql_port {DEFAULT_MYSQL_PORT};
|
int m_mysql_port {DEFAULT_MYSQL_PORT};
|
||||||
int m_health_port {DEFAULT_HEALTH_PORT};
|
int m_health_port {DEFAULT_HEALTH_PORT};
|
||||||
int m_health_check_threshold {DEFAULT_HEALTH_CHECK_THRESHOLD};
|
int m_health_check_threshold {DEFAULT_HEALTH_CHECK_THRESHOLD};
|
||||||
int m_nRunning {0};
|
int m_nRunning {0};
|
||||||
SERVER* m_pServer {nullptr};
|
SERVER* m_pServer {nullptr};
|
||||||
MYSQL* m_pCon {nullptr};
|
MYSQL* m_pCon {nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const ClustrixNode& x)
|
inline std::ostream& operator<<(std::ostream& out, const XpandNode& x)
|
||||||
{
|
{
|
||||||
x.print(out);
|
x.print(out);
|
||||||
return out;
|
return out;
|
@ -185,7 +185,7 @@ public:
|
|||||||
|
|
||||||
bypass_whitespace();
|
bypass_whitespace();
|
||||||
|
|
||||||
if (is_set(m_pI))
|
if (m_pEnd - m_pI > 3 && is_set(m_pI))
|
||||||
{
|
{
|
||||||
rv = parse(pResult);
|
rv = parse(pResult);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user