Commit 5fea8ffc authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-30100 preparation: Simplify InnoDB transaction commit further

trx_commit_complete_for_mysql(): Remove some conditions.
We will rely on trx_flush_log_if_needed().

trx_t::must_flush_log_later: Remove. trx_commit_complete_for_mysql()
can simply check for trx_t::flush_log_later.

trx_t::commit_in_memory(): Treat flush_log_later as input and output.

trx_flush_log_if_needed_low(): Renamed to trx_flush_log_if_needed().
Assert that innodb_flush_log_at_trx_commit!=0 was checked by
the caller and that the transaction is not in XA PREPARE state.

trx_write_serialisation_history(): Move some code from
trx_purge_add_undo_to_history().

trx_prepare(): Invoke log_write_up_to() directly if needed.

innobase_commit_ordered_2(): Remove a condition, and do not reset
trx_t::flush_log_later, because it must be passed from
trx_t::commit_in_memory() to trx_commit_complete_for_mysql().
parent be983bec
......@@ -4499,11 +4499,7 @@ innobase_commit_ordered_2(
#endif /* WITH_WSREP */
innobase_commit_low(trx);
if (!read_only) {
trx->mysql_log_file_name = NULL;
trx->flush_log_later = false;
}
DBUG_VOID_RETURN;
}
......
......@@ -772,12 +772,6 @@ struct trx_t : ilist_node<>
defer flush of the logs to disk
until after we release the
mutex. */
bool must_flush_log_later;/*!< set in commit()
if flush_log_later was
set and redo log was written;
in that case we will
flush the log in
trx_commit_complete_for_mysql() */
ulint duplicates; /*!< TRX_DUP_IGNORE | TRX_DUP_REPLACE */
/** whether this modifies InnoDB dictionary tables */
bool dict_operation;
......
......@@ -268,12 +268,7 @@ trx_purge_add_undo_to_history(const trx_t* trx, trx_undo_t*& undo, mtr_t* mtr)
ut_ad(mach_read_from_2(undo_header + TRX_UNDO_NEEDS_PURGE) <= 1);
ut_ad(rseg->needs_purge > trx->id);
if (rseg->last_page_no == FIL_NULL)
{
rseg->last_page_no= undo->hdr_page_no;
rseg->set_last_commit(undo->hdr_offset, trx->rw_trx_hash_element->no);
}
ut_ad(rseg->last_page_no != FIL_NULL);
rseg->history_size++;
......
......@@ -419,7 +419,6 @@ void trx_t::free()
MEM_NOACCESS(&active_commit_ordered, sizeof active_commit_ordered);
MEM_NOACCESS(&check_unique_secondary, sizeof check_unique_secondary);
MEM_NOACCESS(&flush_log_later, sizeof flush_log_later);
MEM_NOACCESS(&must_flush_log_later, sizeof must_flush_log_later);
MEM_NOACCESS(&duplicates, sizeof duplicates);
MEM_NOACCESS(&dict_operation, sizeof dict_operation);
MEM_NOACCESS(&dict_operation_lock_mode, sizeof dict_operation_lock_mode);
......@@ -993,12 +992,14 @@ static void trx_write_serialisation_history(trx_t *trx, mtr_t *mtr)
{
mysql_mutex_lock(&purge_sys.pq_mutex);
trx_sys.assign_new_trx_no(trx);
const trx_id_t end{trx->rw_trx_hash_element->no};
/* If the rollback segment is not empty, trx->no cannot be less
than any trx_t::no already in rseg. User threads only produce
events when a rollback segment is empty. */
purge_sys.purge_queue.push(TrxUndoRsegs(trx->rw_trx_hash_element->no,
*rseg));
purge_sys.purge_queue.push(TrxUndoRsegs{end, *rseg});
mysql_mutex_unlock(&purge_sys.pq_mutex);
rseg->last_page_no= undo->hdr_page_no;
rseg->set_last_commit(undo->hdr_offset, end);
}
else
trx_sys.assign_new_trx_no(trx);
......@@ -1086,10 +1087,10 @@ extern "C" void thd_decrement_pending_ops(MYSQL_THD);
@param trx transaction; 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, const trx_t *trx)
static void trx_flush_log_if_needed(lsn_t lsn, trx_t *trx)
{
if (!srv_flush_log_at_trx_commit)
return;
ut_ad(srv_flush_log_at_trx_commit);
ut_ad(trx->state != TRX_STATE_PREPARED);
if (log_sys.get_flushed_lsn() > lsn)
return;
......@@ -1097,39 +1098,18 @@ static void trx_flush_log_if_needed_low(lsn_t lsn, const trx_t *trx)
const 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.*/
sync:
log_write_up_to(lsn, flush);
return;
}
completion_callback cb;
if ((cb.m_param = thd_increment_pending_ops(trx->mysql_thd)))
if ((cb.m_param= thd_increment_pending_ops(trx->mysql_thd)))
{
cb.m_callback = (void (*)(void *)) thd_decrement_pending_ops;
log_write_up_to(lsn, flush, false, &cb);
}
else
goto sync;
}
/**********************************************************************//**
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(
/*====================*/
lsn_t lsn, /*!< in: lsn up to which logs are to be
flushed. */
trx_t* trx) /*!< in/out: transaction */
{
trx->op_info = "flushing log";
trx_flush_log_if_needed_low(lsn, trx);
trx->op_info = "";
{
trx->op_info= "flushing log";
log_write_up_to(lsn, flush);
trx->op_info= "";
}
}
/** Process tables that were modified by the committing transaction. */
......@@ -1239,7 +1219,6 @@ TRANSACTIONAL_INLINE inline void trx_t::commit_in_memory(const mtr_t *mtr)
{
/* We already detached from rseg in trx_write_serialisation_history() */
ut_ad(!rsegs.m_redo.undo);
must_flush_log_later= false;
read_view.close();
if (is_autocommit_non_locking())
......@@ -1343,11 +1322,9 @@ TRANSACTIONAL_INLINE inline void trx_t::commit_in_memory(const mtr_t *mtr)
commit_lsn= undo_no || !xid.is_null() ? mtr->commit_lsn() : 0;
if (!commit_lsn)
/* Nothing to be done. */;
else if (flush_log_later)
/* Do nothing yet */
must_flush_log_later= true;
else if (srv_flush_log_at_trx_commit)
flush_log_later= false;
else if (flush_log_later);
else if (!(flush_log_later= !srv_flush_log_at_trx_commit))
trx_flush_log_if_needed(commit_lsn, this);
}
......@@ -1603,16 +1580,18 @@ trx_commit_complete_for_mysql(
/*==========================*/
trx_t* trx) /*!< in/out: transaction */
{
if (trx->id != 0
|| !trx->must_flush_log_later
|| (srv_flush_log_at_trx_commit == 1 && trx->active_commit_ordered)) {
if (!trx->flush_log_later)
return;
trx->flush_log_later= false;
switch (srv_flush_log_at_trx_commit) {
case 0:
return;
case 1:
if (trx->active_commit_ordered)
return;
}
trx_flush_log_if_needed(trx->commit_lsn, trx);
trx->must_flush_log_later = false;
}
/**********************************************************************//**
......@@ -1873,8 +1852,10 @@ trx_prepare(
gather behind one doing the physical log write to disk.
We must not be holding any mutexes or latches here. */
trx_flush_log_if_needed(lsn, trx);
if (auto f = srv_flush_log_at_trx_commit) {
log_write_up_to(lsn, (f & 1) && srv_file_flush_method
!= SRV_NOSYNC);
}
if (!UT_LIST_GET_LEN(trx->lock.trx_locks)
|| trx->isolation_level == TRX_ISO_SERIALIZABLE) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment