Merge branch '2.3' into 2.4

This commit is contained in:
Markus Mäkelä 2019-07-10 08:14:56 +03:00
commit f9b1a0a0c4
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
10 changed files with 89 additions and 17 deletions

View File

@ -31,7 +31,7 @@ For more information, please refer to the [Limitations](../About/Limitations.md)
RPM and Debian packages are provided for supported the Linux distributions.
Packages can be downloaded [here](https://mariadb.com/downloads/mariadb-tx/maxscale).
Packages can be downloaded [here](https://mariadb.com/downloads/#mariadb_platform-mariadb_maxscale).
## Source Code

View File

@ -415,5 +415,8 @@ private:
RouteInfo m_route_info;
bool m_trx_is_read_only;
bool m_ps_continuation;
uint32_t m_prev_ps_id = 0; /**< For direct PS execution, storest latest prepared PS ID.
* https://mariadb.com/kb/en/library/com_stmt_execute/#statement-id **/
};
}

View File

@ -994,6 +994,9 @@ add_test_executable(mxs2521_double_exec.cpp mxs2521_double_exec mxs2521_double_e
# MXS-2572: Add smartrouter tests.
add_test_executable(sr_basics.cpp sr_basics sr_basics LABELS REPL_BACKEND)
# MXS-2490: Direct execution doesn't work with MaxScale
add_test_executable(mxs2490_ps_execute_direct.cpp mxs2490_ps_execute_direct replication LABELS REPL_BACKEND readwritesplit)
############################################
# BEGIN: binlogrouter and avrorouter tests #
############################################

View File

@ -0,0 +1,26 @@
/**
* MXS-2490: Unknown prepared statement handler (0) given to mysqld_stmt_execute
*
* See:
*
* https://mariadb.com/kb/en/library/mariadb_stmt_execute_direct/
* https://mariadb.com/kb/en/library/com_stmt_execute/#statement-id
*/
#include "testconnections.h"
int main(int argc, char** argv)
{
TestConnections test(argc, argv);
test.set_timeout(30);
test.maxscales->connect();
MYSQL_STMT* stmt = mysql_stmt_init(test.maxscales->conn_rwsplit[0]);
std::string query = "SELECT user FROM mysql.user";
test.expect(mariadb_stmt_execute_direct(stmt, query.c_str(), query.length()) == 0,
"execute_direct should work: %s", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
return test.global_result;
}

View File

@ -56,7 +56,7 @@ static void get_command_output(char* output, size_t size, const char* format, ..
}
}
static void extract_file_and_line(const char* symbols, char* cmd, size_t size)
static void extract_file_and_line(char* symbols, char* cmd, size_t size)
{
const char* filename_end = strchr(symbols, '(');
const char* symname_end = strchr(symbols, ')');
@ -116,6 +116,30 @@ static void extract_file_and_line(const char* symbols, char* cmd, size_t size)
snprintf(symname, sizeof(symname), "%.*s", (int)(symname_end - symname_start), symname_start);
get_command_output(cmd, size, "addr2line -e %s %s", filename, symname);
}
const char prefix[] = "MaxScale/";
// Remove common source prefix
if (char* str = strstr(cmd, prefix))
{
str += sizeof(prefix) - 1;
memmove(cmd, str, strlen(cmd) - (str - cmd) + 1);
}
// Strip the directory name from the symbols (could this be useful?)
if (char* str = strrchr(symbols, '/'))
{
++str;
memmove(symbols, str, strlen(symbols) - (str - symbols) + 1);
}
// Remove the address where the symbol is in memory (i.e. the [0xdeadbeef] that follows the
// (main+0xa1) part), we're only interested where it is in the library.
if (char* str = strchr(symbols, '['))
{
str--;
*str = '\0';
}
}
}
}
@ -129,12 +153,21 @@ void dump_stacktrace(std::function<void(const char*, const char*)> handler)
int count = backtrace(addrs, 128);
char** symbols = backtrace_symbols(addrs, count);
int rc = system("/bin/test -f /bin/nm -a -f /bin/addr2line");
bool do_extract = WIFEXITED(rc) && WEXITSTATUS(rc) == 0;
if (symbols)
{
for (int n = 0; n < count; n++)
// Skip first five frames, they are inside the stacktrace printing function and signal handlers
for (int n = 4; n < count; n++)
{
char cmd[PATH_MAX + 1024] = "<not found>";
extract_file_and_line(symbols[n], cmd, sizeof(cmd));
char cmd[PATH_MAX + 1024] = "<binutils not installed>";
if (do_extract)
{
extract_file_and_line(symbols[n], cmd, sizeof(cmd));
}
handler(symbols[n], cmd);
}
free(symbols);

View File

@ -958,6 +958,8 @@ static void dcb_log_write_failure(DCB* dcb, GWBUF* queue, int eno)
*/
int dcb_drain_writeq(DCB* dcb)
{
mxb_assert(dcb->owner == RoutingWorker::get_current());
if (dcb->ssl_read_want_write)
{
/** The SSL library needs to write more data */

View File

@ -644,6 +644,13 @@ uint32_t QueryClassifier::ps_id_internal_get(GWBUF* pBuffer)
// All COM_STMT type statements store the ID in the same place
uint32_t external_id = mysql_extract_ps_id(pBuffer);
if (external_id == 0xffffffff)
{
// "Direct execution" that refers to the latest prepared statement
external_id = m_prev_ps_id;
}
auto it = m_ps_handles.find(external_id);
if (it != m_ps_handles.end())
@ -663,6 +670,7 @@ uint32_t QueryClassifier::ps_id_internal_get(GWBUF* pBuffer)
void QueryClassifier::ps_store_response(uint32_t internal_id, GWBUF* buffer)
{
auto external_id = qc_mysql_extract_ps_id(buffer);
m_prev_ps_id = external_id;
m_ps_handles[external_id] = internal_id;
if (auto param_count = qc_extract_ps_param_count(buffer))

View File

@ -1091,8 +1091,10 @@ bool Service::refresh_users()
MXS_CONFIG* config = config_get_global_options();
/* Check if refresh rate limit has been exceeded */
if (now < m_rate_limits[self].last + config->users_refresh_time)
/* Check if refresh rate limit has been exceeded. Also check whether we are in the middle of starting up.
* If so, allow repeated reloading of users. */
if (now > maxscale_started() + config->users_refresh_time
&& now < m_rate_limits[self].last + config->users_refresh_time)
{
if (!m_rate_limits[self].warned)
{

View File

@ -147,20 +147,15 @@ int32_t RWSplitSession::routeQuery(GWBUF* querybuf)
else
{
// Already busy executing a query, put the query in a queue and route it later
mxb_assert(m_expected_responses > 0 || !m_query_queue.empty());
MXS_INFO("Storing query (len: %d cmd: %0x), expecting %d replies to current command: %s",
gwbuf_length(querybuf), GWBUF_DATA(querybuf)[4], m_expected_responses,
mxs::extract_sql(querybuf, 1024).c_str());
mxb_assert(m_expected_responses > 0 || !m_query_queue.empty());
m_query_queue.emplace_back(querybuf);
querybuf = NULL;
rval = 1;
mxb_assert(m_expected_responses != 0);
if (m_expected_responses == 0 && !route_stored_query())
{
rval = 0;
}
}
if (querybuf != NULL)

View File

@ -1,7 +1,7 @@
version: '2'
services:
server1:
image: mariadb:10.2
image: mariadb:10.3
network_mode: "host"
container_name: server1
environment:
@ -11,7 +11,7 @@ services:
command: mysqld --log-bin=binlog --binlog-format=ROW --server-id=3000 --port=3000 --log-slave-updates
server2:
image: mariadb:10.2
image: mariadb:10.3
container_name: server2
network_mode: "host"
environment:
@ -21,7 +21,7 @@ services:
command: mysqld --log-bin=binlog --binlog-format=ROW --server-id=3001 --port=3001 --log-slave-updates
server3:
image: mariadb:10.2
image: mariadb:10.3
container_name: server3
network_mode: "host"
environment:
@ -31,7 +31,7 @@ services:
command: mysqld --log-bin=binlog --binlog-format=ROW --server-id=3002 --port=3002 --log-slave-updates
server4:
image: mariadb:10.2
image: mariadb:10.3
container_name: server4
network_mode: "host"
environment: