Commit 394fc71f authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-24569: Merge 10.5 into 10.6

fseg_page_is_free(): Because MDEV-24167 changed fil_space_t::latch
to a simple non-recursive rw-lock, we must avoid acquiring a shared
latch if the current thread already holds an exclusive latch.
This affects the test innodb.innodb_bug59733, which is exercising
the change buffer.

fil_space_t::is_owner(): Make available in non-debug builds.
parents 6d05a95c deadec4e
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation. Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -400,7 +400,7 @@ xdes_get_descriptor_const( ...@@ -400,7 +400,7 @@ xdes_get_descriptor_const(
page_no_t offset, page_no_t offset,
mtr_t* mtr) mtr_t* mtr)
{ {
ut_ad(mtr->memo_contains(*space, true)); ut_ad(space->is_owner() || mtr->memo_contains(*space, true));
ut_ad(offset < space->free_limit); ut_ad(offset < space->free_limit);
ut_ad(offset < space->size_in_header); ut_ad(offset < space->size_in_header);
...@@ -2563,7 +2563,9 @@ fseg_page_is_free(fil_space_t* space, unsigned page) ...@@ -2563,7 +2563,9 @@ fseg_page_is_free(fil_space_t* space, unsigned page)
page); page);
mtr.start(); mtr.start();
mtr.s_lock_space(space); if (!space->is_owner()) {
mtr.s_lock_space(space);
}
if (page >= space->free_limit || page >= space->size_in_header) { if (page >= space->free_limit || page >= space->size_in_header) {
is_free = true; is_free = true;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2020, MariaDB Corporation. Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -4109,6 +4109,29 @@ bool ibuf_page_exists(const page_id_t id, ulint zip_size) ...@@ -4109,6 +4109,29 @@ bool ibuf_page_exists(const page_id_t id, ulint zip_size)
return bitmap_bits; return bitmap_bits;
} }
/** Reset the bits in the bitmap page for the given block and page id.
@param b X-latched secondary index page (nullptr to discard changes)
@param page_id page identifier
@param zip_size ROW_FORMAT=COMPRESSED page size, or 0
@param mtr mini-transaction */
static void ibuf_reset_bitmap(buf_block_t *b, page_id_t page_id,
ulint zip_size, mtr_t *mtr)
{
buf_block_t *bitmap= ibuf_bitmap_get_map_page(page_id, zip_size, mtr);
if (!bitmap)
return;
const ulint physical_size = zip_size ? zip_size : srv_page_size;
/* FIXME: update the bitmap byte only once! */
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>(bitmap, page_id,
physical_size, false, mtr);
if (b)
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(bitmap, page_id, physical_size,
ibuf_index_page_calc_free(b),
mtr);
}
/** When an index page is read from a disk to the buffer pool, this function /** When an index page is read from a disk to the buffer pool, this function
applies any buffered operations to the page and deletes the entries from the applies any buffered operations to the page and deletes the entries from the
insert buffer. If the page is not read, but created in the buffer pool, this insert buffer. If the page is not read, but created in the buffer pool, this
...@@ -4170,6 +4193,14 @@ void ibuf_merge_or_delete_for_page(buf_block_t *block, const page_id_t page_id, ...@@ -4170,6 +4193,14 @@ void ibuf_merge_or_delete_for_page(buf_block_t *block, const page_id_t page_id,
ibuf_mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
if (bitmap_bits && fseg_page_is_free(
space, page_id.page_no())) {
ibuf_mtr_start(&mtr);
ibuf_reset_bitmap(block, page_id, zip_size, &mtr);
ibuf_mtr_commit(&mtr);
bitmap_bits = 0;
}
if (!bitmap_bits) { if (!bitmap_bits) {
/* No changes are buffered for this page. */ /* No changes are buffered for this page. */
space->release(); space->release();
...@@ -4373,18 +4404,8 @@ void ibuf_merge_or_delete_for_page(buf_block_t *block, const page_id_t page_id, ...@@ -4373,18 +4404,8 @@ void ibuf_merge_or_delete_for_page(buf_block_t *block, const page_id_t page_id,
} }
reset_bit: reset_bit:
if (!space) { if (space) {
} else if (buf_block_t* bitmap = ibuf_bitmap_get_map_page( ibuf_reset_bitmap(block, page_id, zip_size, &mtr);
page_id, zip_size, &mtr)) {
/* FIXME: update the bitmap byte only once! */
ibuf_bitmap_page_set_bits<IBUF_BITMAP_BUFFERED>(
bitmap, page_id, physical_size, false, &mtr);
if (block != NULL) {
ibuf_bitmap_page_set_bits<IBUF_BITMAP_FREE>(
bitmap, page_id, physical_size,
ibuf_index_page_calc_free(block), &mtr);
}
} }
ibuf_mtr_commit(&mtr); ibuf_mtr_commit(&mtr);
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2020, MariaDB Corporation. Copyright (c) 2013, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -398,7 +398,7 @@ struct fil_space_t final ...@@ -398,7 +398,7 @@ struct fil_space_t final
static constexpr uint32_t PENDING= ~(STOPPING | CLOSING | NEEDS_FSYNC); static constexpr uint32_t PENDING= ~(STOPPING | CLOSING | NEEDS_FSYNC);
/** latch protecting all page allocation bitmap pages */ /** latch protecting all page allocation bitmap pages */
srw_lock latch; srw_lock latch;
ut_d(os_thread_id_t latch_owner;) os_thread_id_t latch_owner;
ut_d(Atomic_relaxed<uint32_t> latch_count;) ut_d(Atomic_relaxed<uint32_t> latch_count;)
public: public:
UT_LIST_NODE_T(fil_space_t) named_spaces; UT_LIST_NODE_T(fil_space_t) named_spaces;
...@@ -996,14 +996,14 @@ struct fil_space_t final ...@@ -996,14 +996,14 @@ struct fil_space_t final
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
bool is_latched() const { return latch_count != 0; } bool is_latched() const { return latch_count != 0; }
bool is_owner() const { return latch_owner == os_thread_get_curr_id(); }
#endif #endif
bool is_owner() const { return latch_owner == os_thread_get_curr_id(); }
/** Acquire the allocation latch in exclusive mode */ /** Acquire the allocation latch in exclusive mode */
void x_lock() void x_lock()
{ {
latch.wr_lock(SRW_LOCK_CALL); latch.wr_lock(SRW_LOCK_CALL);
ut_ad(!latch_owner); ut_ad(!latch_owner);
ut_d(latch_owner= os_thread_get_curr_id()); latch_owner= os_thread_get_curr_id();
ut_ad(!latch_count.fetch_add(1)); ut_ad(!latch_count.fetch_add(1));
} }
/** Release the allocation latch from exclusive mode */ /** Release the allocation latch from exclusive mode */
...@@ -1011,12 +1011,13 @@ struct fil_space_t final ...@@ -1011,12 +1011,13 @@ struct fil_space_t final
{ {
ut_ad(latch_count.fetch_sub(1) == 1); ut_ad(latch_count.fetch_sub(1) == 1);
ut_ad(latch_owner == os_thread_get_curr_id()); ut_ad(latch_owner == os_thread_get_curr_id());
ut_d(latch_owner= 0); latch_owner= 0;
latch.wr_unlock(); latch.wr_unlock();
} }
/** Acquire the allocation latch in shared mode */ /** Acquire the allocation latch in shared mode */
void s_lock() void s_lock()
{ {
ut_ad(!is_owner());
latch.rd_lock(SRW_LOCK_CALL); latch.rd_lock(SRW_LOCK_CALL);
ut_ad(!latch_owner); ut_ad(!latch_owner);
ut_d(latch_count.fetch_add(1)); ut_d(latch_count.fetch_add(1));
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc. Copyright (c) 2012, Facebook Inc.
Copyright (c) 2013, 2020, MariaDB Corporation. Copyright (c) 2013, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -253,29 +253,29 @@ struct mtr_t { ...@@ -253,29 +253,29 @@ struct mtr_t {
memo_push(lock, MTR_MEMO_SX_LOCK); memo_push(lock, MTR_MEMO_SX_LOCK);
} }
/** Acquire a tablespace S-latch. /** Acquire a tablespace S-latch.
@param[in] space tablespace */ @param space tablespace */
void s_lock_space(fil_space_t* space) void s_lock_space(fil_space_t *space)
{ {
ut_ad(space->purpose == FIL_TYPE_TEMPORARY ut_ad(space->purpose == FIL_TYPE_TEMPORARY ||
|| space->purpose == FIL_TYPE_IMPORT space->purpose == FIL_TYPE_IMPORT ||
|| space->purpose == FIL_TYPE_TABLESPACE); space->purpose == FIL_TYPE_TABLESPACE);
memo_push(space, MTR_MEMO_SPACE_S_LOCK); memo_push(space, MTR_MEMO_SPACE_S_LOCK);
space->s_lock(); space->s_lock();
} }
/** Acquire a tablespace X-latch. /** Acquire an exclusive tablespace latch.
@param[in] space tablespace */ @param space tablespace */
void x_lock_space(fil_space_t* space); void x_lock_space(fil_space_t *space);
/** Release an object in the memo stack. /** Release an object in the memo stack.
@param object object @param object object
@param type object type @param type object type
@return bool if lock released */ @return bool if lock released */
bool memo_release(const void* object, ulint type); bool memo_release(const void *object, ulint type);
/** Release a page latch. /** Release a page latch.
@param[in] ptr pointer to within a page frame @param[in] ptr pointer to within a page frame
@param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */ @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */
void release_page(const void* ptr, mtr_memo_type_t type); void release_page(const void *ptr, mtr_memo_type_t type);
private: private:
/** Note that the mini-transaction will modify data. */ /** Note that the mini-transaction will modify data. */
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation. Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -336,9 +336,9 @@ enum mtr_memo_type_t { ...@@ -336,9 +336,9 @@ enum mtr_memo_type_t {
MTR_MEMO_SX_LOCK = RW_SX_LATCH << 5, MTR_MEMO_SX_LOCK = RW_SX_LATCH << 5,
/** rd_lock() on fil_space_t::latch */
MTR_MEMO_SPACE_X_LOCK = MTR_MEMO_SX_LOCK << 1,
/** wr_lock() on fil_space_t::latch */ /** wr_lock() on fil_space_t::latch */
MTR_MEMO_SPACE_X_LOCK = MTR_MEMO_SX_LOCK << 1,
/** rd_lock() on fil_space_t::latch */
MTR_MEMO_SPACE_S_LOCK = MTR_MEMO_SX_LOCK << 2 MTR_MEMO_SPACE_S_LOCK = MTR_MEMO_SX_LOCK << 2
}; };
#endif /* !UNIV_INNOCHECKSUM */ #endif /* !UNIV_INNOCHECKSUM */
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2020, MariaDB Corporation. Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -569,8 +569,8 @@ mtr_t::x_lock_space(ulint space_id) ...@@ -569,8 +569,8 @@ mtr_t::x_lock_space(ulint space_id)
return(space); return(space);
} }
/** Acquire a tablespace X-latch. /** Acquire an exclusive tablespace latch.
@param[in] space tablespace */ @param space tablespace */
void mtr_t::x_lock_space(fil_space_t *space) void mtr_t::x_lock_space(fil_space_t *space)
{ {
ut_ad(space->purpose == FIL_TYPE_TEMPORARY || ut_ad(space->purpose == FIL_TYPE_TEMPORARY ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment