From 2343326ecc96ede6690616b4f5fc013f44783850 Mon Sep 17 00:00:00 2001 From: Niclas Antti Date: Mon, 17 Jun 2019 06:40:42 +0300 Subject: [PATCH] MXS-2555 Add execute_kill version, that kills all but a given mysql_thread_id NOTE: This does not work whit unix scokets. The reason is that LocalClient assumes network sockets. TODO: to add unix socket support. --- include/maxscale/protocol/mysql.hh | 11 +++++++++ server/modules/protocol/MySQL/mysql_common.cc | 24 +++++++++++++++---- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/maxscale/protocol/mysql.hh b/include/maxscale/protocol/mysql.hh index 2678a60cf..47e4e19be 100644 --- a/include/maxscale/protocol/mysql.hh +++ b/include/maxscale/protocol/mysql.hh @@ -700,6 +700,17 @@ typedef enum kill_type } kill_type_t; void mxs_mysql_execute_kill(MXS_SESSION* issuer, uint64_t target_id, kill_type_t type); + +/** Send KILL to all but the keep_protocol_thread_id. If keep_protocol_thread_id==0, kill all. + * TODO: The naming: issuer, target_id, protocol_thread_id is not very descriptive, + * and really goes to the heart of explaining what the session_id/thread_id means in terms + * of a service/server pipeline and the recursiveness of this call. + */ +void mxs_mysql_execute_kill_all_others(MXS_SESSION* issuer, + uint64_t target_id, + uint64_t keep_protocol_thread_id, + kill_type_t type); + void mxs_mysql_execute_kill_user(MXS_SESSION* issuer, const char* user, kill_type_t type); MXS_END_DECLS diff --git a/server/modules/protocol/MySQL/mysql_common.cc b/server/modules/protocol/MySQL/mysql_common.cc index 8b313ba7f..f68e0d8a9 100644 --- a/server/modules/protocol/MySQL/mysql_common.cc +++ b/server/modules/protocol/MySQL/mysql_common.cc @@ -1347,13 +1347,15 @@ static bool kill_func(DCB* dcb, void* data); struct ConnKillInfo : public KillInfo { - ConnKillInfo(uint64_t id, std::string query, MXS_SESSION* ses) + ConnKillInfo(uint64_t id, std::string query, MXS_SESSION* ses, uint64_t keep_thread_id) : KillInfo(query, ses, kill_func) , target_id(id) + , keep_thread_id(keep_thread_id) { } uint64_t target_id; + uint64_t keep_thread_id; }; static bool kill_user_func(DCB* dcb, void* data); @@ -1372,11 +1374,12 @@ struct UserKillInfo : public KillInfo static bool kill_func(DCB* dcb, void* data) { ConnKillInfo* info = static_cast(data); + MySQLProtocol* proto = static_cast(dcb->protocol); - if (dcb->session->ses_id == info->target_id && dcb->role == DCB::Role::BACKEND) + if (dcb->session->ses_id == info->target_id + && dcb->role == DCB::Role::BACKEND + && (info->keep_thread_id == 0 || proto->thread_id != info->keep_thread_id)) { - MySQLProtocol* proto = (MySQLProtocol*)dcb->protocol; - if (proto->thread_id) { // DCB is connected and we know the thread ID so we can kill it @@ -1430,6 +1433,14 @@ static void worker_func(int thread_id, void* data) } void mxs_mysql_execute_kill(MXS_SESSION* issuer, uint64_t target_id, kill_type_t type) +{ + mxs_mysql_execute_kill_all_others(issuer, target_id, 0, type); +} + +void mxs_mysql_execute_kill_all_others(MXS_SESSION* issuer, + uint64_t target_id, + uint64_t keep_protocol_thread_id, + kill_type_t type) { const char* hard = (type & KT_HARD) ? "HARD " : (type & KT_SOFT) ? "SOFT " : ""; const char* query = (type & KT_QUERY) ? "QUERY " : ""; @@ -1443,7 +1454,10 @@ void mxs_mysql_execute_kill(MXS_SESSION* issuer, uint64_t target_id, kill_type_t mxb_worker_post_message(worker, MXB_WORKER_MSG_CALL, (intptr_t)worker_func, - (intptr_t) new ConnKillInfo(target_id, ss.str(), issuer)); + (intptr_t) new ConnKillInfo(target_id, + ss.str(), + issuer, + keep_protocol_thread_id)); } }