mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Merge 10.5 into 10.6
This commit is contained in:
commit
30dc4287ec
11 changed files with 98 additions and 114 deletions
|
|
@ -711,9 +711,11 @@ void btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr,
|
|||
fseg_header_t* seg_header = &root[blob || page_is_leaf(block->frame)
|
||||
? PAGE_HEADER + PAGE_BTR_SEG_LEAF
|
||||
: PAGE_HEADER + PAGE_BTR_SEG_TOP];
|
||||
fseg_free_page(seg_header,
|
||||
index->table->space, id.page_no(), mtr, space_latched);
|
||||
buf_page_free(id, mtr);
|
||||
fil_space_t* space= index->table->space;
|
||||
const uint32_t page= id.page_no();
|
||||
|
||||
fseg_free_page(seg_header, space, page, mtr, space_latched);
|
||||
buf_page_free(space, page, mtr);
|
||||
|
||||
/* The page was marked free in the allocation bitmap, but it
|
||||
should remain exclusively latched until mtr_t::commit() or until it
|
||||
|
|
|
|||
|
|
@ -2473,45 +2473,45 @@ retry:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/** Mark the page status as FREED for the given tablespace id and
|
||||
page number. If the page is not in the buffer pool then ignore it.
|
||||
X-lock should be taken on the page before marking the page status
|
||||
as FREED. It avoids the concurrent flushing of freed page.
|
||||
Currently, this function only marks the page as FREED if it is
|
||||
in buffer pool.
|
||||
@param[in] page_id page id
|
||||
/** Mark the page status as FREED for the given tablespace and page number.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page page number
|
||||
@param[in,out] mtr mini-transaction */
|
||||
void buf_page_free(const page_id_t page_id, mtr_t *mtr)
|
||||
void buf_page_free(fil_space_t *space, uint32_t page, mtr_t *mtr)
|
||||
{
|
||||
ut_ad(mtr);
|
||||
ut_ad(mtr->is_active());
|
||||
buf_pool.stat.n_page_gets++;
|
||||
|
||||
if (srv_immediate_scrub_data_uncompressed
|
||||
#if defined HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE || defined _WIN32
|
||||
|| space->is_compressed()
|
||||
#endif
|
||||
)
|
||||
mtr->add_freed_offset(space, page);
|
||||
|
||||
buf_pool.stat.n_page_gets++;
|
||||
const page_id_t page_id(space->id, page);
|
||||
const ulint fold= page_id.fold();
|
||||
page_hash_latch *hash_lock= buf_pool.page_hash.lock<false>(fold);
|
||||
buf_block_t *block= reinterpret_cast<buf_block_t*>
|
||||
(buf_pool.page_hash_get_low(page_id, fold));
|
||||
|
||||
/* TODO: try to all this part of mtr_t::free() */
|
||||
if (srv_immediate_scrub_data_uncompressed || mtr->is_page_compressed())
|
||||
mtr->add_freed_offset(page_id);
|
||||
|
||||
if (!block || block->page.state() != BUF_BLOCK_FILE_PAGE)
|
||||
if (buf_block_t *block= reinterpret_cast<buf_block_t*>
|
||||
(buf_pool.page_hash_get_low(page_id, fold)))
|
||||
{
|
||||
/* FIXME: if block!=NULL, convert to BUF_BLOCK_FILE_PAGE,
|
||||
but avoid buf_zip_decompress() */
|
||||
hash_lock->read_unlock();
|
||||
return;
|
||||
if (block->page.state() != BUF_BLOCK_FILE_PAGE)
|
||||
/* FIXME: convert, but avoid buf_zip_decompress() */;
|
||||
else
|
||||
{
|
||||
buf_block_buf_fix_inc(block);
|
||||
ut_ad(block->page.buf_fix_count());
|
||||
hash_lock->read_unlock();
|
||||
|
||||
mtr->memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||
block->lock.x_lock();
|
||||
|
||||
block->page.status= buf_page_t::FREED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buf_block_buf_fix_inc(block);
|
||||
ut_ad(block->page.buf_fix_count());
|
||||
|
||||
mtr->memo_push(block, MTR_MEMO_PAGE_X_FIX);
|
||||
block->lock.x_lock();
|
||||
|
||||
block->page.status= buf_page_t::FREED;
|
||||
hash_lock->read_unlock();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1396,6 +1396,19 @@ static void fil_crypt_return_iops(rotate_thread_t *state, bool wake= true)
|
|||
fil_crypt_update_total_stat(state);
|
||||
}
|
||||
|
||||
/** Acquire a tablespace reference.
|
||||
@return whether a tablespace reference was successfully acquired */
|
||||
inline bool fil_space_t::acquire_if_not_stopped()
|
||||
{
|
||||
mysql_mutex_assert_owner(&fil_system.mutex);
|
||||
const uint32_t n= acquire_low();
|
||||
if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
|
||||
return true;
|
||||
if (UNIV_UNLIKELY(n & STOPPING))
|
||||
return false;
|
||||
return UNIV_LIKELY(!(n & CLOSING)) || prepare(true);
|
||||
}
|
||||
|
||||
/** Return the next tablespace from rotation_list.
|
||||
@param space previous tablespace (NULL to start from the start)
|
||||
@param recheck whether the removal condition needs to be rechecked after
|
||||
|
|
@ -1444,7 +1457,7 @@ inline fil_space_t *fil_system_t::keyrotate_next(fil_space_t *space,
|
|||
do
|
||||
{
|
||||
space= &*it;
|
||||
if (space->acquire_if_not_stopped(true))
|
||||
if (space->acquire_if_not_stopped())
|
||||
return space;
|
||||
if (++it == end)
|
||||
return nullptr;
|
||||
|
|
@ -2168,7 +2181,7 @@ static void fil_crypt_rotation_list_fill()
|
|||
if (space->purpose != FIL_TYPE_TABLESPACE
|
||||
|| space->is_in_rotation_list
|
||||
|| UT_LIST_GET_LEN(space->chain) == 0
|
||||
|| !space->acquire_if_not_stopped(true)) {
|
||||
|| !space->acquire_if_not_stopped()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2631,9 +2631,7 @@ fseg_free_extent(
|
|||
|
||||
for (ulint i = 0; i < FSP_EXTENT_SIZE; i++) {
|
||||
if (!xdes_is_free(descr, i)) {
|
||||
buf_page_free(
|
||||
page_id_t(space->id, first_page_in_extent + 1),
|
||||
mtr);
|
||||
buf_page_free(space, first_page_in_extent + 1, mtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1935,7 +1935,7 @@ ibuf_remove_free_page(void)
|
|||
ibuf_bitmap_page_set_bits<IBUF_BITMAP_IBUF>(
|
||||
bitmap_page, page_id, srv_page_size, false, &mtr);
|
||||
|
||||
buf_page_free(page_id, &mtr);
|
||||
buf_page_free(fil_system.sys_space, page_no, &mtr);
|
||||
|
||||
ibuf_mtr_commit(&mtr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -332,11 +332,11 @@ buf_page_release_latch(
|
|||
RW_NO_LATCH */
|
||||
/** Move a block to the start of the LRU list. */
|
||||
void buf_page_make_young(buf_page_t *bpage);
|
||||
/** Mark the page status as FREED for the given tablespace id and
|
||||
page number. If the page is not in buffer pool then ignore it.
|
||||
@param[in] page_id page_id
|
||||
/** Mark the page status as FREED for the given tablespace and page number.
|
||||
@param[in,out] space tablespace
|
||||
@param[in] page page number
|
||||
@param[in,out] mtr mini-transaction */
|
||||
void buf_page_free(const page_id_t page_id, mtr_t *mtr);
|
||||
void buf_page_free(fil_space_t *space, uint32_t page, mtr_t *mtr);
|
||||
|
||||
/********************************************************************//**
|
||||
Reads the freed_page_clock of a buffer block.
|
||||
|
|
|
|||
|
|
@ -527,8 +527,9 @@ private:
|
|||
}
|
||||
public:
|
||||
MY_ATTRIBUTE((warn_unused_result))
|
||||
/** @return whether a tablespace reference was successfully acquired */
|
||||
inline bool acquire_if_not_stopped(bool have_mutex= false);
|
||||
/** Acquire a tablespace reference.
|
||||
@return whether a tablespace reference was successfully acquired */
|
||||
inline bool acquire_if_not_stopped();
|
||||
|
||||
MY_ATTRIBUTE((warn_unused_result))
|
||||
/** Acquire a tablespace reference for I/O.
|
||||
|
|
@ -1475,17 +1476,6 @@ inline void fil_space_t::reacquire()
|
|||
#endif /* SAFE_MUTEX */
|
||||
}
|
||||
|
||||
inline bool fil_space_t::acquire_if_not_stopped(bool have_mutex)
|
||||
{
|
||||
#ifdef SAFE_MUTEX
|
||||
ut_ad(mysql_mutex_is_owner(&fil_system.mutex) == have_mutex);
|
||||
#endif
|
||||
const uint32_t n= acquire_low();
|
||||
if (UNIV_LIKELY(!(n & (STOPPING | CLOSING))))
|
||||
return true;
|
||||
return UNIV_LIKELY(!(n & CLOSING)) || prepare(have_mutex);
|
||||
}
|
||||
|
||||
/** Note that operations on the tablespace must stop or can resume */
|
||||
inline void fil_space_t::set_stopping(bool stopping)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -511,16 +511,18 @@ inline void mtr_t::memcpy(const buf_block_t &b, void *dest, const void *str,
|
|||
@param[in,out] b buffer page */
|
||||
inline void mtr_t::init(buf_block_t *b)
|
||||
{
|
||||
if (UNIV_LIKELY_NULL(m_freed_pages))
|
||||
const page_id_t id{b->page.id()};
|
||||
ut_ad(is_named_space(id.space()));
|
||||
ut_ad(!m_freed_pages == !m_freed_space);
|
||||
|
||||
if (UNIV_LIKELY_NULL(m_freed_space) &&
|
||||
m_freed_space->id == id.space() &&
|
||||
m_freed_pages->remove_if_exists(b->page.id().page_no()) &&
|
||||
m_freed_pages->empty())
|
||||
{
|
||||
ut_ad(m_log_mode != MTR_LOG_ALL ||
|
||||
m_user_space_id == b->page.id().space());
|
||||
if (m_freed_pages->remove_if_exists(b->page.id().page_no()) &&
|
||||
m_freed_pages->empty())
|
||||
{
|
||||
delete m_freed_pages;
|
||||
m_freed_pages= nullptr;
|
||||
}
|
||||
delete m_freed_pages;
|
||||
m_freed_pages= nullptr;
|
||||
m_freed_space= nullptr;
|
||||
}
|
||||
|
||||
b->page.status= buf_page_t::INIT_ON_FLUSH;
|
||||
|
|
@ -540,15 +542,11 @@ inline void mtr_t::init(buf_block_t *b)
|
|||
@param[in] offset page offset to be freed */
|
||||
inline void mtr_t::free(fil_space_t &space, uint32_t offset)
|
||||
{
|
||||
page_id_t freed_page_id(space.id, offset);
|
||||
if (m_log_mode == MTR_LOG_ALL)
|
||||
m_log.close(log_write<FREE_PAGE>(freed_page_id, nullptr));
|
||||
ut_ad(is_named_space(&space));
|
||||
ut_ad(!m_freed_space || m_freed_space == &space);
|
||||
|
||||
ut_ad(!m_user_space || m_user_space == &space);
|
||||
if (&space == fil_system.sys_space)
|
||||
freed_system_tablespace_page();
|
||||
else
|
||||
m_user_space= &space;
|
||||
if (m_log_mode == MTR_LOG_ALL)
|
||||
m_log.close(log_write<FREE_PAGE>({space.id, offset}, nullptr));
|
||||
}
|
||||
|
||||
/** Write an EXTENDED log record.
|
||||
|
|
|
|||
|
|
@ -306,25 +306,12 @@ public:
|
|||
/** @return true if we are inside the change buffer code */
|
||||
bool is_inside_ibuf() const { return m_inside_ibuf; }
|
||||
|
||||
/** Note that system tablespace page has been freed. */
|
||||
void freed_system_tablespace_page() { m_freed_in_system_tablespace= true; }
|
||||
|
||||
/** Note that pages has been trimed */
|
||||
void set_trim_pages() { m_trim_pages= true; }
|
||||
|
||||
/** @return true if pages has been trimed */
|
||||
bool is_trim_pages() { return m_trim_pages; }
|
||||
|
||||
/** @return whether a page_compressed table was modified */
|
||||
bool is_page_compressed() const
|
||||
{
|
||||
#if defined(HAVE_FALLOC_PUNCH_HOLE_AND_KEEP_SIZE) || defined(_WIN32)
|
||||
return m_user_space && m_user_space->is_compressed();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** 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 */
|
||||
|
|
@ -377,12 +364,6 @@ public:
|
|||
|
||||
/** @return the memo stack */
|
||||
mtr_buf_t* get_memo() { return &m_memo; }
|
||||
|
||||
/** @return true if system tablespace page has been freed */
|
||||
bool is_freed_system_tablespace_page()
|
||||
{
|
||||
return m_freed_in_system_tablespace;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/** @return true if a record was added to the mini-transaction */
|
||||
|
|
@ -588,12 +569,18 @@ public:
|
|||
const char *new_path= nullptr);
|
||||
|
||||
/** Add freed page numbers to freed_pages */
|
||||
void add_freed_offset(page_id_t id)
|
||||
void add_freed_offset(fil_space_t *space, uint32_t page)
|
||||
{
|
||||
ut_ad(m_user_space == NULL || id.space() == m_user_space->id);
|
||||
ut_ad(is_named_space(space));
|
||||
if (!m_freed_pages)
|
||||
{
|
||||
m_freed_pages= new range_set();
|
||||
m_freed_pages->add_value(id.page_no());
|
||||
ut_ad(!m_freed_space);
|
||||
m_freed_space= space;
|
||||
}
|
||||
else
|
||||
ut_ad(m_freed_space == space);
|
||||
m_freed_pages->add_value(page);
|
||||
}
|
||||
|
||||
/** Determine the added buffer fix count of a block.
|
||||
|
|
@ -671,9 +658,6 @@ private:
|
|||
to suppress some read-ahead operations, @see ibuf_inside() */
|
||||
uint16_t m_inside_ibuf:1;
|
||||
|
||||
/** whether the page has been freed in system tablespace */
|
||||
uint16_t m_freed_in_system_tablespace:1;
|
||||
|
||||
/** whether the pages has been trimmed */
|
||||
uint16_t m_trim_pages:1;
|
||||
|
||||
|
|
@ -695,6 +679,8 @@ private:
|
|||
/** LSN at commit time */
|
||||
lsn_t m_commit_lsn;
|
||||
|
||||
/** tablespace where pages have been freed */
|
||||
fil_space_t *m_freed_space= nullptr;
|
||||
/** set of freed page ids */
|
||||
range_set *m_freed_pages= nullptr;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -355,8 +355,10 @@ struct ReleaseBlocks
|
|||
void mtr_t::start()
|
||||
{
|
||||
ut_ad(!m_freed_pages);
|
||||
ut_ad(!m_freed_space);
|
||||
MEM_UNDEFINED(this, sizeof *this);
|
||||
MEM_MAKE_DEFINED(&m_freed_pages, sizeof(m_freed_pages));
|
||||
MEM_MAKE_DEFINED(&m_freed_space, sizeof m_freed_space);
|
||||
MEM_MAKE_DEFINED(&m_freed_pages, sizeof m_freed_pages);
|
||||
|
||||
ut_d(m_start= true);
|
||||
ut_d(m_commit= false);
|
||||
|
|
@ -374,7 +376,7 @@ void mtr_t::start()
|
|||
ut_d(m_user_space_id= TRX_SYS_SPACE);
|
||||
m_user_space= nullptr;
|
||||
m_commit_lsn= 0;
|
||||
m_freed_in_system_tablespace= m_trim_pages= false;
|
||||
m_trim_pages= false;
|
||||
}
|
||||
|
||||
/** Release the resources */
|
||||
|
|
@ -419,28 +421,23 @@ void mtr_t::commit()
|
|||
if (m_freed_pages)
|
||||
{
|
||||
ut_ad(!m_freed_pages->empty());
|
||||
fil_space_t *freed_space= m_user_space;
|
||||
/* Get the freed tablespace in case of predefined tablespace */
|
||||
if (!freed_space)
|
||||
{
|
||||
ut_ad(is_freed_system_tablespace_page());
|
||||
freed_space= fil_system.sys_space;
|
||||
}
|
||||
|
||||
ut_ad(freed_space->is_owner());
|
||||
ut_ad(m_freed_space);
|
||||
ut_ad(m_freed_space->is_owner());
|
||||
ut_ad(is_named_space(m_freed_space));
|
||||
/* Update the last freed lsn */
|
||||
freed_space->update_last_freed_lsn(m_commit_lsn);
|
||||
m_freed_space->update_last_freed_lsn(m_commit_lsn);
|
||||
|
||||
if (!is_trim_pages())
|
||||
for (const auto &range : *m_freed_pages)
|
||||
freed_space->add_free_range(range);
|
||||
m_freed_space->add_free_range(range);
|
||||
else
|
||||
freed_space->clear_freed_ranges();
|
||||
m_freed_space->clear_freed_ranges();
|
||||
delete m_freed_pages;
|
||||
m_freed_pages= nullptr;
|
||||
/* Reset of m_trim_pages and m_freed_in_system_tablespace
|
||||
happens in mtr_t::start() */
|
||||
/* mtr_t::start() will reset m_trim_pages */
|
||||
}
|
||||
else
|
||||
ut_ad(!m_freed_space);
|
||||
|
||||
m_memo.for_each_block_in_reverse(CIterate<const ReleaseBlocks>
|
||||
(ReleaseBlocks(lsns.first, m_commit_lsn,
|
||||
|
|
@ -477,8 +474,8 @@ void mtr_t::commit_files(lsn_t checkpoint_lsn)
|
|||
ut_ad(!m_made_dirty);
|
||||
ut_ad(m_memo.size() == 0);
|
||||
ut_ad(!srv_read_only_mode);
|
||||
ut_ad(!m_freed_space);
|
||||
ut_ad(!m_freed_pages);
|
||||
ut_ad(!m_freed_in_system_tablespace);
|
||||
|
||||
if (checkpoint_lsn) {
|
||||
byte* ptr = m_log.push<byte*>(SIZE_OF_FILE_CHECKPOINT);
|
||||
|
|
|
|||
|
|
@ -622,7 +622,7 @@ trx_undo_free_page(
|
|||
fseg_free_page(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
|
||||
+ header_block->frame,
|
||||
rseg->space, page_no, mtr);
|
||||
buf_page_free(page_id_t(space, page_no), mtr);
|
||||
buf_page_free(rseg->space, page_no, mtr);
|
||||
|
||||
const fil_addr_t last_addr = flst_get_last(
|
||||
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + header_block->frame);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue