summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-11-08 11:37:43 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2022-11-08 11:37:43 +0200
commitb737d09dbc6ab588f1b1a61bb98e33ed8000acd7 (patch)
tree84e56ea9646a8877a2758d374f241ad7cc8501d8
parent49a0ad695b83f98993e068d89c02bdcc15724a71 (diff)
downloadmariadb-git-b737d09dbc6ab588f1b1a61bb98e33ed8000acd7.tar.gz
MDEV-29905 Change buffer operations fail to check for log file overflow
Every operation that is going to write redo log is supposed to invoke log_free_check() before acquiring any latches. If there is a risk of log buffer overrun, a log checkpoint would be triggered by that call. ibuf_merge_space(), ibuf_merge_in_background(), ibuf_delete_for_discarded_space(): Invoke log_free_check() when the current thread is not holding any page latches. Unfortunately, in lower-level code called from ibuf_insert() or ibuf_merge_or_delete_for_page(), some page latches may be held and a call to log_free_check() could hang. ibuf_set_bitmap_for_bulk_load(): Use the caller's mini-transaction. The caller should have invoked log_free_check() while not holding any page latches.
-rw-r--r--storage/innobase/btr/btr0bulk.cc5
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc46
-rw-r--r--storage/innobase/include/ibuf0ibuf.h23
3 files changed, 28 insertions, 46 deletions
diff --git a/storage/innobase/btr/btr0bulk.cc b/storage/innobase/btr/btr0bulk.cc
index 0b53438feb7..cf14ffc5376 100644
--- a/storage/innobase/btr/btr0bulk.cc
+++ b/storage/innobase/btr/btr0bulk.cc
@@ -398,8 +398,9 @@ PageBulk::finish()
void PageBulk::commit(bool success)
{
finish();
- if (success && !dict_index_is_clust(m_index) && page_is_leaf(m_page))
- ibuf_set_bitmap_for_bulk_load(m_block, innobase_fill_factor == 100);
+ if (success && !m_index->is_clust() && page_is_leaf(m_page))
+ ibuf_set_bitmap_for_bulk_load(m_block, &m_mtr,
+ innobase_fill_factor == 100);
m_mtr.commit();
}
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index 65abacf3fd5..ce6705ea369 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -1067,12 +1067,12 @@ bitmap page)
bitmap page if the page is not one of the fixed address ibuf pages, or NULL,
in which case a new transaction is created.
@return TRUE if level 2 or level 3 page */
-ibool
+bool
ibuf_page_low(
const page_id_t page_id,
const page_size_t& page_size,
#ifdef UNIV_DEBUG
- ibool x_latch,
+ bool x_latch,
#endif /* UNIV_DEBUG */
const char* file,
unsigned line,
@@ -1954,10 +1954,7 @@ ibuf_data_too_much_free(void)
Allocates a new page from the ibuf file segment and adds it to the free
list.
@return TRUE on success, FALSE if no space left */
-static
-ibool
-ibuf_add_free_page(void)
-/*====================*/
+static bool ibuf_add_free_page()
{
mtr_t mtr;
page_t* header_page;
@@ -1966,7 +1963,7 @@ ibuf_add_free_page(void)
page_t* root;
page_t* bitmap_page;
- mtr_start(&mtr);
+ mtr.start();
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
mtr_x_lock_space(fil_system.sys_space, &mtr);
@@ -1987,9 +1984,8 @@ ibuf_add_free_page(void)
&mtr);
if (block == NULL) {
- mtr_commit(&mtr);
-
- return(FALSE);
+ mtr.commit();
+ return false;
}
ut_ad(rw_lock_get_x_lock_count(&block->lock) == 1);
@@ -2023,8 +2019,7 @@ ibuf_add_free_page(void)
IBUF_BITMAP_IBUF, TRUE, &mtr);
ibuf_mtr_commit(&mtr);
-
- return(TRUE);
+ return true;
}
/*********************************************************************//**
@@ -2520,6 +2515,7 @@ ibuf_merge_space(
ut_ad(space < SRV_LOG_SPACE_FIRST_ID);
+ log_free_check();
ibuf_mtr_start(&mtr);
/* Position the cursor on the first matching record. */
@@ -2675,6 +2671,8 @@ ibuf_merge_in_background(
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
while (sum_pages < n_pages) {
+ log_free_check();
+
ulint n_bytes;
n_bytes = ibuf_merge(&n_pag2, false);
@@ -4729,6 +4727,7 @@ ibuf_delete_for_discarded_space(
memset(dops, 0, sizeof(dops));
loop:
+ log_free_check();
ibuf_mtr_start(&mtr);
/* Position pcur in the insert buffer at the first entry for the
@@ -4886,9 +4885,6 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
}
mtr_start(&mtr);
-
- mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
-
ibuf_enter(&mtr);
bitmap_page = ibuf_bitmap_get_map_page(
@@ -4978,36 +4974,24 @@ dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
return(DB_SUCCESS);
}
-/** Updates free bits and buffered bits for bulk loaded page.
-@param[in] block index page
-@param[in] reset flag if reset free val */
-void
-ibuf_set_bitmap_for_bulk_load(
- buf_block_t* block,
- bool reset)
+void ibuf_set_bitmap_for_bulk_load(buf_block_t *block, mtr_t *mtr, bool reset)
{
page_t* bitmap_page;
- mtr_t mtr;
ulint free_val;
ut_a(page_is_leaf(buf_block_get_frame(block)));
free_val = ibuf_index_page_calc_free(block);
- mtr_start(&mtr);
- mtr.set_named_space_id(block->page.id.space());
-
bitmap_page = ibuf_bitmap_get_map_page(block->page.id,
- block->page.size, &mtr);
+ block->page.size, mtr);
free_val = reset ? 0 : ibuf_index_page_calc_free(block);
ibuf_bitmap_page_set_bits(
bitmap_page, block->page.id, block->page.size,
- IBUF_BITMAP_FREE, free_val, &mtr);
+ IBUF_BITMAP_FREE, free_val, mtr);
ibuf_bitmap_page_set_bits(
bitmap_page, block->page.id, block->page.size,
- IBUF_BITMAP_BUFFERED, FALSE, &mtr);
-
- mtr_commit(&mtr);
+ IBUF_BITMAP_BUFFERED, FALSE, mtr);
}
diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
index f9d9ab27549..94fd56c62d6 100644
--- a/storage/innobase/include/ibuf0ibuf.h
+++ b/storage/innobase/include/ibuf0ibuf.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2016, 2019, MariaDB Corporation.
+Copyright (c) 2016, 2022, 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
@@ -261,12 +261,12 @@ bitmap page)
bitmap page if the page is not one of the fixed address ibuf pages, or NULL,
in which case a new transaction is created.
@return TRUE if level 2 or level 3 page */
-ibool
+bool
ibuf_page_low(
const page_id_t page_id,
const page_size_t& page_size,
#ifdef UNIV_DEBUG
- ibool x_latch,
+ bool x_latch,
#endif /* UNIV_DEBUG */
const char* file,
unsigned line,
@@ -274,7 +274,6 @@ ibuf_page_low(
MY_ATTRIBUTE((warn_unused_result));
#ifdef UNIV_DEBUG
-
/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
Must not be called when recv_no_ibuf_operations==true.
@param[in] page_id tablespace/page identifier
@@ -284,7 +283,7 @@ Must not be called when recv_no_ibuf_operations==true.
# define ibuf_page(page_id, page_size, mtr) \
ibuf_page_low(page_id, page_size, TRUE, __FILE__, __LINE__, mtr)
-#else /* UVIV_DEBUG */
+#else /* UNIV_DEBUG */
/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
Must not be called when recv_no_ibuf_operations==true.
@@ -295,7 +294,7 @@ Must not be called when recv_no_ibuf_operations==true.
# define ibuf_page(page_id, page_size, mtr) \
ibuf_page_low(page_id, page_size, __FILE__, __LINE__, mtr)
-#endif /* UVIV_DEBUG */
+#endif /* UNIV_DEBUG */
/***********************************************************************//**
Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a
@@ -418,13 +417,11 @@ ibuf_close(void);
dberr_t ibuf_check_bitmap_on_import(const trx_t* trx, fil_space_t* space)
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/** Updates free bits and buffered bits for bulk loaded page.
-@param[in] block index page
-@param]in] reset flag if reset free val */
-void
-ibuf_set_bitmap_for_bulk_load(
- buf_block_t* block,
- bool reset);
+/** Update free bits and buffered bits for bulk loaded page.
+@param block secondary index leaf page
+@param mtr mini-transaction
+@param reset whether the page is full */
+void ibuf_set_bitmap_for_bulk_load(buf_block_t *block, mtr_t *mtr, bool reset);
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO