diff --git a/server/core/CMakeLists.txt b/server/core/CMakeLists.txt index e44d7dd57..79761cdc8 100644 --- a/server/core/CMakeLists.txt +++ b/server/core/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c filter.cc externcmd.c paths.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.cc poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c ssl.c mysql_utils.c mysql_binlog.c modulecmd.c trxboundarymatcher.cc) +add_library(maxscale-common SHARED adminusers.c alloc.c authenticator.c atomic.c buffer.c config.c config_runtime.c dcb.c filter.c filter.cc externcmd.c paths.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c misc.c mlist.c modutil.c monitor.c queuemanager.c query_classifier.cc poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c skygw_utils.cc statistics.c listener.c ssl.c mysql_utils.c mysql_binlog.c modulecmd.c) if(WITH_JEMALLOC) target_link_libraries(maxscale-common ${JEMALLOC_LIBRARIES}) diff --git a/server/core/maxscale/query_classifier.h b/server/core/maxscale/query_classifier.h index 5adff4d31..3de89dff9 100644 --- a/server/core/maxscale/query_classifier.h +++ b/server/core/maxscale/query_classifier.h @@ -20,7 +20,6 @@ MXS_BEGIN_DECLS typedef enum qc_trx_parse_using { QC_TRX_PARSE_USING_QC, /**< Use the query classifier. */ - QC_TRX_PARSE_USING_REGEX, /**< Use regexp mathing. */ QC_TRX_PARSE_USING_PARSER, /**< Use custom parser. */ } qc_trx_parse_using_t; diff --git a/server/core/maxscale/trxboundarymatcher.hh b/server/core/maxscale/trxboundarymatcher.hh deleted file mode 100644 index 83864d15b..000000000 --- a/server/core/maxscale/trxboundarymatcher.hh +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once -/* - * Copyright (c) 2016 MariaDB Corporation Ab - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file and at www.mariadb.com/bsl11. - * - * Change Date: 2019-07-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2 or later of the General - * Public License. - */ - -#include -#include -#include - -namespace maxscale -{ - -/** - * @class TrxBoundaryMatcher - * - * @ TrxBoundaryMatcher is a class capable of, using regexes, to recognize - * and return the correct type mask of statements affecting the transaction - * state and* autocommit mode. - */ -class TrxBoundaryMatcher -{ -public: - /** - * To be called once at process startup. After a successful call, - * @type_mask_of() can be used in the calling thread. - * - * @return True, if the initialization succeeded, false otherwise. - */ - static bool process_init(); - - /** - * To be called once at process shut down. - */ - static void process_end(); - - /** - * To be called once in each thread, other that the one where @process_init() - * was called. After a successful call, @type_mask_of() can be used in the - * calling thread. - * - * @return True, if the initialization succeeded, false otherwise. - */ - static bool thread_init(); - - /** - * To be called once at thread shut down. - */ - static void thread_end(); - - /** - * Return the type mask of a statement, provided the statement affects - * transaction state or autocommit mode. - * - * @param pSql Sql statement. - * @param len Length of @c pSql. - * - * @return The corresponding type mask or 0, if the statement does not - * affect transaction state or autocommit mode. - */ - static uint32_t type_mask_of(const char* pSql, size_t len); - - /** - * Return the type mask of a statement, provided the statement affects - * transaction state or autocommit mode. - * - * @param pBuf A COM_QUERY - * - * @return The corresponding type mask or 0, if the statement does not - * affect transaction state or autocommit mode. - */ - static uint32_t type_mask_of(GWBUF* pBuf); - -private: - TrxBoundaryMatcher(const TrxBoundaryMatcher&); - TrxBoundaryMatcher& operator = (const TrxBoundaryMatcher&); -}; - -} diff --git a/server/core/query_classifier.cc b/server/core/query_classifier.cc index a5dfff84f..43aaa44da 100644 --- a/server/core/query_classifier.cc +++ b/server/core/query_classifier.cc @@ -18,7 +18,6 @@ #include #include #include -#include "maxscale/trxboundarymatcher.hh" #include "maxscale/trxboundaryparser.hh" #include "../core/maxscale/modules.h" @@ -87,11 +86,6 @@ bool qc_process_init(uint32_t kind) qc_trx_parse_using = QC_TRX_PARSE_USING_QC; MXS_NOTICE("Transaction detection using QC."); } - else if (strcmp(parse_using, "QC_TRX_PARSE_USING_REGEX") == 0) - { - qc_trx_parse_using = QC_TRX_PARSE_USING_REGEX; - MXS_NOTICE("Transaction detection using REGEX."); - } else if (strcmp(parse_using, "QC_TRX_PARSE_USING_PARSER") == 0) { qc_trx_parse_using = QC_TRX_PARSE_USING_PARSER; @@ -104,32 +98,19 @@ bool qc_process_init(uint32_t kind) } } - bool rc = maxscale::TrxBoundaryMatcher::process_init(); + bool rc = qc_thread_init(QC_INIT_SELF); if (rc) { - rc = qc_thread_init(QC_INIT_SELF); - - if (rc) + if (kind & QC_INIT_PLUGIN) { - if (kind & QC_INIT_PLUGIN) - { - rc = classifier->qc_process_init() == 0; + rc = classifier->qc_process_init() == 0; - if (!rc) - { - qc_thread_end(QC_INIT_SELF); - } + if (!rc) + { + qc_thread_end(QC_INIT_SELF); } } - else - { - maxscale::TrxBoundaryMatcher::process_end(); - } - } - else - { - MXS_ERROR("Could not compile transaction regexes."); } return rc; @@ -146,8 +127,6 @@ void qc_process_end(uint32_t kind) } qc_thread_end(QC_INIT_SELF); - - maxscale::TrxBoundaryMatcher::process_end(); } QUERY_CLASSIFIER* qc_load(const char* plugin_name) @@ -178,20 +157,11 @@ bool qc_thread_init(uint32_t kind) QC_TRACE(); ss_dassert(classifier); - bool rc = maxscale::TrxBoundaryMatcher::thread_init(); + bool rc = true; - if (rc) + if (kind & QC_INIT_PLUGIN) { - if (kind & QC_INIT_PLUGIN) - { - rc = classifier->qc_thread_init() == 0; - - if (!rc) - { - maxscale::TrxBoundaryMatcher::thread_end(); - rc = false; - } - } + rc = classifier->qc_thread_init() == 0; } return rc; @@ -206,8 +176,6 @@ void qc_thread_end(uint32_t kind) { classifier->qc_thread_end(); } - - maxscale::TrxBoundaryMatcher::thread_end(); } qc_parse_result_t qc_parse(GWBUF* query) @@ -901,11 +869,6 @@ static uint32_t qc_get_trx_type_mask_using_qc(GWBUF* stmt) return type_mask; } -static uint32_t qc_get_trx_type_mask_using_regex(GWBUF* stmt) -{ - return maxscale::TrxBoundaryMatcher::type_mask_of(stmt); -} - static uint32_t qc_get_trx_type_mask_using_parser(GWBUF* stmt) { maxscale::TrxBoundaryParser parser; @@ -923,10 +886,6 @@ uint32_t qc_get_trx_type_mask_using(GWBUF* stmt, qc_trx_parse_using_t use) type_mask = qc_get_trx_type_mask_using_qc(stmt); break; - case QC_TRX_PARSE_USING_REGEX: - type_mask = qc_get_trx_type_mask_using_regex(stmt); - break; - case QC_TRX_PARSE_USING_PARSER: type_mask = qc_get_trx_type_mask_using_parser(stmt); break; diff --git a/server/core/test/testtrxtracking.cc b/server/core/test/testtrxtracking.cc index 65f072057..7ee715f15 100644 --- a/server/core/test/testtrxtracking.cc +++ b/server/core/test/testtrxtracking.cc @@ -27,7 +27,6 @@ enum test_target_t { TEST_PARSER = 0x1, TEST_QC = 0x2, - TEST_REGEX = 0x4, TEST_ALL = (TEST_PARSER | TEST_QC) }; @@ -54,11 +53,6 @@ uint32_t get_qc_trx_type_mask(GWBUF* pBuf) return qc_get_trx_type_mask_using(pBuf, QC_TRX_PARSE_USING_QC); } -uint32_t get_regex_trx_type_mask(GWBUF* pBuf) -{ - return qc_get_trx_type_mask_using(pBuf, QC_TRX_PARSE_USING_REGEX); -} - uint32_t get_parser_trx_type_mask(GWBUF* pBuf) { return qc_get_trx_type_mask_using(pBuf, QC_TRX_PARSE_USING_PARSER); @@ -376,7 +370,7 @@ int main(int argc, char* argv[]) bool dont_bail_out = false; int c; - while ((c = getopt(argc, argv, "dpqr")) != -1) + while ((c = getopt(argc, argv, "dpq")) != -1) { switch (c) { @@ -390,11 +384,6 @@ int main(int argc, char* argv[]) test_target = TEST_QC; break; - case 'r': - test_all = false; - test_target = TEST_REGEX; - break; - case 'd': dont_bail_out = true; break; @@ -436,17 +425,6 @@ int main(int argc, char* argv[]) cout << endl; } - if (test_target & TEST_REGEX) - { - cout << "Regex" << endl; - cout << "=====" << endl; - if (!test(get_regex_trx_type_mask, dont_bail_out)) - { - rc = EXIT_FAILURE; - } - cout << endl; - } - if (test_target & TEST_PARSER) { cout << "Parser" << endl; diff --git a/server/core/trxboundarymatcher.cc b/server/core/trxboundarymatcher.cc deleted file mode 100644 index c2e9f054e..000000000 --- a/server/core/trxboundarymatcher.cc +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (c) 2016 MariaDB Corporation Ab - * - * Use of this software is governed by the Business Source License included - * in the LICENSE.TXT file and at www.mariadb.com/bsl11. - * - * Change Date: 2019-07-01 - * - * On the date above, in accordance with the Business Source License, use - * of this software will be governed by version 2 or later of the General - * Public License. - */ - -#include "maxscale/trxboundarymatcher.hh" -#include -#include - -namespace -{ - -struct REGEX_DATA -{ - const char* zMatch; - uint32_t type_mask; - pcre2_code* pCode; -}; - -REGEX_DATA this_unit_regexes[] = -{ - { - "^\\s*BEGIN(\\s+WORK)?\\s*;?\\s*$", - QUERY_TYPE_BEGIN_TRX - }, - { - "^\\s*COMMIT(\\s+WORK)?\\s*;?\\s*$", - QUERY_TYPE_COMMIT, - }, - { - "^\\s*ROLLBACK(\\s+WORK)?\\s*;?\\s*$", - QUERY_TYPE_ROLLBACK - }, - { - "^\\s*START\\s+TRANSACTION\\s+(" - "READ\\s+ONLY|" - "READ\\s+ONLY\\s*,\\s*WITH\\s+CONSISTENT\\s+SNAPSHOT|" - "WITH\\s+CONSISTENT\\s+SNAPSHOT\\s*,\\s*READ\\s+ONLY" - ")\\s*;?\\s*$", - QUERY_TYPE_BEGIN_TRX | QUERY_TYPE_READ - }, - { - "^\\s*START\\s+TRANSACTION\\s+(" - "READ\\s+WRITE|" - "READ\\s+WRITE\\s*,\\s*WITH\\s+CONSISTENT\\s+SNAPSHOT|" - "WITH\\s+CONSISTENT\\s+SNAPSHOT\\s*,\\s*READ\\s+WRITE" - ")\\s*;?\\s*$", - QUERY_TYPE_BEGIN_TRX | QUERY_TYPE_WRITE - }, - { - "^\\s*START\\s+TRANSACTION(\\s+WITH\\s+CONSISTENT\\s+SNAPSHOT)?\\s*;?\\s*$", - QUERY_TYPE_BEGIN_TRX - }, - { - "^\\s*SET\\s+AUTOCOMMIT\\s*\\=\\s*(1|true)\\s*;?\\s*$", - QUERY_TYPE_COMMIT|QUERY_TYPE_ENABLE_AUTOCOMMIT - }, - { - "^\\s*SET\\s+AUTOCOMMIT\\s*\\=\\s*(0|false)\\s*;?\\s*$", - QUERY_TYPE_BEGIN_TRX|QUERY_TYPE_DISABLE_AUTOCOMMIT - } -}; - -const size_t N_REGEXES = sizeof(this_unit_regexes)/sizeof(this_unit_regexes[0]); - -struct this_unit -{ - const char* zMatch; - pcre2_code* pCode; - REGEX_DATA* pRegexes; -} this_unit = -{ - .zMatch = "^\\s*(BEGIN|COMMIT|ROLLBACK|START|SET)", - NULL, - .pRegexes = this_unit_regexes -}; - -thread_local struct this_thread -{ - pcre2_match_data* pData; - pcre2_match_data* match_datas[N_REGEXES]; -} this_thread; - - -bool compile_regexes(); -void free_regexes(); - -bool create_thread_data(); -void free_thread_data(); - -void log_pcre2_error(const char* zMatch, int errcode, int erroffset) -{ - PCRE2_UCHAR errbuf[512]; - pcre2_get_error_message(errcode, errbuf, sizeof(errbuf)); - - MXS_ERROR("Regex compilation failed at %d for regex '%s', i.e. '%s': %s.", - erroffset, zMatch, zMatch + erroffset, errbuf); -} - -bool compile_regexes() -{ - bool success = true; - - int errcode; - PCRE2_SIZE erroffset; - - this_unit.pCode = pcre2_compile((PCRE2_SPTR)this_unit.zMatch, - PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, - &errcode, &erroffset, NULL); - - if (this_unit.pCode) - { - REGEX_DATA* i = this_unit.pRegexes; - REGEX_DATA* end = i + N_REGEXES; - - while (success && (i < end)) - { - i->pCode = pcre2_compile((PCRE2_SPTR)i->zMatch, PCRE2_ZERO_TERMINATED, PCRE2_CASELESS, - &errcode, &erroffset, NULL); - - if (!i->pCode) - { - success = false; - log_pcre2_error(i->zMatch, errcode, erroffset); - } - - ++i; - } - - if (!success) - { - free_regexes(); - } - } - else - { - success = false; - log_pcre2_error(this_unit.zMatch, errcode, erroffset); - } - - return success; -} - -void free_regexes() -{ - REGEX_DATA* begin = this_unit.pRegexes; - REGEX_DATA* i = begin + N_REGEXES; - - while (i > begin) - { - --i; - - if (i->pCode) - { - pcre2_code_free(i->pCode); - i->pCode = NULL; - } - } - - if (this_unit.pCode) - { - pcre2_code_free(this_unit.pCode); - this_unit.pCode = NULL; - } -} - -bool create_thread_data() -{ - bool success = true; - - this_thread.pData = pcre2_match_data_create_from_pattern(this_unit.pCode, NULL); - - if (this_thread.pData) - { - REGEX_DATA* i = this_unit.pRegexes; - REGEX_DATA* end = i + N_REGEXES; - - pcre2_match_data** ppData = this_thread.match_datas; - - while (success && (i < end)) - { - *ppData = pcre2_match_data_create_from_pattern(i->pCode, NULL); - - if (!*ppData) - { - success = false; - MXS_ERROR("PCRE2 match data creation failed."); - } - - ++i; - ++ppData; - } - - if (!success) - { - free_thread_data(); - } - } - else - { - success = false; - MXS_ERROR("PCRE2 match data creation failed."); - } - - return success; -} - -void free_thread_data() -{ - pcre2_match_data** begin = this_thread.match_datas; - pcre2_match_data** i = begin + N_REGEXES; - - while (i > begin) - { - --i; - - if (*i) - { - pcre2_match_data_free(*i); - *i = NULL; - } - } - - pcre2_match_data_free(this_thread.pData); - this_thread.pData = NULL; -} - -} - -namespace maxscale -{ - -//static -bool TrxBoundaryMatcher::process_init() -{ - bool rc = compile_regexes(); - - if (rc) - { - rc = thread_init(); - - if (!rc) - { - free_regexes(); - } - } - - return rc; -} - -//static -void TrxBoundaryMatcher::process_end() -{ - thread_end(); - free_regexes(); -} - -//static -bool TrxBoundaryMatcher::thread_init() -{ - return create_thread_data(); -} - -//static -void TrxBoundaryMatcher::thread_end() -{ - free_thread_data(); -} - -//static -uint32_t TrxBoundaryMatcher::type_mask_of(const char* pSql, size_t len) -{ - uint32_t type_mask = 0; - - if (pcre2_match(this_unit.pCode, (PCRE2_SPTR)pSql, len, 0, 0, this_thread.pData, NULL) >= 0) - { - REGEX_DATA* i = this_unit.pRegexes; - REGEX_DATA* end = i + N_REGEXES; - pcre2_match_data** ppData = this_thread.match_datas; - - while ((type_mask == 0) && (i < end)) - { - if (pcre2_match(i->pCode, (PCRE2_SPTR)pSql, len, 0, 0, *ppData, NULL) >= 0) - { - type_mask = i->type_mask; - } - - ++i; - ++ppData; - } - } - - return type_mask; -} - -//static -uint32_t TrxBoundaryMatcher::type_mask_of(GWBUF* pBuf) -{ - uint32_t type_mask = 0; - - char* pSql; - int len; - - // This will exclude prepared statement but we are fine with that. - if (modutil_extract_SQL(pBuf, &pSql, &len)) - { - type_mask = type_mask_of(pSql, len); - } - - return type_mask; -} - -}