MXS-1356: Allow tee filter to be disabled at runtime

Disabling the tee filter at runtime is desirable for cases where the
branched service is not always needed. Migrations and pre-production
setups are one where changes to the branched service are expected and
splitting the queries would result in an error.
This commit is contained in:
Markus Mäkelä 2017-08-10 13:34:49 +03:00
parent 53bf21f785
commit b768d3ca76
5 changed files with 69 additions and 2 deletions

View File

@ -99,6 +99,23 @@ sessions that are connected using this username are replicated.
user=john
```
## Module commands
Read [Module Commands](../Reference/Module-Commands.md) documentation for
details about module commands.
The tee filter supports the following module commands.
### `tee disable [FILTER]`
This commmad disables a tee filter instance. A disabled tee filter will not send
any queries to the target service.
### `tee enable [FILTER]`
Enable a disabled tee filter. This resumes the sending of queries to the target
service.
## Examples
### Example 1 - Replicate all inserts into the orders table

View File

@ -59,6 +59,13 @@ The `match` and `exclude` parameters were changed to use PCRE2 syntax for the
regular expressions. The regular expression should be enclosed by slashes
e.g. `match=/select.*from.*test/`.
A tee filter instance can be disabled with the new `tee disable [FILTER]` and
`tee enable [FILTER]` module commands. Refer to the
[module command documentation](../Reference/Module-Commands.md) for more
details on module commands and the
[Tee Filter documentation](../Filters/Tee-Filter.md) for details on the tee
filter specific commands.
### Dbfwfilter
The `function` type rule will now match a query that does not use a function

View File

@ -22,6 +22,7 @@
#include <maxscale/alloc.h>
#include <maxscale/modinfo.h>
#include <maxscale/log_manager.h>
#include <maxscale/modulecmd.h>
#include "tee.hh"
#include "local_client.hh"
@ -44,7 +45,8 @@ Tee::Tee(SERVICE* service, std::string user, std::string remote,
m_match_code(match),
m_exclude_code(exclude),
m_match(match_string),
m_exclude(exclude_string)
m_exclude(exclude_string),
m_enabled(true)
{
}
@ -121,6 +123,7 @@ void Tee::diagnostics(DCB *dcb)
dcb_printf(dcb, "\t\tExclude queries that match %s\n",
m_exclude.c_str());
}
dcb_printf(dcb, "\t\tFilter enabled: %s\n", m_enabled ? "yes" : "no");
}
/**
@ -159,9 +162,25 @@ json_t* Tee::diagnostics_json() const
json_object_set_new(rval, "exclude", json_string(m_exclude.c_str()));
}
json_object_set_new(rval, "enabled", json_boolean(m_enabled));
return rval;
}
static bool enable_tee(const MODULECMD_ARG *argv, json_t** output)
{
Tee* instance = reinterpret_cast<Tee*>(filter_def_get_instance(argv->argv[0].value.filter));
instance->set_enabled(true);
return true;
}
static bool disable_tee(const MODULECMD_ARG *argv, json_t** output)
{
Tee* instance = reinterpret_cast<Tee*>(filter_def_get_instance(argv->argv[0].value.filter));
instance->set_enabled(false);
return true;
}
MXS_BEGIN_DECLS
/**
@ -174,6 +193,18 @@ MXS_BEGIN_DECLS
*/
MXS_MODULE* MXS_CREATE_MODULE()
{
modulecmd_arg_type_t argv[] =
{
{
MODULECMD_ARG_FILTER | MODULECMD_ARG_NAME_MATCHES_DOMAIN,
"Filter to modify"
}
};
modulecmd_register_command(MXS_MODULE_NAME, "enable", MODULECMD_TYPE_ACTIVE,
enable_tee, 1, argv, "Enable a tee filter instance");
modulecmd_register_command(MXS_MODULE_NAME, "disable", MODULECMD_TYPE_ACTIVE,
disable_tee, 1, argv, "Disable a tee filter instance");
static MXS_MODULE info =
{

View File

@ -67,6 +67,16 @@ public:
return m_exclude_code;
}
void set_enabled(bool value)
{
m_enabled = value;
}
bool is_enabled() const
{
return m_enabled;
}
private:
Tee(SERVICE* service, std::string user, std::string remote,
pcre2_code* match, std::string match_string,
@ -79,4 +89,5 @@ private:
pcre2_code* m_exclude_code; /* Compiled exclude pattern*/
std::string m_match; /* Pattern for matching queries */
std::string m_exclude; /* Pattern for excluding queries */
bool m_enabled;
};

View File

@ -88,7 +88,8 @@ TeeSession* TeeSession::create(Tee* my_instance, MXS_SESSION* session)
pcre2_match_data* md_match = NULL;
pcre2_match_data* md_exclude = NULL;
if (my_instance->user_matches(session_get_user(session)) &&
if (my_instance->is_enabled() &&
my_instance->user_matches(session_get_user(session)) &&
my_instance->remote_matches(session_get_remote(session)))
{
match = my_instance->get_match();