summaryrefslogtreecommitdiff
path: root/storage/xtradb/mtr/mtr0mtr.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/xtradb/mtr/mtr0mtr.c')
-rw-r--r--storage/xtradb/mtr/mtr0mtr.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/storage/xtradb/mtr/mtr0mtr.c b/storage/xtradb/mtr/mtr0mtr.c
index 092bd702115..9eb7b18f301 100644
--- a/storage/xtradb/mtr/mtr0mtr.c
+++ b/storage/xtradb/mtr/mtr0mtr.c
@@ -38,6 +38,25 @@ Created 11/26/1995 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
# include "log0recv.h"
+
+/***************************************************//**
+Checks if a mini-transaction is dirtying a clean page.
+@return TRUE if the mtr is dirtying a clean page. */
+UNIV_INTERN
+ibool
+mtr_block_dirtied(
+/*==============*/
+ const buf_block_t* block) /*!< in: block being x-fixed */
+{
+ ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
+ ut_ad(block->page.buf_fix_count > 0);
+
+ /* It is OK to read oldest_modification because no
+ other thread can be performing a write of it and it
+ is only during write that the value is reset to 0. */
+ return(block->page.oldest_modification == 0);
+}
+
/*****************************************************************//**
Releases the item in the slot given. */
static
@@ -126,7 +145,7 @@ mtr_memo_slot_note_modification(
buf_block_t* block = (buf_block_t*) slot->object;
#ifdef UNIV_DEBUG
- ut_ad(log_flush_order_mutex_own());
+ ut_ad(!mtr->made_dirty || log_flush_order_mutex_own());
#endif /* UNIV_DEBUG */
buf_flush_note_modification(block, mtr);
}
@@ -202,12 +221,14 @@ mtr_log_reserve_and_write(
Add pages to flush list and exit */
goto func_exit;
}
+ } else {
+ mutex_enter(&log_sys->mutex);
}
data_size = dyn_array_get_data_size(mlog);
/* Open the database log for log_write_low */
- mtr->start_lsn = log_reserve_and_open(data_size);
+ mtr->start_lsn = log_open(data_size);
if (mtr->log_mode == MTR_LOG_ALL) {
@@ -226,7 +247,15 @@ mtr_log_reserve_and_write(
mtr->end_lsn = log_close();
func_exit:
- log_flush_order_mutex_enter();
+
+ /* No need to acquire log_flush_order_mutex if this mtr has
+ not dirtied a clean page. log_flush_order_mutex is used to
+ ensure ordered insertions in the flush_list. We need to
+ insert in the flush_list iff the page in question was clean
+ before modifications. */
+ if (mtr->made_dirty) {
+ log_flush_order_mutex_enter();
+ }
/* It is now safe to release the log mutex because the
flush_order mutex will ensure that we are the first one
@@ -237,7 +266,9 @@ func_exit:
mtr_memo_note_modifications(mtr);
}
- log_flush_order_mutex_exit();
+ if (mtr->made_dirty) {
+ log_flush_order_mutex_exit();
+ }
}
#endif /* !UNIV_HOTBACKUP */