Merge branch '2.3' into 2.4

This commit is contained in:
Markus Mäkelä
2019-07-10 08:14:56 +03:00
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. 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 ## Source Code

View File

@ -415,5 +415,8 @@ private:
RouteInfo m_route_info; RouteInfo m_route_info;
bool m_trx_is_read_only; bool m_trx_is_read_only;
bool m_ps_continuation; 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. # MXS-2572: Add smartrouter tests.
add_test_executable(sr_basics.cpp sr_basics sr_basics LABELS REPL_BACKEND) 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 # # 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* filename_end = strchr(symbols, '(');
const char* symname_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); snprintf(symname, sizeof(symname), "%.*s", (int)(symname_end - symname_start), symname_start);
get_command_output(cmd, size, "addr2line -e %s %s", filename, symname); 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); int count = backtrace(addrs, 128);
char** symbols = backtrace_symbols(addrs, count); 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) 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>"; char cmd[PATH_MAX + 1024] = "<binutils not installed>";
extract_file_and_line(symbols[n], cmd, sizeof(cmd));
if (do_extract)
{
extract_file_and_line(symbols[n], cmd, sizeof(cmd));
}
handler(symbols[n], cmd); handler(symbols[n], cmd);
} }
free(symbols); 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) int dcb_drain_writeq(DCB* dcb)
{ {
mxb_assert(dcb->owner == RoutingWorker::get_current());
if (dcb->ssl_read_want_write) if (dcb->ssl_read_want_write)
{ {
/** The SSL library needs to write more data */ /** 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 // All COM_STMT type statements store the ID in the same place
uint32_t external_id = mysql_extract_ps_id(pBuffer); 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); auto it = m_ps_handles.find(external_id);
if (it != m_ps_handles.end()) 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) void QueryClassifier::ps_store_response(uint32_t internal_id, GWBUF* buffer)
{ {
auto external_id = qc_mysql_extract_ps_id(buffer); auto external_id = qc_mysql_extract_ps_id(buffer);
m_prev_ps_id = external_id;
m_ps_handles[external_id] = internal_id; m_ps_handles[external_id] = internal_id;
if (auto param_count = qc_extract_ps_param_count(buffer)) 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(); MXS_CONFIG* config = config_get_global_options();
/* Check if refresh rate limit has been exceeded */ /* Check if refresh rate limit has been exceeded. Also check whether we are in the middle of starting up.
if (now < m_rate_limits[self].last + config->users_refresh_time) * 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) if (!m_rate_limits[self].warned)
{ {

View File

@ -147,20 +147,15 @@ int32_t RWSplitSession::routeQuery(GWBUF* querybuf)
else else
{ {
// Already busy executing a query, put the query in a queue and route it later // 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", 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, gwbuf_length(querybuf), GWBUF_DATA(querybuf)[4], m_expected_responses,
mxs::extract_sql(querybuf, 1024).c_str()); mxs::extract_sql(querybuf, 1024).c_str());
mxb_assert(m_expected_responses > 0 || !m_query_queue.empty());
m_query_queue.emplace_back(querybuf); m_query_queue.emplace_back(querybuf);
querybuf = NULL; querybuf = NULL;
rval = 1; rval = 1;
mxb_assert(m_expected_responses != 0); mxb_assert(m_expected_responses != 0);
if (m_expected_responses == 0 && !route_stored_query())
{
rval = 0;
}
} }
if (querybuf != NULL) if (querybuf != NULL)

View File

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