diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-08 11:37:43 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-11-08 11:37:43 +0200 |
commit | b737d09dbc6ab588f1b1a61bb98e33ed8000acd7 (patch) | |
tree | 84e56ea9646a8877a2758d374f241ad7cc8501d8 | |
parent | 49a0ad695b83f98993e068d89c02bdcc15724a71 (diff) | |
download | mariadb-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.cc | 5 | ||||
-rw-r--r-- | storage/innobase/ibuf/ibuf0ibuf.cc | 46 | ||||
-rw-r--r-- | storage/innobase/include/ibuf0ibuf.h | 23 |
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 |