mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Reuse THD for new user connections
- To ensure that mallocs are marked for the correct THD, even if it's allocated in another thread, I added the thread_id to the THD constructor - Added st_my_thread_var to thr_lock_info_init() to avoid a call to my_thread_var - Moved things from THD::THD() to THD::init() - Moved some things to THD::cleanup() - Added THD::free_connection() and THD::reset_for_reuse() - Added THD to CONNECT::create_thd() - Added THD::thread_dbug_id and st_my_thread_var->dbug_id. These are needed to ensure that we have a constant thread_id used for debugging with a THD, even if it changes thread_id (=connection_id) - Set variables.pseudo_thread_id in constructor. Removed not needed sets.
This commit is contained in:
150
sql/sql_class.cc
150
sql/sql_class.cc
@ -336,17 +336,6 @@ void thd_set_killed(THD *thd)
|
||||
thd->killed= KILL_CONNECTION;
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
|
||||
@ -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
|
||||
@ -468,6 +457,18 @@ THD *thd_get_current_thd()
|
||||
return 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
|
||||
|
||||
@ -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;
|
||||
delete wsrep_rgi;
|
||||
#endif
|
||||
/* Close connection */
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (net.vio)
|
||||
vio_delete(net.vio);
|
||||
net_end(&net);
|
||||
#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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user