mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug#11759044 - 51325: DROPPING AN EMPTY INNODB TABLE TAKES A LONG TIME
WITH LARGE BUFFER POOL (Note: this a backport of revno:3472 from mysql-trunk) rb://845 approved by: Marko When dropping a table (with an .ibd file i.e.: with innodb_file_per_table set) we scan entire LRU to invalidate pages from that table. This can be painful in case of large buffer pools as we hold the buf_pool->mutex for the scan. Note that gravity of the problem does not depend on the size of the table. Even with an empty table but a large and filled up buffer pool we'll end up scanning a very long LRU list. The fix is to scan flush_list and just remove the blocks belonging to the table from the flush_list, marking them as non-dirty. The blocks are left in the LRU list for eventual eviction due to aging. The flush_list is typically much smaller than the LRU list but for cases where it is very long we have the solution of releasing the buf_pool->mutex after scanning 1K pages. buf_page_[set|unset]_sticky(): Use new IO-state BUF_IO_PIN to ensure that a block stays in the flush_list and LRU list when we release buf_pool->mutex. Previously we have been abusing BUF_IO_READ to achieve this.
This commit is contained in:
@ -910,7 +910,27 @@ buf_block_set_io_fix(
|
||||
/*=================*/
|
||||
buf_block_t* block, /*!< in/out: control block */
|
||||
enum buf_io_fix io_fix);/*!< in: io_fix state */
|
||||
|
||||
/*********************************************************************//**
|
||||
Makes a block sticky. A sticky block implies that even after we release
|
||||
the buf_pool->mutex and the block->mutex:
|
||||
* it cannot be removed from the flush_list
|
||||
* the block descriptor cannot be relocated
|
||||
* it cannot be removed from the LRU list
|
||||
Note that:
|
||||
* the block can still change its position in the LRU list
|
||||
* the next and previous pointers can change. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
buf_page_set_sticky(
|
||||
/*================*/
|
||||
buf_page_t* bpage); /*!< in/out: control block */
|
||||
/*********************************************************************//**
|
||||
Removes stickiness of a block. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
buf_page_unset_sticky(
|
||||
/*==================*/
|
||||
buf_page_t* bpage); /*!< in/out: control block */
|
||||
/********************************************************************//**
|
||||
Determine if a buffer block can be relocated in memory. The block
|
||||
can be dirty, but it must not be I/O-fixed or bufferfixed. */
|
||||
|
Reference in New Issue
Block a user