summaryrefslogtreecommitdiff
path: root/storage/xtradb/mtr
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-07-18 23:04:24 +0200
committerSergei Golubchik <sergii@pisem.net>2011-07-18 23:04:24 +0200
commit4e46d8e5bff140f2549841167dc4b65a3c0a645d (patch)
treec6612dcc1d0fbd801c084e6c36307d9e5913a293 /storage/xtradb/mtr
parent9a02c69f5c6766eaf552284a2a4dd0f1d26ecd2c (diff)
parentd4d7a8fa62c406be73f6c0f6d75e795293db548b (diff)
downloadmariadb-git-4e46d8e5bff140f2549841167dc4b65a3c0a645d.tar.gz
merge with xtradb-5.5.15
fix test cases
Diffstat (limited to 'storage/xtradb/mtr')
-rw-r--r--storage/xtradb/mtr/mtr0log.c24
-rw-r--r--storage/xtradb/mtr/mtr0mtr.c166
2 files changed, 107 insertions, 83 deletions
diff --git a/storage/xtradb/mtr/mtr0log.c b/storage/xtradb/mtr/mtr0log.c
index d22015a575f..864970cef40 100644
--- a/storage/xtradb/mtr/mtr0log.c
+++ b/storage/xtradb/mtr/mtr0log.c
@@ -133,7 +133,7 @@ mlog_parse_initial_log_record(
}
/********************************************************//**
-Parses a log record written by mlog_write_ulint or mlog_write_dulint.
+Parses a log record written by mlog_write_ulint or mlog_write_ull.
@return parsed record end, NULL if not a complete record or a corrupt record */
UNIV_INTERN
byte*
@@ -145,9 +145,9 @@ mlog_parse_nbytes(
byte* page, /*!< in: page where to apply the log record, or NULL */
void* page_zip)/*!< in/out: compressed page, or NULL */
{
- ulint offset;
- ulint val;
- dulint dval;
+ ulint offset;
+ ulint val;
+ ib_uint64_t dval;
ut_a(type <= MLOG_8BYTES);
ut_a(!page || !page_zip || fil_page_get_type(page) != FIL_PAGE_INDEX);
@@ -167,7 +167,7 @@ mlog_parse_nbytes(
}
if (type == MLOG_8BYTES) {
- ptr = mach_dulint_parse_compressed(ptr, end_ptr, &dval);
+ ptr = mach_ull_parse_compressed(ptr, end_ptr, &dval);
if (ptr == NULL) {
@@ -290,11 +290,11 @@ Writes 8 bytes to a file page buffered in the buffer pool.
Writes the corresponding log record to the mini-transaction log. */
UNIV_INTERN
void
-mlog_write_dulint(
-/*==============*/
- byte* ptr, /*!< in: pointer where to write */
- dulint val, /*!< in: value to write */
- mtr_t* mtr) /*!< in: mini-transaction handle */
+mlog_write_ull(
+/*===========*/
+ byte* ptr, /*!< in: pointer where to write */
+ ib_uint64_t val, /*!< in: value to write */
+ mtr_t* mtr) /*!< in: mini-transaction handle */
{
byte* log_ptr;
@@ -316,7 +316,7 @@ mlog_write_dulint(
mach_write_to_2(log_ptr, page_offset(ptr));
log_ptr += 2;
- log_ptr += mach_dulint_write_compressed(log_ptr, val);
+ log_ptr += mach_ull_write_compressed(log_ptr, val);
mlog_close(mtr, log_ptr);
}
@@ -408,7 +408,7 @@ mlog_parse_string(
ptr += 2;
if (UNIV_UNLIKELY(offset >= UNIV_PAGE_SIZE)
- || UNIV_UNLIKELY(len + offset > UNIV_PAGE_SIZE)) {
+ || UNIV_UNLIKELY(len + offset > UNIV_PAGE_SIZE)) {
recv_sys->found_corrupt_log = TRUE;
return(NULL);
diff --git a/storage/xtradb/mtr/mtr0mtr.c b/storage/xtradb/mtr/mtr0mtr.c
index 34e6d3ffc92..5c946ebd756 100644
--- a/storage/xtradb/mtr/mtr0mtr.c
+++ b/storage/xtradb/mtr/mtr0mtr.c
@@ -30,6 +30,7 @@ Created 11/26/1995 Heikki Tuuri
#endif
#include "buf0buf.h"
+#include "buf0flu.h"
#include "page0types.h"
#include "mtr0log.h"
#include "log0log.h"
@@ -39,7 +40,7 @@ Created 11/26/1995 Heikki Tuuri
# include "log0recv.h"
/*****************************************************************//**
Releases the item in the slot given. */
-UNIV_INLINE
+static
void
mtr_memo_slot_release(
/*==================*/
@@ -49,14 +50,19 @@ mtr_memo_slot_release(
void* object;
ulint type;
- ut_ad(mtr && slot);
+ ut_ad(mtr);
+ ut_ad(slot);
+
+#ifndef UNIV_DEBUG
+ UT_NOT_USED(mtr);
+#endif /* UNIV_DEBUG */
object = slot->object;
type = slot->type;
if (UNIV_LIKELY(object != NULL)) {
if (type <= MTR_MEMO_BUF_FIX) {
- buf_page_release((buf_block_t*)object, type, mtr);
+ buf_page_release((buf_block_t*)object, type);
} else if (type == MTR_MEMO_S_LOCK) {
rw_lock_s_unlock((rw_lock_t*)object);
#ifdef UNIV_DEBUG
@@ -74,13 +80,10 @@ mtr_memo_slot_release(
}
/**********************************************************//**
-Releases the mlocks and other objects stored in an mtr memo. They are released
-in the order opposite to which they were pushed to the memo. NOTE! It is
-essential that the x-rw-lock on a modified buffer page is not released before
-buf_page_note_modification is called for that page! Otherwise, some thread
-might race to modify it, and the flush list sort order on lsn would be
-destroyed. */
-UNIV_INLINE
+Releases the mlocks and other objects stored in an mtr memo.
+They are released in the order opposite to which they were pushed
+to the memo. */
+static
void
mtr_memo_pop_all(
/*=============*/
@@ -106,13 +109,42 @@ mtr_memo_pop_all(
}
}
-UNIV_INLINE
+/*****************************************************************//**
+Releases the item in the slot given. */
+static
void
-mtr_memo_note_modification_all(
-/*===========================*/
- mtr_t* mtr) /* in: mtr */
+mtr_memo_slot_note_modification(
+/*============================*/
+ mtr_t* mtr, /*!< in: mtr */
+ mtr_memo_slot_t* slot) /*!< in: memo slot */
+{
+ ut_ad(mtr);
+ ut_ad(mtr->magic_n == MTR_MAGIC_N);
+ ut_ad(mtr->modifications);
+
+ if (slot->object != NULL && slot->type == MTR_MEMO_PAGE_X_FIX) {
+ buf_block_t* block = (buf_block_t*) slot->object;
+
+#ifdef UNIV_DEBUG
+ ut_ad(log_flush_order_mutex_own());
+#endif /* UNIV_DEBUG */
+ buf_flush_note_modification(block, mtr);
+ }
+}
+
+/**********************************************************//**
+Add the modified pages to the buffer flush list. They are released
+in the order opposite to which they were pushed to the memo. NOTE! It is
+essential that the x-rw-lock on a modified buffer page is not released
+before buf_page_note_modification is called for that page! Otherwise,
+some thread might race to modify it, and the flush list sort order on
+lsn would be destroyed. */
+static
+void
+mtr_memo_note_modifications(
+/*========================*/
+ mtr_t* mtr) /*!< in: mtr */
{
- mtr_memo_slot_t* slot;
dyn_array_t* memo;
ulint offset;
@@ -120,21 +152,17 @@ mtr_memo_note_modification_all(
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
commit */
- ut_ad(mtr->modifications);
-
- memo = &(mtr->memo);
+ memo = &mtr->memo;
offset = dyn_array_get_data_size(memo);
while (offset > 0) {
+ mtr_memo_slot_t* slot;
+
offset -= sizeof(mtr_memo_slot_t);
slot = dyn_array_get_element(memo, offset);
- if (UNIV_LIKELY(slot->object != NULL) &&
- slot->type == MTR_MEMO_PAGE_X_FIX) {
- buf_flush_note_modification(
- (buf_block_t*)slot->object, mtr);
- }
+ mtr_memo_slot_note_modification(mtr, slot);
}
}
@@ -170,7 +198,9 @@ mtr_log_reserve_and_write(
&mtr->start_lsn);
if (mtr->end_lsn) {
- return;
+ /* Success. We have the log mutex.
+ Add pages to flush list and exit */
+ goto func_exit;
}
}
@@ -194,6 +224,20 @@ mtr_log_reserve_and_write(
}
mtr->end_lsn = log_close();
+
+func_exit:
+ 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
+ to insert into the flush list. */
+ log_release();
+
+ if (mtr->modifications) {
+ mtr_memo_note_modifications(mtr);
+ }
+
+ log_flush_order_mutex_exit();
}
#endif /* !UNIV_HOTBACKUP */
@@ -205,46 +249,37 @@ mtr_commit(
/*=======*/
mtr_t* mtr) /*!< in: mini-transaction */
{
-#ifndef UNIV_HOTBACKUP
- ibool write_log;
-#endif /* !UNIV_HOTBACKUP */
-
ut_ad(mtr);
ut_ad(mtr->magic_n == MTR_MAGIC_N);
ut_ad(mtr->state == MTR_ACTIVE);
+ ut_ad(!mtr->inside_ibuf);
ut_d(mtr->state = MTR_COMMITTING);
#ifndef UNIV_HOTBACKUP
/* This is a dirty read, for debugging. */
ut_ad(!recv_no_log_write);
- write_log = mtr->modifications && mtr->n_log_recs;
- if (write_log) {
+ if (mtr->modifications && mtr->n_log_recs) {
mtr_log_reserve_and_write(mtr);
-
- mtr_memo_note_modification_all(mtr);
- }
-
- /* We first update the modification info to buffer pages, and only
- after that release the log mutex: this guarantees that when the log
- mutex is free, all buffer pages contain an up-to-date info of their
- modifications. This fact is used in making a checkpoint when we look
- at the oldest modification of any page in the buffer pool. It is also
- required when we insert modified buffer pages in to the flush list
- which must be sorted on oldest_modification. */
-
- if (write_log) {
- log_release();
}
- /* All unlocking has been moved here, after log_sys mutex release. */
mtr_memo_pop_all(mtr);
-
#endif /* !UNIV_HOTBACKUP */
- ut_d(mtr->state = MTR_COMMITTED);
dyn_array_free(&(mtr->memo));
dyn_array_free(&(mtr->log));
+#ifdef UNIV_DEBUG_VALGRIND
+ /* Declare everything uninitialized except
+ mtr->start_lsn, mtr->end_lsn and mtr->state. */
+ {
+ ib_uint64_t start_lsn = mtr->start_lsn;
+ ib_uint64_t end_lsn = mtr->end_lsn;
+ UNIV_MEM_INVALID(mtr, sizeof *mtr);
+ mtr->start_lsn = start_lsn;
+ mtr->end_lsn = end_lsn;
+ }
+#endif /* UNIV_DEBUG_VALGRIND */
+ ut_d(mtr->state = MTR_COMMITTED);
}
#ifndef UNIV_HOTBACKUP
@@ -278,6 +313,10 @@ mtr_rollback_to_savepoint(
slot = dyn_array_get_element(memo, offset);
ut_ad(slot->type != MTR_MEMO_MODIFY);
+
+ /* We do not call mtr_memo_slot_note_modification()
+ because there MUST be no changes made to the buffer
+ pages after the savepoint */
mtr_memo_slot_release(mtr, slot);
}
}
@@ -304,24 +343,26 @@ mtr_memo_release(
offset = dyn_array_get_data_size(memo);
+ log_flush_order_mutex_enter();
while (offset > 0) {
offset -= sizeof(mtr_memo_slot_t);
slot = dyn_array_get_element(memo, offset);
- if ((object == slot->object) && (type == slot->type)) {
- if (mtr->modifications &&
- UNIV_LIKELY(slot->object != NULL) &&
- slot->type == MTR_MEMO_PAGE_X_FIX) {
- buf_flush_note_modification(
- (buf_block_t*)slot->object, mtr);
- }
+ if (object == slot->object && type == slot->type) {
+
+ /* We cannot release a page that has been written
+ to in the middle of a mini-transaction. */
+
+ ut_ad(!(mtr->modifications
+ && slot->type == MTR_MEMO_PAGE_X_FIX));
mtr_memo_slot_release(mtr, slot);
break;
}
}
+ log_flush_order_mutex_exit();
}
#endif /* !UNIV_HOTBACKUP */
@@ -350,23 +391,6 @@ mtr_read_ulint(
}
}
-/********************************************************//**
-Reads 8 bytes from a file page buffered in the buffer pool.
-@return value read */
-UNIV_INTERN
-dulint
-mtr_read_dulint(
-/*============*/
- const byte* ptr, /*!< in: pointer from where to read */
- mtr_t* mtr __attribute__((unused)))
- /*!< in: mini-transaction handle */
-{
- ut_ad(mtr->state == MTR_ACTIVE);
- ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
- || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
- return(mach_read_from_8(ptr));
-}
-
#ifdef UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
/**********************************************************//**