mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
Merge from 5.0
****** manual merge 5.0-bugteam --> 5.1-bugteam (bug 38816)
This commit is contained in:
commit
2bc6b6a800
13 changed files with 110 additions and 119 deletions
|
@ -1430,13 +1430,7 @@ Event_job_data::execute(THD *thd, bool drop)
|
|||
thd->variables.sql_mode= sql_mode;
|
||||
thd->variables.time_zone= time_zone;
|
||||
|
||||
/*
|
||||
Peculiar initialization order is a crutch to avoid races in SHOW
|
||||
PROCESSLIST which reads thd->{query/query_length} without a mutex.
|
||||
*/
|
||||
thd->query_length= 0;
|
||||
thd->query= sp_sql.c_ptr_safe();
|
||||
thd->query_length= sp_sql.length();
|
||||
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
|
||||
|
||||
{
|
||||
Parser_state parser_state(thd, thd->query, thd->query_length);
|
||||
|
@ -1497,13 +1491,8 @@ end_no_lex_start:
|
|||
else
|
||||
{
|
||||
ulong saved_master_access;
|
||||
/*
|
||||
Peculiar initialization order is a crutch to avoid races in SHOW
|
||||
PROCESSLIST which reads thd->{query/query_length} without a mutex.
|
||||
*/
|
||||
thd->query_length= 0;
|
||||
thd->query= sp_sql.c_ptr_safe();
|
||||
thd->query_length= sp_sql.length();
|
||||
|
||||
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
|
||||
|
||||
/*
|
||||
NOTE: even if we run in read-only mode, we should be able to lock
|
||||
|
@ -1528,8 +1517,7 @@ end_no_lex_start:
|
|||
thd->end_statement();
|
||||
thd->cleanup_after_query();
|
||||
/* Avoid races with SHOW PROCESSLIST */
|
||||
thd->query_length= 0;
|
||||
thd->query= NULL;
|
||||
thd->set_query(NULL, 0);
|
||||
|
||||
DBUG_PRINT("info", ("EXECUTED %s.%s ret: %d", dbname.str, name.str, ret));
|
||||
|
||||
|
|
|
@ -625,13 +625,13 @@ Event_scheduler::stop()
|
|||
DBUG_PRINT("info", ("Scheduler thread has id %lu",
|
||||
scheduler_thd->thread_id));
|
||||
/* Lock from delete */
|
||||
pthread_mutex_lock(&scheduler_thd->LOCK_delete);
|
||||
pthread_mutex_lock(&scheduler_thd->LOCK_thd_data);
|
||||
/* This will wake up the thread if it waits on Queue's conditional */
|
||||
sql_print_information("Event Scheduler: Killing the scheduler thread, "
|
||||
"thread id %lu",
|
||||
scheduler_thd->thread_id);
|
||||
scheduler_thd->awake(THD::KILL_CONNECTION);
|
||||
pthread_mutex_unlock(&scheduler_thd->LOCK_delete);
|
||||
pthread_mutex_unlock(&scheduler_thd->LOCK_thd_data);
|
||||
|
||||
/* thd could be 0x0, when shutting down */
|
||||
sql_print_information("Event Scheduler: "
|
||||
|
|
|
@ -253,8 +253,7 @@ static void run_query(THD *thd, char *buf, char *end,
|
|||
const char* found_semicolon= NULL;
|
||||
|
||||
bzero((char*) &thd->net, sizeof(NET));
|
||||
thd->query_length= end - buf;
|
||||
thd->query= buf;
|
||||
thd->set_query(buf, (uint) (end - buf));
|
||||
thd->variables.pseudo_thread_id= thread_id;
|
||||
thd->transaction.stmt.modified_non_trans_table= FALSE;
|
||||
if (disable_binlog)
|
||||
|
@ -297,8 +296,7 @@ static void run_query(THD *thd, char *buf, char *end,
|
|||
thd->main_da.reset_diagnostics_area();
|
||||
|
||||
thd->options= save_thd_options;
|
||||
thd->query_length= save_thd_query_length;
|
||||
thd->query= save_thd_query;
|
||||
thd->set_query(save_thd_query, save_thd_query_length);
|
||||
thd->variables.pseudo_thread_id= save_thread_id;
|
||||
thd->status_var= save_thd_status_var;
|
||||
thd->transaction.all= save_thd_transaction_all;
|
||||
|
|
|
@ -3025,8 +3025,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
|
|||
rpl_filter->db_ok(thd->db))
|
||||
{
|
||||
thd->set_time((time_t)when);
|
||||
thd->query_length= q_len_arg;
|
||||
thd->query= (char*)query_arg;
|
||||
thd->set_query((char*)query_arg, q_len_arg);
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->query_id = next_query_id();
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
|
@ -3231,7 +3230,6 @@ Default database: '%s'. Query: '%s'",
|
|||
} /* End of if (db_ok(... */
|
||||
|
||||
end:
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
/*
|
||||
Probably we have set thd->query, thd->db, thd->catalog to point to places
|
||||
in the data_buf of this event. Now the event is going to be deleted
|
||||
|
@ -3244,10 +3242,8 @@ end:
|
|||
*/
|
||||
thd->catalog= 0;
|
||||
thd->set_db(NULL, 0); /* will free the current database */
|
||||
thd->set_query(NULL, 0);
|
||||
DBUG_PRINT("info", ("end: query= 0"));
|
||||
thd->query= 0; // just to be sure
|
||||
thd->query_length= 0;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
close_thread_tables(thd);
|
||||
/*
|
||||
As a disk space optimization, future masters will not log an event for
|
||||
|
@ -4557,8 +4553,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
|||
print_query(FALSE, load_data_query, &end, (char **)&thd->lex->fname_start,
|
||||
(char **)&thd->lex->fname_end);
|
||||
*end= 0;
|
||||
thd->query_length= end - load_data_query;
|
||||
thd->query= load_data_query;
|
||||
thd->set_query(load_data_query, (uint) (end - load_data_query));
|
||||
|
||||
if (sql_ex.opt_flags & REPLACE_FLAG)
|
||||
{
|
||||
|
@ -4664,12 +4659,9 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
|
|||
error:
|
||||
thd->net.vio = 0;
|
||||
const char *remember_db= thd->db;
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->catalog= 0;
|
||||
thd->set_db(NULL, 0); /* will free the current database */
|
||||
thd->query= 0;
|
||||
thd->query_length= 0;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
thd->set_query(NULL, 0);
|
||||
close_thread_tables(thd);
|
||||
|
||||
DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
|
||||
|
|
21
sql/slave.cc
21
sql/slave.cc
|
@ -512,7 +512,7 @@ terminate_slave_thread(THD *thd,
|
|||
int error;
|
||||
DBUG_PRINT("loop", ("killing slave thread"));
|
||||
|
||||
pthread_mutex_lock(&thd->LOCK_delete);
|
||||
pthread_mutex_lock(&thd->LOCK_thd_data);
|
||||
#ifndef DONT_USE_THR_ALARM
|
||||
/*
|
||||
Error codes from pthread_kill are:
|
||||
|
@ -523,7 +523,7 @@ terminate_slave_thread(THD *thd,
|
|||
DBUG_ASSERT(err != EINVAL);
|
||||
#endif
|
||||
thd->awake(THD::NOT_KILLED);
|
||||
pthread_mutex_unlock(&thd->LOCK_delete);
|
||||
pthread_mutex_unlock(&thd->LOCK_thd_data);
|
||||
|
||||
/*
|
||||
There is a small chance that slave thread might miss the first
|
||||
|
@ -1250,15 +1250,13 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
thd->command = COM_TABLE_DUMP;
|
||||
thd->query_length= packet_len;
|
||||
/* Note that we should not set thd->query until the area is initalized */
|
||||
if (!(query = thd->strmake((char*) net->read_pos, packet_len)))
|
||||
{
|
||||
sql_print_error("create_table_from_dump: out of memory");
|
||||
my_message(ER_GET_ERRNO, "Out of memory", MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
thd->query= query;
|
||||
thd->set_query(query, packet_len);
|
||||
thd->is_slave_error = 0;
|
||||
|
||||
bzero((char*) &tables,sizeof(tables));
|
||||
|
@ -2755,10 +2753,8 @@ err:
|
|||
// print the current replication position
|
||||
sql_print_information("Slave I/O thread exiting, read up to log '%s', position %s",
|
||||
IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff));
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->query = thd->db = 0; // extra safety
|
||||
thd->query_length= thd->db_length= 0;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
thd->set_query(NULL, 0);
|
||||
thd->reset_db(NULL, 0);
|
||||
if (mysql)
|
||||
{
|
||||
/*
|
||||
|
@ -3110,15 +3106,14 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
|
|||
must "proactively" clear playgrounds:
|
||||
*/
|
||||
rli->cleanup_context(thd, 1);
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
/*
|
||||
Some extra safety, which should not been needed (normally, event deletion
|
||||
should already have done these assignments (each event which sets these
|
||||
variables is supposed to set them to 0 before terminating)).
|
||||
*/
|
||||
thd->query= thd->db= thd->catalog= 0;
|
||||
thd->query_length= thd->db_length= 0;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
thd->catalog= 0;
|
||||
thd->set_query(NULL, 0);
|
||||
thd->reset_db(NULL, 0);
|
||||
thd_proc_info(thd, "Waiting for slave mutex on exit");
|
||||
pthread_mutex_lock(&rli->run_lock);
|
||||
/* We need data_lock, at least to wake up any waiting master_pos_wait() */
|
||||
|
|
|
@ -1012,8 +1012,7 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
|
|||
else
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
thd->query= pbuf;
|
||||
thd->query_length= qbuf.length();
|
||||
thd->set_query(pbuf, qbuf.length());
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
@ -2858,8 +2857,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
|
|||
}
|
||||
else
|
||||
*nextp= m_ip+1;
|
||||
thd->query= query;
|
||||
thd->query_length= query_length;
|
||||
thd->set_query(query, query_length);
|
||||
thd->query_name_consts= 0;
|
||||
|
||||
if (!thd->is_error())
|
||||
|
|
|
@ -627,7 +627,7 @@ THD::THD()
|
|||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
active_vio = 0;
|
||||
#endif
|
||||
pthread_mutex_init(&LOCK_delete, MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&LOCK_thd_data, MY_MUTEX_INIT_FAST);
|
||||
|
||||
/* Variables with default values */
|
||||
proc_info="login";
|
||||
|
@ -911,8 +911,8 @@ THD::~THD()
|
|||
THD_CHECK_SENTRY(this);
|
||||
DBUG_ENTER("~THD()");
|
||||
/* Ensure that no one is using THD */
|
||||
pthread_mutex_lock(&LOCK_delete);
|
||||
pthread_mutex_unlock(&LOCK_delete);
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
add_to_status(&global_status_var, &status_var);
|
||||
|
||||
/* Close connection */
|
||||
|
@ -939,7 +939,7 @@ THD::~THD()
|
|||
free_root(&transaction.mem_root,MYF(0));
|
||||
#endif
|
||||
mysys_var=0; // Safety (shouldn't be needed)
|
||||
pthread_mutex_destroy(&LOCK_delete);
|
||||
pthread_mutex_destroy(&LOCK_thd_data);
|
||||
#ifndef DBUG_OFF
|
||||
dbug_sentry= THD_SENTRY_GONE;
|
||||
#endif
|
||||
|
@ -1012,7 +1012,7 @@ void THD::awake(THD::killed_state state_to_set)
|
|||
DBUG_ENTER("THD::awake");
|
||||
DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
|
||||
THD_CHECK_SENTRY(this);
|
||||
safe_mutex_assert_owner(&LOCK_delete);
|
||||
safe_mutex_assert_owner(&LOCK_thd_data);
|
||||
|
||||
killed= state_to_set;
|
||||
if (state_to_set != THD::KILL_QUERY)
|
||||
|
@ -1409,7 +1409,7 @@ int THD::send_explain_fields(select_result *result)
|
|||
void THD::close_active_vio()
|
||||
{
|
||||
DBUG_ENTER("close_active_vio");
|
||||
safe_mutex_assert_owner(&LOCK_delete);
|
||||
safe_mutex_assert_owner(&LOCK_thd_data);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (active_vio)
|
||||
{
|
||||
|
@ -3055,6 +3055,25 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
|
|||
}
|
||||
|
||||
|
||||
void THD::set_statement(Statement *stmt)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
Statement::set_statement(stmt);
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
|
||||
|
||||
/** Assign a new value to thd->query. */
|
||||
|
||||
void THD::set_query(char *query_arg, uint32 query_length_arg)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
query= query_arg;
|
||||
query_length= query_length_arg;
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Mark transaction to rollback and mark error as fatal to a sub-statement.
|
||||
|
||||
|
|
|
@ -631,22 +631,16 @@ public:
|
|||
we need to declare it char * because all table handlers are written
|
||||
in C and need to point to it.
|
||||
|
||||
Note that (A) if we set query = NULL, we must at the same time set
|
||||
query_length = 0, and protect the whole operation with the
|
||||
LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a
|
||||
non-NULL value if its previous value is NULL. We do not need to protect
|
||||
operation (B) with any mutex. To avoid crashes in races, if we do not
|
||||
know that thd->query cannot change at the moment, one should print
|
||||
Note that if we set query = NULL, we must at the same time set
|
||||
query_length = 0, and protect the whole operation with
|
||||
LOCK_thd_data mutex. To avoid crashes in races, if we do not
|
||||
know that thd->query cannot change at the moment, we should print
|
||||
thd->query like this:
|
||||
(1) reserve the LOCK_thread_count mutex;
|
||||
(2) check if thd->query is NULL;
|
||||
(3) if not NULL, then print at most thd->query_length characters from
|
||||
it. We will see the query_length field as either 0, or the right value
|
||||
for it.
|
||||
Assuming that the write and read of an n-bit memory field in an n-bit
|
||||
computer is atomic, we can avoid races in the above way.
|
||||
This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB
|
||||
STATUS.
|
||||
(1) reserve the LOCK_thd_data mutex;
|
||||
(2) print or copy the value of query and query_length
|
||||
(3) release LOCK_thd_data mutex.
|
||||
This printing is needed at least in SHOW PROCESSLIST and SHOW
|
||||
ENGINE INNODB STATUS.
|
||||
*/
|
||||
char *query;
|
||||
uint32 query_length; // current query length
|
||||
|
@ -678,7 +672,7 @@ public:
|
|||
virtual ~Statement();
|
||||
|
||||
/* Assign execution context (note: not all members) of given stmt to self */
|
||||
void set_statement(Statement *stmt);
|
||||
virtual void set_statement(Statement *stmt);
|
||||
void set_n_backup_statement(Statement *stmt, Statement *backup);
|
||||
void restore_backup_statement(Statement *stmt, Statement *backup);
|
||||
/* return class type */
|
||||
|
@ -1298,7 +1292,15 @@ public:
|
|||
THR_LOCK_OWNER main_lock_id; // To use for conventional queries
|
||||
THR_LOCK_OWNER *lock_id; // If not main_lock_id, points to
|
||||
// the lock_id of a cursor.
|
||||
pthread_mutex_t LOCK_delete; // Locked before thd is deleted
|
||||
/**
|
||||
Protects THD data accessed from other threads:
|
||||
- thd->query and thd->query_length (used by SHOW ENGINE
|
||||
INNODB STATUS and SHOW PROCESSLIST
|
||||
- thd->mysys_var (used by KILL statement and shutdown).
|
||||
Is locked when THD is deleted.
|
||||
*/
|
||||
pthread_mutex_t LOCK_thd_data;
|
||||
|
||||
/* all prepared statements and cursors of this connection */
|
||||
Statement_map stmt_map;
|
||||
/*
|
||||
|
@ -1890,15 +1892,15 @@ public:
|
|||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
inline void set_active_vio(Vio* vio)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_delete);
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
active_vio = vio;
|
||||
pthread_mutex_unlock(&LOCK_delete);
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
inline void clear_active_vio()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_delete);
|
||||
pthread_mutex_lock(&LOCK_thd_data);
|
||||
active_vio = 0;
|
||||
pthread_mutex_unlock(&LOCK_delete);
|
||||
pthread_mutex_unlock(&LOCK_thd_data);
|
||||
}
|
||||
void close_active_vio();
|
||||
#endif
|
||||
|
@ -2271,6 +2273,14 @@ public:
|
|||
*/
|
||||
void pop_internal_handler();
|
||||
|
||||
/** Overloaded to guard query/query_length fields */
|
||||
virtual void set_statement(Statement *stmt);
|
||||
|
||||
/**
|
||||
Assign a new value to thd->query.
|
||||
Protected with LOCK_thd_data mutex.
|
||||
*/
|
||||
void set_query(char *query_arg, uint32 query_length_arg);
|
||||
private:
|
||||
/** The current internal error handler for this thread, or NULL. */
|
||||
Internal_error_handler *m_internal_handler;
|
||||
|
|
|
@ -1909,7 +1909,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
|
|||
thread_count++;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
|
||||
di->thd.query= my_strdup(table_list->table_name, MYF(MY_WME));
|
||||
di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0);
|
||||
if (di->thd.db == NULL || di->thd.query == NULL)
|
||||
{
|
||||
/* The error is reported */
|
||||
|
|
|
@ -457,6 +457,7 @@ pthread_handler_t handle_bootstrap(void *arg)
|
|||
thd->init_for_queries();
|
||||
while (fgets(buff, thd->net.max_packet, file))
|
||||
{
|
||||
char *query;
|
||||
/* strlen() can't be deleted because fgets() doesn't return length */
|
||||
ulong length= (ulong) strlen(buff);
|
||||
while (buff[length-1] != '\n' && !feof(file))
|
||||
|
@ -489,11 +490,10 @@ pthread_handler_t handle_bootstrap(void *arg)
|
|||
if (strncmp(buff, STRING_WITH_LEN("delimiter")) == 0)
|
||||
continue;
|
||||
|
||||
thd->query_length=length;
|
||||
thd->query= (char*) thd->memdup_w_gap(buff, length+1,
|
||||
thd->db_length+1+
|
||||
QUERY_CACHE_FLAGS_SIZE);
|
||||
thd->query[length] = '\0';
|
||||
query= (char *) thd->memdup_w_gap(buff, length + 1,
|
||||
thd->db_length + 1 +
|
||||
QUERY_CACHE_FLAGS_SIZE);
|
||||
thd->set_query(query, length);
|
||||
DBUG_PRINT("query",("%-.4096s",thd->query));
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.start_new_query();
|
||||
|
@ -658,8 +658,7 @@ int mysql_table_dump(THD *thd, LEX_STRING *db, char *tbl_name)
|
|||
if (check_one_table_access(thd, SELECT_ACL, table_list))
|
||||
goto err;
|
||||
thd->free_list = 0;
|
||||
thd->query_length=(uint) strlen(tbl_name);
|
||||
thd->query = tbl_name;
|
||||
thd->set_query(tbl_name, (uint) strlen(tbl_name));
|
||||
if ((error = mysqld_dump_create_info(thd, table_list, -1)))
|
||||
{
|
||||
my_error(ER_GET_ERRNO, MYF(0), my_errno);
|
||||
|
@ -1239,9 +1238,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
thd->profiling.set_query_source(beginning_of_next_stmt, length);
|
||||
#endif
|
||||
|
||||
thd->set_query(beginning_of_next_stmt, length);
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->query_length= length;
|
||||
thd->query= beginning_of_next_stmt;
|
||||
/*
|
||||
Count each statement from the client.
|
||||
*/
|
||||
|
@ -1294,9 +1292,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
table_list.schema_table= schema_table;
|
||||
}
|
||||
|
||||
thd->query_length= (uint) (packet_end - packet); // Don't count end \0
|
||||
if (!(thd->query=fields= (char*) thd->memdup(packet,thd->query_length+1)))
|
||||
uint query_length= (uint) (packet_end - packet); // Don't count end \0
|
||||
if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
|
||||
break;
|
||||
thd->set_query(fields, query_length);
|
||||
general_log_print(thd, command, "%s %s", table_list.table_name, fields);
|
||||
if (lower_case_table_names)
|
||||
my_casedn_str(files_charset_info, table_list.table_name);
|
||||
|
@ -1589,13 +1588,12 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||
log_slow_statement(thd);
|
||||
|
||||
thd_proc_info(thd, "cleaning up");
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
|
||||
thd_proc_info(thd, 0);
|
||||
thd->set_query(NULL, 0);
|
||||
thd->command=COM_SLEEP;
|
||||
thd->query=0;
|
||||
thd->query_length=0;
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
|
||||
thread_running--;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
thd_proc_info(thd, 0);
|
||||
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
|
||||
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
|
||||
DBUG_RETURN(error);
|
||||
|
@ -1788,6 +1786,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
|||
|
||||
bool alloc_query(THD *thd, const char *packet, uint packet_length)
|
||||
{
|
||||
char *query;
|
||||
/* Remove garbage at start and end of query */
|
||||
while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
|
||||
{
|
||||
|
@ -1802,14 +1801,13 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
|
|||
packet_length--;
|
||||
}
|
||||
/* We must allocate some extra memory for query cache */
|
||||
thd->query_length= 0; // Extra safety: Avoid races
|
||||
if (!(thd->query= (char*) thd->memdup_w_gap((uchar*) (packet),
|
||||
packet_length,
|
||||
thd->db_length+ 1 +
|
||||
QUERY_CACHE_FLAGS_SIZE)))
|
||||
return TRUE;
|
||||
thd->query[packet_length]=0;
|
||||
thd->query_length= packet_length;
|
||||
if (! (query= (char*) thd->memdup_w_gap(packet,
|
||||
packet_length,
|
||||
1 + thd->db_length +
|
||||
QUERY_CACHE_FLAGS_SIZE)))
|
||||
return TRUE;
|
||||
query[packet_length]= '\0';
|
||||
thd->set_query(query, packet_length);
|
||||
|
||||
/* Reclaim some memory */
|
||||
thd->packet.shrink(thd->variables.net_buffer_length);
|
||||
|
@ -6950,7 +6948,7 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
|
|||
continue;
|
||||
if (tmp->thread_id == id)
|
||||
{
|
||||
pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete
|
||||
pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6983,7 +6981,7 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
|
|||
}
|
||||
else
|
||||
error=ER_KILL_DENIED_ERROR;
|
||||
pthread_mutex_unlock(&tmp->LOCK_delete);
|
||||
pthread_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
}
|
||||
DBUG_PRINT("exit", ("%d", error));
|
||||
DBUG_RETURN(error);
|
||||
|
|
|
@ -1102,7 +1102,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
|
|||
if (tmp->command == COM_BINLOG_DUMP &&
|
||||
tmp->server_id == slave_server_id)
|
||||
{
|
||||
pthread_mutex_lock(&tmp->LOCK_delete); // Lock from delete
|
||||
pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1115,7 +1115,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
|
|||
again. We just to do kill the thread ourselves.
|
||||
*/
|
||||
tmp->awake(THD::KILL_QUERY);
|
||||
pthread_mutex_unlock(&tmp->LOCK_delete);
|
||||
pthread_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1768,16 +1768,14 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
|
|||
|
||||
thd_info->start_time= tmp->start_time;
|
||||
thd_info->query=0;
|
||||
/* Lock THD mutex that protects its data when looking at it. */
|
||||
pthread_mutex_lock(&tmp->LOCK_thd_data);
|
||||
if (tmp->query)
|
||||
{
|
||||
/*
|
||||
query_length is always set to 0 when we set query = NULL; see
|
||||
the comment in sql_class.h why this prevents crashes in possible
|
||||
races with query_length
|
||||
*/
|
||||
uint length= min(max_query_length, tmp->query_length);
|
||||
thd_info->query=(char*) thd->strmake(tmp->query,length);
|
||||
}
|
||||
pthread_mutex_unlock(&tmp->LOCK_thd_data);
|
||||
thread_infos.append(thd_info);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1612,10 +1612,8 @@ bool ha_myisam::check_and_repair(THD *thd)
|
|||
|
||||
old_query= thd->query;
|
||||
old_query_length= thd->query_length;
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->query= table->s->table_name.str;
|
||||
thd->query_length= (uint) table->s->table_name.length;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->set_query(table->s->table_name.str,
|
||||
(uint) table->s->table_name.length);
|
||||
|
||||
if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
|
||||
{
|
||||
|
@ -1628,10 +1626,7 @@ bool ha_myisam::check_and_repair(THD *thd)
|
|||
if (repair(thd, &check_opt))
|
||||
error=1;
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->query= old_query;
|
||||
thd->query_length= old_query_length;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
thd->set_query(old_query, old_query_length);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue