Merge branch '2.3' into 2.4
This commit is contained in:
commit
3e85500491
@ -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=$?
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 =
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo service maxscale stop
|
||||
sudo systemctl stop maxscale || sudo service maxscale stop
|
||||
|
||||
hm=`pwd`
|
||||
$hm/start_killer.sh &
|
||||
|
@ -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))
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)))
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user