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., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
19
/******************************************************
20
The database buffer pool LRU replacement algorithm
22
Created 11/5/1995 Heikki Tuuri
23
*******************************************************/
30
#include "buf0types.h"
32
/** The return type of buf_LRU_free_block() */
33
enum buf_lru_free_block_status {
36
/** not freed because the caller asked to remove the
37
uncompressed frame but the control block cannot be
39
BUF_LRU_CANNOT_RELOCATE,
40
/** not freed because of some other reason */
44
/**********************************************************************
45
Tries to remove LRU flushed blocks from the end of the LRU list and put them
46
to the free list. This is beneficial for the efficiency of the insert buffer
47
operation, as flushed pages from non-unique non-clustered indexes are here
48
taken out of the buffer pool, and their inserts redirected to the insert
49
buffer. Otherwise, the flushed blocks could get modified again before read
50
operations need new buffer blocks, and the i/o work done in flushing would be
54
buf_LRU_try_free_flushed_blocks(void);
55
/*==================================*/
56
/**********************************************************************
57
Returns TRUE if less than 25 % of the buffer pool is available. This can be
58
used in heuristics to prevent huge transactions eating up the whole buffer
59
pool for their locks. */
62
buf_LRU_buf_pool_running_out(void);
63
/*==============================*/
64
/* out: TRUE if less than 25 % of buffer pool
67
/*#######################################################################
68
These are low-level functions
69
#########################################################################*/
71
/* Minimum LRU list length for which the LRU_old pointer is defined */
73
#define BUF_LRU_OLD_MIN_LEN 80
75
#define BUF_LRU_FREE_SEARCH_LEN (5 + 2 * BUF_READ_AHEAD_AREA)
77
/**********************************************************************
78
Invalidates all pages belonging to a given tablespace when we are deleting
79
the data file(s) of that tablespace. A PROBLEM: if readahead is being started,
80
what guarantees that it will not try to read in pages after this operation has
84
buf_LRU_invalidate_tablespace(
85
/*==========================*/
86
ulint id); /* in: space id */
87
/**********************************************************************
88
Gets the minimum LRU_position field for the blocks in an initial segment
89
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
90
guaranteed to be precise, because the ulint_clock may wrap around. */
93
buf_LRU_get_recent_limit(void);
94
/*==========================*/
95
/* out: the limit; zero if could not determine it */
96
/************************************************************************
97
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
100
buf_LRU_insert_zip_clean(
101
/*=====================*/
102
buf_page_t* bpage); /* in: pointer to the block in question */
104
/**********************************************************************
105
Try to free a block. If bpage is a descriptor of a compressed-only
106
page, the descriptor object will be freed as well.
108
NOTE: If this function returns BUF_LRU_FREED, it will not temporarily
109
release buf_pool_mutex. Furthermore, the page frame will no longer be
110
accessible via bpage.
112
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
113
release these two mutexes after the call. No other
114
buf_page_get_mutex() may be held when calling this function. */
116
enum buf_lru_free_block_status
119
/* out: BUF_LRU_FREED if freed,
120
BUF_LRU_CANNOT_RELOCATE or
121
BUF_LRU_NOT_FREED otherwise. */
122
buf_page_t* bpage, /* in: block to be freed */
123
ibool zip, /* in: TRUE if should remove also the
124
compressed page of an uncompressed page */
125
ibool* buf_pool_mutex_released);
126
/* in: pointer to a variable that will
127
be assigned TRUE if buf_pool_mutex
128
was temporarily released, or NULL */
129
/**********************************************************************
130
Try to free a replaceable block. */
133
buf_LRU_search_and_free_block(
134
/*==========================*/
135
/* out: TRUE if found and freed */
136
ulint n_iterations); /* in: how many times this has been called
137
repeatedly without result: a high value means
138
that we should search farther; if
139
n_iterations < 10, then we search
140
n_iterations / 10 * buf_pool->curr_size
141
pages from the end of the LRU list; if
142
n_iterations < 5, then we will also search
143
n_iterations / 5 of the unzip_LRU list. */
144
/**********************************************************************
145
Returns a free block from the buf_pool. The block is taken off the
146
free list. If it is empty, returns NULL. */
149
buf_LRU_get_free_only(void);
150
/*=======================*/
151
/* out: a free control block, or NULL
152
if the buf_block->free list is empty */
153
/**********************************************************************
154
Returns a free block from the buf_pool. The block is taken off the
155
free list. If it is empty, blocks are moved from the end of the
156
LRU list to the free list. */
159
buf_LRU_get_free_block(
160
/*===================*/
161
/* out: the free control block,
162
in state BUF_BLOCK_READY_FOR_USE */
163
ulint zip_size); /* in: compressed page size in bytes,
164
or 0 if uncompressed tablespace */
166
/**********************************************************************
167
Puts a block back to the free list. */
170
buf_LRU_block_free_non_file_page(
171
/*=============================*/
172
buf_block_t* block); /* in: block, must not contain a file page */
173
/**********************************************************************
174
Adds a block to the LRU list. */
179
buf_page_t* bpage, /* in: control block */
180
ibool old); /* in: TRUE if should be put to the old
181
blocks in the LRU list, else put to the
182
start; if the LRU list is very short, added to
183
the start regardless of this parameter */
184
/**********************************************************************
185
Adds a block to the LRU list of decompressed zip pages. */
188
buf_unzip_LRU_add_block(
189
/*====================*/
190
buf_block_t* block, /* in: control block */
191
ibool old); /* in: TRUE if should be put to the end
192
of the list, else put to the start */
193
/**********************************************************************
194
Moves a block to the start of the LRU list. */
197
buf_LRU_make_block_young(
198
/*=====================*/
199
buf_page_t* bpage); /* in: control block */
200
/**********************************************************************
201
Moves a block to the end of the LRU list. */
204
buf_LRU_make_block_old(
205
/*===================*/
206
buf_page_t* bpage); /* in: control block */
207
/************************************************************************
208
Update the historical stats that we are collecting for LRU eviction
209
policy at the end of each interval. */
212
buf_LRU_stat_update(void);
213
/*=====================*/
214
/**********************************************************************
215
Reset buffer LRU variables. */
218
buf_LRU_var_init(void);
219
/*==================*/
220
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
221
/**************************************************************************
222
Validates the LRU list. */
225
buf_LRU_validate(void);
226
/*==================*/
227
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
228
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
229
/**************************************************************************
230
Prints the LRU list. */
235
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
237
/**********************************************************************
238
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
239
and page_zip_decompress() operations. Based on the statistics we decide
240
if we want to evict from buf_pool->unzip_LRU or buf_pool->LRU. */
242
/** Statistics for selecting the LRU list for eviction. */
243
struct buf_LRU_stat_struct
245
ulint io; /**< Counter of buffer pool I/O operations. */
246
ulint unzip; /**< Counter of page_zip_decompress operations. */
249
typedef struct buf_LRU_stat_struct buf_LRU_stat_t;
251
/** Current operation counters. Not protected by any mutex.
252
Cleared by buf_LRU_stat_update(). */
253
extern buf_LRU_stat_t buf_LRU_stat_cur;
255
/** Running sum of past values of buf_LRU_stat_cur.
256
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
257
extern buf_LRU_stat_t buf_LRU_stat_sum;
259
/************************************************************************
260
Increments the I/O counter in buf_LRU_stat_cur. */
261
#define buf_LRU_stat_inc_io() buf_LRU_stat_cur.io++
262
/************************************************************************
263
Increments the page_zip_decompress() counter in buf_LRU_stat_cur. */
264
#define buf_LRU_stat_inc_unzip() buf_LRU_stat_cur.unzip++
267
#include "buf0lru.ic"