Merge branch '2.3' into 2.4

This commit is contained in:
Markus Mäkelä 2019-07-02 08:38:15 +03:00
commit 3e85500491
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
16 changed files with 75 additions and 29 deletions

View File

@ -51,8 +51,7 @@ export sshopt="$scpopt $sshuser@$IP"
old_version=`ssh $sshopt "maxscale --version" `
${mdbci_dir}/mdbci setup_repo --product maxscale_ci --product-version ${target} $name/maxscale
${mdbci_dir}/mdbci install_product --product maxscale_ci $name/maxscale
${mdbci_dir}/mdbci install_product --product maxscale_ci --product-version ${target} $name/maxscale
res=$?

View File

@ -140,14 +140,15 @@ typedef enum
*/
typedef struct mysql_session
{
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]; /*< SHA1(password) */
char user[MYSQL_USER_MAXLEN + 1]; /*< username */
char db[MYSQL_DATABASE_MAXLEN + 1]; /*< database */
int auth_token_len; /*< token length */
uint8_t* auth_token; /*< token */
bool correct_authenticator; /*< is session using mysql_native_password? */
uint8_t next_sequence; /*< Next packet sequence */
bool auth_switch_sent; /*< Expecting a response to AuthSwitchRequest? */
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]; /*< SHA1(password) */
char user[MYSQL_USER_MAXLEN + 1]; /*< username */
char db[MYSQL_DATABASE_MAXLEN + 1]; /*< database */
int auth_token_len; /*< token length */
uint8_t* auth_token; /*< token */
bool correct_authenticator; /*< is session using mysql_native_password? */
uint8_t next_sequence; /*< Next packet sequence */
bool auth_switch_sent; /*< Expecting a response to AuthSwitchRequest? */
bool changing_user; /*< True if a COM_CHANGE_USER is in progress */
} MYSQL_session;
/** Protocol packing macros. */

View File

@ -233,6 +233,16 @@ public:
return m_reply_state == REPLY_STATE_DONE;
}
/**
* Check if a partial response has been received from the backend
*
* @return True if some parts of the reply have been received
*/
bool reply_has_started() const
{
return m_reply_state != REPLY_STATE_START && m_reply_state != REPLY_STATE_DONE;
}
void process_packets(GWBUF* buffer);
// Controlled by the session

View File

@ -56,7 +56,7 @@ port = 4009
[throttle]
type = filter
module = throttlefilter
max_qps = 1000
max_qps = 500
throttling_duration = 10000
sampling_duration = 250
continuous_duration = 2000

View File

@ -15,7 +15,7 @@ DEFINE_EXCEPTION(Whoopsy);
// TODO these should be read from maxscale.cnf. Maybe the test-lib should replace
// any "###ENV_VAR###", with environment variables so that code and conf can share.
constexpr int max_qps = 1000;
constexpr int max_qps = 500;
constexpr float throttling_duration = 10000 / 1000.0;
constexpr float sampling_duration = 250 / 1000.0;
constexpr float continuous_duration = 2000 / 1000.0;
@ -132,7 +132,7 @@ void gauge_raw_speed(TestConnections& test)
std::ostringstream os;
os << "The raw speed is too slow, " << rs.qps
<< "qps, compared to max_qps = " << max_qps << "qps for accurate testing.";
test.add_result(1, "%s", os.str().c_str());
exit(0);
}
}

View File

