summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc40
1 files changed, 23 insertions, 17 deletions
diff --git a/sql/log.cc b/sql/log.cc
index 1af2f3a4ddc..e8366c47863 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -153,7 +153,7 @@ private:
class binlog_trx_data {
public:
binlog_trx_data()
- : at_least_one_stmt(0), incident(FALSE), m_pending(0),
+ : at_least_one_stmt_committed(0), incident(FALSE), m_pending(0),
before_stmt_pos(MY_OFF_T_UNDEF)
{
trans_log.end_of_file= max_binlog_cache_size;
@@ -182,7 +182,10 @@ public:
{
DBUG_PRINT("info", ("truncating to position %lu", (ulong) pos));
DBUG_PRINT("info", ("before_stmt_pos=%lu", (ulong) pos));
- delete pending();
+ if (pending())
+ {
+ delete pending();
+ }
set_pending(0);
reinit_io_cache(&trans_log, WRITE_CACHE, pos, 0, 0);
trans_log.end_of_file= max_binlog_cache_size;
@@ -192,12 +195,12 @@ public:
/*
The only valid positions that can be truncated to are at the
beginning of a statement. We are relying on this fact to be able
- to set the at_least_one_stmt flag correctly. In other word, if
+ to set the at_least_one_stmt_committed flag correctly. In other word, if
we are truncating to the beginning of the transaction cache,
there will be no statements in the cache, otherwhise, we will
have at least one statement in the transaction cache.
*/
- at_least_one_stmt= (pos > 0);
+ at_least_one_stmt_committed= (pos > 0);
}
/*
@@ -239,7 +242,7 @@ public:
Boolean that is true if there is at least one statement in the
transaction cache.
*/
- bool at_least_one_stmt;
+ bool at_least_one_stmt_committed;
bool incident;
private:
@@ -1024,14 +1027,10 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
Log_event_handler **current_handler= general_log_handler_list;
char user_host_buff[MAX_USER_HOST_SIZE + 1];
Security_context *sctx= thd->security_ctx;
- ulong id;
uint user_host_len= 0;
time_t current_time;
- if (thd)
- id= thd->thread_id; /* Normal thread */
- else
- id= 0; /* Log from connect handler */
+ DBUG_ASSERT(thd);
lock_shared();
if (!opt_log)
@@ -1050,7 +1049,7 @@ bool LOGGER::general_log_write(THD *thd, enum enum_server_command command,
while (*current_handler)
error|= (*current_handler++)->
log_general(thd, current_time, user_host_buff,
- user_host_len, id,
+ user_host_len, thd->thread_id,
command_name[(uint) command].str,
command_name[(uint) command].length,
query, query_length,
@@ -1276,7 +1275,7 @@ static bool stmt_has_updated_trans_table(THD *thd)
{
Ha_trx_info *ha_info;
- for (ha_info= thd->transaction.stmt.ha_list; ha_info; ha_info= ha_info->next())
+ for (ha_info= thd->transaction.stmt.ha_list; ha_info && ha_info->is_started(); ha_info= ha_info->next())
{
if (ha_info->is_trx_read_write() && ha_info->ht() != binlog_hton)
return (TRUE);
@@ -1539,13 +1538,17 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
YESNO(in_transaction),
YESNO(thd->transaction.all.modified_non_trans_table),
YESNO(thd->transaction.stmt.modified_non_trans_table)));
- if (!in_transaction || all)
+ if (!in_transaction || all ||
+ (!all && !trx_data->at_least_one_stmt_committed &&
+ !stmt_has_updated_trans_table(thd) &&
+ thd->transaction.stmt.modified_non_trans_table))
{
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
error= binlog_end_trans(thd, trx_data, &qev, all);
- goto end;
}
+ trx_data->at_least_one_stmt_committed = my_b_tell(&trx_data->trans_log) > 0;
+
end:
if (!all)
trx_data->before_stmt_pos = MY_OFF_T_UNDEF; // part of the stmt commit
@@ -1612,15 +1615,18 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
{
/*
We flush the cache with a rollback, wrapped in a beging/rollback if:
- . aborting a transcation that modified a non-transactional table or;
+ . aborting a transaction that modified a non-transactional table;
. aborting a statement that modified both transactional and
- non-transctional tables but which is not in the boundaries of any
- transaction;
+ non-transactional tables but which is not in the boundaries of any
+ transaction or there was no early change;
. the OPTION_KEEP_LOG is activate.
*/
if ((all && thd->transaction.all.modified_non_trans_table) ||
(!all && thd->transaction.stmt.modified_non_trans_table &&
!(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) ||
+ (!all && thd->transaction.stmt.modified_non_trans_table &&
+ !trx_data->at_least_one_stmt_committed &&
+ thd->current_stmt_binlog_row_based) ||
((thd->options & OPTION_KEEP_LOG)))
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);