summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc85
1 files changed, 63 insertions, 22 deletions
diff --git a/sql/log.cc b/sql/log.cc
index 92ffcc58961..18f812d96bf 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1576,7 +1576,7 @@ binlog_truncate_trx_cache(THD *thd, binlog_cache_mngr *cache_mngr, bool all)
inside a transaction, we reset the transaction cache.
*/
thd->binlog_remove_pending_rows_event(TRUE, is_transactional);
- if (all || !thd->in_multi_stmt_transaction())
+ if (ending_trans(thd, all))
{
if (cache_mngr->trx_cache.has_incident())
error= mysql_bin_log.write_incident(thd, TRUE);
@@ -1682,12 +1682,11 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
DBUG_ENTER("binlog_commit");
binlog_cache_mngr *const cache_mngr=
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
- bool const in_transaction= thd->in_multi_stmt_transaction();
DBUG_PRINT("debug",
("all: %d, in_transaction: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
all,
- YESNO(in_transaction),
+ YESNO(thd->in_multi_stmt_transaction()),
YESNO(thd->transaction.all.modified_non_trans_table),
YESNO(thd->transaction.stmt.modified_non_trans_table)));
@@ -1711,7 +1710,7 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
- We are in a transaction and a full transaction is committed.
Otherwise, we accumulate the changes.
*/
- if (!in_transaction || all)
+ if (ending_trans(thd, all))
{
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE, TRUE, 0);
error= binlog_flush_trx_cache(thd, cache_mngr, &qev);
@@ -1789,29 +1788,28 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
{
/*
We flush the cache wrapped in a beging/rollback if:
- . aborting a transcation that modified a non-transactional table or;
- . aborting a statement that modified both transactional and
- non-transctional tables but which is not in the boundaries of any
- transaction;
+ . 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.
*/
- if (thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
- ((all && thd->transaction.all.modified_non_trans_table) ||
- (!all && thd->transaction.stmt.modified_non_trans_table &&
- !thd->in_multi_stmt_transaction()) ||
- (thd->variables.option_bits & OPTION_KEEP_LOG)))
+ 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)))
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE, TRUE, 0);
error= binlog_flush_trx_cache(thd, cache_mngr, &qev);
}
/*
- Otherwise, we simply truncate the cache as there is no change on
- non-transactional tables as follows.
+ 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.
*/
- else if (all || (!all &&
- (!thd->transaction.stmt.modified_non_trans_table ||
- !thd->in_multi_stmt_transaction() ||
- thd->variables.binlog_format != BINLOG_FORMAT_STMT)))
+ 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))))
error= binlog_truncate_trx_cache(thd, cache_mngr, all);
}
@@ -1909,7 +1907,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
non-transactional table. Otherwise, truncate the binlog cache starting
from the SAVEPOINT command.
*/
- if (unlikely(thd->transaction.all.modified_non_trans_table ||
+ if (unlikely(trans_has_updated_non_trans_table(thd) ||
(thd->variables.option_bits & OPTION_KEEP_LOG)))
{
int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
@@ -4257,6 +4255,49 @@ bool use_trans_cache(const THD* thd, bool is_transactional)
(is_transactional || !cache_mngr->trx_cache.empty()));
}
+/**
+ This function checks if a transaction, either a multi-statement
+ or 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 transaction, otherwise @c false.
+*/
+bool ending_trans(THD* thd, const bool all)
+{
+ return (all || (!all && !thd->in_multi_stmt_transaction()));
+}
+
+/**
+ This function checks if a non-transactional table was updated by
+ the current transaction.
+
+ @param thd The client thread that executed the current statement.
+ @return
+ @c true if a non-transactional table was updated, @c false
+ otherwise.
+*/
+bool trans_has_updated_non_trans_table(const THD* thd)
+{
+ return (thd->transaction.all.modified_non_trans_table ||
+ thd->transaction.stmt.modified_non_trans_table);
+}
+
+/**
+ This function checks if a non-transactional table was updated by the
+ current statement.
+
+ @param thd The client thread that executed the current statement.
+ @return
+ @c true if a non-transactional table was updated, @c false otherwise.
+*/
+bool stmt_has_updated_non_trans_table(const THD* thd)
+{
+ return (thd->transaction.stmt.modified_non_trans_table);
+}
+
/*
These functions are placed in this file since they need access to
binlog_hton, which has internal linkage.
@@ -4539,7 +4580,7 @@ MYSQL_BIN_LOG::flush_and_set_pending_rows_event(THD *thd,
{
set_write_error(thd);
if (check_write_error(thd) && cache_data &&
- thd->transaction.stmt.modified_non_trans_table)
+ stmt_has_updated_non_trans_table(thd))
cache_data->set_incident();
DBUG_RETURN(1);
}
@@ -4740,7 +4781,7 @@ unlock:
{
set_write_error(thd);
if (check_write_error(thd) && cache_data &&
- thd->transaction.stmt.modified_non_trans_table)
+ stmt_has_updated_non_trans_table(thd))
cache_data->set_incident();
}
}