diff options
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 150 |
1 files changed, 104 insertions, 46 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4be28457859..c8347d0f585 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -337,17 +337,6 @@ void thd_set_killed(THD *thd) } /** - Clear errors from the previous THD - - @param thd THD object -*/ -void thd_clear_errors(THD *thd) -{ - my_errno= 0; - thd->mysys_var->abort= 0; -} - -/** Set thread stack in THD object @param thd Thread object @@ -456,7 +445,7 @@ my_socket thd_get_fd(THD *thd) { return mysql_socket_getfd(thd->net.vio->mysql_socket); } -#endif +#endif /* ONLY_FOR_MYSQL_CLOSED_SOURCE_SCHEDULED */ /** Get current THD object from thread local data @@ -469,6 +458,18 @@ THD *thd_get_current_thd() } /** + Clear errors from the previous THD + + @param thd THD object +*/ +void thd_clear_errors(THD *thd) +{ + my_errno= 0; + thd->mysys_var->abort= 0; +} + + +/** Get thread attributes for connection threads @retval Reference to thread attribute for connection threads @@ -845,7 +846,7 @@ extern "C" void thd_kill_timeout(THD* thd) } -THD::THD(bool is_wsrep_applier) +THD::THD(my_thread_id id, bool is_wsrep_applier) :Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION, /* statement id */ 0), rli_fake(0), rgi_fake(0), rgi_slave(NULL), @@ -854,17 +855,13 @@ THD::THD(bool is_wsrep_applier) binlog_unsafe_warning_flags(0), binlog_table_maps(0), table_map_for_update(0), - arg_of_last_insert_id_function(FALSE), - first_successful_insert_id_in_prev_stmt(0), - first_successful_insert_id_in_prev_stmt_for_binlog(0), - first_successful_insert_id_in_cur_stmt(0), - stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE), m_examined_row_count(0), accessed_rows_and_keys(0), m_digest(NULL), m_statement_psi(NULL), m_idle_psi(NULL), - thread_id(0), + thread_id(id), + thread_dbug_id(id), os_thread_id(0), global_disable_checkpoint(0), failed_com_change_user(0), @@ -910,6 +907,7 @@ THD::THD(bool is_wsrep_applier) set_current_thd(this); status_var.local_memory_used= sizeof(THD); status_var.global_memory_used= 0; + variables.pseudo_thread_id= thread_id; main_da.init(); /* @@ -973,14 +971,12 @@ THD::THD(bool is_wsrep_applier) #ifndef DBUG_OFF dbug_sentry=THD_SENTRY_MAGIC; #endif -#ifndef EMBEDDED_LIBRARY mysql_audit_init_thd(this); -#endif net.vio=0; net.buff= 0; client_capabilities= 0; // minimalistic client system_thread= NON_SYSTEM_THREAD; - cleanup_done= abort_on_warning= 0; + cleanup_done= free_connection_done= abort_on_warning= 0; peer_port= 0; // For SHOW PROCESSLIST transaction.m_pending_rows_event= 0; transaction.on= 1; @@ -1003,7 +999,6 @@ THD::THD(bool is_wsrep_applier) /* Variables with default values */ proc_info="login"; where= THD::DEFAULT_WHERE; - variables.server_id = global_system_variables.server_id; slave_net = 0; m_command=COM_CONNECT; *scramble= '\0'; @@ -1064,7 +1059,6 @@ THD::THD(bool is_wsrep_applier) tmp= (ulong) (my_rnd(&sql_rand) * 0xffffffff); my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id); substitute_null_with_insert_id = FALSE; - thr_lock_info_init(&lock_info); /* safety: will be reset after start */ lock_info.mysql_thd= (void *)this; m_token_array= NULL; @@ -1425,10 +1419,16 @@ void THD::init(void) reset_binlog_local_stmt_filter(); set_status_var_init(); bzero((char *) &org_status_var, sizeof(org_status_var)); + status_in_global= 0; start_bytes_received= 0; last_commit_gtid.seq_no= 0; last_stmt= NULL; - status_in_global= 0; + /* Reset status of last insert id */ + arg_of_last_insert_id_function= FALSE; + stmt_depends_on_first_successful_insert_id_in_prev_stmt= FALSE; + first_successful_insert_id_in_prev_stmt= 0; + first_successful_insert_id_in_prev_stmt_for_binlog= 0; + first_successful_insert_id_in_cur_stmt= 0; #ifdef WITH_WSREP wsrep_exec_mode= wsrep_applier ? REPL_RECV : LOCAL_STATE; wsrep_conflict_state= NO_CONFLICT; @@ -1547,12 +1547,14 @@ void THD::init_for_queries() void THD::change_user(void) { - add_status_to_global(); + if (!status_in_global) // Reset in init() + add_status_to_global(); - cleanup(); - reset_killed(); + if (!cleanup_done) + cleanup(); cleanup_done= 0; - status_in_global= 0; + reset_killed(); + thd_clear_errors(this); init(); stmt_map.reset(); my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, @@ -1616,6 +1618,8 @@ void THD::cleanup(void) my_hash_free(&user_vars); sp_cache_clear(&sp_proc_cache); sp_cache_clear(&sp_func_cache); + auto_inc_intervals_forced.empty(); + auto_inc_intervals_in_cur_stmt_for_binlog.empty(); mysql_ull_cleanup(this); /* All metadata locks must have been released by now. */ @@ -1627,6 +1631,63 @@ void THD::cleanup(void) } +/* + Free all connection related resources associated with a THD. + This is used when we put a thread into the thread cache. + After this call should either call ~THD or reset_for_reuse() depending on + circumstances. +*/ + +void THD::free_connection() +{ + DBUG_ASSERT(free_connection_done == 0); + my_free(db); + db= NULL; +#ifndef EMBEDDED_LIBRARY + if (net.vio) + vio_delete(net.vio); + net.vio= 0; + net_end(&net); +#endif + ha_close_connection(this); + plugin_thdvar_cleanup(this); + mysql_audit_free_thd(this); + main_security_ctx.destroy(); + /* close all prepared statements, to save memory */ + stmt_map.reset(); + free_connection_done= 1; + profiling.restart(); // Reset profiling +} + +/* + Reset thd for reuse by another connection + This is only used for user connections, so the following variables doesn't + have to be reset: + - Replication (slave) variables. + - Variables not reset between each statements. See reset_for_next_command. +*/ + +void THD::reset_for_reuse() +{ + mysql_audit_init_thd(this); + change_user(); // Calls cleanup() & init() + get_stmt_da()->reset_diagnostics_area(); + main_security_ctx.init(); + failed_com_change_user= 0; + is_fatal_error= 0; + client_capabilities= 0; + peer_port= 0; + query_name_consts= 0; // Safety + abort_on_warning= 0; + free_connection_done= 0; + m_command= COM_CONNECT; + profiling.reset(); +#ifdef SIGNAL_WITH_VIO_CLOSE + active_vio = 0; +#endif +} + + THD::~THD() { THD *orig_thd= current_thd; @@ -1653,26 +1714,15 @@ THD::~THD() mysql_mutex_lock(&LOCK_wsrep_thd); mysql_mutex_unlock(&LOCK_wsrep_thd); mysql_mutex_destroy(&LOCK_wsrep_thd); - if (wsrep_rgi) delete wsrep_rgi; -#endif - /* Close connection */ -#ifndef EMBEDDED_LIBRARY - if (net.vio) - vio_delete(net.vio); - net_end(&net); + delete wsrep_rgi; #endif - stmt_map.reset(); /* close all prepared statements */ + if (!free_connection_done) + free_connection(); if (!cleanup_done) cleanup(); mdl_context.destroy(); - ha_close_connection(this); - mysql_audit_release(this); - plugin_thdvar_cleanup(this); - main_security_ctx.destroy(); - my_free(db); - db= NULL; free_root(&transaction.mem_root,MYF(0)); mysql_cond_destroy(&COND_wakeup_ready); mysql_mutex_destroy(&LOCK_wakeup_ready); @@ -1692,7 +1742,6 @@ THD::~THD() rli_fake= NULL; } - mysql_audit_free_thd(this); if (rgi_slave) rgi_slave->cleanup_after_session(); my_free(semisync_info); @@ -2089,7 +2138,16 @@ bool THD::store_globals() Let mysqld define the thread id (not mysys) This allows us to move THD to different threads if needed. */ - mysys_var->id= thread_id; + mysys_var->id= thread_id; + + /* thread_dbug_id should not change for a THD */ + if (!thread_dbug_id) + thread_dbug_id= mysys_var->dbug_id; + else + { + /* This only changes if we are using pool-of-threads */ + mysys_var->dbug_id= thread_dbug_id; + } #ifdef __NR_gettid os_thread_id= (uint32)syscall(__NR_gettid); #else @@ -2106,7 +2164,7 @@ bool THD::store_globals() We have to call thr_lock_info_init() again here as THD may have been created in another thread */ - thr_lock_info_init(&lock_info); + thr_lock_info_init(&lock_info, mysys_var); return 0; } |