diff options
author | Sergei Golubchik <sergii@pisem.net> | 2013-01-18 19:04:23 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2013-01-18 19:04:23 +0100 |
commit | d41d43f42165cafe87d361f473e226fee24e91ba (patch) | |
tree | 20afb41b68fe7982e4500aa9427401fca3ff2fa7 /sql | |
parent | 5649377b558d182a4856a86157070e0df93097a7 (diff) | |
download | mariadb-git-d41d43f42165cafe87d361f473e226fee24e91ba.tar.gz |
MDEV-4065 thd_kill_statement service
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.cc | 13 | ||||
-rw-r--r-- | sql/handler.h | 6 | ||||
-rw-r--r-- | sql/sql_class.cc | 33 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 7 | ||||
-rw-r--r-- | sql/sql_plugin_services.h | 15 |
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 } }; |