|
|
@ -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; |
|
|
|