diff options
-rw-r--r-- | sql/event_data_objects.cc | 20 | ||||
-rw-r--r-- | sql/event_scheduler.cc | 4 | ||||
-rw-r--r-- | sql/ha_ndbcluster_binlog.cc | 6 | ||||
-rw-r--r-- | sql/log_event.cc | 16 | ||||
-rw-r--r-- | sql/slave.cc | 21 | ||||
-rw-r--r-- | sql/sp_head.cc | 6 | ||||
-rw-r--r-- | sql/sql_class.cc | 31 | ||||
-rw-r--r-- | sql/sql_class.h | 52 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 48 | ||||
-rw-r--r-- | sql/sql_repl.cc | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 8 | ||||
-rw-r--r-- | storage/myisam/ha_myisam.cc | 11 |
13 files changed, 110 insertions, 119 deletions
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 0eba357b632..dba32cac6b2 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -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)); diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index d9d010783e8..78aad2b4c3d 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -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: " diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index f705af8bf47..a3adbe4a952 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -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; diff --git a/sql/log_event.cc b/sql/log_event.cc index 5f77ab3dcc4..e7cbbaba38e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -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", diff --git a/sql/slave.cc b/sql/slave.cc index 83a4d8c73d1..3b64e23ece5 100644 --- a/sql/slave.cc +++ b/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() */ diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8a8a5b06cc1..018937fec2f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -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()) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 48ddb42f0d8..54684e4987e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -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. diff --git a/sql/sql_class.h b/sql/sql_class.h index a758d24131b..f1b56551b50 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -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; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 104c81ca984..7d581f8c3a9 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -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 */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 542ce992537..88699ea6979 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 476c8aaaefb..0ec8d91214c 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -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); } } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a1f6798244e..35dbb64dfef 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -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); } } diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index d0e5f5a5c88..5198e685817 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -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); } |