Merge branch '2.3' of github.com:mariadb-corporation/MaxScale into 2.3
This commit is contained in:
commit
802a19879b
@ -8,7 +8,10 @@ if [ "$box_type" == "RPM" ] ; then
|
||||
# Build can be executed to check if it is possible to build
|
||||
# and to run install and upgrade tests
|
||||
# with thre real RHEL, but we use CentOS packages for production
|
||||
if [ "$platform" != "rhel" ] ; then
|
||||
if [[ "$platform" != "rhel" || ( "$platform" == "rhel" && "$platform_version" == "8" ) ]]; then
|
||||
if [[ "$platform" == "rhel" && "$platform_version" == "8" ]]; then
|
||||
export platform="centos"
|
||||
fi
|
||||
export arch=`ssh $sshopt "arch"`
|
||||
. ${script_dir}/generate_build_info_path.sh
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
For more details, please refer to:
|
||||
|
||||
* [MariaDB MaxScale 2.3.6 Release Notes](Release-Notes/MaxScale-2.3.6-Release-Notes.md)
|
||||
* [MariaDB MaxScale 2.3.5 Release Notes](Release-Notes/MaxScale-2.3.5-Release-Notes.md)
|
||||
* [MariaDB MaxScale 2.3.4 Release Notes](Release-Notes/MaxScale-2.3.4-Release-Notes.md)
|
||||
* [MariaDB MaxScale 2.3.3 Release Notes](Release-Notes/MaxScale-2.3.3-Release-Notes.md)
|
||||
|
@ -679,7 +679,9 @@ _qc_sqlite_.
|
||||
#### `query_classifier_cache_size`
|
||||
|
||||
Specifies the maximum size of the query classifier cache. The default limit is
|
||||
40% of total system memory.
|
||||
15% of total system memory starting with MaxScale 2.3.7. In older versions the
|
||||
default limit was 40% of total system memory. This feature was added in MaxScale
|
||||
2.3.0.
|
||||
|
||||
When the query classifier cache has been enabled, MaxScale will, after a
|
||||
statement has been parsed, store the classification result using the
|
||||
@ -855,7 +857,7 @@ than `0`, this configuration setting will not have an effect.
|
||||
#### `writeq_high_water`
|
||||
|
||||
High water mark for network write buffer. Controls when network traffic
|
||||
throtting is started. The parameter accepts size type values.
|
||||
throtting is started. The parameter accepts [size type values](#sizes).
|
||||
|
||||
More specifically, if the client side write queue is above this value, it will
|
||||
block traffic coming from backend servers. If the backend side write queue is
|
||||
@ -869,7 +871,7 @@ throtting is enabled. By default, traffic throttling is disabled.
|
||||
|
||||
Low water mark for network write buffer. Once the traffic throttling is enabled,
|
||||
it will only be disabled when the write queue is below `writeq_low_water`. The
|
||||
parameter accepts size type values. The minimum allowed size is 512
|
||||
parameter accepts [size type values](#sizes). The minimum allowed size is 512
|
||||
bytes. `writeq_high_water` must always be greater than `writeq_low_water`.
|
||||
|
||||
#### `load_persisted_configs`
|
||||
|
@ -651,7 +651,7 @@ executed.
|
||||
|
||||
Both `replication_user` and `replication_password` parameters must be defined if
|
||||
a custom replication user is used. If neither of the parameters is defined, the
|
||||
`CHANGE MASTER TO` command will use the monitor credentials for the replication
|
||||
`CHANGE MASTER TO`-command will use the monitor credentials for the replication
|
||||
user.
|
||||
|
||||
The credentials used for replication must have the `REPLICATION SLAVE`
|
||||
@ -661,6 +661,19 @@ privilege.
|
||||
parameters. If password encryption is in use, `replication_password` must be
|
||||
encrypted with the same key to avoid erroneous decryption.
|
||||
|
||||
#### `replication_master_ssl`
|
||||
|
||||
Type: bool Default: off
|
||||
|
||||
If set to ON, any `CHANGE MASTER TO`-command generated will set `MASTER_SSL=1` to enable
|
||||
encryption for the replication stream. This setting should only be enabled if the backend
|
||||
servers are configured for ssl. This typically means setting *ssl_ca*, *ssl_cert* and
|
||||
*ssl_key* in the server configuration file. Additionally, credentials for the replication
|
||||
user should require an encrypted connection (`e.g. ALTER USER repl@'%' REQUIRE SSL;`).
|
||||
|
||||
If the setting is left OFF, `MASTER_SSL` is not set at all, which will preserve existing
|
||||
settings when redirecting a slave connection.
|
||||
|
||||
#### `failover_timeout` and `switchover_timeout`
|
||||
|
||||
Time limit for failover and switchover operations, in seconds. The default
|
||||
|
@ -11,6 +11,7 @@ report on [our Jira](https://jira.mariadb.org/projects/MXS).
|
||||
## New Features
|
||||
|
||||
* [MXS-2417](https://jira.mariadb.org/browse/MXS-2417) MaxScale main config should take precedence over runtime config on restart
|
||||
* [MXS-2344](https://jira.mariadb.org/browse/MXS-2344) Support MASTER_SSL in mariadbmon for encrypting replication traffic
|
||||
|
||||
### REST API & MaxCtrl: Hard maintenance mode
|
||||
|
||||
@ -24,8 +25,12 @@ the `set` endpoint.
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* [MXS-2423](https://jira.mariadb.org/browse/MXS-2423) retain_last_statements not in maxctrl show maxscale
|
||||
* [MXS-2419](https://jira.mariadb.org/browse/MXS-2419) Hangs on query during multiple transaction replays
|
||||
* [MXS-2418](https://jira.mariadb.org/browse/MXS-2418) Crash on transaction replay if log_info is on and session starts with no master
|
||||
* [MXS-2416](https://jira.mariadb.org/browse/MXS-2416) Possible memory leak
|
||||
* [MXS-2324](https://jira.mariadb.org/browse/MXS-2324) Maxscale disconnect after commit without begin from Icinga2
|
||||
* [MXS-2259](https://jira.mariadb.org/browse/MXS-2259) Maxscale consumes large amounts of memory even with buffer limits set.
|
||||
|
||||
## Known Issues and Limitations
|
||||
|
||||
|
@ -156,6 +156,7 @@ private:
|
||||
bool m_local_infile_requested; /**< Whether a LOCAL INFILE was requested */
|
||||
ResponseStat m_response_stat;
|
||||
uint64_t m_num_coldefs = 0;
|
||||
bool m_skip_next = false;
|
||||
|
||||
inline bool is_opening_cursor() const
|
||||
{
|
||||
|
@ -135,6 +135,28 @@ exports.builder = function(yargs) {
|
||||
return updateValue(host, 'maxscale', 'data.attributes.parameters.' + argv.key, argv.value)
|
||||
})
|
||||
})
|
||||
.command('user <name> <password>', 'Alter admin user passwords', function(yargs) {
|
||||
return yargs.epilog('Changes the password for a user. To change the user type, destroy the user and then create it again.')
|
||||
.usage('Usage: alter user <name> <password>')
|
||||
}, function(argv) {
|
||||
maxctrl(argv, function(host) {
|
||||
|
||||
var user = {
|
||||
'data': {
|
||||
'id': argv.name,
|
||||
'type': 'inet',
|
||||
'attributes': {
|
||||
'password': argv.password
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getJson(host, 'users/inet/' + argv.name)
|
||||
.then((res) => user.data.attributes.account = res.data.attributes.account)
|
||||
.then(() => doRequest(host, 'users/inet/' + argv.name, null, {method: 'DELETE'}))
|
||||
.then(() => doRequest(host, 'users/inet', null, {method: 'POST', body: user}))
|
||||
})
|
||||
})
|
||||
.usage('Usage: alter <command>')
|
||||
.help()
|
||||
.command('*', 'the default command', {}, function(argv) {
|
||||
|
@ -159,12 +159,10 @@ exports.builder = function(yargs) {
|
||||
}
|
||||
}
|
||||
|
||||
if (argv.params) {
|
||||
var err = validateParams(argv, argv.params)
|
||||
if (err) {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
var err = false;
|
||||
|
||||
if (argv.params) {
|
||||
err = validateParams(argv, argv.params)
|
||||
monitor.data.attributes.parameters = argv.params.reduce(to_obj, {})
|
||||
}
|
||||
|
||||
@ -182,6 +180,9 @@ exports.builder = function(yargs) {
|
||||
}
|
||||
|
||||
maxctrl(argv, function(host) {
|
||||
if (err) {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
return doRequest(host, 'monitors', null, {method: 'POST', body: monitor})
|
||||
})
|
||||
})
|
||||
|
@ -108,5 +108,17 @@ describe("Alter Commands", function() {
|
||||
.should.be.rejected
|
||||
})
|
||||
|
||||
it('creates user', function() {
|
||||
return verifyCommand('create user testuser test', 'users/inet/testuser')
|
||||
})
|
||||
|
||||
it('alters the password of a user', function() {
|
||||
return verifyCommand('alter user testuser test2', 'users/inet/testuser')
|
||||
})
|
||||
|
||||
it('destroys the altered user', function() {
|
||||
return doCommand('destroy user testuser')
|
||||
})
|
||||
|
||||
after(stopMaxScale)
|
||||
});
|
||||
|
@ -18,6 +18,18 @@ describe("Create/Destroy Commands", function() {
|
||||
.should.be.rejected
|
||||
})
|
||||
|
||||
it('monitor without parameters fails due to missing user parameter', function() {
|
||||
return verifyCommand('create monitor my-monitor mysqlmon', 'monitors/my-monitor')
|
||||
.should.be.rejected
|
||||
})
|
||||
|
||||
it('destroy monitor created without parameters', function() {
|
||||
return doCommand('destroy monitor my-monitor')
|
||||
.should.be.fulfilled
|
||||
.then(() => doCommand('show monitor my-monitor'))
|
||||
.should.be.rejected
|
||||
})
|
||||
|
||||
it('will not destroy the same monitor again', function() {
|
||||
return doCommand('destroy monitor my-monitor')
|
||||
.should.be.rejected
|
||||
@ -38,6 +50,11 @@ describe("Create/Destroy Commands", function() {
|
||||
.should.be.rejected
|
||||
})
|
||||
|
||||
it('will not create monitor with malformed parameters', function() {
|
||||
return doCommand('create monitor my-monitor mariadbmon not-a-param')
|
||||
.should.be.rejected
|
||||
})
|
||||
|
||||
it('create monitor with options', function() {
|
||||
return doCommand('unlink monitor MariaDB-Monitor server4')
|
||||
.then(() => verifyCommand('create monitor my-monitor mysqlmon --servers server4 --monitor-user maxuser --monitor-password maxpwd',
|
||||
|
@ -15,5 +15,10 @@ describe("Draining servers", function() {
|
||||
.should.eventually.have.string("Maintenance")
|
||||
})
|
||||
|
||||
it('does not drain non-existent server', function() {
|
||||
return doCommand('drain server not-a-server')
|
||||
.should.be.rejected
|
||||
})
|
||||
|
||||
after(stopMaxScale)
|
||||
});
|
||||
|
@ -19,7 +19,8 @@ describe("Unknown Commands", function() {
|
||||
'alter',
|
||||
'rotate',
|
||||
'call',
|
||||
'cluster'
|
||||
'cluster',
|
||||
'drain'
|
||||
]
|
||||
|
||||
endpoints.forEach(function (i) {
|
||||
|
@ -18,8 +18,6 @@
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
|
||||
// #include <version.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Connect to the MaxScale server
|
||||
|
@ -7,7 +7,7 @@ wsrep_on=ON
|
||||
# Row binary log format is required by Galera
|
||||
binlog_format=ROW
|
||||
|
||||
log-bin
|
||||
log-bin=mar-bin
|
||||
|
||||
# InnoDB is currently the only storage engine supported by Galera
|
||||
default-storage-engine=innodb
|
||||
@ -16,9 +16,6 @@ innodb_file_per_table
|
||||
# To avoid issues with 'bulk mode inserts' using autoincrement fields
|
||||
innodb_autoinc_lock_mode=2
|
||||
|
||||
# Required to prevent deadlocks on parallel transaction execution
|
||||
innodb_locks_unsafe_for_binlog=1
|
||||
|
||||
# Query Cache is not supported by Galera wsrep replication
|
||||
query_cache_size=0
|
||||
query_cache_type=0
|
||||
@ -87,9 +84,6 @@ wsrep_auto_increment_control=1
|
||||
# Retry autoinc insert, when the insert failed for "duplicate key error"
|
||||
wsrep_drupal_282555_workaround=0
|
||||
|
||||
# Enable "strictly synchronous" semantics for read operations
|
||||
wsrep_causal_reads=1
|
||||
|
||||
# Command to call when node status or cluster membership changes.
|
||||
# Will be passed all or some of the following options:
|
||||
# --status - new status of this node
|
||||
|
@ -7,7 +7,7 @@ wsrep_on=ON
|
||||
# Row binary log format is required by Galera
|
||||
binlog_format=ROW
|
||||
|
||||
log-bin
|
||||
log-bin=mar-bin
|
||||
|
||||
# InnoDB is currently the only storage engine supported by Galera
|
||||
default-storage-engine=innodb
|
||||
@ -16,9 +16,6 @@ innodb_file_per_table
|
||||
# To avoid issues with 'bulk mode inserts' using autoincrement fields
|
||||
innodb_autoinc_lock_mode=2
|
||||
|
||||
# Required to prevent deadlocks on parallel transaction execution
|
||||
innodb_locks_unsafe_for_binlog=1
|
||||
|
||||
# Query Cache is not supported by Galera wsrep replication
|
||||
query_cache_size=0
|
||||
query_cache_type=0
|
||||
@ -87,9 +84,6 @@ wsrep_auto_increment_control=1
|
||||
# Retry autoinc insert, when the insert failed for "duplicate key error"
|
||||
wsrep_drupal_282555_workaround=0
|
||||
|
||||
# Enable "strictly synchronous" semantics for read operations
|
||||
wsrep_causal_reads=1
|
||||
|
||||
# Command to call when node status or cluster membership changes.
|
||||
# Will be passed all or some of the following options:
|
||||
# --status - new status of this node
|
||||
|
@ -7,7 +7,7 @@ wsrep_on=ON
|
||||
# Row binary log format is required by Galera
|
||||
binlog_format=ROW
|
||||
|
||||
log-bin
|
||||
log-bin=mar-bin
|
||||
|
||||
# InnoDB is currently the only storage engine supported by Galera
|
||||
default-storage-engine=innodb
|
||||
@ -16,9 +16,6 @@ innodb_file_per_table
|
||||
# To avoid issues with 'bulk mode inserts' using autoincrement fields
|
||||
innodb_autoinc_lock_mode=2
|
||||
|
||||
# Required to prevent deadlocks on parallel transaction execution
|
||||
innodb_locks_unsafe_for_binlog=1
|
||||
|
||||
# Query Cache is not supported by Galera wsrep replication
|
||||
query_cache_size=0
|
||||
query_cache_type=0
|
||||
@ -87,9 +84,6 @@ wsrep_auto_increment_control=1
|
||||
# Retry autoinc insert, when the insert failed for "duplicate key error"
|
||||
wsrep_drupal_282555_workaround=0
|
||||
|
||||
# Enable "strictly synchronous" semantics for read operations
|
||||
wsrep_causal_reads=1
|
||||
|
||||
# Command to call when node status or cluster membership changes.
|
||||
# Will be passed all or some of the following options:
|
||||
# --status - new status of this node
|
||||
|
@ -7,7 +7,7 @@ wsrep_on=ON
|
||||
# Row binary log format is required by Galera
|
||||
binlog_format=ROW
|
||||
|
||||
log-bin
|
||||
log-bin=mar-bin
|
||||
|
||||
# InnoDB is currently the only storage engine supported by Galera
|
||||
default-storage-engine=innodb
|
||||
@ -16,9 +16,6 @@ innodb_file_per_table
|
||||
# To avoid issues with 'bulk mode inserts' using autoincrement fields
|
||||
innodb_autoinc_lock_mode=2
|
||||
|
||||
# Required to prevent deadlocks on parallel transaction execution
|
||||
innodb_locks_unsafe_for_binlog=1
|
||||
|
||||
# Query Cache is not supported by Galera wsrep replication
|
||||
query_cache_size=0
|
||||
query_cache_type=0
|
||||
@ -87,9 +84,6 @@ wsrep_auto_increment_control=1
|
||||
# Retry autoinc insert, when the insert failed for "duplicate key error"
|
||||
wsrep_drupal_282555_workaround=0
|
||||
|
||||
# Enable "strictly synchronous" semantics for read operations
|
||||
wsrep_causal_reads=1
|
||||
|
||||
# Command to call when node status or cluster membership changes.
|
||||
# Will be passed all or some of the following options:
|
||||
# --status - new status of this node
|
||||
|
@ -114,6 +114,7 @@ int main(int argc, char* argv[])
|
||||
test.try_query(test.maxscales->conn_rwsplit[0], "DROP TABLE IF EXISTS t1");
|
||||
test.maxscales->close_maxscale_connections(0);
|
||||
|
||||
test.maxscales->wait_for_monitor();
|
||||
test.check_maxscale_alive(0);
|
||||
test.log_excludes(0, "due to authentication failure");
|
||||
test.log_excludes(0, "due to handshake failure");
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
import maxpython
|
||||
|
||||
test1 = maxpython.MaxScaleTest("mxs585.py")
|
||||
test1 = maxpython.MaxScaleTest("mxs585.py1")
|
||||
|
||||
for i in range(0,100):
|
||||
if i % 10 == 0:
|
||||
|
@ -50,9 +50,7 @@ void Nodes::generate_ssh_cmd(char* cmd, int node, const char* ssh, bool sudo)
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(cmd,
|
||||
"%s",
|
||||
ssh);
|
||||
sprintf(cmd, "%s", ssh);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -413,6 +413,24 @@ TestConnections::TestConnections(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if ((maxscale::restart_galera) && (galera))
|
||||
{
|
||||
galera->stop_nodes();
|
||||
galera->start_replication();
|
||||
}
|
||||
|
||||
if (maxscale::check_nodes)
|
||||
{
|
||||
if (repl && !repl->fix_replication())
|
||||
{
|
||||
exit(BROKEN_VM_FAUILT);
|
||||
}
|
||||
if (galera && !galera->fix_replication())
|
||||
{
|
||||
exit(BROKEN_VM_FAUILT);
|
||||
}
|
||||
}
|
||||
|
||||
if (repl && maxscale::required_repl_version.length())
|
||||
{
|
||||
int ver_repl_required = get_int_version(maxscale::required_repl_version);
|
||||
@ -443,24 +461,6 @@ TestConnections::TestConnections(int argc, char* argv[])
|
||||
}
|
||||
}
|
||||
|
||||
if ((maxscale::restart_galera) && (galera))
|
||||
{
|
||||
galera->stop_nodes();
|
||||
galera->start_replication();
|
||||
}
|
||||
|
||||
if (maxscale::check_nodes)
|
||||
{
|
||||
if (repl && !repl->fix_replication())
|
||||
{
|
||||
exit(BROKEN_VM_FAUILT);
|
||||
}
|
||||
if (galera && !galera->fix_replication())
|
||||
{
|
||||
exit(BROKEN_VM_FAUILT);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxscale_init)
|
||||
{
|
||||
init_maxscales();
|
||||
@ -605,7 +605,8 @@ void TestConnections::read_mdbci_info()
|
||||
target = readenv("target", "develop");
|
||||
|
||||
mdbci_config_name = readenv("mdbci_config_name", "local");
|
||||
vm_path = std::string(mdbci_vm_path) + std::string(mdbci_config_name);
|
||||
vm_path = std::string(mdbci_vm_path) + "/" + std::string(mdbci_config_name);
|
||||
|
||||
if (mdbci_config_name != NULL)
|
||||
{
|
||||
std::ifstream nc_file;
|
||||
@ -2191,6 +2192,13 @@ int TestConnections::call_mdbci(const char * options)
|
||||
tprintf("MDBCI failed to bring up virtual machines");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::string team_keys = readenv("team_keys", "~/.ssh/id_rsa.pub");
|
||||
system((std::string("mdbci public_keys --key ") +
|
||||
team_keys +
|
||||
std::string(" ") +
|
||||
std::string(mdbci_config_name)).c_str() );
|
||||
|
||||
read_env();
|
||||
if (repl)
|
||||
{
|
||||
|
@ -2850,7 +2850,7 @@ void config_set_global_defaults()
|
||||
gateway.peer_password[0] = '\0';
|
||||
gateway.log_target = MXB_LOG_TARGET_DEFAULT;
|
||||
|
||||
gateway.qc_cache_properties.max_size = get_total_memory() * 0.4;
|
||||
gateway.qc_cache_properties.max_size = get_total_memory() * 0.15;
|
||||
|
||||
if (gateway.qc_cache_properties.max_size == 0)
|
||||
{
|
||||
|
@ -176,10 +176,15 @@ public:
|
||||
mxb_assert(peek(canonical_stmt) == nullptr);
|
||||
mxb_assert(this_unit.classifier);
|
||||
|
||||
// 0xffffff is the maximum packet size, 4 is for packet header and 1 is for command byte. These are
|
||||
// MariaDB/MySQL protocol specific values that are also defined in <maxscale/protocol/mysql.h> but
|
||||
// should not be exposed to the core.
|
||||
constexpr int64_t max_entry_size = 0xffffff - 5;
|
||||
|
||||
int64_t cache_max_size = this_unit.cache_max_size() / config_get_global_options()->n_threads;
|
||||
int64_t size = canonical_stmt.size();
|
||||
|
||||
if (size <= cache_max_size)
|
||||
if (size < max_entry_size && size <= cache_max_size)
|
||||
{
|
||||
int64_t required_space = (m_stats.size + size) - cache_max_size;
|
||||
|
||||
|
@ -56,17 +56,22 @@ static std::string do_query(MXS_MONITORED_SERVER* srv, const char* query)
|
||||
// Returns a numeric version similar to mysql_get_server_version
|
||||
int get_cs_version(MXS_MONITORED_SERVER* srv)
|
||||
{
|
||||
// GCC 4.8 appears to have a broken std::regex_constants::ECMAScript that doesn't support brackets
|
||||
std::regex re("Columnstore \\([0-9]*\\)[.]\\([0-9]*\\)[.]\\([0-9]*\\)-[0-9]*",
|
||||
std::regex_constants::basic);
|
||||
std::string result = do_query(srv, "SELECT @@version_comment");
|
||||
std::smatch match;
|
||||
int rval = 0;
|
||||
std::string prefix = "Columnstore ";
|
||||
std::string result = do_query(srv, "SELECT @@version_comment");
|
||||
auto pos = result.find(prefix);
|
||||
|
||||
if (std::regex_match(result, match, re) && match.size() == 4)
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
rval = atoi(match[1].str().c_str()) * 10000 + atoi(match[2].str().c_str()) * 100
|
||||
+ atoi(match[3].str().c_str());
|
||||
std::istringstream os(result.substr(pos + prefix.length()));
|
||||
int major = 0, minor = 0, patch = 0;
|
||||
char dot;
|
||||
os >> major;
|
||||
os >> dot;
|
||||
os >> minor;
|
||||
os >> dot;
|
||||
os >> patch;
|
||||
rval = major * 10000 + minor * 100 + patch;
|
||||
}
|
||||
|
||||
return rval;
|
||||
|
@ -27,13 +27,11 @@ using maxscale::string_printf;
|
||||
using maxbase::StopWatch;
|
||||
using maxbase::Duration;
|
||||
|
||||
static const char RE_ENABLE_FMT[] = "To re-enable automatic %s, manually set '%s' to 'true' "
|
||||
"for monitor '%s' via MaxAdmin or the REST API, or restart MaxScale.";
|
||||
const char NO_SERVER[] = "Server '%s' is not monitored by '%s'.";
|
||||
const char FAILOVER_OK[] = "Failover '%s' -> '%s' performed.";
|
||||
const char FAILOVER_FAIL[] = "Failover '%s' -> '%s' failed.";
|
||||
const char SWITCHOVER_OK[] = "Switchover '%s' -> '%s' performed.";
|
||||
const char SWITCHOVER_FAIL[] = "Switchover %s -> %s failed";
|
||||
const char SWITCHOVER_FAIL[] = "Switchover %s -> %s failed.";
|
||||
|
||||
/**
|
||||
* Run a manual switchover, promoting a new master server and demoting the existing master.
|
||||
@ -64,14 +62,8 @@ bool MariaDBMonitor::manual_switchover(SERVER* promotion_server, SERVER* demotio
|
||||
{
|
||||
string msg = string_printf(SWITCHOVER_FAIL,
|
||||
op->demotion.target->name(), op->promotion.target->name());
|
||||
bool failover_setting = config_get_bool(m_monitor->parameters, CN_AUTO_FAILOVER);
|
||||
if (failover_setting)
|
||||
{
|
||||
disable_setting(CN_AUTO_FAILOVER);
|
||||
msg += ", automatic failover has been disabled";
|
||||
}
|
||||
msg += ".";
|
||||
PRINT_MXS_JSON_ERROR(error_out, "%s", msg.c_str());
|
||||
delay_auto_cluster_ops();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -411,6 +403,10 @@ string MariaDBMonitor::generate_change_master_cmd(const string& master_host, int
|
||||
change_cmd << "CHANGE MASTER TO MASTER_HOST = '" << master_host << "', ";
|
||||
change_cmd << "MASTER_PORT = " << master_port << ", ";
|
||||
change_cmd << "MASTER_USE_GTID = current_pos, ";
|
||||
if (m_replication_ssl)
|
||||
{
|
||||
change_cmd << "MASTER_SSL = 1, ";
|
||||
}
|
||||
change_cmd << "MASTER_USER = '" << m_replication_user << "', ";
|
||||
const char MASTER_PW[] = "MASTER_PASSWORD = '";
|
||||
const char END[] = "';";
|
||||
@ -621,6 +617,7 @@ uint32_t MariaDBMonitor::do_rejoin(const ServerArray& joinable_servers, json_t**
|
||||
SERVER* master_server = m_master->m_server_base->server;
|
||||
const char* master_name = master_server->name;
|
||||
uint32_t servers_joined = 0;
|
||||
bool rejoin_error = false;
|
||||
if (!joinable_servers.empty())
|
||||
{
|
||||
for (MariaDBServer* joinable : joinable_servers)
|
||||
@ -630,7 +627,8 @@ uint32_t MariaDBMonitor::do_rejoin(const ServerArray& joinable_servers, json_t**
|
||||
// Rejoin doesn't have its own time limit setting. Use switchover time limit for now since
|
||||
// the first phase of standalone rejoin is similar to switchover.
|
||||
maxbase::Duration time_limit((double)m_switchover_timeout);
|
||||
GeneralOpData general(m_replication_user, m_replication_password, output, time_limit);
|
||||
GeneralOpData general(m_replication_user, m_replication_password, m_replication_ssl,
|
||||
output, time_limit);
|
||||
|
||||
if (joinable->m_slave_status.empty())
|
||||
{
|
||||
@ -651,7 +649,8 @@ uint32_t MariaDBMonitor::do_rejoin(const ServerArray& joinable_servers, json_t**
|
||||
else
|
||||
{
|
||||
PRINT_MXS_JSON_ERROR(output,
|
||||
"Failed to prepare (demote) standalone server '%s' for rejoin.", name);
|
||||
"Failed to prepare (demote) standalone server '%s' for rejoin.",
|
||||
name);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -670,8 +669,17 @@ uint32_t MariaDBMonitor::do_rejoin(const ServerArray& joinable_servers, json_t**
|
||||
servers_joined++;
|
||||
m_cluster_modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
rejoin_error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rejoin_error)
|
||||
{
|
||||
delay_auto_cluster_ops();
|
||||
}
|
||||
return servers_joined;
|
||||
}
|
||||
|
||||
@ -1410,7 +1418,8 @@ unique_ptr<MariaDBMonitor::FailoverParams> MariaDBMonitor::failover_prepare(Log
|
||||
ServerOperation promotion(promotion_target, promoting_to_master,
|
||||
m_handle_event_scheduler, m_promote_sql_file,
|
||||
demotion_target->m_slave_status, demotion_target->m_enabled_events);
|
||||
GeneralOpData general(m_replication_user, m_replication_password, error_out, time_limit);
|
||||
GeneralOpData general(m_replication_user, m_replication_password, m_replication_ssl,
|
||||
error_out, time_limit);
|
||||
rval.reset(new FailoverParams(promotion, demotion_target, general));
|
||||
}
|
||||
}
|
||||
@ -1468,7 +1477,7 @@ void MariaDBMonitor::handle_auto_failover()
|
||||
else
|
||||
{
|
||||
MXS_ERROR(FAILOVER_FAIL, op->demotion_target->name(), op->promotion.target->name());
|
||||
report_and_disable("failover", CN_AUTO_FAILOVER, &m_auto_failover);
|
||||
delay_auto_cluster_ops();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1529,26 +1538,10 @@ void MariaDBMonitor::check_cluster_operations_support()
|
||||
{
|
||||
const char PROBLEMS[] =
|
||||
"The backend cluster does not support failover/switchover due to the following reason(s):\n"
|
||||
"%s\n"
|
||||
"Automatic failover/switchover has been disabled. They should only be enabled "
|
||||
"after the above issues have been resolved.";
|
||||
string p1 = string_printf(PROBLEMS, all_reasons.c_str());
|
||||
string p2 = string_printf(RE_ENABLE_FMT, "failover", CN_AUTO_FAILOVER, m_monitor->name);
|
||||
string p3 = string_printf(RE_ENABLE_FMT, "switchover", CN_SWITCHOVER_ON_LOW_DISK_SPACE,
|
||||
m_monitor->name);
|
||||
string total_msg = p1 + " " + p2 + " " + p3;
|
||||
MXS_ERROR("%s", total_msg.c_str());
|
||||
|
||||
if (m_auto_failover)
|
||||
{
|
||||
m_auto_failover = false;
|
||||
disable_setting(CN_AUTO_FAILOVER);
|
||||
}
|
||||
if (m_switchover_on_low_disk_space)
|
||||
{
|
||||
m_switchover_on_low_disk_space = false;
|
||||
disable_setting(CN_SWITCHOVER_ON_LOW_DISK_SPACE);
|
||||
}
|
||||
"%s\n";
|
||||
string msg = string_printf(PROBLEMS, all_reasons.c_str());
|
||||
MXS_ERROR("%s", msg.c_str());
|
||||
delay_auto_cluster_ops();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1703,7 +1696,8 @@ MariaDBMonitor::switchover_prepare(SERVER* promotion_server, SERVER* demotion_se
|
||||
ServerOperation demotion(demotion_target, master_swap, m_handle_event_scheduler,
|
||||
m_demote_sql_file, promotion_target->m_slave_status,
|
||||
EventNameSet() /* unused */);
|
||||
GeneralOpData general(m_replication_user, m_replication_password, error_out, time_limit);
|
||||
GeneralOpData general(m_replication_user, m_replication_password, m_replication_ssl,
|
||||
error_out, time_limit);
|
||||
rval.reset(new SwitchoverParams(promotion, demotion, general));
|
||||
}
|
||||
return rval;
|
||||
@ -1712,6 +1706,7 @@ MariaDBMonitor::switchover_prepare(SERVER* promotion_server, SERVER* demotion_se
|
||||
void MariaDBMonitor::enforce_read_only_on_slaves()
|
||||
{
|
||||
const char QUERY[] = "SET GLOBAL read_only=1;";
|
||||
bool error = false;
|
||||
for (MariaDBServer* server : m_servers)
|
||||
{
|
||||
if (server->is_slave() && !server->is_read_only()
|
||||
@ -1725,9 +1720,15 @@ void MariaDBMonitor::enforce_read_only_on_slaves()
|
||||
else
|
||||
{
|
||||
MXS_ERROR("Setting read_only on '%s' failed: '%s'.", server->name(), mysql_error(conn));
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
delay_auto_cluster_ops();
|
||||
}
|
||||
}
|
||||
|
||||
void MariaDBMonitor::handle_low_disk_space_master()
|
||||
@ -1755,8 +1756,7 @@ void MariaDBMonitor::handle_low_disk_space_master()
|
||||
else
|
||||
{
|
||||
MXS_ERROR(SWITCHOVER_FAIL, op->demotion.target->name(), op->promotion.target->name());
|
||||
report_and_disable("switchover", CN_SWITCHOVER_ON_LOW_DISK_SPACE,
|
||||
&m_switchover_on_low_disk_space);
|
||||
delay_auto_cluster_ops();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1791,19 +1791,6 @@ void MariaDBMonitor::handle_auto_rejoin()
|
||||
// get_joinable_servers prints an error if master is unresponsive
|
||||
}
|
||||
|
||||
void MariaDBMonitor::report_and_disable(const string& operation, const string& setting_name,
|
||||
bool* setting_var)
|
||||
{
|
||||
string p1 = string_printf("Automatic %s failed, disabling automatic %s.",
|
||||
operation.c_str(),
|
||||
operation.c_str());
|
||||
string p2 = string_printf(RE_ENABLE_FMT, operation.c_str(), setting_name.c_str(), m_monitor->name);
|
||||
string error_msg = p1 + " " + p2;
|
||||
MXS_ERROR("%s", error_msg.c_str());
|
||||
*setting_var = false;
|
||||
disable_setting(setting_name.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the slaves to demotion target are using gtid replication and that the gtid domain of the
|
||||
* cluster is defined. Only the slave connections to the demotion target are checked.
|
||||
@ -1871,6 +1858,24 @@ ServerArray MariaDBMonitor::get_redirectables(const MariaDBServer* old_master,
|
||||
return redirectable_slaves;
|
||||
}
|
||||
|
||||
void MariaDBMonitor::delay_auto_cluster_ops()
|
||||
{
|
||||
if (m_auto_failover || m_auto_rejoin || m_enforce_read_only_slaves || m_switchover_on_low_disk_space)
|
||||
{
|
||||
const char DISABLING_AUTO_OPS[] = "Disabling automatic cluster operations for %i monitor ticks.";
|
||||
MXS_NOTICE(DISABLING_AUTO_OPS, m_failcount);
|
||||
}
|
||||
// + 1 because the start of next tick subtracts 1.
|
||||
cluster_operation_disable_timer = m_failcount + 1;
|
||||
|
||||
}
|
||||
|
||||
bool MariaDBMonitor::can_perform_cluster_ops()
|
||||
{
|
||||
return (!config_get_global_options()->passive && cluster_operation_disable_timer <= 0 &&
|
||||
!m_cluster_modified);
|
||||
}
|
||||
|
||||
MariaDBMonitor::SwitchoverParams::SwitchoverParams(const ServerOperation& promotion,
|
||||
const ServerOperation& demotion,
|
||||
const GeneralOpData& general)
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include <maxscale/routingworker.h>
|
||||
#include <maxscale/secrets.h>
|
||||
#include <maxscale/utils.hh>
|
||||
// TODO: For monitor_add_parameters
|
||||
#include "../../../core/internal/monitor.h"
|
||||
|
||||
using std::string;
|
||||
using maxscale::string_printf;
|
||||
@ -54,9 +52,7 @@ static const char CN_MASTER_FAILURE_TIMEOUT[] = "master_failure_timeout";
|
||||
// Replication credentials parameters for failover/switchover/join
|
||||
static const char CN_REPLICATION_USER[] = "replication_user";
|
||||
static const char CN_REPLICATION_PASSWORD[] = "replication_password";
|
||||
|
||||
static const char DIAG_ERROR[] = "Internal error, could not print diagnostics. "
|
||||
"Check log for more information.";
|
||||
static const char CN_REPLICATION_MASTER_SSL[] = "replication_master_ssl";
|
||||
|
||||
MariaDBMonitor::MariaDBMonitor(MXS_MONITOR* monitor)
|
||||
: maxscale::MonitorInstance(monitor)
|
||||
@ -227,6 +223,7 @@ bool MariaDBMonitor::configure(const MXS_CONFIG_PARAMETER* params)
|
||||
m_switchover_on_low_disk_space = config_get_bool(params, CN_SWITCHOVER_ON_LOW_DISK_SPACE);
|
||||
m_maintenance_on_low_disk_space = config_get_bool(params, CN_MAINTENANCE_ON_LOW_DISK_SPACE);
|
||||
m_handle_event_scheduler = config_get_bool(params, CN_HANDLE_EVENTS);
|
||||
m_replication_ssl = config_get_bool(params, CN_REPLICATION_MASTER_SSL);
|
||||
|
||||
/* Reset all monitored state info. The server dependent values must be reset as servers could have been
|
||||
* added, removed and modified. */
|
||||
@ -441,6 +438,11 @@ void MariaDBMonitor::tick()
|
||||
mon_srv->mon_prev_status = status;
|
||||
}
|
||||
|
||||
if (cluster_operation_disable_timer > 0)
|
||||
{
|
||||
cluster_operation_disable_timer--;
|
||||
}
|
||||
|
||||
// Query all servers for their status.
|
||||
for (MariaDBServer* server : m_servers)
|
||||
{
|
||||
@ -458,7 +460,7 @@ void MariaDBMonitor::tick()
|
||||
update_topology();
|
||||
m_cluster_topology_changed = false;
|
||||
// If cluster operations are enabled, check topology support and disable if needed.
|
||||
if (m_auto_failover || m_switchover_on_low_disk_space)
|
||||
if (m_auto_failover || m_switchover_on_low_disk_space || m_auto_rejoin)
|
||||
{
|
||||
check_cluster_operations_support();
|
||||
}
|
||||
@ -531,16 +533,16 @@ void MariaDBMonitor::process_state_changes()
|
||||
}
|
||||
}
|
||||
|
||||
if (!config_get_global_options()->passive)
|
||||
if (can_perform_cluster_ops())
|
||||
{
|
||||
if (m_auto_failover && !m_cluster_modified)
|
||||
if (m_auto_failover)
|
||||
{
|
||||
handle_auto_failover();
|
||||
}
|
||||
|
||||
// Do not auto-join servers on this monitor loop if a failover (or any other cluster modification)
|
||||
// has been performed, as server states have not been updated yet. It will happen next iteration.
|
||||
if (m_auto_rejoin && !m_cluster_modified && cluster_can_be_joined())
|
||||
if (m_auto_rejoin && cluster_can_be_joined() && can_perform_cluster_ops())
|
||||
{
|
||||
// Check if any servers should be autojoined to the cluster and try to join them.
|
||||
handle_auto_rejoin();
|
||||
@ -549,13 +551,13 @@ void MariaDBMonitor::process_state_changes()
|
||||
/* Check if any slave servers have read-only off and turn it on if user so wishes. Again, do not
|
||||
* perform this if cluster has been modified this loop since it may not be clear which server
|
||||
* should be a slave. */
|
||||
if (m_enforce_read_only_slaves && !m_cluster_modified)
|
||||
if (m_enforce_read_only_slaves && can_perform_cluster_ops())
|
||||
{
|
||||
enforce_read_only_on_slaves();
|
||||
}
|
||||
|
||||
/* Check if the master server is on low disk space and act on it. */
|
||||
if (m_switchover_on_low_disk_space && !m_cluster_modified)
|
||||
if (m_switchover_on_low_disk_space && can_perform_cluster_ops())
|
||||
{
|
||||
handle_low_disk_space_master();
|
||||
}
|
||||
@ -684,25 +686,6 @@ void MariaDBMonitor::assign_new_master(MariaDBServer* new_master)
|
||||
m_warn_have_better_master = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a monitor config parameter to "false". The effect persists over stopMonitor/startMonitor but not
|
||||
* MaxScale restart. Only use on boolean config settings.
|
||||
*
|
||||
* @param setting_name Setting to disable
|
||||
*/
|
||||
void MariaDBMonitor::disable_setting(const std::string& setting)
|
||||
{
|
||||
Worker* worker = static_cast<Worker*>(mxs_rworker_get(MXS_RWORKER_MAIN));
|
||||
|
||||
worker->execute([=]() {
|
||||
MXS_CONFIG_PARAMETER p = {};
|
||||
p.name = const_cast<char*>(setting.c_str());
|
||||
p.value = const_cast<char*>("false");
|
||||
monitor_add_parameters(m_monitor, &p);
|
||||
},
|
||||
EXECUTE_AUTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check sql text file parameters. A parameter should either be empty or a valid file which can be opened.
|
||||
*
|
||||
@ -1067,6 +1050,9 @@ extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
CN_REPLICATION_PASSWORD, MXS_MODULE_PARAM_STRING
|
||||
},
|
||||
{
|
||||
CN_REPLICATION_MASTER_SSL, MXS_MODULE_PARAM_BOOL, "false"
|
||||
},
|
||||
{
|
||||
CN_VERIFY_MASTER_FAILURE, MXS_MODULE_PARAM_BOOL, "true"
|
||||
},
|
||||
|
@ -177,6 +177,10 @@ private:
|
||||
* Causes a topology rebuild on the current tick. */
|
||||
bool m_cluster_modified = false; /* Has a cluster operation been performed this loop? Prevents
|
||||
* other operations during this tick. */
|
||||
|
||||
/* Counter for temporary automatic cluster operation disabling. */
|
||||
int cluster_operation_disable_timer = 0;
|
||||
|
||||
CycleMap m_cycles; /* Map from cycle number to cycle member servers */
|
||||
CycleInfo m_master_cycle_status; /* Info about master server cycle from previous round */
|
||||
|
||||
@ -212,6 +216,7 @@ private:
|
||||
// Cluster operations additional settings
|
||||
std::string m_replication_user; /* Replication user for CHANGE MASTER TO-commands */
|
||||
std::string m_replication_password; /* Replication password for CHANGE MASTER TO-commands */
|
||||
bool m_replication_ssl = false; /* Set MASTER_SSL = 1 in CHANGE MASTER TO-commands */
|
||||
bool m_handle_event_scheduler = true;/* Should failover/switchover enable/disable any scheduled
|
||||
* events on the servers during promote/demote? */
|
||||
uint32_t m_failover_timeout = 10; /* Time limit in seconds for failover */
|
||||
@ -295,6 +300,9 @@ private:
|
||||
bool switchover_perform(SwitchoverParams& operation);
|
||||
bool failover_perform(FailoverParams& op);
|
||||
|
||||
void delay_auto_cluster_ops();
|
||||
bool can_perform_cluster_ops();
|
||||
|
||||
// Methods used by failover/switchover/rejoin
|
||||
MariaDBServer* select_promotion_target(MariaDBServer* current_master, OperationType op,
|
||||
Log log_mode, json_t** error_out);
|
||||
@ -318,8 +326,6 @@ private:
|
||||
std::string generate_change_master_cmd(const std::string& master_host, int master_port);
|
||||
void wait_cluster_stabilization(GeneralOpData& op, const ServerArray& slaves,
|
||||
const MariaDBServer* new_master);
|
||||
void report_and_disable(const std::string& operation, const std::string& setting_name,
|
||||
bool* setting_var);
|
||||
|
||||
// Rejoin methods
|
||||
bool cluster_can_be_joined();
|
||||
@ -327,8 +333,6 @@ private:
|
||||
bool server_is_rejoin_suspect(MariaDBServer* rejoin_cand, json_t** output);
|
||||
uint32_t do_rejoin(const ServerArray& joinable_servers, json_t** output);
|
||||
|
||||
// Other methods
|
||||
void disable_setting(const std::string& setting);
|
||||
bool check_sql_files();
|
||||
void enforce_read_only_on_slaves();
|
||||
void log_master_changes();
|
||||
|
@ -2064,6 +2064,10 @@ string MariaDBServer::generate_change_master_cmd(GeneralOpData& op, const SlaveS
|
||||
slave_conn.name.c_str(),
|
||||
slave_conn.master_host.c_str(), slave_conn.master_port);
|
||||
change_cmd += "MASTER_USE_GTID = current_pos, ";
|
||||
if (op.replication_ssl)
|
||||
{
|
||||
change_cmd += "MASTER_SSL = 1, ";
|
||||
}
|
||||
change_cmd += string_printf("MASTER_USER = '%s', ", op.replication_user.c_str());
|
||||
const char MASTER_PW[] = "MASTER_PASSWORD = '%s';";
|
||||
#if defined (SS_DEBUG)
|
||||
|
@ -174,10 +174,11 @@ ServerOperation::ServerOperation(MariaDBServer* target, bool was_is_master, bool
|
||||
{
|
||||
}
|
||||
|
||||
GeneralOpData::GeneralOpData(const string& replication_user, const string& replication_password,
|
||||
json_t** error, maxbase::Duration time_remaining)
|
||||
GeneralOpData::GeneralOpData(const std::string& replication_user, const std::string& replication_password,
|
||||
bool replication_ssl, json_t** error, maxbase::Duration time_remaining)
|
||||
: replication_user(replication_user)
|
||||
, replication_password(replication_password)
|
||||
, replication_ssl(replication_ssl)
|
||||
, error_out(error)
|
||||
, time_remaining(time_remaining)
|
||||
{
|
||||
|
@ -224,11 +224,12 @@ class GeneralOpData
|
||||
public:
|
||||
const std::string replication_user; // User for CHANGE MASTER TO ...
|
||||
const std::string replication_password; // Password for CHANGE MASTER TO ...
|
||||
const bool replication_ssl; // MASTER_SSL=1 in CHANGE MASTER TO ...
|
||||
json_t** const error_out; // Json error output
|
||||
maxbase::Duration time_remaining; // How much time remains to complete the operation
|
||||
|
||||
GeneralOpData(const std::string& replication_user, const std::string& replication_password,
|
||||
json_t** error, maxbase::Duration time_remaining);
|
||||
bool replication_ssl, json_t** error, maxbase::Duration time_remaining);
|
||||
};
|
||||
|
||||
// Operation data which concerns a single server
|
||||
|
@ -296,6 +296,17 @@ void RWBackend::process_packets(GWBUF* result)
|
||||
auto end = std::next(it, len);
|
||||
uint8_t cmd = *it;
|
||||
|
||||
// Ignore the tail end of a large packet large packet. Only resultsets can generate packets this large
|
||||
// and we don't care what the contents are and thus it is safe to ignore it.
|
||||
bool skip_next = m_skip_next;
|
||||
m_skip_next = len == GW_MYSQL_MAX_PACKET_LEN;
|
||||
|
||||
if (skip_next)
|
||||
{
|
||||
it = end;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (m_reply_state)
|
||||
{
|
||||
case REPLY_STATE_START:
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <maxscale/alloc.h>
|
||||
#include <maxscale/buffer.hh>
|
||||
#include <maxscale/utils.hh>
|
||||
#include <maxscale/routingworker.hh>
|
||||
|
||||
std::pair<std::string, std::string> get_avrofile_and_gtid(std::string file);
|
||||
|
||||
@ -239,22 +240,14 @@ bool file_in_dir(const char* dir, const char* file)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The client callback for sending data
|
||||
*
|
||||
* @param dcb Client DCB
|
||||
* @param reason Why the callback was called
|
||||
* @param userdata Data provided when the callback was added
|
||||
* @return Always 0
|
||||
* Queue the client callback for execution
|
||||
*/
|
||||
int avro_client_callback(DCB* dcb, DCB_REASON reason, void* userdata)
|
||||
void AvroSession::queue_client_callback()
|
||||
{
|
||||
if (reason == DCB_REASON_DRAINED)
|
||||
{
|
||||
AvroSession* client = static_cast<AvroSession*>(userdata);
|
||||
client->client_callback();
|
||||
}
|
||||
|
||||
return 0;
|
||||
auto worker = mxs::RoutingWorker::get(mxs::RoutingWorker::MAIN);
|
||||
worker->execute([this]() {
|
||||
client_callback();
|
||||
}, mxs::RoutingWorker::EXECUTE_QUEUED);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,11 +331,7 @@ void AvroSession::process_command(GWBUF* queue)
|
||||
|
||||
if (file_in_dir(router->avrodir.c_str(), avro_binfile.c_str()))
|
||||
{
|
||||
/* set callback routine for data sending */
|
||||
dcb_add_callback(dcb, DCB_REASON_DRAINED, avro_client_callback, this);
|
||||
|
||||
/* Add fake event that will call the avro_client_callback() routine */
|
||||
poll_fake_write_event(dcb);
|
||||
queue_client_callback();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -734,7 +723,7 @@ void AvroSession::client_callback()
|
||||
|
||||
if (next_file || read_more)
|
||||
{
|
||||
poll_fake_write_event(dcb);
|
||||
queue_client_callback();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,11 +170,6 @@ public:
|
||||
*/
|
||||
int routeQuery(GWBUF* buffer);
|
||||
|
||||
/**
|
||||
* Handler for the EPOLLOUT event
|
||||
*/
|
||||
void client_callback();
|
||||
|
||||
private:
|
||||
AvroSession(Avro* instance, MXS_SESSION* session);
|
||||
|
||||
@ -187,6 +182,8 @@ private:
|
||||
bool seek_to_gtid();
|
||||
bool stream_data();
|
||||
void rotate_avro_file(std::string fullname);
|
||||
void client_callback();
|
||||
void queue_client_callback();
|
||||
};
|
||||
|
||||
void read_table_info(uint8_t* ptr,
|
||||
|
Loading…
x
Reference in New Issue
Block a user