diff options
-rw-r--r-- | storage/innobase/include/buf0buf.ic | 4 | ||||
-rw-r--r-- | storage/innobase/include/mtr0log.ic | 4 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 9 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.ic | 2 | ||||
-rw-r--r-- | storage/innobase/include/mtr0types.h | 2 | ||||
-rw-r--r-- | storage/innobase/mtr/mtr0mtr.cc | 130 |
6 files changed, 121 insertions, 30 deletions
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 49b741ab5c8..c8c71997c8f 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -1372,6 +1372,10 @@ buf_page_release_latch( } else if (rw_latch == RW_X_LATCH) { rw_lock_x_unlock(&block->lock); } +#ifdef UNIV_DEBUG + else + assert(rw_latch == RW_NO_LATCH); +#endif } #ifdef UNIV_DEBUG diff --git a/storage/innobase/include/mtr0log.ic b/storage/innobase/include/mtr0log.ic index 5cfc08622d5..0864c373731 100644 --- a/storage/innobase/include/mtr0log.ic +++ b/storage/innobase/include/mtr0log.ic @@ -191,6 +191,8 @@ mlog_write_initial_log_record_low( || type == MLOG_FILE_WRITE_CRYPT_DATA || mtr->is_named_space(space_id)); +// mtr->memo_modify_page(space_id, page_no); + mach_write_to_1(log_ptr, type); log_ptr++; @@ -223,7 +225,7 @@ mlog_write_initial_log_record_fast( ulint offset; ut_ad(log_ptr); - ut_d(mtr->memo_modify_page(ptr)); + mtr->memo_modify_page(ptr); page = (const byte*) ut_align_down(ptr, UNIV_PAGE_SIZE); space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index b57a38f8eab..d3d1842762c 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -389,10 +389,6 @@ struct mtr_t { const byte* ptr, ulint flags) const; - /** Mark the given latched page as modified. - @param[in] ptr pointer to within buffer frame */ - void memo_modify_page(const byte* ptr); - /** Print info of an mtr handle. */ void print() const; @@ -409,6 +405,11 @@ struct mtr_t { mtr_buf_t* get_memo() { return &m_memo; } #endif /* UNIV_DEBUG */ + /** Mark the given latched page as modified. + @param[in] ptr pointer to within buffer frame */ + void memo_modify_page(const byte* ptr); + void memo_modify_page(ulint space, ulint page); + /** @return true if a record was added to the mini-transaction */ bool is_dirty() const { return m_made_dirty; } diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic index a45d088d5d7..cf9756fb8c2 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -170,7 +170,7 @@ mtr_t::release_block_at_savepoint( ut_a(slot->object == block); - buf_page_release_latch(block, slot->type); + buf_page_release_latch(block, slot->type & ~MTR_MEMO_MODIFY); buf_block_unfix(reinterpret_cast<buf_block_t*>(block)); diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h index 2d4cd7b97ac..9791eda6d5f 100644 --- a/storage/innobase/include/mtr0types.h +++ b/storage/innobase/include/mtr0types.h @@ -255,9 +255,7 @@ enum mtr_memo_type_t { MTR_MEMO_BUF_FIX = RW_NO_LATCH, -#ifdef UNIV_DEBUG MTR_MEMO_MODIFY = 16, -#endif /* UNIV_DEBUG */ MTR_MEMO_S_LOCK = RW_S_LATCH << 5, diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index fefc0687ddb..5e9f6b729d1 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -114,7 +114,7 @@ struct Find { /** @return false if the object was found. */ bool operator()(mtr_memo_slot_t* slot) { - if (m_object == slot->object && m_type == slot->type) { + if (m_object == slot->object && m_type == (slot->type & ~MTR_MEMO_MODIFY)) { m_slot = slot; return(false); } @@ -159,7 +159,7 @@ struct FindPage { ut_ad(m_slot == NULL); - if (!(m_flags & slot->type) || slot->object == NULL) { + if (!(m_flags & (slot->type & ~MTR_MEMO_MODIFY)) || slot->object == NULL) { return(true); } @@ -204,14 +204,12 @@ private: @param slot memo slot */ static void memo_slot_release(mtr_memo_slot_t *slot) { - switch (slot->type) { -#ifdef UNIV_DEBUG + switch (slot->type & ~MTR_MEMO_MODIFY) { default: ut_ad(!"invalid type"); break; case MTR_MEMO_MODIFY: break; -#endif /* UNIV_DEBUG */ case MTR_MEMO_S_LOCK: rw_lock_s_unlock(reinterpret_cast<rw_lock_t*>(slot->object)); break; @@ -233,7 +231,7 @@ static void memo_slot_release(mtr_memo_slot_t *slot) case MTR_MEMO_PAGE_SX_FIX: case MTR_MEMO_PAGE_X_FIX: buf_block_t *block= reinterpret_cast<buf_block_t*>(slot->object); - buf_page_release_latch(block, slot->type); + buf_page_release_latch(block, slot->type & ~MTR_MEMO_MODIFY); buf_block_unfix(block); break; } @@ -247,14 +245,12 @@ struct ReleaseLatches { { if (!slot->object) return true; - switch (slot->type) { -#ifdef UNIV_DEBUG + switch (slot->type & ~MTR_MEMO_MODIFY) { default: ut_ad(!"invalid type"); break; case MTR_MEMO_MODIFY: break; -#endif /* UNIV_DEBUG */ case MTR_MEMO_S_LOCK: rw_lock_s_unlock(reinterpret_cast<rw_lock_t*>(slot->object)); break; @@ -276,7 +272,7 @@ struct ReleaseLatches { case MTR_MEMO_PAGE_SX_FIX: case MTR_MEMO_PAGE_X_FIX: buf_block_t *block= reinterpret_cast<buf_block_t*>(slot->object); - buf_page_release_latch(block, slot->type); + buf_page_release_latch(block, slot->type & ~MTR_MEMO_MODIFY); buf_block_unfix(block); break; } @@ -338,9 +334,10 @@ struct ReleaseBlocks { bool operator()(mtr_memo_slot_t* slot) const { if (slot->object != NULL) { - - if (slot->type == MTR_MEMO_PAGE_X_FIX - || slot->type == MTR_MEMO_PAGE_SX_FIX) { + ulint type = slot->type;// & ~MTR_MEMO_MODIFY; + if (type == (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_MODIFY) + || type == (MTR_MEMO_PAGE_SX_FIX | MTR_MEMO_MODIFY) + /*&& (slot->type & MTR_MEMO_MODIFY)*/) { add_dirty_page_to_flush_list(slot); } @@ -814,7 +811,7 @@ struct FindBlockX /** @return whether the block was not found x-latched */ bool operator()(const mtr_memo_slot_t *slot) const { - return slot->object != &block || slot->type != MTR_MEMO_PAGE_X_FIX; + return slot->object != &block || (slot->type & ~MTR_MEMO_MODIFY) != MTR_MEMO_PAGE_X_FIX; } }; @@ -952,6 +949,17 @@ mtr_t::memo_contains_flagged(const void* ptr, ulint flags) const CIterate<FlaggedCheck>(FlaggedCheck(ptr, flags))); } +/** Print info of an mtr handle. */ +void +mtr_t::print() const +{ + ib::info() << "Mini-transaction handle: memo size " + << m_memo.size() << " bytes log size " + << get_log()->size() << " bytes"; +} + +#endif /* UNIV_DEBUG */ + /** Check if memo contains the given page. @param[in] ptr pointer to within buffer frame @param[in] flags specify types of object with OR of @@ -968,11 +976,65 @@ mtr_t::memo_contains_page_flagged( ? NULL : iteration.functor.get_block(); } + +/** Find a block, preferrably in MTR_MEMO_MODIFY state */ +struct FindModifiedSpacePage +{ + mtr_memo_slot_t *found= nullptr; +// const byte *ptr; + ulint space; + ulint page; + +// FindModified(ulint space, ulint page) : space(space), page(page) {} + FindModifiedSpacePage(ulint space, ulint page) : space(space), page(page) {} + + bool operator()(mtr_memo_slot_t *slot) + { + if (!(slot->type & (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX))) + return true; + + const byte *frame = static_cast<buf_block_t *>(slot->object)->frame; + uint32_t page_space = mach_read_from_4(frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); + uint32_t page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET); + + if (page_space != space || page_no != page) + return true; + + found= slot; + return !(slot->type & (MTR_MEMO_MODIFY | + MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); + } +}; + +struct FindModifiedPtr +{ + mtr_memo_slot_t *found= nullptr; + const byte *ptr; + + FindModifiedPtr(const byte *ptr) : ptr(ptr) {} + + bool operator()(mtr_memo_slot_t *slot) + { + if (!slot->object + || !(slot->type & (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)) + || ptr < static_cast<buf_block_t *>(slot->object)->frame + || ptr >= (static_cast<buf_block_t *>(slot->object)->frame + + static_cast<buf_block_t *>(slot->object)->page.size.logical())) + return true; + found= slot; + return !(slot->type & (MTR_MEMO_MODIFY | + MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX)); + } +}; + + /** Mark the given latched page as modified. @param[in] ptr pointer to within buffer frame */ void -mtr_t::memo_modify_page(const byte* ptr) +//mtr_t::memo_modify_page(const byte* ptr) +mtr_t::memo_modify_page(ulint space, ulint page) { +/* buf_block_t* block = memo_contains_page_flagged( ptr, MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX); ut_ad(block != NULL); @@ -980,15 +1042,39 @@ mtr_t::memo_modify_page(const byte* ptr) if (!memo_contains(get_memo(), block, MTR_MEMO_MODIFY)) { memo_push(block, MTR_MEMO_MODIFY); } +*/ + Iterate<FindModifiedSpacePage> iteration((FindModifiedSpacePage(space, page))); + if (UNIV_UNLIKELY(m_memo.for_each_block(iteration))) + { + ut_ad("modifying an unlatched page" == 0); + return; + } + iteration.functor.found->type= static_cast<mtr_memo_type_t> + (iteration.functor.found->type | MTR_MEMO_MODIFY); } -/** Print info of an mtr handle. */ + void -mtr_t::print() const +mtr_t::memo_modify_page(const byte* ptr) { - ib::info() << "Mini-transaction handle: memo size " - << m_memo.size() << " bytes log size " - << get_log()->size() << " bytes"; -} +/* + buf_block_t* block = memo_contains_page_flagged( + ptr, MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX); + ut_ad(block != NULL); -#endif /* UNIV_DEBUG */ + if (!memo_contains(get_memo(), block, MTR_MEMO_MODIFY)) { + memo_push(block, MTR_MEMO_MODIFY); + } +*/ + + Iterate<FindModifiedPtr> iteration((FindModifiedPtr(ptr))); + if (UNIV_UNLIKELY(m_memo.for_each_block(iteration))) + { + ut_ad("modifying an unlatched page" == 0); + return; + } + + iteration.functor.found->type= static_cast<mtr_memo_type_t> + (iteration.functor.found->type | MTR_MEMO_MODIFY); + +} |