summaryrefslogtreecommitdiff
path: root/storage/innobase/trx/trx0trx.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/trx/trx0trx.cc')
-rw-r--r--storage/innobase/trx/trx0trx.cc122
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();