diff options
author | Alfranio Correia <alfranio.correia@sun.com> | 2010-06-17 01:25:07 +0100 |
---|---|---|
committer | Alfranio Correia <alfranio.correia@sun.com> | 2010-06-17 01:25:07 +0100 |
commit | cdc4e9ebce32aa41cef21d2f821959d6cd08e064 (patch) | |
tree | 5072ba6ab5f2c0a1a636b09f62d1a845e9847eb2 /sql/log.cc | |
parent | d2e58e4e49f4c42c3c6b1220ccc0004ed6963192 (diff) | |
parent | 3f8bde448c6b97f073576e1283224c3058320dea (diff) | |
download | mariadb-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.cc | 108 |
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 |