summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-01-18 19:04:23 +0100
committerSergei Golubchik <sergii@pisem.net>2013-01-18 19:04:23 +0100
commitd41d43f42165cafe87d361f473e226fee24e91ba (patch)
tree20afb41b68fe7982e4500aa9427401fca3ff2fa7 /sql
parent5649377b558d182a4856a86157070e0df93097a7 (diff)
downloadmariadb-git-d41d43f42165cafe87d361f473e226fee24e91ba.tar.gz
MDEV-4065 thd_kill_statement service
Diffstat (limited to 'sql')
-rw-r--r--sql/handler.cc13
-rw-r--r--sql/handler.h6
-rw-r--r--sql/sql_class.cc33
-rw-r--r--sql/sql_plugin.cc7
-rw-r--r--sql/sql_plugin_services.h15
5 files changed, 48 insertions, 26 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 11265abb9d0..058e219f76c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -673,21 +673,20 @@ void ha_close_connection(THD* thd)
}
static my_bool kill_handlerton(THD *thd, plugin_ref plugin,
- void *hard_kill)
+ void *level)
{
handlerton *hton= plugin_data(plugin, handlerton *);
if (hton->state == SHOW_OPTION_YES && hton->kill_query &&
thd_get_ha_data(thd, hton))
- hton->kill_query(hton, thd, * (my_bool*) hard_kill);
+ hton->kill_query(hton, thd, *(enum thd_kill_levels *) level);
return FALSE;
}
-void ha_kill_query(THD* thd, my_bool hard_kill)
+void ha_kill_query(THD* thd, enum thd_kill_levels level)
{
DBUG_ENTER("ha_kill_query");
- plugin_foreach(thd, kill_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN,
- &hard_kill);
+ plugin_foreach(thd, kill_handlerton, MYSQL_STORAGE_ENGINE_PLUGIN, &level);
DBUG_VOID_RETURN;
}
@@ -4721,7 +4720,9 @@ extern "C" enum icp_result handler_index_cond_check(void* h_arg)
THD *thd= h->table->in_use;
enum icp_result res;
- if (thd_killed(thd))
+ enum thd_kill_levels abort_at= h->has_transactions() ?
+ THD_ABORT_SOFTLY : THD_ABORT_ASAP;
+ if (thd_kill_level(thd) > abort_at)
return ICP_ABORTED_BY_USER;
if (h->end_range && h->compare_key2(h->end_range) > 0)
diff --git a/sql/handler.h b/sql/handler.h
index 9e390b2a62a..4a91d989e52 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -866,10 +866,8 @@ struct handlerton
int (*close_connection)(handlerton *hton, THD *thd);
/*
Tell handler that query has been killed.
- hard_kill is set in case of HARD KILL (abort query even if
- it may corrupt table).
*/
- void (*kill_query)(handlerton *hton, THD *thd, my_bool hard_kill);
+ void (*kill_query)(handlerton *hton, THD *thd, enum thd_kill_levels level);
/*
sv points to an uninitialized storage area of requested size
(see savepoint_offset description)
@@ -2983,7 +2981,7 @@ int ha_finalize_handlerton(st_plugin_int *plugin);
TYPELIB *ha_known_exts(void);
int ha_panic(enum ha_panic_function flag);
void ha_close_connection(THD* thd);
-void ha_kill_query(THD* thd, my_bool hard_kill);
+void ha_kill_query(THD* thd, enum thd_kill_levels level);
bool ha_flush_logs(handlerton *db_type);
void ha_drop_database(char* path);
void ha_checkpoint_state(bool disable);
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 616e827a552..43e72973ab9 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1613,7 +1613,7 @@ void THD::awake(killed_state state_to_set)
/* Interrupt target waiting inside a storage engine. */
if (state_to_set != NOT_KILLED)
- ha_kill_query(this, test(state_to_set & KILL_HARD_BIT));
+ ha_kill_query(this, thd_kill_level(this));
/* Broadcast a condition to kick the target if it is waiting on it. */
if (mysys_var)
@@ -3834,15 +3834,13 @@ void THD::restore_backup_open_tables_state(Open_tables_backup *backup)
DBUG_VOID_RETURN;
}
+#if MARIA_PLUGIN_INTERFACE_VERSION < 0x0200
/**
- Check the killed state of a user thread
- @param thd user thread
- @retval 0 the user thread is active
- @retval 1 the user thread has been killed
-
- This is used to signal a storage engine if it should be killed.
+ This is a backward compatibility method, made obsolete
+ by the thd_kill_statement service. Keep it here to avoid breaking the
+ ABI in case some binary plugins still use it.
*/
-
+#undef thd_killed
extern "C" int thd_killed(const MYSQL_THD thd)
{
if (!thd)
@@ -3850,9 +3848,26 @@ extern "C" int thd_killed(const MYSQL_THD thd)
if (!(thd->killed & KILL_HARD_BIT))
return 0;
- return thd->killed;
+ return thd->killed != 0;
}
+#else
+#error now thd_killed() function can go away
+#endif
+
+/*
+ return thd->killed status to the client,
+ mapped to the API enum thd_kill_levels values.
+*/
+extern "C" enum thd_kill_levels thd_kill_level(const MYSQL_THD thd)
+{
+ if (!thd)
+ thd= current_thd;
+
+ if (likely(thd->killed == NOT_KILLED))
+ return THD_IS_NOT_KILLED;
+ return thd->killed & KILL_HARD_BIT ? THD_ABORT_ASAP : THD_ABORT_SOFTLY;
+}
/**
Send an out-of-band progress report to the client
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index cec577b2273..bf3537c0ed9 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1872,8 +1872,11 @@ static bool plugin_load_list(MEM_ROOT *tmp_root, int *argc, char **argv,
DBUG_RETURN(FALSE);
error:
mysql_mutex_unlock(&LOCK_plugin);
- sql_print_error("Couldn't load plugin named '%s' with soname '%s'.",
- name.str, dl.str);
+ if (name.str)
+ sql_print_error("Couldn't load plugin '%s' from '%s'.",
+ name.str, dl.str);
+ else
+ sql_print_error("Couldn't load plugins from '%s'.", dl.str);
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h
index c779547059d..e3ef338eaad 100644
--- a/sql/sql_plugin_services.h
+++ b/sql/sql_plugin_services.h
@@ -54,13 +54,18 @@ static struct progress_report_service_st progress_report_handler= {
set_thd_proc_info
};
+static struct kill_statement_service_st thd_kill_statement_handler= {
+ thd_kill_level
+};
+
static struct st_service_ref list_of_services[]=
{
- { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
- { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler },
- { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
+ { "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
+ { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler },
+ { "thd_wait_service", VERSION_thd_wait, &thd_wait_handler },
{ "my_thread_scheduler_service", VERSION_my_thread_scheduler, &my_thread_scheduler_handler },
- { "progress_report_service", VERSION_progress_report, &progress_report_handler },
- { "debug_sync_service", VERSION_debug_sync, 0 } // updated in plugin_init()
+ { "progress_report_service", VERSION_progress_report, &progress_report_handler },
+ { "debug_sync_service", VERSION_debug_sync, 0 }, // updated in plugin_init()
+ { "thd_kill_statement_service", VERSION_kill_statement, &thd_kill_statement_handler }
};