summaryrefslogtreecommitdiff
path: root/storage/innobase/mtr/mtr0mtr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/mtr/mtr0mtr.cc')
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc422
1 files changed, 230 insertions, 192 deletions
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 04b20de8e96..d2f62b5c39e 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -37,6 +37,8 @@ Created 11/26/1995 Heikki Tuuri
void mtr_memo_slot_t::release() const
{
+ ut_ad(object);
+
switch (type) {
case MTR_MEMO_S_LOCK:
static_cast<index_lock*>(object)->s_unlock();
@@ -153,10 +155,13 @@ inline void buf_pool_t::insert_into_flush_list(buf_page_t *prev,
block->page.set_oldest_modification(lsn);
}
+mtr_t::mtr_t()= default;
+mtr_t::~mtr_t()= default;
+
/** Start a mini-transaction. */
void mtr_t::start()
{
- ut_ad(!m_memo);
+ ut_ad(m_memo.empty());
ut_ad(!m_freed_pages);
ut_ad(!m_freed_space);
MEM_UNDEFINED(this, sizeof *this);
@@ -187,7 +192,7 @@ void mtr_t::start()
inline void mtr_t::release_resources()
{
ut_ad(is_active());
- ut_ad(!m_memo);
+ ut_ad(m_memo.empty());
m_log.erase();
ut_d(m_commit= true);
}
@@ -242,15 +247,13 @@ void mtr_t::release_unlogged()
{
ut_ad(m_log_mode == MTR_LOG_NO_REDO);
ut_ad(m_log.size() == 0);
- ut_ad(m_memo);
process_freed_pages();
- for (auto it= m_memo->rbegin(); it != m_memo->rend(); it++)
+ for (auto it= m_memo.rbegin(); it != m_memo.rend(); it++)
{
mtr_memo_slot_t &slot= *it;
- if (!slot.object)
- continue;
+ ut_ad(slot.object);
switch (slot.type) {
case MTR_MEMO_S_LOCK:
static_cast<index_lock*>(slot.object)->s_unlock();
@@ -277,10 +280,8 @@ void mtr_t::release_unlogged()
{
ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY ||
slot.type == MTR_MEMO_PAGE_SX_MODIFY);
- if (UNIV_LIKELY(block->page.id() >= end_page_id))
- block->page.set_temp_modified();
- else
- insert_imported(block);
+ ut_ad(block->page.id() < end_page_id);
+ insert_imported(block);
}
switch (slot.type) {
@@ -299,23 +300,14 @@ void mtr_t::release_unlogged()
}
}
- delete m_memo;
- m_memo= nullptr;
+ m_memo.clear();
}
void mtr_t::release()
{
- if (m_memo)
- {
- for (auto it= m_memo->rbegin(); it != m_memo->rend(); it++)
- {
- mtr_memo_slot_t &slot= *it;
- if (slot.object)
- slot.release();
- }
- delete m_memo;
- m_memo= nullptr;
- }
+ for (auto it= m_memo.rbegin(); it != m_memo.rend(); it++)
+ it->release();
+ m_memo.clear();
}
/** Commit a mini-transaction. */
@@ -342,19 +334,18 @@ void mtr_t::commit()
if (m_made_dirty)
{
- ut_ad(m_memo);
size_t modified= 0;
- auto it= m_memo->rbegin();
+ auto it= m_memo.rbegin();
mysql_mutex_lock(&buf_pool.flush_list_mutex);
buf_page_t *const prev=
buf_pool.prepare_insert_into_flush_list(lsns.first);
- while (it != m_memo->rend())
+ while (it != m_memo.rend())
{
const mtr_memo_slot_t &slot= *it++;
- if (slot.object && slot.type & MTR_MEMO_MODIFY)
+ if (slot.type & MTR_MEMO_MODIFY)
{
ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY ||
slot.type == MTR_MEMO_PAGE_SX_MODIFY);
@@ -399,72 +390,67 @@ void mtr_t::commit()
else
log_sys.latch.rd_unlock();
- if (m_memo)
- {
- size_t modified= 0;
+ size_t modified= 0;
- for (auto it= m_memo->rbegin(); it != m_memo->rend(); )
- {
- const mtr_memo_slot_t &slot= *it++;
- if (!slot.object)
- continue;
- switch (slot.type) {
- case MTR_MEMO_S_LOCK:
- static_cast<index_lock*>(slot.object)->s_unlock();
- break;
- case MTR_MEMO_SPACE_X_LOCK:
- static_cast<fil_space_t*>(slot.object)->set_committed_size();
- static_cast<fil_space_t*>(slot.object)->x_unlock();
- break;
- case MTR_MEMO_SPACE_S_LOCK:
- static_cast<fil_space_t*>(slot.object)->s_unlock();
- break;
- case MTR_MEMO_X_LOCK:
- case MTR_MEMO_SX_LOCK:
- static_cast<index_lock*>(slot.object)->
- u_or_x_unlock(slot.type == MTR_MEMO_SX_LOCK);
- break;
- default:
- buf_page_t *bpage= static_cast<buf_page_t*>(slot.object);
- const auto s= bpage->unfix();
- if (slot.type & MTR_MEMO_MODIFY)
+ for (auto it= m_memo.rbegin(); it != m_memo.rend(); )
+ {
+ const mtr_memo_slot_t &slot= *it++;
+ ut_ad(slot.object);
+ switch (slot.type) {
+ case MTR_MEMO_S_LOCK:
+ static_cast<index_lock*>(slot.object)->s_unlock();
+ break;
+ case MTR_MEMO_SPACE_X_LOCK:
+ static_cast<fil_space_t*>(slot.object)->set_committed_size();
+ static_cast<fil_space_t*>(slot.object)->x_unlock();
+ break;
+ case MTR_MEMO_SPACE_S_LOCK:
+ static_cast<fil_space_t*>(slot.object)->s_unlock();
+ break;
+ case MTR_MEMO_X_LOCK:
+ case MTR_MEMO_SX_LOCK:
+ static_cast<index_lock*>(slot.object)->
+ u_or_x_unlock(slot.type == MTR_MEMO_SX_LOCK);
+ break;
+ default:
+ buf_page_t *bpage= static_cast<buf_page_t*>(slot.object);
+ const auto s= bpage->unfix();
+ if (slot.type & MTR_MEMO_MODIFY)
+ {
+ ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY ||
+ slot.type == MTR_MEMO_PAGE_SX_MODIFY);
+ ut_ad(bpage->oldest_modification() > 1);
+ ut_ad(bpage->oldest_modification() < m_commit_lsn);
+ ut_ad(bpage->id() < end_page_id);
+ ut_ad(s >= buf_page_t::FREED);
+ ut_ad(s < buf_page_t::READ_FIX);
+ ut_ad(mach_read_from_8(bpage->frame + FIL_PAGE_LSN) <=
+ m_commit_lsn);
+ if (s >= buf_page_t::UNFIXED)
{
- ut_ad(slot.type == MTR_MEMO_PAGE_X_MODIFY ||
- slot.type == MTR_MEMO_PAGE_SX_MODIFY);
- ut_ad(bpage->oldest_modification() > 1);
- ut_ad(bpage->oldest_modification() < m_commit_lsn);
- ut_ad(bpage->id() < end_page_id);
- ut_ad(s >= buf_page_t::FREED);
- ut_ad(s < buf_page_t::READ_FIX);
- ut_ad(mach_read_from_8(bpage->frame + FIL_PAGE_LSN) <=
- m_commit_lsn);
- if (s >= buf_page_t::UNFIXED)
- {
- mach_write_to_8(bpage->frame + FIL_PAGE_LSN, m_commit_lsn);
- if (UNIV_LIKELY_NULL(bpage->zip.data))
- memcpy_aligned<8>(FIL_PAGE_LSN + bpage->zip.data,
- FIL_PAGE_LSN + bpage->frame, 8);
- }
- modified++;
- }
- switch (auto latch= slot.type & ~MTR_MEMO_MODIFY) {
- case MTR_MEMO_PAGE_S_FIX:
- bpage->lock.s_unlock();
- continue;
- case MTR_MEMO_PAGE_SX_FIX:
- case MTR_MEMO_PAGE_X_FIX:
- bpage->lock.u_or_x_unlock(latch == MTR_MEMO_PAGE_SX_FIX);
- continue;
- default:
- ut_ad(latch == MTR_MEMO_BUF_FIX);
+ mach_write_to_8(bpage->frame + FIL_PAGE_LSN, m_commit_lsn);
+ if (UNIV_LIKELY_NULL(bpage->zip.data))
+ memcpy_aligned<8>(FIL_PAGE_LSN + bpage->zip.data,
+ FIL_PAGE_LSN + bpage->frame, 8);
}
+ modified++;
+ }
+ switch (auto latch= slot.type & ~MTR_MEMO_MODIFY) {
+ case MTR_MEMO_PAGE_S_FIX:
+ bpage->lock.s_unlock();
+ continue;
+ case MTR_MEMO_PAGE_SX_FIX:
+ case MTR_MEMO_PAGE_X_FIX:
+ bpage->lock.u_or_x_unlock(latch == MTR_MEMO_PAGE_SX_FIX);
+ continue;
+ default:
+ ut_ad(latch == MTR_MEMO_BUF_FIX);
}
}
-
- buf_pool.add_flush_list_requests(modified);
- delete m_memo;
- m_memo= nullptr;
}
+
+ buf_pool.add_flush_list_requests(modified);
+ m_memo.clear();
}
if (UNIV_UNLIKELY(lsns.second != PAGE_FLUSH_NO))
@@ -479,16 +465,14 @@ func_exit:
void mtr_t::rollback_to_savepoint(ulint begin, ulint end)
{
- ut_ad(m_memo);
- ut_ad(end <= m_memo->size());
+ ut_ad(end <= m_memo.size());
ut_ad(begin <= end);
ulint s= end;
while (s-- > begin)
{
- const mtr_memo_slot_t &slot= (*m_memo)[s];
- if (!slot.object)
- continue;
+ const mtr_memo_slot_t &slot= m_memo[s];
+ ut_ad(slot.object);
/* This is intended for releasing latches on indexes or unmodified
buffer pool pages. */
ut_ad(slot.type <= MTR_MEMO_SX_LOCK);
@@ -496,7 +480,7 @@ void mtr_t::rollback_to_savepoint(ulint begin, ulint end)
slot.release();
}
- m_memo->erase(m_memo->begin() + begin, m_memo->begin() + end);
+ m_memo.erase(m_memo.begin() + begin, m_memo.begin() + end);
}
/** Commit a mini-transaction that is shrinking a tablespace.
@@ -507,9 +491,10 @@ void mtr_t::commit_shrink(fil_space_t &space)
ut_ad(!high_level_read_only);
ut_ad(m_modifications);
ut_ad(m_made_dirty);
- ut_ad(m_memo);
+ ut_ad(!m_memo.empty());
ut_ad(!recv_recovery_is_on());
ut_ad(m_log_mode == MTR_LOG_ALL);
+ ut_ad(!m_freed_pages);
ut_ad(UT_LIST_GET_LEN(space.chain) == 1);
log_write_and_flush_prepare();
@@ -528,22 +513,21 @@ void mtr_t::commit_shrink(fil_space_t &space)
os_file_truncate(space.chain.start->name, space.chain.start->handle,
os_offset_t{space.size} << srv_page_size_shift, true);
- ut_ad(!m_freed_pages || m_freed_space == &space);
- process_freed_pages();
+ space.clear_freed_ranges();
const page_id_t high{space.id, space.size};
size_t modified= 0;
- auto it= m_memo->rbegin();
+ auto it= m_memo.rbegin();
mysql_mutex_lock(&buf_pool.flush_list_mutex);
buf_page_t *const prev= buf_pool.prepare_insert_into_flush_list(start_lsn);
- while (it != m_memo->rend())
+ while (it != m_memo.rend())
{
mtr_memo_slot_t &slot= *it++;
- if (!slot.object);
- else if (slot.type == MTR_MEMO_SPACE_X_LOCK)
+ ut_ad(slot.object);
+ if (slot.type == MTR_MEMO_SPACE_X_LOCK)
ut_ad(high.space() == static_cast<fil_space_t*>(slot.object)->id);
else
{
@@ -722,7 +706,7 @@ lsn_t mtr_t::commit_files(lsn_t checkpoint_lsn)
ut_ad(is_active());
ut_ad(m_log_mode == MTR_LOG_ALL);
ut_ad(!m_made_dirty);
- ut_ad(!m_memo);
+ ut_ad(m_memo.empty());
ut_ad(!srv_read_only_mode);
ut_ad(!m_freed_space);
ut_ad(!m_freed_pages);
@@ -832,19 +816,18 @@ void mtr_t::x_lock_space(fil_space_t *space)
void mtr_t::release(const void *object)
{
ut_ad(is_active());
- ut_ad(m_memo);
auto it=
- std::find_if(m_memo->begin(), m_memo->end(),
+ std::find_if(m_memo.begin(), m_memo.end(),
[object](const mtr_memo_slot_t& slot)
{ return slot.object == object; });
- ut_ad(it != m_memo->end());
+ ut_ad(it != m_memo.end());
ut_ad(!(it->type & MTR_MEMO_MODIFY));
it->release();
- m_memo->erase(it);
- ut_ad(std::find_if(m_memo->begin(), m_memo->end(),
+ m_memo.erase(it, it + 1);
+ ut_ad(std::find_if(m_memo.begin(), m_memo.end(),
[object](const mtr_memo_slot_t& slot)
- { return slot.object == &object; }) == m_memo->end());
+ { return slot.object == &object; }) == m_memo.end());
}
static time_t log_close_warn_time;
@@ -1023,11 +1006,11 @@ std::pair<lsn_t,mtr_t::page_flush_ahead> mtr_t::do_write()
#ifndef DBUG_OFF
do
{
- if (!m_memo || m_log_mode != MTR_LOG_ALL)
+ if (m_log_mode != MTR_LOG_ALL)
continue;
DBUG_EXECUTE_IF("skip_page_checksum", continue;);
- for (const mtr_memo_slot_t& slot : *m_memo)
+ for (const mtr_memo_slot_t& slot : m_memo)
if (slot.type & MTR_MEMO_MODIFY)
{
const buf_page_t &b= *static_cast<const buf_page_t*>(slot.object);
@@ -1279,12 +1262,9 @@ mtr_t::finish_write(size_t len)
bool mtr_t::have_x_latch(const buf_block_t &block) const
{
- if (!m_memo)
- return false;
-
ut_d(const mtr_memo_slot_t *found= nullptr);
- for (const mtr_memo_slot_t &slot : *m_memo)
+ for (const mtr_memo_slot_t &slot : m_memo)
{
if (slot.object != &block)
continue;
@@ -1304,16 +1284,13 @@ bool mtr_t::have_x_latch(const buf_block_t &block) const
bool mtr_t::have_u_or_x_latch(const buf_block_t &block) const
{
- if (m_memo)
+ for (const mtr_memo_slot_t &slot : m_memo)
{
- for (const mtr_memo_slot_t &slot : *m_memo)
+ if (slot.object == &block &&
+ slot.type & (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX))
{
- if (slot.object == &block &&
- slot.type & (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX))
- {
- ut_ad(block.page.lock.have_u_or_x());
- return true;
- }
+ ut_ad(block.page.lock.have_u_or_x());
+ return true;
}
}
return false;
@@ -1325,18 +1302,15 @@ bool mtr_t::have_u_or_x_latch(const buf_block_t &block) const
@return whether space.latch is being held */
bool mtr_t::memo_contains(const fil_space_t& space, bool shared) const
{
- if (m_memo)
- {
- const mtr_memo_type_t type= shared
- ? MTR_MEMO_SPACE_S_LOCK : MTR_MEMO_SPACE_X_LOCK;
+ const mtr_memo_type_t type= shared
+ ? MTR_MEMO_SPACE_S_LOCK : MTR_MEMO_SPACE_X_LOCK;
- for (const mtr_memo_slot_t &slot : *m_memo)
+ for (const mtr_memo_slot_t &slot : m_memo)
+ {
+ if (slot.object == &space && slot.type == type)
{
- if (slot.object == &space && slot.type == type)
- {
- ut_ad(shared || space.is_owner());
- return true;
- }
+ ut_ad(shared || space.is_owner());
+ return true;
}
}
@@ -1346,9 +1320,8 @@ bool mtr_t::memo_contains(const fil_space_t& space, bool shared) const
void mtr_t::page_lock_upgrade(const buf_block_t &block)
{
ut_ad(block.page.lock.have_x());
- ut_ad(m_memo);
- for (mtr_memo_slot_t &slot : *m_memo)
+ for (mtr_memo_slot_t &slot : m_memo)
if (slot.object == &block && slot.type & MTR_MEMO_PAGE_SX_FIX)
slot.type= mtr_memo_type_t(slot.type ^
(MTR_MEMO_PAGE_SX_FIX | MTR_MEMO_PAGE_X_FIX));
@@ -1358,16 +1331,6 @@ void mtr_t::page_lock_upgrade(const buf_block_t &block)
#endif /* BTR_CUR_HASH_ADAPT */
}
-void mtr_t::lock_upgrade(const index_lock &lock)
-{
- ut_ad(lock.have_x());
- ut_ad(m_memo);
-
- for (mtr_memo_slot_t &slot : *m_memo)
- if (slot.object == &lock && slot.type == MTR_MEMO_SX_LOCK)
- slot.type= MTR_MEMO_X_LOCK;
-}
-
/** Latch a buffer pool block.
@param block block to be latched
@param rw_latch RW_S_LATCH, RW_SX_LATCH, RW_X_LATCH, RW_NO_LATCH */
@@ -1416,27 +1379,29 @@ done:
void mtr_t::upgrade_buffer_fix(ulint savepoint, rw_lock_type_t rw_latch)
{
ut_ad(is_active());
- ut_ad(m_memo);
- ut_ad(savepoint < m_memo->size());
-
- mtr_memo_slot_t &slot= (*m_memo)[savepoint];
+ mtr_memo_slot_t &slot= m_memo[savepoint];
ut_ad(slot.type == MTR_MEMO_BUF_FIX);
buf_block_t *block= static_cast<buf_block_t*>(slot.object);
ut_d(const auto state= block->page.state());
ut_ad(state > buf_page_t::UNFIXED);
ut_ad(state > buf_page_t::WRITE_FIX || state < buf_page_t::READ_FIX);
+ static_assert(int{MTR_MEMO_PAGE_S_FIX} == int{RW_S_LATCH}, "");
+ static_assert(int{MTR_MEMO_PAGE_X_FIX} == int{RW_X_LATCH}, "");
+ static_assert(int{MTR_MEMO_PAGE_SX_FIX} == int{RW_SX_LATCH}, "");
+ slot.type= mtr_memo_type_t(rw_latch);
switch (rw_latch) {
default:
ut_ad("invalid state" == 0);
break;
+ case RW_S_LATCH:
+ block->page.lock.s_lock();
+ break;
case RW_SX_LATCH:
- slot.type= MTR_MEMO_PAGE_SX_FIX;
block->page.lock.u_lock();
ut_ad(!block->page.is_io_fixed());
break;
case RW_X_LATCH:
- slot.type= MTR_MEMO_PAGE_X_FIX;
block->page.lock.x_lock();
ut_ad(!block->page.is_io_fixed());
}
@@ -1458,27 +1423,24 @@ bool mtr_t::memo_contains(const index_lock &lock, mtr_memo_type_t type) const
ut_ad(type == MTR_MEMO_X_LOCK || type == MTR_MEMO_S_LOCK ||
type == MTR_MEMO_SX_LOCK);
- if (m_memo)
+ for (const mtr_memo_slot_t &slot : m_memo)
{
- for (const mtr_memo_slot_t &slot : *m_memo)
+ if (slot.object == &lock && slot.type == type)
{
- if (slot.object == &lock && slot.type == type)
- {
- switch (type) {
- case MTR_MEMO_X_LOCK:
- ut_ad(lock.have_x());
- break;
- case MTR_MEMO_SX_LOCK:
- ut_ad(lock.have_u_or_x());
- break;
- case MTR_MEMO_S_LOCK:
- ut_ad(lock.have_s());
- break;
- default:
- break;
- }
- return true;
+ switch (type) {
+ case MTR_MEMO_X_LOCK:
+ ut_ad(lock.have_x());
+ break;
+ case MTR_MEMO_SX_LOCK:
+ ut_ad(lock.have_u_or_x());
+ break;
+ case MTR_MEMO_S_LOCK:
+ ut_ad(lock.have_s());
+ break;
+ default:
+ break;
}
+ return true;
}
}
@@ -1506,7 +1468,7 @@ bool mtr_t::memo_contains_flagged(const void *object, ulint flags) const
MTR_MEMO_MODIFY)) ==
!!(flags & (MTR_MEMO_X_LOCK | MTR_MEMO_SX_LOCK | MTR_MEMO_S_LOCK)));
- for (const mtr_memo_slot_t &slot : *m_memo)
+ for (const mtr_memo_slot_t &slot : m_memo)
{
if (object != slot.object)
continue;
@@ -1541,9 +1503,10 @@ buf_block_t* mtr_t::memo_contains_page_flagged(const byte *ptr, ulint flags)
{
ptr= page_align(ptr);
- for (const mtr_memo_slot_t &slot : *m_memo)
+ for (const mtr_memo_slot_t &slot : m_memo)
{
- if (!slot.object || !(flags & slot.type))
+ ut_ad(slot.object);
+ if (!(flags & slot.type))
continue;
buf_page_t *bpage= static_cast<buf_page_t*>(slot.object);
@@ -1564,35 +1527,84 @@ buf_block_t* mtr_t::memo_contains_page_flagged(const byte *ptr, ulint flags)
/** Mark the given latched page as modified.
@param block page that will be modified */
-void mtr_t::modify(const buf_block_t &block)
+void mtr_t::set_modified(const buf_block_t &block)
{
- if (UNIV_UNLIKELY(!m_memo))
+ if (block.page.id().space() >= SRV_TMP_SPACE_ID)
{
- /* This must be PageConverter::update_page() in IMPORT TABLESPACE. */
- ut_ad(!block.page.in_LRU_list);
+ const_cast<buf_block_t&>(block).page.set_temp_modified();
return;
}
- mtr_memo_slot_t *found= nullptr;
+ m_modifications= true;
- for (mtr_memo_slot_t &slot : *m_memo)
+ if (UNIV_UNLIKELY(m_log_mode == MTR_LOG_NONE))
+ return;
+
+ for (mtr_memo_slot_t &slot : m_memo)
{
if (slot.object == &block &&
slot.type & (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX))
{
- found= &slot;
- break;
+ if (slot.type & MTR_MEMO_MODIFY)
+ ut_ad(m_made_dirty || block.page.oldest_modification() > 1);
+ else
+ {
+ slot.type= static_cast<mtr_memo_type_t>(slot.type | MTR_MEMO_MODIFY);
+ if (!m_made_dirty)
+ m_made_dirty= block.page.oldest_modification() <= 1;
+ }
+ return;
}
}
- if (UNIV_UNLIKELY(!found))
+ /* This must be PageConverter::update_page() in IMPORT TABLESPACE. */
+ ut_ad(m_memo.empty());
+ ut_ad(!block.page.in_LRU_list);
+}
+
+void mtr_t::init(buf_block_t *b)
+{
+ const page_id_t id{b->page.id()};
+ ut_ad(is_named_space(id.space()));
+ ut_ad(!m_freed_pages == !m_freed_space);
+ ut_ad(memo_contains_flagged(b, MTR_MEMO_PAGE_X_FIX));
+
+ if (id.space() >= SRV_TMP_SPACE_ID)
+ b->page.set_temp_modified();
+ else
{
- ut_ad("modifying an unlatched page" == 0);
- return;
+ for (mtr_memo_slot_t &slot : m_memo)
+ {
+ if (slot.object == b && slot.type & MTR_MEMO_PAGE_X_FIX)
+ {
+ slot.type= MTR_MEMO_PAGE_X_MODIFY;
+ m_modifications= true;
+ if (!m_made_dirty)
+ m_made_dirty= b->page.oldest_modification() <= 1;
+ goto found;
+ }
+ }
+ ut_ad("block not X-latched" == 0);
}
- found->type= static_cast<mtr_memo_type_t>(found->type | MTR_MEMO_MODIFY);
- if (!m_made_dirty)
- m_made_dirty= is_block_dirtied(block.page);
+
+ found:
+ if (UNIV_LIKELY_NULL(m_freed_space) &&
+ m_freed_space->id == id.space() &&
+ m_freed_pages->remove_if_exists(id.page_no()) &&
+ m_freed_pages->empty())
+ {
+ delete m_freed_pages;
+ m_freed_pages= nullptr;
+ m_freed_space= nullptr;
+ }
+
+ b->page.set_reinit(b->page.state() & buf_page_t::LRU_MASK);
+
+ if (!is_logged())
+ return;
+
+ m_log.close(log_write<INIT_PAGE>(id, &b->page));
+ m_last_offset= FIL_PAGE_TYPE;
}
/** Free a page.
@@ -1605,24 +1617,26 @@ void mtr_t::free(const fil_space_t &space, uint32_t offset)
if (is_logged())
{
- ut_ad(m_memo);
buf_block_t *freed= nullptr;
const page_id_t id{space.id, offset};
- for (auto it= m_memo->rbegin(); it != m_memo->rend(); it++)
+ for (auto it= m_memo.end(); it != m_memo.begin(); )
{
+ it--;
+ next:
mtr_memo_slot_t &slot= *it;
buf_block_t *block= static_cast<buf_block_t*>(slot.object);
- if (!block);
- else if (block == freed)
+ ut_ad(block);
+ if (block == freed)
{
if (slot.type & (MTR_MEMO_PAGE_SX_FIX | MTR_MEMO_PAGE_X_FIX))
slot.type= MTR_MEMO_PAGE_X_FIX;
else
{
ut_ad(slot.type == MTR_MEMO_BUF_FIX);
- slot.object= nullptr;
block->page.unfix();
+ m_memo.erase(it, it + 1);
+ goto next;
}
}
else if (slot.type & (MTR_MEMO_PAGE_X_FIX | MTR_MEMO_PAGE_SX_FIX) &&
@@ -1636,7 +1650,17 @@ void mtr_t::free(const fil_space_t &space, uint32_t offset)
ut_d(bool upgraded=) block->page.lock.x_lock_upgraded();
ut_ad(upgraded);
}
- slot.type= MTR_MEMO_PAGE_X_MODIFY;
+ if (id.space() >= SRV_TMP_SPACE_ID)
+ {
+ block->page.set_temp_modified();
+ slot.type= MTR_MEMO_PAGE_X_FIX;
+ }
+ else
+ {
+ slot.type= MTR_MEMO_PAGE_X_MODIFY;
+ if (!m_made_dirty)
+ m_made_dirty= block->page.oldest_modification() <= 1;
+ }
#ifdef BTR_CUR_HASH_ADAPT
if (block->index)
btr_search_drop_page_hash_index(block, false);
@@ -1645,8 +1669,22 @@ void mtr_t::free(const fil_space_t &space, uint32_t offset)
}
}
- if (freed && !m_made_dirty)
- m_made_dirty= is_block_dirtied(freed->page);
m_log.close(log_write<FREE_PAGE>(id, nullptr));
}
}
+
+void small_vector_base::grow_by_1(void *small, size_t element_size)
+{
+ const size_t cap= Capacity*= 2, s= cap * element_size;
+ void *new_begin;
+ if (BeginX == small)
+ {
+ new_begin= my_malloc(PSI_NOT_INSTRUMENTED, s, MYF(0));
+ memcpy(new_begin, BeginX, size() * element_size);
+ TRASH_FREE(small, size() * element_size);
+ }
+ else
+ new_begin= my_realloc(PSI_NOT_INSTRUMENTED, BeginX, s, MYF(0));
+
+ BeginX= new_begin;
+}