If MAXSCALE_SCHEMA.REPLICATION_HEARTBEAT isn't replicated, a warning is logged.
This commit is contained in:
Markus Makela
2015-10-27 20:25:12 +02:00
parent c1eb84b377
commit cd55f62051
3 changed files with 365 additions and 1 deletions

View File

@ -38,6 +38,19 @@ extern int lm_enabled_logfiles_bitmask;
extern size_t log_ses_count[];
extern __thread log_info_t tls_log_info;
/** These are used when converting MySQL wildcards to regular expressions */
static SPINLOCK re_lock = SPINLOCK_INIT;
static bool pattern_init = false;
static pcre2_code *re_percent = NULL;
static pcre2_code *re_single = NULL;
static pcre2_code *re_escape = NULL;
static const PCRE2_SPTR pattern_percent = (PCRE2_SPTR) "%";
static const PCRE2_SPTR pattern_single = (PCRE2_SPTR) "([^\\\\]|^)_";
static const PCRE2_SPTR pattern_escape = (PCRE2_SPTR) "[.]";
static const char* sub_percent = ".*";
static const char* sub_single = "$1.";
static const char* sub_escape = "\\.";
static void modutil_reply_routing_error(
DCB* backend_dcb,
int error,
@ -842,3 +855,119 @@ int modutil_count_statements(GWBUF* buffer)
return num;
}
/**
* Initialize the PCRE2 patterns used when converting MySQL wildcards to PCRE syntax.
*/
void init_pcre2_patterns()
{
spinlock_acquire(&re_lock);
if (!pattern_init)
{
int err;
size_t erroff;
PCRE2_UCHAR errbuf[STRERROR_BUFLEN];
if ((re_percent = pcre2_compile(pattern_percent, PCRE2_ZERO_TERMINATED,
0, &err, &erroff, NULL)) &&
(re_single = pcre2_compile(pattern_single, PCRE2_ZERO_TERMINATED,
0, &err, &erroff, NULL)) &&
(re_escape = pcre2_compile(pattern_escape, PCRE2_ZERO_TERMINATED,
0, &err, &erroff, NULL)))
{
pattern_init = true;
}
else
{
pcre2_get_error_message(err, errbuf, sizeof(errbuf));
skygw_log_write(LE, "Error: Failed to compile PCRE2 pattern: %s",
errbuf);
}
if (!pattern_init)
{
pcre2_code_free(re_percent);
pcre2_code_free(re_single);
pcre2_code_free(re_escape);
re_percent = NULL;
re_single = NULL;
re_escape = NULL;
}
}
spinlock_release(&re_lock);
}
/**
* Check if @c string matches @c pattern according to the MySQL wildcard rules.
* The wildcard character @c '%%' is replaced with @c '.*' and @c '_' is replaced
* with @c '.'. All Regular expression special characters are escaped before
* matching is made.
* @param pattern Wildcard pattern
* @param string String to match
* @return MXS_PCRE2_MATCH if the pattern matches, MXS_PCRE2_NOMATCH if it does
* not match and MXS_PCRE2_ERROR if an error occurred
* @see maxscale_pcre2.h
*/
mxs_pcre2_result_t modutil_mysql_wildcard_match(const char* pattern, const char* string)
{
if (!pattern_init)
{
init_pcre2_patterns();
}
mxs_pcre2_result_t rval = MXS_PCRE2_ERROR;
bool err = false;
PCRE2_SIZE matchsize = strlen(string) + 1;
PCRE2_SIZE tempsize = matchsize;
char* matchstr = (char*) malloc(matchsize);
char* tempstr = (char*) malloc(tempsize);
pcre2_match_data *mdata_percent = pcre2_match_data_create_from_pattern(re_percent, NULL);
pcre2_match_data *mdata_single = pcre2_match_data_create_from_pattern(re_single, NULL);
pcre2_match_data *mdata_escape = pcre2_match_data_create_from_pattern(re_escape, NULL);
if (matchstr && tempstr && mdata_percent && mdata_single && mdata_escape)
{
if (mxs_pcre2_substitute(re_escape, pattern, sub_escape,
&matchstr, &matchsize) == MXS_PCRE2_ERROR ||
mxs_pcre2_substitute(re_single, matchstr, sub_single,
&tempstr, &tempsize) == MXS_PCRE2_ERROR ||
mxs_pcre2_substitute(re_percent, tempstr, sub_percent,
&matchstr, &matchsize) == MXS_PCRE2_ERROR)
{
err = true;
}
if (!err)
{
int errcode;
rval = mxs_pcre2_simple_match(matchstr, string, PCRE2_CASELESS, &errcode);
if (rval == MXS_PCRE2_ERROR)
{
if(errcode != 0)
{
PCRE2_UCHAR errbuf[STRERROR_BUFLEN];
pcre2_get_error_message(errcode, errbuf, sizeof(errbuf));
skygw_log_write(LE, "Error: Failed to match pattern: %s",
errbuf);
}
err = true;
}
}
}
else
{
err = true;
}
if (err)
{
skygw_log_write(LE, "Error: Fatal error when matching wildcard patterns.");
}
pcre2_match_data_free(mdata_percent);
pcre2_match_data_free(mdata_single);
pcre2_match_data_free(mdata_escape);
free(matchstr);
free(tempstr);
return rval;
}