diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-11-13 22:06:50 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-11-13 22:06:50 +0200 |
commit | e8f8992801988465ff422197bbf439f69d679e6e (patch) | |
tree | 627ba8f95f731d9bb206b182c7115a4950712cfe /storage | |
parent | ca331bdcda21173dcb4dd4108bad57ce6ff10650 (diff) | |
parent | 749ecedfece22d5bdb27a5f682d430e1aa6ec194 (diff) | |
download | mariadb-git-e8f8992801988465ff422197bbf439f69d679e6e.tar.gz |
MDEV-24188: Merge 10.4 into 10.5
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 30 | ||||
-rw-r--r-- | storage/innobase/include/dyn0buf.h | 18 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 4 | ||||
-rw-r--r-- | storage/innobase/include/sync0rw.h | 2 | ||||
-rw-r--r-- | storage/innobase/mtr/mtr0mtr.cc | 55 | ||||
-rw-r--r-- | storage/innobase/sync/sync0rw.cc | 2 |
6 files changed, 81 insertions, 30 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 3bbc499bab5..acd221b8b52 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -3772,18 +3772,29 @@ loop: ut_ad(0); break; case BUF_BLOCK_FILE_PAGE: - buf_block_buf_fix_inc(block, __FILE__, __LINE__); + if (!mtr->have_x_latch(*block)) { - const auto num_fix_count= mtr->get_fix_count(block) + 1; - while (block->page.io_fix() != BUF_IO_NONE || - num_fix_count != block->page.buf_fix_count()) + buf_block_buf_fix_inc(block, __FILE__, __LINE__); { - mysql_mutex_unlock(&buf_pool.mutex); - os_thread_yield(); - mysql_mutex_lock(&buf_pool.mutex); + while (block->page.io_fix() != BUF_IO_NONE || + block->page.buf_fix_count() != 1) + { + timespec abstime; + set_timespec_nsec(abstime, 1000000); + mysql_cond_timedwait(&buf_pool.done_flush_list, &buf_pool.mutex, + &abstime); + } } + rw_lock_x_lock(&block->lock); + mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX); + } + else + { + ut_ad(!block->page.ibuf_exist); +#ifdef BTR_CUR_HASH_ADAPT + ut_ad(!block->index); +#endif } - rw_lock_x_lock(&block->lock); #ifdef BTR_CUR_HASH_ADAPT drop_hash_entry= block->index; #endif @@ -3808,6 +3819,7 @@ loop: buf_page_free_descriptor(&block->page); block= free_block; buf_block_buf_fix_inc(block, __FILE__, __LINE__); + mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX); break; } @@ -3818,8 +3830,6 @@ loop: btr_search_drop_page_hash_index(block); #endif /* BTR_CUR_HASH_ADAPT */ - mtr_memo_push(mtr, block, MTR_MEMO_PAGE_X_FIX); - if (block->page.ibuf_exist) { if (!recv_recovery_is_on()) diff --git a/storage/innobase/include/dyn0buf.h b/storage/innobase/include/dyn0buf.h index e89733fc9ed..cb8b998f0ea 100644 --- a/storage/innobase/include/dyn0buf.h +++ b/storage/innobase/include/dyn0buf.h @@ -331,6 +331,24 @@ public: } /** + Iterate over each block and call the functor. + @return false if iteration was terminated. */ + template <typename Functor> + bool for_each_block(const Functor& functor) const + { + for (typename list_t::iterator it = m_list.begin(), + end = m_list.end(); + it != end; ++it) { + + if (!functor(&*it)) { + return false; + } + } + + return(true); + } + + /** Iterate over all the blocks in reverse and call the iterator @return false if iteration was terminated. */ template <typename Functor> diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index cf8f37c3fa5..f8ab7cf440f 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -151,6 +151,10 @@ struct mtr_t { return old_mode; } + /** Check if we are holding a block latch in exclusive mode + @param block buffer pool block to search for */ + bool have_x_latch(const buf_block_t &block) const; + /** Copy the tablespaces associated with the mini-transaction (needed for generating FILE_MODIFY records) @param[in] mtr mini-transaction that may modify diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h index fce598f0930..084acc51d1f 100644 --- a/storage/innobase/include/sync0rw.h +++ b/storage/innobase/include/sync0rw.h @@ -506,7 +506,7 @@ the pass value == 0. */ bool rw_lock_own( /*========*/ - rw_lock_t* lock, /*!< in: rw-lock */ + const rw_lock_t*lock, /*!< in: rw-lock */ ulint lock_type) /*!< in: lock type: RW_LOCK_S, RW_LOCK_X */ MY_ATTRIBUTE((warn_unused_result)); diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index dede92ad755..a6f74bf927f 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -893,29 +893,48 @@ inline std::pair<lsn_t,bool> mtr_t::finish_write(ulint len) return std::make_pair(start_lsn, flush); } -/** Find buffer fix count of the given block acquired by the -mini-transaction */ -struct FindBlock +/** Find out whether a block was X-latched by the mini-transaction */ +struct FindBlockX { - int32_t num_fix; - const buf_block_t *const block; + const buf_block_t █ - FindBlock(const buf_block_t *block_buf): num_fix(0), block(block_buf) {} + FindBlockX(const buf_block_t &block): block(block) {} - bool operator()(const mtr_memo_slot_t* slot) + /** @return whether the block was not found x-latched */ + bool operator()(const mtr_memo_slot_t *slot) const { - if (slot->object == block) - num_fix++; - return true; + return slot->object != &block || slot->type == MTR_MEMO_PAGE_X_FIX; + } +}; + +#ifdef UNIV_DEBUG +/** Assert that the block is not present in the mini-transaction */ +struct FindNoBlock +{ + const buf_block_t █ + + FindNoBlock(const buf_block_t &block): block(block) {} + + /** @return whether the block was not found */ + bool operator()(const mtr_memo_slot_t *slot) const + { + return slot->object != █ } }; +#endif /* UNIV_DEBUG */ -uint32_t mtr_t::get_fix_count(const buf_block_t *block) const +bool mtr_t::have_x_latch(const buf_block_t &block) const { - Iterate<FindBlock> iteration((FindBlock(block))); - if (m_memo.for_each_block(iteration)) - return iteration.functor.num_fix; - return 0; + if (m_memo.for_each_block(CIterate<FindBlockX>(FindBlockX(block)))) + { + ut_ad(m_memo.for_each_block(CIterate<FindNoBlock>(FindNoBlock(block)))); + ut_ad(!memo_contains_flagged(&block, + MTR_MEMO_PAGE_S_FIX | MTR_MEMO_PAGE_SX_FIX | + MTR_MEMO_BUF_FIX | MTR_MEMO_MODIFY)); + return false; + } + ut_ad(rw_lock_own(&block.lock, RW_LOCK_X)); + return true; } #ifdef UNIV_DEBUG @@ -931,13 +950,13 @@ bool mtr_t::memo_contains(const rw_lock_t &lock, mtr_memo_type_t type) switch (type) { case MTR_MEMO_X_LOCK: - ut_ad(rw_lock_own(const_cast<rw_lock_t*>(&lock), RW_LOCK_X)); + ut_ad(rw_lock_own(&lock, RW_LOCK_X)); break; case MTR_MEMO_SX_LOCK: - ut_ad(rw_lock_own(const_cast<rw_lock_t*>(&lock), RW_LOCK_SX)); + ut_ad(rw_lock_own(&lock, RW_LOCK_SX)); break; case MTR_MEMO_S_LOCK: - ut_ad(rw_lock_own(const_cast<rw_lock_t*>(&lock), RW_LOCK_S)); + ut_ad(rw_lock_own(&lock, RW_LOCK_S)); break; default: break; diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index b86e11900b8..29a5c6cd036 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -990,7 +990,7 @@ the pass value == 0. bool rw_lock_own( /*========*/ - rw_lock_t* lock, /*!< in: rw-lock */ + const rw_lock_t*lock, /*!< in: rw-lock */ ulint lock_type) /*!< in: lock type: RW_LOCK_S, RW_LOCK_X */ { |