diff options
Diffstat (limited to 'storage/innobase/trx/trx0trx.cc')
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 122 |
1 files changed, 69 insertions, 53 deletions
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 2d9a7d43408..413668e0359 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1162,35 +1162,49 @@ trx_finalize_for_fts( trx->fts_trx = NULL; } -/**********************************************************************//** -If required, flushes the log to disk based on the value of -innodb_flush_log_at_trx_commit. */ -static -void -trx_flush_log_if_needed_low( -/*========================*/ - lsn_t lsn) /*!< in: lsn up to which logs are to be - flushed. */ +extern "C" MYSQL_THD thd_increment_pending_ops(); +extern "C" void thd_decrement_pending_ops(MYSQL_THD); + + +#include "../log/log0sync.h" + +/* + If required, initiates write and optionally flush of the log to + disk + @param[in] lsn - lsn up to which logs are to be flushed. + @param[in] trx_state - if trx_state is PREPARED, the function will + also wait for the flush to complete. +*/ +static void trx_flush_log_if_needed_low(lsn_t lsn, trx_state_t trx_state) { - bool flush = srv_file_flush_method != SRV_NOSYNC; + if (!srv_flush_log_at_trx_commit) + return; - switch (srv_flush_log_at_trx_commit) { - case 3: - case 2: - /* Write the log but do not flush it to disk */ - flush = false; - /* fall through */ - case 1: - /* Write the log and optionally flush it to disk */ - log_write_up_to(lsn, flush); - srv_inc_activity_count(); - return; - case 0: - /* Do nothing */ - return; - } + if (log_sys.get_flushed_lsn() > lsn) + return; - ut_error; + bool flush= srv_file_flush_method != SRV_NOSYNC && + srv_flush_log_at_trx_commit == 1; + + if (trx_state == TRX_STATE_PREPARED) + { + /* XA, which is used with binlog as well. + Be conservative, use synchronous wait.*/ + log_write_up_to(lsn, flush); + return; + } + + completion_callback cb; + if ((cb.m_param = thd_increment_pending_ops())) + { + cb.m_callback = (void (*)(void *)) thd_decrement_pending_ops; + log_write_up_to(lsn, flush, false, &cb); + } + else + { + /* No THD, synchronous write */ + log_write_up_to(lsn, flush); + } } /**********************************************************************//** @@ -1205,51 +1219,53 @@ trx_flush_log_if_needed( trx_t* trx) /*!< in/out: transaction */ { trx->op_info = "flushing log"; - trx_flush_log_if_needed_low(lsn); + trx_flush_log_if_needed_low(lsn,trx->state); trx->op_info = ""; } /** Process tables that were modified by the committing transaction. */ inline void trx_t::commit_tables() { - if (!undo_no || mod_tables.empty()) + if (mod_tables.empty()) return; + if (undo_no) + { #if defined SAFE_MUTEX && defined UNIV_DEBUG - const bool preserve_tables= !innodb_evict_tables_on_commit_debug || - is_recovered || /* avoid trouble with XA recovery */ + const bool preserve_tables= !innodb_evict_tables_on_commit_debug || + is_recovered || /* avoid trouble with XA recovery */ # if 1 /* if dict_stats_exec_sql() were not playing dirty tricks */ - dict_sys.mutex_is_locked(); + dict_sys.mutex_is_locked(); # else /* this would be more proper way to do it */ - dict_operation_lock_mode || dict_operation; + dict_operation_lock_mode || dict_operation; # endif #endif - const trx_id_t max_trx_id= trx_sys.get_max_trx_id(); - const auto now= start_time; + const trx_id_t max_trx_id= trx_sys.get_max_trx_id(); + const auto now= start_time; - for (const auto& p : mod_tables) - { - dict_table_t *table= p.first; - table->update_time= now; - table->query_cache_inv_trx_id= max_trx_id; + for (const auto& p : mod_tables) + { + dict_table_t *table= p.first; + table->update_time= now; + table->query_cache_inv_trx_id= max_trx_id; #if defined SAFE_MUTEX && defined UNIV_DEBUG - if (preserve_tables || table->get_ref_count() || table->is_temporary() || - UT_LIST_GET_LEN(table->locks)) - /* do not evict when committing DDL operations or if some other - transaction is holding the table handle */ - continue; - /* recheck while holding the mutex that blocks - table->acquire() */ - dict_sys.mutex_lock(); - { - LockMutexGuard g{SRW_LOCK_CALL}; - if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks)) - dict_sys.remove(table, true); - } - dict_sys.mutex_unlock(); + if (preserve_tables || table->get_ref_count() || table->is_temporary() || + UT_LIST_GET_LEN(table->locks)) + /* do not evict when committing DDL operations or if some other + transaction is holding the table handle */ + continue; + /* recheck while holding the mutex that blocks table->acquire() */ + dict_sys.mutex_lock(); + { + LockMutexGuard g{SRW_LOCK_CALL}; + if (!table->get_ref_count() && !UT_LIST_GET_LEN(table->locks)) + dict_sys.remove(table, true); + } + dict_sys.mutex_unlock(); #endif + } } mod_tables.clear(); |