summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
authorDavi Arnaut <Davi.Arnaut@Sun.COM>2010-07-15 10:47:50 -0300
committerDavi Arnaut <Davi.Arnaut@Sun.COM>2010-07-15 10:47:50 -0300
commit649390ac814ce5ea1e77b833ab5fe92dfcfe86d5 (patch)
treeac8b15ac65b08a492c256369b73e372f6568c7a4 /sql/log.cc
parent06b8897e8e9a27b6ffc562af90153ab63f30e63e (diff)
parent8df20918d6751dc1eeb47ab722269dbd9d2da297 (diff)
downloadmariadb-git-649390ac814ce5ea1e77b833ab5fe92dfcfe86d5.tar.gz
Merge of mysql-trunk-bugfixing into mysql-trunk-merge.
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc95
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: