1
/*****************************************************************************
3
Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc.,
15
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/buf0lru.h
21
The database buffer pool LRU replacement algorithm
23
Created 11/5/1995 Heikki Tuuri
24
*******************************************************/
30
#ifndef UNIV_HOTBACKUP
32
#include "buf0types.h"
34
// Forward declaration
37
/******************************************************************//**
38
Returns TRUE if less than 25 % of the buffer pool is available. This can be
39
used in heuristics to prevent huge transactions eating up the whole buffer
41
@return TRUE if less than 25 % of buffer pool left */
44
buf_LRU_buf_pool_running_out(void);
45
/*==============================*/
47
/*#######################################################################
48
These are low-level functions
49
#########################################################################*/
51
/** Minimum LRU list length for which the LRU_old pointer is defined */
52
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
54
/******************************************************************//**
55
Flushes all dirty pages or removes all pages belonging
56
to a given tablespace. A PROBLEM: if readahead is being started, what
57
guarantees that it will not try to read in pages after this operation
61
buf_LRU_flush_or_remove_pages(
62
/*==========================*/
63
ulint id, /*!< in: space id */
64
buf_remove_t buf_remove, /*!< in: remove or flush strategy */
65
const trx_t* trx); /*!< to check if the operation must
68
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
69
/********************************************************************//**
70
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
73
buf_LRU_insert_zip_clean(
74
/*=====================*/
75
buf_page_t* bpage); /*!< in: pointer to the block in question */
76
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
78
/******************************************************************//**
79
Try to free a block. If bpage is a descriptor of a compressed-only
80
page, the descriptor object will be freed as well.
82
NOTE: If this function returns true, it will temporarily
83
release buf_pool->mutex. Furthermore, the page frame will no longer be
86
The caller must hold buf_pool->mutex and must not hold any
87
buf_page_get_mutex() when calling this function.
88
@return true if freed, false otherwise. */
93
buf_page_t* bpage, /*!< in: block to be freed */
94
bool zip) /*!< in: true if should remove also the
95
compressed page of an uncompressed page */
96
__attribute__((nonnull));
97
/******************************************************************//**
98
Try to free a replaceable block.
99
@return TRUE if found and freed */
102
buf_LRU_scan_and_free_block(
103
/*========================*/
104
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
105
ibool scan_all) /*!< in: scan whole LRU list
106
if TRUE, otherwise scan only
108
__attribute__((nonnull,warn_unused_result));
109
/******************************************************************//**
110
Returns a free block from the buf_pool. The block is taken off the
111
free list. If it is empty, returns NULL.
112
@return a free control block, or NULL if the buf_block->free list is empty */
115
buf_LRU_get_free_only(
116
/*==================*/
117
buf_pool_t* buf_pool); /*!< buffer pool instance */
118
/******************************************************************//**
119
Returns a free block from the buf_pool. The block is taken off the
120
free list. If it is empty, blocks are moved from the end of the
121
LRU list to the free list.
122
This function is called from a user thread when it needs a clean
123
block to read in a page. Note that we only ever get a block from
124
the free list. Even when we flush a page or find a page in LRU scan
125
we put it to free list to be used.
127
* get a block from free list, success:done
128
* if there is an LRU flush batch in progress:
129
* wait for batch to end: retry free list
130
* if buf_pool->try_LRU_scan is set
131
* scan LRU up to srv_LRU_scan_depth to find a clean block
132
* the above will put the block on free list
133
* success:retry the free list
134
* flush one dirty page from tail of LRU to disk
135
* the above will put the block on free list
136
* success: retry the free list
138
* same as iteration 0 except:
139
* scan whole LRU list
140
* scan LRU list even if buf_pool->try_LRU_scan is not set
142
* same as iteration 1 but sleep 100ms
143
@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
146
buf_LRU_get_free_block(
147
/*===================*/
148
buf_pool_t* buf_pool) /*!< in/out: buffer pool instance */
149
__attribute__((nonnull,warn_unused_result));
150
/******************************************************************//**
151
Determines if the unzip_LRU list should be used for evicting a victim
152
instead of the general LRU list.
153
@return TRUE if should use unzip_LRU */
156
buf_LRU_evict_from_unzip_LRU(
157
/*=========================*/
158
buf_pool_t* buf_pool);
159
/******************************************************************//**
160
Puts a block back to the free list. */
163
buf_LRU_block_free_non_file_page(
164
/*=============================*/
165
buf_block_t* block); /*!< in: block, must not contain a file page */
166
/******************************************************************//**
167
Adds a block to the LRU list. Please make sure that the zip_size is
168
already set into the page zip when invoking the function, so that we
169
can get correct zip_size from the buffer page when adding a block
175
buf_page_t* bpage, /*!< in: control block */
176
ibool old); /*!< in: TRUE if should be put to the old
177
blocks in the LRU list, else put to the
178
start; if the LRU list is very short, added to
179
the start regardless of this parameter */
180
/******************************************************************//**
181
Adds a block to the LRU list of decompressed zip pages. */
184
buf_unzip_LRU_add_block(
185
/*====================*/
186
buf_block_t* block, /*!< in: control block */
187
ibool old); /*!< in: TRUE if should be put to the end
188
of the list, else put to the start */
189
/******************************************************************//**
190
Moves a block to the start of the LRU list. */
193
buf_LRU_make_block_young(
194
/*=====================*/
195
buf_page_t* bpage); /*!< in: control block */
196
/******************************************************************//**
197
Moves a block to the end of the LRU list. */
200
buf_LRU_make_block_old(
201
/*===================*/
202
buf_page_t* bpage); /*!< in: control block */
203
/**********************************************************************//**
204
Updates buf_pool->LRU_old_ratio.
205
@return updated old_pct */
208
buf_LRU_old_ratio_update(
209
/*=====================*/
210
uint old_pct,/*!< in: Reserve this percentage of
211
the buffer pool for "old" blocks. */
212
ibool adjust);/*!< in: TRUE=adjust the LRU list;
213
FALSE=just assign buf_pool->LRU_old_ratio
214
during the initialization of InnoDB */
215
/********************************************************************//**
216
Update the historical stats that we are collecting for LRU eviction
217
policy at the end of each interval. */
220
buf_LRU_stat_update(void);
221
/*=====================*/
223
/******************************************************************//**
224
Remove one page from LRU list and put it to free list */
227
buf_LRU_free_one_page(
228
/*==================*/
229
buf_page_t* bpage) /*!< in/out: block, must contain a file page and
230
be in a state where it can be freed; there
231
may or may not be a hash index to the page */
232
__attribute__((nonnull));
234
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
235
/**********************************************************************//**
236
Validates the LRU list.
240
buf_LRU_validate(void);
241
/*==================*/
242
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
243
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
244
/**********************************************************************//**
245
Prints the LRU list. */
250
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
252
/** @name Heuristics for detecting index scan @{ */
253
/** The denominator of buf_pool->LRU_old_ratio. */
254
#define BUF_LRU_OLD_RATIO_DIV 1024
255
/** Maximum value of buf_pool->LRU_old_ratio.
256
@see buf_LRU_old_adjust_len
257
@see buf_pool->LRU_old_ratio_update */
258
#define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV
259
/** Minimum value of buf_pool->LRU_old_ratio.
260
@see buf_LRU_old_adjust_len
261
@see buf_pool->LRU_old_ratio_update
262
The minimum must exceed
263
(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
264
#define BUF_LRU_OLD_RATIO_MIN 51
266
#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
267
# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
269
#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
270
# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
273
/** Move blocks to "new" LRU list only if the first access was at
274
least this many milliseconds ago. Not protected by any mutex or latch. */
275
extern uint buf_LRU_old_threshold_ms;
278
/** @brief Statistics for selecting the LRU list for eviction.
280
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
281
and page_zip_decompress() operations. Based on the statistics we decide
282
if we want to evict from buf_pool->unzip_LRU or buf_pool->LRU. */
283
struct buf_LRU_stat_t
285
ulint io; /**< Counter of buffer pool I/O operations. */
286
ulint unzip; /**< Counter of page_zip_decompress operations. */
289
/** Current operation counters. Not protected by any mutex.
290
Cleared by buf_LRU_stat_update(). */
291
extern buf_LRU_stat_t buf_LRU_stat_cur;
293
/** Running sum of past values of buf_LRU_stat_cur.
294
Updated by buf_LRU_stat_update(). Protected by buf_pool->mutex. */
295
extern buf_LRU_stat_t buf_LRU_stat_sum;
297
/********************************************************************//**
298
Increments the I/O counter in buf_LRU_stat_cur. */
299
#define buf_LRU_stat_inc_io() buf_LRU_stat_cur.io++
300
/********************************************************************//**
301
Increments the page_zip_decompress() counter in buf_LRU_stat_cur. */
302
#define buf_LRU_stat_inc_unzip() buf_LRU_stat_cur.unzip++
305
#include "buf0lru.ic"
308
#endif /* !UNIV_HOTBACKUP */