1
/*****************************************************************************
3
Copyright (C) 1995, 2009, Innobase Oy. 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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/buf0lru.h
21
The database buffer pool LRU replacement algorithm
23
Created 11/5/1995 Heikki Tuuri
24
*******************************************************/
29
#include <sys/types.h>
32
#include "buf0types.h"
34
/** The return type of buf_LRU_free_block() */
35
enum buf_lru_free_block_status {
38
/** not freed because the caller asked to remove the
39
uncompressed frame but the control block cannot be
41
BUF_LRU_CANNOT_RELOCATE,
42
/** not freed because of some other reason */
46
/******************************************************************//**
47
Tries to remove LRU flushed blocks from the end of the LRU list and put them
48
to the free list. This is beneficial for the efficiency of the insert buffer
49
operation, as flushed pages from non-unique non-clustered indexes are here
50
taken out of the buffer pool, and their inserts redirected to the insert
51
buffer. Otherwise, the flushed blocks could get modified again before read
52
operations need new buffer blocks, and the i/o work done in flushing would be
56
buf_LRU_try_free_flushed_blocks(
57
/*============================*/
58
buf_pool_t* buf_pool); /*!< in: buffer pool instance */
59
/******************************************************************//**
60
Returns TRUE if less than 25 % of the buffer pool is available. This can be
61
used in heuristics to prevent huge transactions eating up the whole buffer
63
@return TRUE if less than 25 % of buffer pool left */
66
buf_LRU_buf_pool_running_out(void);
67
/*==============================*/
69
/*#######################################################################
70
These are low-level functions
71
#########################################################################*/
73
/** Minimum LRU list length for which the LRU_old pointer is defined */
74
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
76
/** Maximum LRU list search length in buf_flush_LRU_recommendation() */
77
#define BUF_LRU_FREE_SEARCH_LEN(b) (5 + 2 * BUF_READ_AHEAD_AREA(b))
79
/******************************************************************//**
80
Invalidates all pages belonging to a given tablespace when we are deleting
81
the data file(s) of that tablespace. A PROBLEM: if readahead is being started,
82
what guarantees that it will not try to read in pages after this operation has
86
buf_LRU_invalidate_tablespace(
87
/*==========================*/
88
ulint id); /*!< in: space id */
89
/********************************************************************//**
90
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
93
buf_LRU_insert_zip_clean(
94
/*=====================*/
95
buf_page_t* bpage); /*!< in: pointer to the block in question */
97
/******************************************************************//**
98
Try to free a block. If bpage is a descriptor of a compressed-only
99
page, the descriptor object will be freed as well.
101
NOTE: If this function returns BUF_LRU_FREED, it will temporarily
102
release buf_pool->mutex. Furthermore, the page frame will no longer be
103
accessible via bpage.
105
The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and
106
release these two mutexes after the call. No other
107
buf_page_get_mutex() may be held when calling this function.
108
@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
109
BUF_LRU_NOT_FREED otherwise. */
111
enum buf_lru_free_block_status
114
buf_page_t* bpage, /*!< in: block to be freed */
115
ibool zip, /*!< in: TRUE if should remove also the
116
compressed page of an uncompressed page */
117
ibool* buf_pool_mutex_released);
118
/*!< in: pointer to a variable that will
119
be assigned TRUE if buf_pool->mutex
120
was temporarily released, or NULL */
121
/******************************************************************//**
122
Try to free a replaceable block.
123
@return TRUE if found and freed */
126
buf_LRU_search_and_free_block(
127
/*==========================*/
128
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
129
ulint n_iterations); /*!< in: how many times this has
130
been called repeatedly without
131
result: a high value means that
132
we should search farther; if
133
n_iterations < 10, then we search
134
n_iterations / 10 * buf_pool->curr_size
135
pages from the end of the LRU list; if
136
n_iterations < 5, then we will
137
also search n_iterations / 5
138
of the unzip_LRU list. */
139
/******************************************************************//**
140
Returns a free block from the buf_pool. The block is taken off the
141
free list. If it is empty, returns NULL.
142
@return a free control block, or NULL if the buf_block->free list is empty */
145
buf_LRU_get_free_only(
146
/*==================*/
147
buf_pool_t* buf_pool); /*!< buffer pool instance */
148
/******************************************************************//**
149
Returns a free block from the buf_pool. The block is taken off the
150
free list. If it is empty, blocks are moved from the end of the
151
LRU list to the free list.
152
@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
155
buf_LRU_get_free_block(
156
/*===================*/
157
buf_pool_t* buf_pool, /*!< in: preferred buffer pool */
158
ulint zip_size); /*!< in: compressed page size in bytes,
159
or 0 if uncompressed tablespace */
161
/******************************************************************//**
162
Puts a block back to the free list. */
165
buf_LRU_block_free_non_file_page(
166
/*=============================*/
167
buf_block_t* block); /*!< in: block, must not contain a file page */
168
/******************************************************************//**
169
Adds a block to the LRU list. */
174
buf_page_t* bpage, /*!< in: control block */
175
ibool old); /*!< in: TRUE if should be put to the old
176
blocks in the LRU list, else put to the
177
start; if the LRU list is very short, added to
178
the start regardless of this parameter */
179
/******************************************************************//**
180
Adds a block to the LRU list of decompressed zip pages. */
183
buf_unzip_LRU_add_block(
184
/*====================*/
185
buf_block_t* block, /*!< in: control block */
186
ibool old); /*!< in: TRUE if should be put to the end
187
of the list, else put to the start */
188
/******************************************************************//**
189
Moves a block to the start of the LRU list. */
192
buf_LRU_make_block_young(
193
/*=====================*/
194
buf_page_t* bpage); /*!< in: control block */
195
/******************************************************************//**
196
Moves a block to the end of the LRU list. */
199
buf_LRU_make_block_old(
200
/*===================*/
201
buf_page_t* bpage); /*!< in: control block */
202
/**********************************************************************//**
203
Updates buf_LRU_old_ratio.
204
@return updated old_pct */
207
buf_LRU_old_ratio_update(
208
/*=====================*/
209
uint old_pct,/*!< in: Reserve this percentage of
210
the buffer pool for "old" blocks. */
211
ibool adjust);/*!< in: TRUE=adjust the LRU list;
212
FALSE=just assign buf_LRU_old_ratio
213
during the initialization of InnoDB */
214
/********************************************************************//**
215
Update the historical stats that we are collecting for LRU eviction
216
policy at the end of each interval. */
219
buf_LRU_stat_update(void);
220
/*=====================*/
222
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
223
/**********************************************************************//**
224
Validates the LRU list.
228
buf_LRU_validate(void);
229
/*==================*/
230
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
231
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
232
/**********************************************************************//**
233
Prints the LRU list. */
238
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
240
/** @name Heuristics for detecting index scan @{ */
241
/** Reserve this much/BUF_LRU_OLD_RATIO_DIV of the buffer pool for
242
"old" blocks. Protected by buf_pool->mutex. */
243
extern uint buf_LRU_old_ratio;
244
/** The denominator of buf_LRU_old_ratio. */
245
#define BUF_LRU_OLD_RATIO_DIV 1024
246
/** Maximum value of buf_LRU_old_ratio.
247
@see buf_LRU_old_adjust_len
248
@see buf_LRU_old_ratio_update */
249
#define BUF_LRU_OLD_RATIO_MAX BUF_LRU_OLD_RATIO_DIV
250
/** Minimum value of buf_LRU_old_ratio.
251
@see buf_LRU_old_adjust_len
252
@see buf_LRU_old_ratio_update
253
The minimum must exceed
254
(BUF_LRU_OLD_TOLERANCE + 5) * BUF_LRU_OLD_RATIO_DIV / BUF_LRU_OLD_MIN_LEN. */
255
#define BUF_LRU_OLD_RATIO_MIN 51
257
#if BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX
258
# error "BUF_LRU_OLD_RATIO_MIN >= BUF_LRU_OLD_RATIO_MAX"
260
#if BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV
261
# error "BUF_LRU_OLD_RATIO_MAX > BUF_LRU_OLD_RATIO_DIV"
264
/** Move blocks to "new" LRU list only if the first access was at
265
least this many milliseconds ago. Not protected by any mutex or latch. */
266
extern uint buf_LRU_old_threshold_ms;
269
/** @brief Statistics for selecting the LRU list for eviction.
271
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
272
and page_zip_decompress() operations. Based on the statistics we decide
273
if we want to evict from buf_pool->unzip_LRU or buf_pool->LRU. */
274
struct buf_LRU_stat_struct
276
ulint io; /**< Counter of buffer pool I/O operations. */
277
ulint unzip; /**< Counter of page_zip_decompress operations. */
280
/** Statistics for selecting the LRU list for eviction. */
281
typedef struct buf_LRU_stat_struct buf_LRU_stat_t;
283
/** Current operation counters. Not protected by any mutex.
284
Cleared by buf_LRU_stat_update(). */
285
extern buf_LRU_stat_t buf_LRU_stat_cur;
287
/** Running sum of past values of buf_LRU_stat_cur.
288
Updated by buf_LRU_stat_update(). Protected by buf_pool->mutex. */
289
extern buf_LRU_stat_t buf_LRU_stat_sum;
291
/********************************************************************//**
292
Increments the I/O counter in buf_LRU_stat_cur. */
293
#define buf_LRU_stat_inc_io() buf_LRU_stat_cur.io++
294
/********************************************************************//**
295
Increments the page_zip_decompress() counter in buf_LRU_stat_cur. */
296
#define buf_LRU_stat_inc_unzip() buf_LRU_stat_cur.unzip++
299
#include "buf0lru.ic"