@ -56,7 +56,8 @@ void run_test(TestConnections& test, TestCase test_case)
mysql_stmt_close(stmt);
test.expect(mysql_query(test.maxscales->conn_rwsplit[0], "SELECT 1") == 0, "Normal queries should work");
test.expect(mysql_query(test.maxscales->conn_rwsplit[0], "SELECT 1") == 0,
"Normal queries should work: %s", mysql_error(test.maxscales->conn_rwsplit[0]));
test.maxscales->disconnect();
}
@ -79,6 +80,7 @@ int main(int argc, char* argv[])
test.try_query(test.maxscales->conn_rwsplit[0], "COMMIT");
test.maxscales->disconnect();
test.repl->sync_slaves();
vector<TestCase> tests =
{

View File

@ -1,6 +1,6 @@
#!/bin/bash
sudo service maxscale stop
sudo systemctl stop maxscale || sudo service maxscale stop
hm=`pwd`
$hm/start_killer.sh &

View File

@ -2348,12 +2348,6 @@ int TestConnections::reinstall_maxscales()
maxscales->ssh_node(i, "yum remove maxscale -y", true);
maxscales->ssh_node(i, "yum clean all", true);
sprintf(sys, "mdbci setup_repo --product maxscale_ci --product-version %s %s/%s_%03d",
target, mdbci_config_name, maxscales->prefix, i);
if (system(sys))
{
return 1;
}
sprintf(sys, "mdbci install_product --product maxscale_ci --product-version %s %s/%s_%03d",
target, mdbci_config_name, maxscales->prefix, i);
if (system(sys))

View File

@ -994,6 +994,9 @@ QueryClassifier::RouteInfo QueryClassifier::update_route_info(
uint32_t type_mask = QUERY_TYPE_UNKNOWN;
uint32_t stmt_id = 0;
// Reset for every classification
m_ps_continuation = false;
// TODO: It may be sufficient to simply check whether we are in a read-only
// TODO: transaction.
bool in_read_only_trx =

View File

@ -448,6 +448,8 @@ bool mxs_worker_should_shutdown(MXB_WORKER* pWorker)
RoutingWorker* RoutingWorker::get(int worker_id)
{
mxb_assert(this_unit.initialized);
if (worker_id == MAIN)
{
worker_id = this_unit.id_main_worker;

View File

@ -918,6 +918,9 @@ static int gw_read_and_write(DCB* dcb)
*/
GWBUF_DATA(read_buffer)[3] = 0x3;
proto->changing_user = false;
auto s = (MYSQL_session*)session->client_dcb->data;
s->changing_user = false;
}
}

View File

@ -1718,7 +1718,15 @@ static int gw_client_hangup_event(DCB* dcb)
errmsg += ": " + extra;
}
modutil_send_mysql_err_packet(dcb, 0, 0, 1927, "08S01", errmsg.c_str());
int seqno = 1;
if (dcb->data && ((MYSQL_session*)dcb->data)->changing_user)
{
// In case a COM_CHANGE_USER is in progress, we need to send the error with the seqno 3
seqno = 3;
}
modutil_send_mysql_err_packet(dcb, seqno, 0, 1927, "08S01", errmsg.c_str());
}
dcb_close(dcb);
}
@ -1921,6 +1929,10 @@ static int route_by_statement(MXS_SESSION* session, uint64_t capabilities, GWBUF
if (!proto->changing_user && proto->current_command == MXS_COM_CHANGE_USER)
{
// Track the COM_CHANGE_USER progress at the session level
auto s = (MYSQL_session*)session->client_dcb->data;
s->changing_user = true;
changed_user = true;
send_auth_switch_request_packet(session->client_dcb);

View File

@ -38,7 +38,7 @@ uint8_t null_client_sha1[MYSQL_SCRAMBLE_LEN] = "";
MYSQL_session* mysql_session_alloc()
{
MYSQL_session* ses = (MYSQL_session*)MXS_CALLOC(1, sizeof(MYSQL_session));
ses->changing_user = false;
return ses;
}

View File

@ -96,6 +96,14 @@ bool RWBackend::write(GWBUF* buffer, response_type type)
if (mxs_mysql_is_ps_command(cmd))
{
// We need to completely separate the buffer this backend owns and the one that the caller owns to
// prevent any modifications from affecting the one that was written through this backend. If the
// buffer gets placed into the write queue of the DCB, subsequent modifications to the original buffer
// would be propagated to the one this backend owns.
GWBUF* tmp = gwbuf_deep_clone(buffer);
gwbuf_free(buffer);
buffer = tmp;
uint32_t id = mxs_mysql_extract_ps_id(buffer);
BackendHandleMap::iterator it = m_ps_handles.find(id);

View File

@ -235,12 +235,7 @@ bool RWSplitSession::route_single_stmt(GWBUF* querybuf)
RWBackend* target = nullptr;
if (command == MXS_COM_STMT_EXECUTE && stmt_id == 0)
{
// Unknown prepared statement ID
succp = send_unknown_ps_error(extract_binary_ps_id(querybuf));
}
else if (TARGET_IS_ALL(route_target))
if (TARGET_IS_ALL(route_target))
{
succp = handle_target_is_all(route_target, querybuf, command, qtype);
}
@ -282,6 +277,11 @@ bool RWSplitSession::route_single_stmt(GWBUF* querybuf)
target = m_prev_target;
succp = true;
}
else if (mxs_mysql_is_ps_command(command) && stmt_id == 0)
{
// Unknown prepared statement ID
succp = send_unknown_ps_error(extract_binary_ps_id(querybuf));
}
else if (TARGET_IS_NAMED_SERVER(route_target) || TARGET_IS_RLAG_MAX(route_target))
{
if ((target = handle_hinted_target(querybuf, route_target)))

View File

@ -985,6 +985,18 @@ void RWSplitSession::handleError(GWBUF* errmsgbuf,
RWBackend* backend = get_backend_from_dcb(problem_dcb);
mxb_assert(backend->in_use());
if (backend->reply_has_started())
{
MXS_ERROR("Server '%s' was lost in the middle of a resultset, cannot continue the session: %s",
backend->name(), extract_error(errmsgbuf).c_str());
// This effectively causes an instant termination of the client connection and prevents any errors
// from being sent to the client (MXS-2562).
dcb_close(m_client);
*succp = true;
return;
}
switch (action)
{
case ERRACT_NEW_CONNECTION: