diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-07-15 10:47:50 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-07-15 10:47:50 -0300 |
commit | 649390ac814ce5ea1e77b833ab5fe92dfcfe86d5 (patch) | |
tree | ac8b15ac65b08a492c256369b73e372f6568c7a4 /sql/log.cc | |
parent | 06b8897e8e9a27b6ffc562af90153ab63f30e63e (diff) | |
parent | 8df20918d6751dc1eeb47ab722269dbd9d2da297 (diff) | |
download | mariadb-git-649390ac814ce5ea1e77b833ab5fe92dfcfe86d5.tar.gz |
Merge of mysql-trunk-bugfixing into mysql-trunk-merge.
Diffstat (limited to 'sql/log.cc')
-rw-r--r-- | sql/log.cc | 95 |
1 files changed, 75 insertions, 20 deletions
diff --git a/sql/log.cc b/sql/log.cc index cbf6d2589b0..b398cb1e73f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -209,7 +209,7 @@ class binlog_cache_data { public: binlog_cache_data(): m_pending(0), before_stmt_pos(MY_OFF_T_UNDEF), - incident(FALSE) + incident(FALSE), changes_to_non_trans_temp_table_flag(FALSE) { cache_log.end_of_file= max_binlog_cache_size; } @@ -245,9 +245,20 @@ public: return(incident); } + void set_changes_to_non_trans_temp_table() + { + changes_to_non_trans_temp_table_flag= TRUE; + } + + bool changes_to_non_trans_temp_table() + { + return (changes_to_non_trans_temp_table_flag); + } + void reset() { truncate(0); + changes_to_non_trans_temp_table_flag= FALSE; incident= FALSE; before_stmt_pos= MY_OFF_T_UNDEF; cache_log.end_of_file= max_binlog_cache_size; @@ -305,6 +316,12 @@ private: bool incident; /* + This flag indicates if the cache has changes to temporary tables. + @TODO This a temporary fix and should be removed after BUG#54562. + */ + bool changes_to_non_trans_temp_table_flag; + + /* It truncates the cache to a certain position. This includes deleting the pending event. */ @@ -1484,7 +1501,7 @@ static int binlog_close_connection(handlerton *hton, THD *thd) DBUG_ASSERT(cache_mngr->trx_cache.empty() && cache_mngr->stmt_cache.empty()); thd_set_ha_data(thd, binlog_hton, NULL); cache_mngr->~binlog_cache_mngr(); - my_free((uchar*)cache_mngr, MYF(0)); + my_free(cache_mngr); return 0; } @@ -1772,13 +1789,23 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) /* We flush the cache wrapped in a beging/rollback if: . aborting a single or multi-statement transaction and; - . the format is STMT and non-trans engines were updated or; - . the OPTION_KEEP_LOG is activate. + . the OPTION_KEEP_LOG is active or; + . the format is STMT and a non-trans table was updated or; + . the format is MIXED and a temporary non-trans table was + updated or; + . the format is MIXED, non-trans table was updated and + aborting a single statement transaction; */ + if (ending_trans(thd, all) && ((thd->variables.option_bits & OPTION_KEEP_LOG) || (trans_has_updated_non_trans_table(thd) && - thd->variables.binlog_format == BINLOG_FORMAT_STMT))) + thd->variables.binlog_format == BINLOG_FORMAT_STMT) || + (cache_mngr->trx_cache.changes_to_non_trans_temp_table() && + thd->variables.binlog_format == BINLOG_FORMAT_MIXED) || + (trans_has_updated_non_trans_table(thd) && + ending_single_stmt_trans(thd,all) && + thd->variables.binlog_format == BINLOG_FORMAT_MIXED))) { Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE, TRUE, 0); error= binlog_flush_trx_cache(thd, cache_mngr, &qev); @@ -1786,13 +1813,18 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all) /* Truncate the cache if: . aborting a single or multi-statement transaction or; - . the OPTION_KEEP_LOG is not activate and; - . the format is not STMT or no non-trans were updated. + . the OPTION_KEEP_LOG is not active and; + . the format is not STMT or no non-trans table was + updated and; + . the format is not MIXED or no temporary non-trans table + was updated. */ else if (ending_trans(thd, all) || (!(thd->variables.option_bits & OPTION_KEEP_LOG) && - ((!stmt_has_updated_non_trans_table(thd) || - thd->variables.binlog_format != BINLOG_FORMAT_STMT)))) + (!stmt_has_updated_non_trans_table(thd) || + thd->variables.binlog_format != BINLOG_FORMAT_STMT) && + (!cache_mngr->trx_cache.changes_to_non_trans_temp_table() || + thd->variables.binlog_format != BINLOG_FORMAT_MIXED))) error= binlog_truncate_trx_cache(thd, cache_mngr, all); } @@ -2213,7 +2245,8 @@ shutdown the MySQL server and restart it.", name, errno); if (file >= 0) mysql_file_close(file, MYF(0)); end_io_cache(&log_file); - safeFree(name); + my_free(name); + name= NULL; log_state= LOG_CLOSED; DBUG_RETURN(1); } @@ -2274,7 +2307,8 @@ void MYSQL_LOG::close(uint exiting) } log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED; - safeFree(name); + my_free(name); + name= NULL; DBUG_VOID_RETURN; } @@ -2352,7 +2386,7 @@ void MYSQL_QUERY_LOG::reopen_file() */ open(save_name, log_type, 0, io_cache_type); - my_free(save_name, MYF(0)); + my_free(save_name); mysql_mutex_unlock(&LOCK_log); @@ -2953,7 +2987,8 @@ shutdown the MySQL server and restart it.", name, errno); mysql_file_close(file, MYF(0)); end_io_cache(&log_file); end_io_cache(&index_file); - safeFree(name); + my_free(name); + name= NULL; log_state= LOG_CLOSED; DBUG_RETURN(1); } @@ -3286,7 +3321,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) need_start_event=1; if (!open_index_file(index_file_name, 0, FALSE)) open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE); - my_free((uchar*) save_name, MYF(0)); + my_free((void *) save_name); err: if (error == 1) @@ -3424,7 +3459,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included) DBUG_ASSERT(!included || rli->linfo.index_file_start_offset == 0); err: - my_free(to_purge_if_included, MYF(0)); + my_free(to_purge_if_included); mysql_mutex_unlock(&LOCK_index); DBUG_RETURN(error); } @@ -4064,7 +4099,7 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock) if (!open_index_file(index_file_name, 0, FALSE)) open(old_name, log_type, new_name_ptr, io_cache_type, no_auto_events, max_size, 1, FALSE); - my_free(old_name,MYF(0)); + my_free(old_name); end: if (need_lock) @@ -4254,7 +4289,23 @@ bool use_trans_cache(const THD* thd, bool is_transactional) */ bool ending_trans(THD* thd, const bool all) { - return (all || (!all && !thd->in_multi_stmt_transaction_mode())); + return (all || ending_single_stmt_trans(thd, all)); +} + +/** + This function checks if a single statement transaction is about + to commit or not. + + @param thd The client thread that executed the current statement. + @param all Committing a transaction (i.e. TRUE) or a statement + (i.e. FALSE). + @return + @c true if committing a single statement transaction, otherwise + @c false. +*/ +bool ending_single_stmt_trans(THD* thd, const bool all) +{ + return (!all && !thd->in_multi_stmt_transaction_mode()); } /** @@ -4306,7 +4357,7 @@ int THD::binlog_setup_trx_data() open_cached_file(&cache_mngr->trx_cache.cache_log, mysql_tmpdir, LOG_PREFIX, binlog_cache_size, MYF(MY_WME))) { - my_free((uchar*)cache_mngr, MYF(MY_ALLOW_ZERO_PTR)); + my_free(cache_mngr); DBUG_RETURN(1); // Didn't manage to set it up } thd_set_ha_data(this, binlog_hton, cache_mngr); @@ -4653,6 +4704,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) file= cache_mngr->get_binlog_cache_log(is_trans_cache); cache_data= cache_mngr->get_binlog_cache_data(is_trans_cache); + if (thd->stmt_accessed_non_trans_temp_table()) + cache_data->set_changes_to_non_trans_temp_table(); + thd->binlog_start_trans_and_stmt(); } DBUG_PRINT("info",("event type: %d",event_info->get_type_code())); @@ -5310,7 +5364,8 @@ void MYSQL_BIN_LOG::close(uint exiting) } } log_state= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED; - safeFree(name); + my_free(name); + name= NULL; DBUG_VOID_RETURN; } @@ -6001,7 +6056,7 @@ void TC_LOG_MMAP::close() mysql_cond_destroy(&pages[i].cond); } case 3: - my_free((uchar*)pages, MYF(0)); + my_free(pages); case 2: my_munmap((char*)data, (size_t)file_length); case 1: |