summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-01-14 16:35:05 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-01-14 16:35:05 +0200
commit394fc71f4fa8f8b1b6d24adfead0ec45121d271e (patch)
tree3ba343dba520abb4624b71b893ef1da37b005207
parent6d05a95c652dd0b39dd1337a1514365b58957bf9 (diff)
parentdeadec4e689c9435e20ebb89fd8f84d3f0f90ff3 (diff)
downloadmariadb-git-394fc71f4fa8f8b1b6d24adfead0ec45121d271e.tar.gz
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.
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc8
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc47
-rw-r--r--storage/innobase/include/fil0fil.h11
-rw-r--r--storage/innobase/include/mtr0mtr.h46
-rw-r--r--storage/innobase/include/mtr0types.h6
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc6
6 files changed, 74 insertions, 50 deletions
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 3240d655bd3..24bcbdbb949 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
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
the terms of the GNU General Public License as published by the Free Software
@@ -400,7 +400,7 @@ xdes_get_descriptor_const(
page_no_t offset,
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->size_in_header);
@@ -2563,7 +2563,9 @@ fseg_page_is_free(fil_space_t* space, unsigned page)
page);
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) {
is_free = true;
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 36918640fa8..717aa6a91a4 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
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
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)
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
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
@@ -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);
+ 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) {
/* No changes are buffered for this page. */
space->release();
@@ -4373,18 +4404,8 @@ loop:
}
reset_bit:
- if (!space) {
- } else if (buf_block_t* bitmap = ibuf_bitmap_get_map_page(
- 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);
- }
+ if (space) {
+ ibuf_reset_bitmap(block, page_id, zip_size, &mtr);
}
ibuf_mtr_commit(&mtr);
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 2fbb2a1764e..94740c68410 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -1,7 +1,7 @@
/*****************************************************************************
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
the terms of the GNU General Public License as published by the Free Software
@@ -398,7 +398,7 @@ private:
static constexpr uint32_t PENDING= ~(STOPPING | CLOSING | NEEDS_FSYNC);
/** latch protecting all page allocation bitmap pages */
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;)
public:
UT_LIST_NODE_T(fil_space_t) named_spaces;
@@ -996,14 +996,14 @@ public:
#ifdef UNIV_DEBUG
bool is_latched() const { return latch_count != 0; }
- bool is_owner() const { return latch_owner == os_thread_get_curr_id(); }
#endif
+ bool is_owner() const { return latch_owner == os_thread_get_curr_id(); }
/** Acquire the allocation latch in exclusive mode */
void x_lock()
{
latch.wr_lock(SRW_LOCK_CALL);
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));
}
/** Release the allocation latch from exclusive mode */
@@ -1011,12 +1011,13 @@ public:
{
ut_ad(latch_count.fetch_sub(1) == 1);
ut_ad(latch_owner == os_thread_get_curr_id());
- ut_d(latch_owner= 0);
+ latch_owner= 0;
latch.wr_unlock();
}
/** Acquire the allocation latch in shared mode */
void s_lock()
{
+ ut_ad(!is_owner());
latch.rd_lock(SRW_LOCK_CALL);
ut_ad(!latch_owner);
ut_d(latch_count.fetch_add(1));
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 448a0af3b27..3c6cddf87ba 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
the terms of the GNU General Public License as published by the Free Software
@@ -253,29 +253,29 @@ struct mtr_t {
memo_push(lock, MTR_MEMO_SX_LOCK);
}
- /** Acquire a tablespace S-latch.
- @param[in] space tablespace */
- void s_lock_space(fil_space_t* space)
- {
- ut_ad(space->purpose == FIL_TYPE_TEMPORARY
- || space->purpose == FIL_TYPE_IMPORT
- || space->purpose == FIL_TYPE_TABLESPACE);
- memo_push(space, MTR_MEMO_SPACE_S_LOCK);
- space->s_lock();
- }
+ /** Acquire a tablespace S-latch.
+ @param space tablespace */
+ void s_lock_space(fil_space_t *space)
+ {
+ ut_ad(space->purpose == FIL_TYPE_TEMPORARY ||
+ space->purpose == FIL_TYPE_IMPORT ||
+ space->purpose == FIL_TYPE_TABLESPACE);
+ memo_push(space, MTR_MEMO_SPACE_S_LOCK);
+ space->s_lock();
+ }
- /** Acquire a tablespace X-latch.
- @param[in] space tablespace */
- void x_lock_space(fil_space_t* space);
- /** Release an object in the memo stack.
- @param object object
- @param type object type
- @return bool if lock released */
- bool memo_release(const void* object, ulint type);
- /** Release a page latch.
- @param[in] ptr pointer to within a page frame
- @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */
- void release_page(const void* ptr, mtr_memo_type_t type);
+ /** Acquire an exclusive tablespace latch.
+ @param space tablespace */
+ void x_lock_space(fil_space_t *space);
+ /** Release an object in the memo stack.
+ @param object object
+ @param type object type
+ @return bool if lock released */
+ bool memo_release(const void *object, ulint type);
+ /** Release a page latch.
+ @param[in] ptr pointer to within a page frame
+ @param[in] type object type: MTR_MEMO_PAGE_X_FIX, ... */
+ void release_page(const void *ptr, mtr_memo_type_t type);
private:
/** Note that the mini-transaction will modify data. */
diff --git a/storage/innobase/include/mtr0types.h b/storage/innobase/include/mtr0types.h
index 5445dc0a763..c09aa644b44 100644
--- a/storage/innobase/include/mtr0types.h
+++ b/storage/innobase/include/mtr0types.h
@@ -1,7 +1,7 @@
/*****************************************************************************
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
the terms of the GNU General Public License as published by the Free Software
@@ -336,9 +336,9 @@ enum mtr_memo_type_t {
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 */
+ 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
};
#endif /* !UNIV_INNOCHECKSUM */
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index 7db9494e26f..4f80bc0c7a4 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
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
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)
return(space);
}
-/** Acquire a tablespace X-latch.
-@param[in] space tablespace */
+/** Acquire an exclusive tablespace latch.
+@param space tablespace */
void mtr_t::x_lock_space(fil_space_t *space)
{
ut_ad(space->purpose == FIL_TYPE_TEMPORARY ||