diff options
author | Sergei Golubchik <sergii@pisem.net> | 2011-07-18 23:04:24 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2011-07-18 23:04:24 +0200 |
commit | 4e46d8e5bff140f2549841167dc4b65a3c0a645d (patch) | |
tree | c6612dcc1d0fbd801c084e6c36307d9e5913a293 /storage/xtradb/mtr | |
parent | 9a02c69f5c6766eaf552284a2a4dd0f1d26ecd2c (diff) | |
parent | d4d7a8fa62c406be73f6c0f6d75e795293db548b (diff) | |
download | mariadb-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.c | 24 | ||||
-rw-r--r-- | storage/xtradb/mtr/mtr0mtr.c | 166 |
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 /**********************************************************//** |