mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 11:27:39 +02:00
MDEV-6936: Buffer pool list scan optimization
Merged Facebook commit 617aef9f911d825e9053f3d611d0389e02031225 authored by Inaam Rana to InnoDB storage engine (not XtraDB) from https://github.com/facebook/mysql-5.6 WL#7047 - Optimize buffer pool list scans and related batch processing Reduce excessive scanning of pages when doing flush list batches. The fix is to introduce the concept of "Hazard Pointer", this reduces the time complexity of the scan from O(n*n) to O. The concept of hazard pointer is reversed in this work. Academically hazard pointer is a pointer that the thread working on it will declar such and as long as that thread is not done no other thread is allowe do anything with it. In this WL we declare the pointer as a hazard pointer and then if any thread attempts to work on it, it is allowed to do so but it has to a the hazard pointer to the next valid value. We use hazard pointer sol reverse traversal of lists within a buffer pool instance. Add an event to control the background flush thread. The background f thread wait has been converted to an os event timed wait so that it c signalled by threads that want to kick start a background flush when buffer pool is running low on free/dirty pages.
This commit is contained in:
parent
84de277099
commit
a03dd94be8
18 changed files with 776 additions and 512 deletions
|
|
@ -37,6 +37,17 @@ Created 11/5/1995 Heikki Tuuri
|
|||
/** Flag indicating if the page_cleaner is in active state. */
|
||||
extern ibool buf_page_cleaner_is_active;
|
||||
|
||||
/** Event to synchronise with the flushing. */
|
||||
extern os_event_t buf_flush_event;
|
||||
|
||||
/** Handled page counters for a single flush */
|
||||
struct flush_counters_t {
|
||||
ulint flushed; /*!< number of dirty pages flushed */
|
||||
ulint evicted; /*!< number of clean pages evicted */
|
||||
ulint unzip_LRU_evicted;/*!< number of uncompressed page images
|
||||
evicted */
|
||||
};
|
||||
|
||||
/********************************************************************//**
|
||||
Remove a block from the flush list of modified blocks. */
|
||||
UNIV_INTERN
|
||||
|
|
@ -111,12 +122,12 @@ buf_flush_list(
|
|||
which were processed is passed
|
||||
back to caller. Ignored if NULL */
|
||||
/******************************************************************//**
|
||||
This function picks up a single dirty page from the tail of the LRU
|
||||
list, flushes it, removes it from page_hash and LRU list and puts
|
||||
it on the free list. It is called from user threads when they are
|
||||
unable to find a replacable page at the tail of the LRU list i.e.:
|
||||
when the background LRU flushing in the page_cleaner thread is not
|
||||
fast enough to keep pace with the workload.
|
||||
This function picks up a single page from the tail of the LRU
|
||||
list, flushes it (if it is dirty), removes it from page_hash and LRU
|
||||
list and puts it on the free list. It is called from user threads when
|
||||
they are unable to find a replaceable page at the tail of the LRU
|
||||
list i.e.: when the background LRU flushing in the page_cleaner thread
|
||||
is not fast enough to keep pace with the workload.
|
||||
@return TRUE if success. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
|
|
@ -309,9 +320,9 @@ This utility flushes dirty blocks from the end of the LRU list or flush_list.
|
|||
NOTE 1: in the case of an LRU flush the calling thread may own latches to
|
||||
pages: to avoid deadlocks, this function must be written so that it cannot
|
||||
end up waiting for these latches! NOTE 2: in the case of a flush list flush,
|
||||
the calling thread is not allowed to own any latches on pages!
|
||||
@return number of blocks for which the write request was queued */
|
||||
ulint
|
||||
the calling thread is not allowed to own any latches on pages! */
|
||||
__attribute__((nonnull))
|
||||
void
|
||||
buf_flush_batch(
|
||||
/*============*/
|
||||
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
|
||||
|
|
@ -322,11 +333,13 @@ buf_flush_batch(
|
|||
ulint min_n, /*!< in: wished minimum mumber of blocks
|
||||
flushed (it is not guaranteed that the
|
||||
actual number is that big, though) */
|
||||
lsn_t lsn_limit); /*!< in: in the case of BUF_FLUSH_LIST
|
||||
lsn_t lsn_limit, /*!< in: in the case of BUF_FLUSH_LIST
|
||||
all blocks whose oldest_modification is
|
||||
smaller than this should be flushed
|
||||
(if their number does not exceed
|
||||
min_n), otherwise ignored */
|
||||
flush_counters_t* n); /*!< out: flushed/evicted page
|
||||
counts */
|
||||
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue