diff --git a/Documentation/Changelog.md b/Documentation/Changelog.md index bcb618699..99138ed62 100644 --- a/Documentation/Changelog.md +++ b/Documentation/Changelog.md @@ -63,6 +63,7 @@ For more details, please refer to: the master. There is also limited capability for rejoining nodes. For more details, please refer to: +* [MariaDB MaxScale 2.2.18 Release Notes](Release-Notes/MaxScale-2.2.18-Release-Notes.md) * [MariaDB MaxScale 2.2.17 Release Notes](Release-Notes/MaxScale-2.2.17-Release-Notes.md) * [MariaDB MaxScale 2.2.16 Release Notes](Release-Notes/MaxScale-2.2.16-Release-Notes.md) * [MariaDB MaxScale 2.2.15 Release Notes](Release-Notes/MaxScale-2.2.15-Release-Notes.md) diff --git a/Documentation/Release-Notes/MaxScale-2.2.18-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.2.18-Release-Notes.md new file mode 100644 index 000000000..d20cfab6f --- /dev/null +++ b/Documentation/Release-Notes/MaxScale-2.2.18-Release-Notes.md @@ -0,0 +1,37 @@ +# MariaDB MaxScale 2.2.18 Release Notes -- 2018-12-13 + +Release 2.2.18 is a GA release. + +This document describes the changes in release 2.2.18, when compared to the +previous release in the same series. + +For any problems you encounter, please consider submitting a bug +report on [our Jira](https://jira.mariadb.org/projects/MXS). + +## Bug fixes + +* [MXS-2221](https://jira.mariadb.org/browse/MXS-2221) Fatal signal handling does not always create a core +* [MXS-2216](https://jira.mariadb.org/browse/MXS-2216) Read past stack buffer +* [MXS-2213](https://jira.mariadb.org/browse/MXS-2213) Growing memory consumption with 2.2.17 +* [MXS-2207](https://jira.mariadb.org/browse/MXS-2207) qc_mysqlembedded does not classify SET STATEMENT ... FOR UPDATE correctly. +* [MXS-2183](https://jira.mariadb.org/browse/MXS-2183) Excessive memory use, but not growing endlessly + +## Known Issues and Limitations + +There are some limitations and known issues within this version of MaxScale. +For more information, please refer to the [Limitations](../About/Limitations.md) document. + +## Packaging + +RPM and Debian packages are provided for supported the Linux distributions. + +Packages can be downloaded [here](https://mariadb.com/downloads/mariadb-tx/maxscale). + +## Source Code + +The source code of MaxScale is tagged at GitHub with a tag, which is identical +with the version of MaxScale. For instance, the tag of version X.Y.Z of MaxScale +is `maxscale-X.Y.Z`. Further, the default branch is always the latest GA version +of MaxScale. + +The source code is available [here](https://github.com/mariadb-corporation/MaxScale). diff --git a/VERSION22.cmake b/VERSION22.cmake index f9a456930..6ba5b4cc3 100644 --- a/VERSION22.cmake +++ b/VERSION22.cmake @@ -5,7 +5,7 @@ set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version") set(MAXSCALE_VERSION_MINOR "2" CACHE STRING "Minor version") -set(MAXSCALE_VERSION_PATCH "18" CACHE STRING "Patch version") +set(MAXSCALE_VERSION_PATCH "19" CACHE STRING "Patch version") # This should only be incremented if a package is rebuilt set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number") diff --git a/server/core/gateway.cc b/server/core/gateway.cc index 28b052931..07bd72ed4 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -402,12 +402,12 @@ static int signal_set(int sig, void (* handler)(int)); static void sigfatal_handler(int i) { - if (fatal_handling) - { - fprintf(stderr, "Fatal signal %d while backtracing\n", i); - _exit(1); - } - fatal_handling = 1; + // The same signal being handled *now* can occur in another thread (and is often likely). + // By setting the default handler here we will always get a core, but not necessarily + // the backtrace into the log file. This should be overhauled to proper signal handling + // (MXS-599). + signal_set(i, SIG_DFL); + MXS_CONFIG* cnf = config_get_global_options(); fprintf(stderr, "Fatal: MaxScale " MAXSCALE_VERSION " received fatal signal %d. " @@ -435,7 +435,6 @@ static void sigfatal_handler(int i) /* re-raise signal to enforce core dump */ fprintf(stderr, "\n\nWriting core dump\n"); - signal_set(i, SIG_DFL); raise(i); } diff --git a/server/core/queryclassifier.cc b/server/core/queryclassifier.cc index d45b9aff8..802a2fe5f 100644 --- a/server/core/queryclassifier.cc +++ b/server/core/queryclassifier.cc @@ -61,6 +61,20 @@ bool qc_mysql_is_ps_command(uint8_t cmd) || cmd == MXS_COM_STMT_RESET; } +// Copied from mysql_common.cc +uint32_t qc_mysql_extract_ps_id(GWBUF* buffer) +{ + uint32_t rval = 0; + uint8_t id[MYSQL_PS_ID_SIZE]; + + if (gwbuf_copy_data(buffer, MYSQL_PS_ID_OFFSET, sizeof(id), id) == sizeof(id)) + { + rval = gw_mysql_get_byte4(id); + } + + return rval; +} + bool have_semicolon(const char* ptr, int len) { for (int i = 0; i < len; i++) @@ -376,7 +390,8 @@ uint32_t QueryClassifier::ps_get_type(std::string id) const void QueryClassifier::ps_erase(GWBUF* buffer) { - return m_sPs_manager->erase(buffer); + m_ps_handles.erase(qc_mysql_extract_ps_id(buffer)); + m_sPs_manager->erase(buffer); } bool QueryClassifier::query_type_is_read_only(uint32_t qtype) const diff --git a/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc b/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc index a80ef7943..3e4f5da2d 100644 --- a/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc +++ b/server/modules/protocol/MySQL/mariadbbackend/mysql_backend.cc @@ -694,24 +694,25 @@ static inline bool complete_ps_response(GWBUF* buffer) if (mxs_mysql_extract_ps_response(buffer, &resp)) { - int expected_eof = 0; + int expected_packets = 1; if (resp.columns > 0) { - expected_eof++; + // Column definition packets plus one for the EOF + expected_packets += resp.columns + 1; } if (resp.parameters > 0) { - expected_eof++; + // Parameter definition packets plus one for the EOF + expected_packets += resp.parameters + 1; } - bool more; - int n_eof = modutil_count_signal_packets(buffer, 0, &more, NULL); + int n_packets = modutil_count_packets(buffer); - MXS_DEBUG("Expecting %u EOF, have %u", n_eof, expected_eof); + MXS_DEBUG("Expecting %u packets, have %u", n_packets, expected_packets); - rval = n_eof == expected_eof; + rval = n_packets == expected_packets; } return rval; diff --git a/server/modules/protocol/MySQL/rwbackend.cc b/server/modules/protocol/MySQL/rwbackend.cc index 416716d60..e2161d10d 100644 --- a/server/modules/protocol/MySQL/rwbackend.cc +++ b/server/modules/protocol/MySQL/rwbackend.cc @@ -104,6 +104,10 @@ bool RWBackend::write(GWBUF* buffer, response_type type) // Any non-zero flag value means that we have an open cursor m_opening_cursor = flags != 0; } + else if (cmd == MXS_COM_STMT_CLOSE) + { + m_ps_handles.erase(it); + } else if (cmd == MXS_COM_STMT_FETCH) { // Number of rows to fetch is a 4 byte integer after the ID diff --git a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc index 259a13f56..971029fee 100644 --- a/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc +++ b/server/modules/routing/readwritesplit/rwsplit_route_stmt.cc @@ -412,6 +412,13 @@ bool RWSplitSession::route_session_write(GWBUF* querybuf, uint8_t command, uint3 { if (mxs_mysql_is_ps_command(m_qc.current_route_info().command())) { + if (command == MXS_COM_STMT_CLOSE) + { + // Remove the command from the PS mapping + m_qc.ps_erase(querybuf); + m_exec_map.erase(m_qc.current_route_info().stmt_id()); + } + /** * Replace the ID with our internal one, the backends will replace it with their own ID * when the packet is being written. We use the internal ID when we store the command @@ -519,6 +526,11 @@ bool RWSplitSession::route_session_write(GWBUF* querybuf, uint8_t command, uint3 { m_sescmd_responses.erase(m_sescmd_responses.begin(), it); } + else + { + // All responses processed + m_sescmd_responses.clear(); + } } else { diff --git a/server/modules/routing/readwritesplit/rwsplitsession.hh b/server/modules/routing/readwritesplit/rwsplitsession.hh index 00418122a..bf8f9a0ec 100644 --- a/server/modules/routing/readwritesplit/rwsplitsession.hh +++ b/server/modules/routing/readwritesplit/rwsplitsession.hh @@ -149,7 +149,6 @@ public: uint64_t m_sent_sescmd; /**< ID of the last sent session command*/ uint64_t m_recv_sescmd; /**< ID of the most recently completed session * command */ - ClientHandleMap m_ps_handles; /**< Client PS handle to internal ID mapping */ ExecMap m_exec_map; /**< Map of COM_STMT_EXECUTE statement IDs to * Backends */ std::string m_gtid_pos; /**< Gtid position for causal read */