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.
This commit is contained in:
parent
49a0ad695b
commit
b737d09dbc
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user