summaryrefslogtreecommitdiff
path: root/sql/log.cc
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@sun.com>2010-06-17 01:25:07 +0100
committerAlfranio Correia <alfranio.correia@sun.com>2010-06-17 01:25:07 +0100
commitcdc4e9ebce32aa41cef21d2f821959d6cd08e064 (patch)
tree5072ba6ab5f2c0a1a636b09f62d1a845e9847eb2 /sql/log.cc
parentd2e58e4e49f4c42c3c6b1220ccc0004ed6963192 (diff)
parent3f8bde448c6b97f073576e1283224c3058320dea (diff)
downloadmariadb-git-cdc4e9ebce32aa41cef21d2f821959d6cd08e064.tar.gz
merge mysql-5.1-bugteam (local) --> mysql-5.1-bugteam
Diffstat (limited to 'sql/log.cc')
-rw-r--r--sql/log.cc108
1 files changed, 82 insertions, 26 deletions
diff --git a/sql/log.cc b/sql/log.cc
index 7d820b48c43..b3554d2a068 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -1510,27 +1510,23 @@ static int binlog_commit(handlerton *hton, THD *thd, bool all)
}
/*
- We commit the transaction if:
+ We flush the cache if:
- - We are not in a transaction and committing a statement, or
+ - we are committing a transaction or;
+ - no statement was committed before and just non-transactional
+ tables were updated.
- - We are in a transaction and a full transaction is committed
-
- Otherwise, we accumulate the statement
+ Otherwise, we collect the changes.
*/
- ulonglong const in_transaction=
- thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN);
DBUG_PRINT("debug",
- ("all: %d, empty: %s, in_transaction: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
+ ("all: %d, empty: %s, all.modified_non_trans_table: %s, stmt.modified_non_trans_table: %s",
all,
YESNO(trx_data->empty()),
- YESNO(in_transaction),
YESNO(thd->transaction.all.modified_non_trans_table),
YESNO(thd->transaction.stmt.modified_non_trans_table)));
- 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))
+ if (ending_trans(thd, all) ||
+ (trans_has_no_stmt_committed(thd, all) &&
+ !stmt_has_updated_trans_table(thd) && stmt_has_updated_non_trans_table(thd)))
{
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, TRUE, 0);
error= binlog_end_trans(thd, trx_data, &qev, all);
@@ -1593,7 +1589,7 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
On the other hand, if a statement is transactional, we just safely roll it
back.
*/
- if ((thd->transaction.stmt.modified_non_trans_table ||
+ if ((stmt_has_updated_non_trans_table(thd) ||
(thd->options & OPTION_KEEP_LOG)) &&
mysql_bin_log.check_write_error(thd))
trx_data->set_incident();
@@ -1603,19 +1599,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 transaction that modified a non-transactional table;
+ . aborting a transaction that modified a non-transactional table or
+ the OPTION_KEEP_LOG is activate.
. aborting a statement that modified both transactional and
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)))
+ if ((ending_trans(thd, all) &&
+ (trans_has_updated_non_trans_table(thd) ||
+ (thd->options & OPTION_KEEP_LOG))) ||
+ (trans_has_no_stmt_committed(thd, all) &&
+ stmt_has_updated_non_trans_table(thd) &&
+ thd->current_stmt_binlog_row_based))
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, TRUE, 0);
error= binlog_end_trans(thd, trx_data, &qev, all);
@@ -1624,8 +1619,8 @@ static int binlog_rollback(handlerton *hton, THD *thd, bool all)
Otherwise, we simply truncate the cache as there is no change on
non-transactional tables as follows.
*/
- else if ((all && !thd->transaction.all.modified_non_trans_table) ||
- (!all && !thd->transaction.stmt.modified_non_trans_table))
+ else if (ending_trans(thd, all) ||
+ (!(thd->options & OPTION_KEEP_LOG) && !stmt_has_updated_non_trans_table(thd)))
error= binlog_end_trans(thd, trx_data, 0, all);
}
if (!all)
@@ -1721,7 +1716,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->options & OPTION_KEEP_LOG)))
{
String log_query;
@@ -3934,6 +3929,67 @@ bool MYSQL_BIN_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
query_id_param >= thd->binlog_evt_union.first_query_id);
}
+/**
+ 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(const THD* thd, const bool all)
+{
+ return (all || (!all && !(thd->options &
+ (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))));
+}
+
+/**
+ 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 any statement was committed and cached.
+
+ @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 at a statement was committed and cached, @c false
+ otherwise.
+*/
+bool trans_has_no_stmt_committed(const THD* thd, bool all)
+{
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton);
+
+ return (!all && !trx_data->at_least_one_stmt_committed);
+}
+
+/**
+ 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