diff --git a/sql/field.cc b/sql/field.cc index a24ffe28600..aeeacf7f88d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7612,7 +7612,8 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs) } Field_blob::store_length(length); - if (table->copy_blobs || length <= MAX_FIELD_WIDTH) + if ((table->copy_blobs || length <= MAX_FIELD_WIDTH) && + from != value.ptr()) { // Must make a copy value.copy(from, length, cs); from= value.ptr(); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index d31f7b8e5cb..3b280c45608 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2018,10 +2018,21 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join, */ if (expr && !expr->fixed) { - SELECT_LEX *save_current_select= thd->lex->current_select; - thd->lex->current_select= thd->lex->current_select->outer_select(); bool tmp; + SELECT_LEX *save_current_select= thd->lex->current_select; + Item_subselect *save_item; + + thd->lex->current_select= thd->lex->current_select->outer_select(); + /* + For st_select_lex::mark_as_dependent, who needs to mark + this sub query as correlated. + */ + save_item= thd->lex->current_select->master_unit()->item; + thd->lex->current_select->master_unit()->item= this; + tmp= expr->fix_fields(thd, 0); + + thd->lex->current_select->master_unit()->item= save_item; thd->lex->current_select= save_current_select; if (tmp) DBUG_RETURN(true); diff --git a/sql/log.cc b/sql/log.cc index 9722f20869d..0940cb9b56c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3676,6 +3676,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) { int error; char *to_purge_if_included= NULL; + ulonglong log_space_reclaimed= 0; DBUG_ENTER("purge_first_log"); DBUG_ASSERT(is_open()); @@ -3724,17 +3725,13 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE();); - mysql_mutex_lock(&rli->log_space_lock); rli->relay_log.purge_logs(to_purge_if_included, included, - 0, 0, &rli->log_space_total); - mysql_mutex_unlock(&rli->log_space_lock); + 0, 0, &log_space_reclaimed); - /* - Ok to broadcast after the critical region as there is no risk of - the mutex being destroyed by this thread later - this helps save - context switches - */ + mysql_mutex_lock(&rli->log_space_lock); + rli->log_space_total-= log_space_reclaimed; mysql_cond_broadcast(&rli->log_space_cond); + mysql_mutex_unlock(&rli->log_space_lock); /* * Need to update the log pos because purge logs has been called @@ -3783,8 +3780,8 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads @param need_mutex @param need_update_threads If we want to update the log coordinates of all threads. False for relay logs, true otherwise. - @param freed_log_space If not null, decrement this variable of - the amount of log space freed + @param reclaimeed_log_space If not null, increment this variable to + the amount of log space freed @note If any of the logs before the deleted one is in use, @@ -3800,10 +3797,10 @@ int MYSQL_BIN_LOG::update_log_index(LOG_INFO* log_info, bool need_update_threads */ int MYSQL_BIN_LOG::purge_logs(const char *to_log, - bool included, - bool need_mutex, - bool need_update_threads, - ulonglong *decrease_log_space) + bool included, + bool need_mutex, + bool need_update_threads, + ulonglong *reclaimed_space) { int error= 0; bool exit_loop= 0; @@ -3868,7 +3865,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, err: /* Read each entry from purge_index_file and delete the file. */ if (is_inited_purge_index_file() && - (error= purge_index_entry(thd, decrease_log_space, FALSE))) + (error= purge_index_entry(thd, reclaimed_space, FALSE))) sql_print_error("MSYQL_BIN_LOG::purge_logs failed to process registered files" " that would be purged."); close_purge_index_file(); @@ -3973,7 +3970,7 @@ int MYSQL_BIN_LOG::register_create_index_entry(const char *entry) DBUG_RETURN(register_purge_index_entry(entry)); } -int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space, +int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *reclaimed_space, bool need_mutex) { DBUG_ENTER("MYSQL_BIN_LOG:purge_index_entry"); @@ -4093,8 +4090,8 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space, DBUG_PRINT("info",("purging %s",log_info.log_file_name)); if (!my_delete(log_info.log_file_name, MYF(0))) { - if (decrease_log_space) - *decrease_log_space-= s.st_size; + if (reclaimed_space) + *reclaimed_space+= s.st_size; } else { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0178f927bab..1f741bf0a65 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2488,7 +2488,6 @@ void unlink_thd(THD *thd) thd->add_status_to_global(); mysql_mutex_lock(&LOCK_thread_count); - thread_count--; thd->unlink(); /* Used by binlog_reset_master. It would be cleaner to use @@ -2496,6 +2495,16 @@ void unlink_thd(THD *thd) sync feature has been shut down at this point. */ DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5);); + if (unlikely(abort_loop)) + { + /* + During shutdown, we have to delete thd inside the mutex + to not refer to mutexes that may be deleted during shutdown + */ + delete thd; + thd= 0; + } + thread_count--; mysql_mutex_unlock(&LOCK_thread_count); delete thd; diff --git a/sql/slave.cc b/sql/slave.cc index 2fe7ebb575d..fe96b1de008 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3556,9 +3556,7 @@ pthread_handler_t handle_slave_sql(void *arg) rli->clear_error(); //tell the I/O thread to take relay_log_space_limit into account from now on - mysql_mutex_lock(&rli->log_space_lock); rli->ignore_log_space_limit= 0; - mysql_mutex_unlock(&rli->log_space_lock); rli->trans_retries= 0; // start from "no error" DBUG_PRINT("info", ("rli->trans_retries: %lu", rli->trans_retries)); @@ -5228,14 +5226,8 @@ static Log_event* next_event(Relay_log_info* rli) rli->ignore_log_space_limit= true; } - /* - If the I/O thread is blocked, unblock it. Ok to broadcast - after unlock, because the mutex is only destroyed in - ~Relay_log_info(), i.e. when rli is destroyed, and rli will - not be destroyed before we exit the present function. - */ - mysql_mutex_unlock(&rli->log_space_lock); mysql_cond_broadcast(&rli->log_space_cond); + mysql_mutex_unlock(&rli->log_space_lock); // Note that wait_for_update_relay_log unlocks lock_log ! rli->relay_log.wait_for_update_relay_log(rli->sql_thd); // re-acquire data lock since we released it earlier