summaryrefslogtreecommitdiffstats
path: root/storage/innobase/ibuf
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 13:22:53 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 13:22:53 +0000
commit347c164c35eddab388009470e6848cb361ac93f8 (patch)
tree2c0c44eac690f510bb0a35b2a13b36d606b77b6b /storage/innobase/ibuf
parentReleasing progress-linux version 1:10.11.7-4~progress7.99u1. (diff)
downloadmariadb-347c164c35eddab388009470e6848cb361ac93f8.tar.xz
mariadb-347c164c35eddab388009470e6848cb361ac93f8.zip
Merging upstream version 1:10.11.8.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'storage/innobase/ibuf')
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc61
1 files changed, 27 insertions, 34 deletions
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 4ec07b81..e77401ed 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -24,6 +24,7 @@ Insert buffer
Created 7/19/1997 Heikki Tuuri
*******************************************************/
+#include <tuple>
#include "ibuf0ibuf.h"
#include "btr0sea.h"
@@ -1833,7 +1834,7 @@ corrupted:
err = flst_add_last(ibuf_root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
block, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE,
- &mtr);
+ fil_system.sys_space->free_limit, &mtr);
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
goto corrupted;
}
@@ -1864,7 +1865,6 @@ Removes a page from the free list and frees it to the fsp system. */
static void ibuf_remove_free_page()
{
mtr_t mtr;
- mtr_t mtr2;
page_t* header_page;
log_free_check();
@@ -1891,26 +1891,28 @@ early_exit:
return;
}
- ibuf_mtr_start(&mtr2);
-
- buf_block_t* root = ibuf_tree_root_get(&mtr2);
+ buf_block_t* root = ibuf_tree_root_get(&mtr);
if (UNIV_UNLIKELY(!root)) {
- ibuf_mtr_commit(&mtr2);
goto early_exit;
}
- mysql_mutex_unlock(&ibuf_mutex);
-
+ const auto root_savepoint = mtr.get_savepoint() - 1;
const uint32_t page_no = flst_get_last(PAGE_HEADER
+ PAGE_BTR_IBUF_FREE_LIST
+ root->page.frame).page;
+ if (page_no >= fil_system.sys_space->free_limit) {
+ goto early_exit;
+ }
+
+ mysql_mutex_unlock(&ibuf_mutex);
+
/* NOTE that we must release the latch on the ibuf tree root
because in fseg_free_page we access level 1 pages, and the root
is a level 2 page. */
-
- ibuf_mtr_commit(&mtr2);
+ root->page.lock.u_unlock();
+ mtr.lock_register(root_savepoint, MTR_MEMO_BUF_FIX);
ibuf_exit(&mtr);
/* Since pessimistic inserts were prevented, we know that the
@@ -1933,15 +1935,7 @@ early_exit:
ibuf_enter(&mtr);
mysql_mutex_lock(&ibuf_mutex);
-
- root = ibuf_tree_root_get(&mtr, &err);
- if (UNIV_UNLIKELY(!root)) {
- mysql_mutex_unlock(&ibuf_pessimistic_insert_mutex);
- goto func_exit;
- }
-
- ut_ad(page_no == flst_get_last(PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST
- + root->page.frame).page);
+ mtr.upgrade_buffer_fix(root_savepoint, RW_X_LATCH);
/* Remove the page from the free list and update the ibuf size data */
if (buf_block_t* block =
@@ -1950,7 +1944,7 @@ early_exit:
err = flst_remove(root, PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
block,
PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE,
- &mtr);
+ fil_system.sys_space->free_limit, &mtr);
}
mysql_mutex_unlock(&ibuf_pessimistic_insert_mutex);
@@ -2332,7 +2326,8 @@ func_exit:
/** Merge the change buffer to some pages. */
static void ibuf_read_merge_pages(const uint32_t* space_ids,
- const uint32_t* page_nos, ulint n_stored)
+ const uint32_t* page_nos, ulint n_stored,
+ bool slow_shutdown_cleanup)
{
for (ulint i = 0; i < n_stored; i++) {
const uint32_t space_id = space_ids[i];
@@ -2357,30 +2352,28 @@ tablespace_deleted:
if (UNIV_LIKELY(page_nos[i] < size)) {
mtr.start();
dberr_t err;
- buf_block_t *block =
+ /* Load the page and apply change buffers. */
+ std::ignore =
buf_page_get_gen(page_id_t(space_id, page_nos[i]),
zip_size, RW_X_LATCH, nullptr,
BUF_GET_POSSIBLY_FREED,
&mtr, &err, true);
- bool remove = !block
- || fil_page_get_type(block->page.frame)
- != FIL_PAGE_INDEX
- || !page_is_leaf(block->page.frame);
mtr.commit();
if (err == DB_TABLESPACE_DELETED) {
s->x_unlock();
goto tablespace_deleted;
}
- if (!remove) {
- s->x_unlock();
- continue;
- }
}
s->x_unlock();
- if (srv_shutdown_state == SRV_SHUTDOWN_NONE
- || srv_fast_shutdown) {
+ /* During slow shutdown cleanup, we apply all pending IBUF
+ changes and need to cleanup any left-over IBUF records. There
+ are a few cases when the changes are already discarded and IBUF
+ bitmap is cleaned but we miss to delete the record. Even after
+ the issues are fixed, we need to keep this safety measure for
+ upgraded DBs with such left over records. */
+ if (!slow_shutdown_cleanup) {
continue;
}
@@ -2451,7 +2444,7 @@ ATTRIBUTE_COLD ulint ibuf_contract()
space_ids, page_nos, &n_pages);
ibuf_mtr_commit(&mtr);
- ibuf_read_merge_pages(space_ids, page_nos, n_pages);
+ ibuf_read_merge_pages(space_ids, page_nos, n_pages, true);
return(sum_sizes + 1);
}
@@ -2532,7 +2525,7 @@ ibuf_merge_space(
}
#endif /* UNIV_DEBUG */
- ibuf_read_merge_pages(spaces, pages, n_pages);
+ ibuf_read_merge_pages(spaces, pages, n_pages, false);
}
return(n_pages);