diff options
Diffstat (limited to 'sql/sql_show.cc')
-rw-r--r-- | sql/sql_show.cc | 77 |
1 files changed, 60 insertions, 17 deletions
diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1ef3ce2e40a..1f860fe23db 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -458,7 +458,7 @@ bool ignore_db_dirs_init() { return my_init_dynamic_array(&ignore_db_dirs_array, sizeof(LEX_STRING *), - 0, 0); + 0, 0, MYF(0)); } @@ -737,7 +737,8 @@ find_files(THD *thd, List<LEX_STRING> *files, const char *db, bzero((char*) &table_list,sizeof(table_list)); - if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0)))) + if (!(dirp = my_dir(path,MYF((dir ? MY_WANT_STAT : 0) | + MY_THREAD_SPECIFIC)))) { if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db); @@ -2334,11 +2335,14 @@ void Show_explain_request::call_in_target_thread() target_thd->query_length(), target_thd->query_charset()); + DBUG_ASSERT(current_thd == target_thd); + set_current_thd(request_thd); if (target_thd->lex->unit.print_explain(explain_buf, 0 /* explain flags*/, &printed_anything)) { failed_to_produce= TRUE; } + set_current_thd(target_thd); if (!printed_anything) failed_to_produce= TRUE; @@ -2349,10 +2353,20 @@ void Show_explain_request::call_in_target_thread() int select_result_explain_buffer::send_data(List<Item> &items) { + int res; + THD *cur_thd= current_thd; + DBUG_ENTER("select_result_explain_buffer::send_data"); + + /* + Switch to the recieveing thread, so that we correctly count memory used + by it. This is needed as it's the receiving thread that will free the + memory. + */ + set_current_thd(thd); fill_record(thd, dst_table, dst_table->field, items, TRUE, FALSE); - if ((dst_table->file->ha_write_tmp_row(dst_table->record[0]))) - return 1; - return 0; + res= dst_table->file->ha_write_tmp_row(dst_table->record[0]); + set_current_thd(cur_thd); + DBUG_RETURN(test(res)); } @@ -2578,6 +2592,18 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) } mysql_mutex_unlock(&tmp->LOCK_thd_data); + /* + This may become negative if we free a memory allocated by another + thread in this thread. However it's better that we notice it eventually + than hide it. + */ + table->field[12]->store((longlong) (tmp->status_var.memory_used + + sizeof(THD)), + FALSE); + table->field[12]->set_notnull(); + table->field[13]->store((longlong) tmp->get_examined_row_count(), TRUE); + table->field[13]->set_notnull(); + if (schema_table_store_record(thd, table)) { mysql_mutex_unlock(&LOCK_thread_count); @@ -2650,7 +2676,7 @@ int add_status_vars(SHOW_VAR *list) if (status_vars_inited) mysql_mutex_lock(&LOCK_status); if (!all_status_vars.buffer && // array is not allocated yet - do it now - my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20)) + my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20, MYF(0))) { res= 1; goto err; @@ -2784,7 +2810,6 @@ static bool show_status_array(THD *thd, const char *wild, int len; LEX_STRING null_lex_str; SHOW_VAR tmp, *var; - COND *partial_cond= 0; enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; bool res= FALSE; CHARSET_INFO *charset= system_charset_info; @@ -2798,7 +2823,6 @@ static bool show_status_array(THD *thd, const char *wild, if (*prefix) *prefix_end++= '_'; len=name_buffer + sizeof(name_buffer) - prefix_end; - partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list); for (; variables->name; variables++) { @@ -2836,14 +2860,14 @@ static bool show_status_array(THD *thd, const char *wild, if (show_type == SHOW_ARRAY) { show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type, - status_var, name_buffer, table, ucase_names, partial_cond); + status_var, name_buffer, table, ucase_names, cond); } else { if ((wild_checked || (wild && wild[0] && wild_case_compare(system_charset_info, name_buffer, wild))) && - (!partial_cond || partial_cond->val_int())) + (!cond || cond->val_int())) { char *value=var->value; const char *pos, *end; // We assign a lot of const's @@ -2999,7 +3023,8 @@ static int aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats) { // First entry for this role. if (!(agg_user= (USER_STATS*) my_malloc(sizeof(USER_STATS), - MYF(MY_WME | MY_ZEROFILL)))) + MYF(MY_WME | MY_ZEROFILL| + MY_THREAD_SPECIFIC)))) { sql_print_error("Malloc in aggregate_user_stats failed"); DBUG_RETURN(1); @@ -4372,7 +4397,7 @@ static int fill_schema_table_from_frm(THD *thd, TABLE_LIST *tables, if (schema_table->i_s_requested_object & OPEN_TRIGGER_ONLY) { - init_sql_alloc(&tbl.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); + init_sql_alloc(&tbl.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); if (!Table_triggers_list::check_n_load(thd, db_name->str, table_name->str, &tbl, 1)) { @@ -5870,7 +5895,13 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) { DBUG_RETURN(1); } - proc_table->file->ha_index_init(0, 1); + + if (proc_table->file->ha_index_init(0, 1)) + { + res= 1; + goto err; + } + if ((res= proc_table->file->ha_index_first(proc_table->record[0]))) { res= (res == HA_ERR_END_OF_FILE) ? 0 : 1; @@ -5896,7 +5927,9 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) } err: - proc_table->file->ha_index_end(); + if (proc_table->file->inited) + (void) proc_table->file->ha_index_end(); + close_system_tables(thd, &open_tables_state_backup); DBUG_RETURN(res); } @@ -7095,9 +7128,12 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) schema_table_idx == SCH_GLOBAL_VARIABLES) option_type= OPT_GLOBAL; + COND *partial_cond= make_cond_for_info_schema(cond, tables); + mysql_rwlock_rdlock(&LOCK_system_variables_hash); res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, option_type), - option_type, NULL, "", tables->table, upper_case_names, cond); + option_type, NULL, "", tables->table, + upper_case_names, partial_cond); mysql_rwlock_unlock(&LOCK_system_variables_hash); DBUG_RETURN(res); } @@ -7134,13 +7170,18 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) tmp1= &thd->status_var; } + COND *partial_cond= make_cond_for_info_schema(cond, tables); + // Evaluate and cache const subqueries now, before the mutex. + if (partial_cond) + partial_cond->val_int(); + mysql_mutex_lock(&LOCK_status); if (option_type == OPT_GLOBAL) calc_sum_of_all_status(&tmp); res= show_status_array(thd, wild, (SHOW_VAR *)all_status_vars.buffer, option_type, tmp1, "", tables->table, - upper_case_names, cond); + upper_case_names, partial_cond); mysql_mutex_unlock(&LOCK_status); DBUG_RETURN(res); } @@ -8612,6 +8653,8 @@ ST_FIELD_INFO processlist_fields_info[]= {"MAX_STAGE", 2, MYSQL_TYPE_TINY, 0, 0, "Max_stage", SKIP_OPEN_TABLE}, {"PROGRESS", 703, MYSQL_TYPE_DECIMAL, 0, 0, "Progress", SKIP_OPEN_TABLE}, + {"MEMORY_USED", 7, MYSQL_TYPE_LONG, 0, 0, "Memory_used", SKIP_OPEN_TABLE}, + {"EXAMINED_ROWS", 7, MYSQL_TYPE_LONG, 0, 0, "Examined_rows", SKIP_OPEN_TABLE}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE} }; @@ -8941,7 +8984,7 @@ int initialize_schema_table(st_plugin_int *plugin) DBUG_ENTER("initialize_schema_table"); if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE), - MYF(MY_WME | MY_ZEROFILL)))) + MYF(MY_WME | MY_ZEROFILL)))) DBUG_RETURN(1); /* Historical Requirement */ plugin->data= schema_table; // shortcut for the future |