~drizzle-trunk/drizzle/development

641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1
/*****************************************************************************
2
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
3
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
4
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.
8
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.
12
13
You should have received a copy of the GNU General Public License along with
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
16
17
*****************************************************************************/
18
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
19
/**************************************************//**
20
@file buf/buf0lru.c
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
21
The database buffer replacement algorithm
22
23
Created 11/5/1995 Heikki Tuuri
24
*******************************************************/
25
1819.5.140 by Stewart Smith
innobase buf0lru.c needs to include config.h first
26
#include "config.h"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
27
#include "buf0lru.h"
28
29
#ifdef UNIV_NONINL
30
#include "buf0lru.ic"
31
#endif
32
33
#include "ut0byte.h"
34
#include "ut0lst.h"
35
#include "ut0rnd.h"
36
#include "sync0sync.h"
37
#include "sync0rw.h"
38
#include "hash0hash.h"
39
#include "os0sync.h"
40
#include "fil0fil.h"
41
#include "btr0btr.h"
42
#include "buf0buddy.h"
43
#include "buf0buf.h"
44
#include "buf0flu.h"
45
#include "buf0rea.h"
46
#include "btr0sea.h"
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
47
#include "ibuf0ibuf.h"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
48
#include "os0file.h"
49
#include "page0zip.h"
50
#include "log0recv.h"
51
#include "srv0srv.h"
52
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
53
/** The number of blocks from the LRU_old pointer onward, including
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
54
the block pointed to, must be buf_pool->LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
55
of the whole LRU list length, except that the tolerance defined below
56
is allowed. Note that the tolerance must be small enough such that for
57
even the BUF_LRU_OLD_MIN_LEN long LRU list, the LRU_old pointer is not
58
allowed to point to either end of the LRU list. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
59
60
#define BUF_LRU_OLD_TOLERANCE	20
61
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
62
/** The minimum amount of non-old blocks when the LRU_old list exists
63
(that is, when there are more than BUF_LRU_OLD_MIN_LEN blocks).
64
@see buf_LRU_old_adjust_len */
65
#define BUF_LRU_NON_OLD_MIN_LEN	5
66
#if BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN
67
# error "BUF_LRU_NON_OLD_MIN_LEN >= BUF_LRU_OLD_MIN_LEN"
68
#endif
69
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
70
/** When dropping the search hash index entries before deleting an ibd
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
71
file, we build a local array of pages belonging to that tablespace
72
in the buffer pool. Following is the size of that array. */
73
#define BUF_LRU_DROP_SEARCH_HASH_SIZE	1024
74
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
75
/** If we switch on the InnoDB monitor because there are too few available
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
76
frames in the buffer pool, we set this to TRUE */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
77
static ibool	buf_lru_switched_on_innodb_mon	= FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
78
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
79
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
80
These statistics are not 'of' LRU but 'for' LRU.  We keep count of I/O
81
and page_zip_decompress() operations.  Based on the statistics,
82
buf_LRU_evict_from_unzip_LRU() decides if we want to evict from
83
unzip_LRU or the regular LRU.  From unzip_LRU, we will only evict the
84
uncompressed frame (meaning we can evict dirty blocks as well).  From
85
the regular LRU, we will evict the entire block (i.e.: both the
86
uncompressed and compressed data), which must be clean. */
87
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
88
/* @{ */
89
90
/** Number of intervals for which we keep the history of these stats.
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
91
Each interval is 1 second, defined by the rate at which
92
srv_error_monitor_thread() calls buf_LRU_stat_update(). */
93
#define BUF_LRU_STAT_N_INTERVAL 50
94
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
95
/** Co-efficient with which we multiply I/O operations to equate them
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
96
with page_zip_decompress() operations. */
97
#define BUF_LRU_IO_TO_UNZIP_FACTOR 50
98
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
99
/** Sampled values buf_LRU_stat_cur.
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
100
Not protected by any mutex.  Updated by buf_LRU_stat_update(). */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
101
static buf_LRU_stat_t		buf_LRU_stat_arr[BUF_LRU_STAT_N_INTERVAL];
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
102
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
103
/** Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
104
static ulint			buf_LRU_stat_arr_ind;
105
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
106
/** Current operation counters.  Not protected by any mutex.  Cleared
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
107
by buf_LRU_stat_update(). */
108
UNIV_INTERN buf_LRU_stat_t	buf_LRU_stat_cur;
109
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
110
/** Running sum of past values of buf_LRU_stat_cur.
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
111
Updated by buf_LRU_stat_update().  Not Protected by any mutex. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
112
UNIV_INTERN buf_LRU_stat_t	buf_LRU_stat_sum;
113
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
114
/* @} */
115
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
116
/** @name Heuristics for detecting index scan @{ */
117
/** Move blocks to "new" LRU list only if the first access was at
118
least this many milliseconds ago.  Not protected by any mutex or latch. */
119
UNIV_INTERN uint	buf_LRU_old_threshold_ms;
120
/* @} */
121
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
122
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
123
Takes a block out of the LRU list and page hash table.
124
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
125
the object will be freed and buf_pool->zip_mutex will be released.
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
126
127
If a compressed page or a compressed-only block descriptor is freed,
128
other compressed pages or compressed-only block descriptors may be
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
129
relocated.
130
@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
131
was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
132
static
133
enum buf_page_state
134
buf_LRU_block_remove_hashed_page(
135
/*=============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
136
	buf_page_t*	bpage,	/*!< in: block, must contain a file page and
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
137
				be in a state where it can be freed; there
138
				may or may not be a hash index to the page */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
139
	ibool		zip);	/*!< in: TRUE if should remove also the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
140
				compressed page of an uncompressed page */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
141
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
142
Puts a file page whose has no hash index to the free list. */
143
static
144
void
145
buf_LRU_block_free_hashed_page(
146
/*===========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
147
	buf_block_t*	block);	/*!< in: block, must contain a file page and
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
148
				be in a state where it can be freed */
149
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
150
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
151
Determines if the unzip_LRU list should be used for evicting a victim
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
152
instead of the general LRU list.
153
@return	TRUE if should use unzip_LRU */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
154
UNIV_INLINE
155
ibool
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
156
buf_LRU_evict_from_unzip_LRU(
157
/*=========================*/
158
	buf_pool_t*	buf_pool)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
159
{
160
	ulint	io_avg;
161
	ulint	unzip_avg;
162
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
163
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
164
165
	/* If the unzip_LRU list is empty, we can only use the LRU. */
166
	if (UT_LIST_GET_LEN(buf_pool->unzip_LRU) == 0) {
167
		return(FALSE);
168
	}
169
170
	/* If unzip_LRU is at most 10% of the size of the LRU list,
171
	then use the LRU.  This slack allows us to keep hot
172
	decompressed pages in the buffer pool. */
173
	if (UT_LIST_GET_LEN(buf_pool->unzip_LRU)
174
	    <= UT_LIST_GET_LEN(buf_pool->LRU) / 10) {
175
		return(FALSE);
176
	}
177
178
	/* If eviction hasn't started yet, we assume by default
179
	that a workload is disk bound. */
180
	if (buf_pool->freed_page_clock == 0) {
181
		return(TRUE);
182
	}
183
184
	/* Calculate the average over past intervals, and add the values
185
	of the current interval. */
186
	io_avg = buf_LRU_stat_sum.io / BUF_LRU_STAT_N_INTERVAL
187
		+ buf_LRU_stat_cur.io;
188
	unzip_avg = buf_LRU_stat_sum.unzip / BUF_LRU_STAT_N_INTERVAL
189
		+ buf_LRU_stat_cur.unzip;
190
191
	/* Decide based on our formula.  If the load is I/O bound
192
	(unzip_avg is smaller than the weighted io_avg), evict an
193
	uncompressed frame from unzip_LRU.  Otherwise we assume that
194
	the load is CPU bound and evict from the regular LRU. */
195
	return(unzip_avg <= io_avg * BUF_LRU_IO_TO_UNZIP_FACTOR);
196
}
197
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
198
/******************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
199
Attempts to drop page hash index on a batch of pages belonging to a
200
particular space id. */
201
static
202
void
203
buf_LRU_drop_page_hash_batch(
204
/*=========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
205
	ulint		space_id,	/*!< in: space id */
206
	ulint		zip_size,	/*!< in: compressed page size in bytes
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
207
					or 0 for uncompressed pages */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
208
	const ulint*	arr,		/*!< in: array of page_no */
209
	ulint		count)		/*!< in: number of entries in array */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
210
{
211
	ulint	i;
212
213
	ut_ad(arr != NULL);
214
	ut_ad(count <= BUF_LRU_DROP_SEARCH_HASH_SIZE);
215
216
	for (i = 0; i < count; ++i) {
217
		btr_search_drop_page_hash_when_freed(space_id, zip_size,
218
						     arr[i]);
219
	}
220
}
221
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
222
/******************************************************************//**
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
223
When doing a DROP TABLE/DISCARD TABLESPACE we have to drop all page
224
hash index entries belonging to that table. This function tries to
225
do that in batch. Note that this is a 'best effort' attempt and does
226
not guarantee that ALL hash entries will be removed. */
227
static
228
void
229
buf_LRU_drop_page_hash_for_tablespace(
230
/*==================================*/
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
231
	buf_pool_t*	buf_pool,	/*!< in: buffer pool instance */
232
	ulint		id)		/*!< in: space id */
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
233
{
234
	buf_page_t*	bpage;
235
	ulint*		page_arr;
236
	ulint		num_entries;
237
	ulint		zip_size;
238
239
	zip_size = fil_space_get_zip_size(id);
240
241
	if (UNIV_UNLIKELY(zip_size == ULINT_UNDEFINED)) {
242
		/* Somehow, the tablespace does not exist.  Nothing to drop. */
243
		ut_ad(0);
244
		return;
245
	}
246
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
247
	page_arr = ut_malloc(
248
		sizeof(ulint) * BUF_LRU_DROP_SEARCH_HASH_SIZE);
249
250
	buf_pool_mutex_enter(buf_pool);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
251
252
scan_again:
253
	num_entries = 0;
254
	bpage = UT_LIST_GET_LAST(buf_pool->LRU);
255
256
	while (bpage != NULL) {
257
		mutex_t*	block_mutex = buf_page_get_mutex(bpage);
258
		buf_page_t*	prev_bpage;
259
260
		mutex_enter(block_mutex);
261
		prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
262
263
		ut_a(buf_page_in_file(bpage));
264
265
		if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
266
		    || bpage->space != id
267
		    || bpage->buf_fix_count > 0
268
		    || bpage->io_fix != BUF_IO_NONE) {
269
			/* We leave the fixed pages as is in this scan.
270
			To be dealt with later in the final scan. */
271
			mutex_exit(block_mutex);
272
			goto next_page;
273
		}
274
275
		if (((buf_block_t*) bpage)->is_hashed) {
276
277
			/* Store the offset(i.e.: page_no) in the array
278
			so that we can drop hash index in a batch
279
			later. */
280
			page_arr[num_entries] = bpage->offset;
281
			mutex_exit(block_mutex);
282
			ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
283
			++num_entries;
284
285
			if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
286
				goto next_page;
287
			}
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
288
289
			/* Array full. We release the buf_pool->mutex to
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
290
			obey the latching order. */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
291
			buf_pool_mutex_exit(buf_pool);
292
293
			buf_LRU_drop_page_hash_batch(
294
				id, zip_size, page_arr, num_entries);
295
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
296
			num_entries = 0;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
297
298
			buf_pool_mutex_enter(buf_pool);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
299
		} else {
300
			mutex_exit(block_mutex);
301
		}
302
303
next_page:
304
		/* Note that we may have released the buf_pool mutex
305
		above after reading the prev_bpage during processing
306
		of a page_hash_batch (i.e.: when the array was full).
307
		This means that prev_bpage can change in LRU list.
308
		This is OK because this function is a 'best effort'
309
		to drop as many search hash entries as possible and
310
		it does not guarantee that ALL such entries will be
311
		dropped. */
312
		bpage = prev_bpage;
313
314
		/* If, however, bpage has been removed from LRU list
315
		to the free list then we should restart the scan.
316
		bpage->state is protected by buf_pool mutex. */
317
		if (bpage && !buf_page_in_file(bpage)) {
318
			ut_a(num_entries == 0);
319
			goto scan_again;
320
		}
321
	}
322
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
323
	buf_pool_mutex_exit(buf_pool);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
324
325
	/* Drop any remaining batch of search hashed pages. */
326
	buf_LRU_drop_page_hash_batch(id, zip_size, page_arr, num_entries);
327
	ut_free(page_arr);
328
}
329
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
330
/******************************************************************//**
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
331
Invalidates all pages belonging to a given tablespace inside a specific
332
buffer pool instance when we are deleting the data file(s) of that
333
tablespace. */
334
static
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
335
void
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
336
buf_LRU_invalidate_tablespace_buf_pool_instance(
337
/*============================================*/
338
	buf_pool_t*	buf_pool,	/*!< buffer pool instance */
339
	ulint		id)		/*!< in: space id */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
340
{
341
	buf_page_t*	bpage;
342
	ibool		all_freed;
343
344
scan_again:
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
345
	buf_pool_mutex_enter(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
346
347
	all_freed = TRUE;
348
349
	bpage = UT_LIST_GET_LAST(buf_pool->LRU);
350
351
	while (bpage != NULL) {
352
		buf_page_t*	prev_bpage;
1819.5.186 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6548 from MySQL InnoDB
353
		ibool		prev_bpage_buf_fix = FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
354
355
		ut_a(buf_page_in_file(bpage));
356
357
		prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
358
1819.5.177 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6525 from MySQL InnoDB
359
		/* bpage->space and bpage->io_fix are protected by
1819.9.172 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20101020114628-ly1tyc8etgxr985x from MySQL InnoDB
360
		buf_pool->mutex and block_mutex.  It is safe to check
361
		them while holding buf_pool->mutex only. */
1819.5.177 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6525 from MySQL InnoDB
362
363
		if (buf_page_get_space(bpage) != id) {
364
			/* Skip this block, as it does not belong to
365
			the space that is being invalidated. */
366
		} else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
367
			/* We cannot remove this page during this scan
368
			yet; maybe the system is currently reading it
369
			in, or flushing the modifications to the file */
370
371
			all_freed = FALSE;
372
		} else {
373
			mutex_t* block_mutex = buf_page_get_mutex(bpage);
374
			mutex_enter(block_mutex);
375
376
			if (bpage->buf_fix_count > 0) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
377
378
				/* We cannot remove this page during
379
				this scan yet; maybe the system is
380
				currently reading it in, or flushing
381
				the modifications to the file */
382
383
				all_freed = FALSE;
384
385
				goto next_page;
386
			}
387
388
#ifdef UNIV_DEBUG
389
			if (buf_debug_prints) {
390
				fprintf(stderr,
391
					"Dropping space %lu page %lu\n",
392
					(ulong) buf_page_get_space(bpage),
393
					(ulong) buf_page_get_page_no(bpage));
394
			}
395
#endif
1819.5.186 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6548 from MySQL InnoDB
396
			if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
397
				/* This is a compressed-only block
398
				descriptor.  Ensure that prev_bpage
399
				cannot be relocated when bpage is freed. */
400
				if (UNIV_LIKELY(prev_bpage != NULL)) {
401
					switch (buf_page_get_state(
402
							prev_bpage)) {
403
					case BUF_BLOCK_FILE_PAGE:
404
						/* Descriptors of uncompressed
405
						blocks will not be relocated,
406
						because we are holding the
1819.9.172 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20101020114628-ly1tyc8etgxr985x from MySQL InnoDB
407
						buf_pool->mutex. */
1819.5.186 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6548 from MySQL InnoDB
408
						break;
409
					case BUF_BLOCK_ZIP_PAGE:
410
					case BUF_BLOCK_ZIP_DIRTY:
411
						/* Descriptors of compressed-
412
						only blocks can be relocated,
413
						unless they are buffer-fixed.
414
						Because both bpage and
415
						prev_bpage are protected by
416
						buf_pool_zip_mutex, it is
417
						not necessary to acquire
418
						further mutexes. */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
419
						ut_ad(&buf_pool->zip_mutex
1819.5.186 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6548 from MySQL InnoDB
420
						      == block_mutex);
421
						ut_ad(mutex_own(block_mutex));
422
						prev_bpage_buf_fix = TRUE;
423
						prev_bpage->buf_fix_count++;
424
						break;
425
					default:
426
						ut_error;
427
					}
428
				}
429
			} else if (((buf_block_t*) bpage)->is_hashed) {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
430
				ulint	page_no;
431
				ulint	zip_size;
432
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
433
				buf_pool_mutex_exit(buf_pool);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
434
435
				zip_size = buf_page_get_zip_size(bpage);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
436
				page_no = buf_page_get_page_no(bpage);
437
438
				mutex_exit(block_mutex);
439
440
				/* Note that the following call will acquire
441
				an S-latch on the page */
442
443
				btr_search_drop_page_hash_when_freed(
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
444
					id, zip_size, page_no);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
445
				goto scan_again;
446
			}
447
448
			if (bpage->oldest_modification != 0) {
449
450
				buf_flush_remove(bpage);
451
			}
452
1819.5.186 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6548 from MySQL InnoDB
453
			/* Remove from the LRU list. */
454
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
455
			if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
456
			    != BUF_BLOCK_ZIP_FREE) {
457
				buf_LRU_block_free_hashed_page((buf_block_t*)
458
							       bpage);
459
			} else {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
460
				/* The block_mutex should have been
461
				released by buf_LRU_block_remove_hashed_page()
462
				when it returns BUF_BLOCK_ZIP_FREE. */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
463
				ut_ad(block_mutex == &buf_pool->zip_mutex);
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
464
				ut_ad(!mutex_own(block_mutex));
465
1819.5.186 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6548 from MySQL InnoDB
466
				if (prev_bpage_buf_fix) {
467
					/* We temporarily buffer-fixed
468
					prev_bpage, so that
469
					buf_buddy_free() could not
470
					relocate it, in case it was a
471
					compressed-only block
472
					descriptor. */
473
474
					mutex_enter(block_mutex);
475
					ut_ad(prev_bpage->buf_fix_count > 0);
476
					prev_bpage->buf_fix_count--;
477
					mutex_exit(block_mutex);
478
				}
479
480
				goto next_page_no_mutex;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
481
			}
1819.5.177 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6525 from MySQL InnoDB
482
next_page:
483
			mutex_exit(block_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
484
		}
1819.5.177 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6525 from MySQL InnoDB
485
1819.5.186 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6548 from MySQL InnoDB
486
next_page_no_mutex:
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
487
		bpage = prev_bpage;
488
	}
489
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
490
	buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
491
492
	if (!all_freed) {
493
		os_thread_sleep(20000);
494
495
		goto scan_again;
496
	}
497
}
498
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
499
/******************************************************************//**
500
Invalidates all pages belonging to a given tablespace when we are deleting
501
the data file(s) of that tablespace. */
502
UNIV_INTERN
503
void
504
buf_LRU_invalidate_tablespace(
505
/*==========================*/
506
	ulint	id)	/*!< in: space id */
507
{
508
	ulint	i;
509
510
	/* Before we attempt to drop pages one by one we first
511
	attempt to drop page hash index entries in batches to make
512
	it more efficient. The batching attempt is a best effort
513
	attempt and does not guarantee that all pages hash entries
514
	will be dropped. We get rid of remaining page hash entries
515
	one by one below. */
516
	for (i = 0; i < srv_buf_pool_instances; i++) {
517
		buf_pool_t*	buf_pool;
518
519
		buf_pool = buf_pool_from_array(i);
520
		buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
521
		buf_LRU_invalidate_tablespace_buf_pool_instance(buf_pool, id);
522
	}
523
}
524
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
525
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
526
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
527
UNIV_INTERN
528
void
529
buf_LRU_insert_zip_clean(
530
/*=====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
531
	buf_page_t*	bpage)	/*!< in: pointer to the block in question */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
532
{
533
	buf_page_t*	b;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
534
	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
535
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
536
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
537
	ut_ad(buf_page_get_state(bpage) == BUF_BLOCK_ZIP_PAGE);
538
539
	/* Find the first successor of bpage in the LRU list
540
	that is in the zip_clean list. */
541
	b = bpage;
542
	do {
543
		b = UT_LIST_GET_NEXT(LRU, b);
544
	} while (b && buf_page_get_state(b) != BUF_BLOCK_ZIP_PAGE);
545
546
	/* Insert bpage before b, i.e., after the predecessor of b. */
547
	if (b) {
548
		b = UT_LIST_GET_PREV(list, b);
549
	}
550
551
	if (b) {
552
		UT_LIST_INSERT_AFTER(list, buf_pool->zip_clean, b, bpage);
553
	} else {
554
		UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
555
	}
556
}
557
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
558
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
559
Try to free an uncompressed page of a compressed block from the unzip
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
560
LRU list.  The compressed page is preserved, and it need not be clean.
561
@return	TRUE if freed */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
562
UNIV_INLINE
563
ibool
564
buf_LRU_free_from_unzip_LRU_list(
565
/*=============================*/
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
566
	buf_pool_t*	buf_pool,	/*!< in: buffer pool instance */
567
	ulint		n_iterations)	/*!< in: how many times this has
568
					been called repeatedly without
569
					result: a high value means that
570
					we should search farther; we will
571
					search n_iterations / 5 of the
572
					unzip_LRU list, or nothing if
573
					n_iterations >= 5 */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
574
{
575
	buf_block_t*	block;
576
	ulint		distance;
577
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
578
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
579
580
	/* Theoratically it should be much easier to find a victim
581
	from unzip_LRU as we can choose even a dirty block (as we'll
582
	be evicting only the uncompressed frame).  In a very unlikely
583
	eventuality that we are unable to find a victim from
584
	unzip_LRU, we fall back to the regular LRU list.  We do this
585
	if we have done five iterations so far. */
586
587
	if (UNIV_UNLIKELY(n_iterations >= 5)
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
588
	    || !buf_LRU_evict_from_unzip_LRU(buf_pool)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
589
590
		return(FALSE);
591
	}
592
593
	distance = 100 + (n_iterations
594
			  * UT_LIST_GET_LEN(buf_pool->unzip_LRU)) / 5;
595
596
	for (block = UT_LIST_GET_LAST(buf_pool->unzip_LRU);
597
	     UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
598
	     block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
599
600
		enum buf_lru_free_block_status	freed;
601
602
		ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
603
		ut_ad(block->in_unzip_LRU_list);
604
		ut_ad(block->page.in_LRU_list);
605
606
		mutex_enter(&block->mutex);
607
		freed = buf_LRU_free_block(&block->page, FALSE, NULL);
608
		mutex_exit(&block->mutex);
609
610
		switch (freed) {
611
		case BUF_LRU_FREED:
612
			return(TRUE);
613
614
		case BUF_LRU_CANNOT_RELOCATE:
615
			/* If we failed to relocate, try
616
			regular LRU eviction. */
617
			return(FALSE);
618
619
		case BUF_LRU_NOT_FREED:
620
			/* The block was buffer-fixed or I/O-fixed.
621
			Keep looking. */
622
			continue;
623
		}
624
625
		/* inappropriate return value from
626
		buf_LRU_free_block() */
627
		ut_error;
628
	}
629
630
	return(FALSE);
631
}
632
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
633
/******************************************************************//**
634
Try to free a clean page from the common LRU list.
635
@return	TRUE if freed */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
636
UNIV_INLINE
637
ibool
638
buf_LRU_free_from_common_LRU_list(
639
/*==============================*/
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
640
	buf_pool_t*	buf_pool,
641
	ulint		n_iterations)
642
				/*!< in: how many times this has been called
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
643
				repeatedly without result: a high value means
644
				that we should search farther; if
645
				n_iterations < 10, then we search
646
				n_iterations / 10 * buf_pool->curr_size
647
				pages from the end of the LRU list */
648
{
649
	buf_page_t*	bpage;
650
	ulint		distance;
651
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
652
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
653
654
	distance = 100 + (n_iterations * buf_pool->curr_size) / 10;
655
656
	for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
657
	     UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
658
	     bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
659
660
		enum buf_lru_free_block_status	freed;
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
661
		unsigned			accessed;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
662
		mutex_t*			block_mutex
663
			= buf_page_get_mutex(bpage);
664
665
		ut_ad(buf_page_in_file(bpage));
666
		ut_ad(bpage->in_LRU_list);
667
668
		mutex_enter(block_mutex);
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
669
		accessed = buf_page_is_accessed(bpage);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
670
		freed = buf_LRU_free_block(bpage, TRUE, NULL);
671
		mutex_exit(block_mutex);
672
673
		switch (freed) {
674
		case BUF_LRU_FREED:
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
675
			/* Keep track of pages that are evicted without
676
			ever being accessed. This gives us a measure of
677
			the effectiveness of readahead */
678
			if (!accessed) {
679
				++buf_pool->stat.n_ra_pages_evicted;
680
			}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
681
			return(TRUE);
682
683
		case BUF_LRU_NOT_FREED:
684
			/* The block was dirty, buffer-fixed, or I/O-fixed.
685
			Keep looking. */
686
			continue;
687
688
		case BUF_LRU_CANNOT_RELOCATE:
689
			/* This should never occur, because we
690
			want to discard the compressed page too. */
691
			break;
692
		}
693
694
		/* inappropriate return value from
695
		buf_LRU_free_block() */
696
		ut_error;
697
	}
698
699
	return(FALSE);
700
}
701
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
702
/******************************************************************//**
703
Try to free a replaceable block.
704
@return	TRUE if found and freed */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
705
UNIV_INTERN
706
ibool
707
buf_LRU_search_and_free_block(
708
/*==========================*/
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
709
	buf_pool_t*	buf_pool,
710
				/*!< in: buffer pool instance */
711
	ulint		n_iterations)
712
				/*!< in: how many times this has been called
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
713
				repeatedly without result: a high value means
714
				that we should search farther; if
715
				n_iterations < 10, then we search
716
				n_iterations / 10 * buf_pool->curr_size
717
				pages from the end of the LRU list; if
718
				n_iterations < 5, then we will also search
719
				n_iterations / 5 of the unzip_LRU list. */
720
{
721
	ibool	freed = FALSE;
722
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
723
	buf_pool_mutex_enter(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
724
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
725
	freed = buf_LRU_free_from_unzip_LRU_list(buf_pool, n_iterations);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
726
727
	if (!freed) {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
728
		freed = buf_LRU_free_from_common_LRU_list(
729
			buf_pool, n_iterations);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
730
	}
731
732
	if (!freed) {
733
		buf_pool->LRU_flush_ended = 0;
734
	} else if (buf_pool->LRU_flush_ended > 0) {
735
		buf_pool->LRU_flush_ended--;
736
	}
737
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
738
	buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
739
740
	return(freed);
741
}
742
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
743
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
744
Tries to remove LRU flushed blocks from the end of the LRU list and put them
745
to the free list. This is beneficial for the efficiency of the insert buffer
746
operation, as flushed pages from non-unique non-clustered indexes are here
747
taken out of the buffer pool, and their inserts redirected to the insert
748
buffer. Otherwise, the flushed blocks could get modified again before read
749
operations need new buffer blocks, and the i/o work done in flushing would be
750
wasted. */
751
UNIV_INTERN
752
void
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
753
buf_LRU_try_free_flushed_blocks(
754
/*============================*/
755
	buf_pool_t*	buf_pool)		/*!< in: buffer pool instance */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
756
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
757
758
	if (buf_pool == NULL) {
759
		ulint	i;
760
761
		for (i = 0; i < srv_buf_pool_instances; i++) {
762
			buf_pool = buf_pool_from_array(i);
763
			buf_LRU_try_free_flushed_blocks(buf_pool);
764
		}
765
	} else {
766
		buf_pool_mutex_enter(buf_pool);
767
768
		while (buf_pool->LRU_flush_ended > 0) {
769
770
			buf_pool_mutex_exit(buf_pool);
771
772
			buf_LRU_search_and_free_block(buf_pool, 1);
773
774
			buf_pool_mutex_enter(buf_pool);
775
		}
776
777
		buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
778
	}
779
}
780
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
781
/******************************************************************//**
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
782
Returns TRUE if less than 25 % of the buffer pool in any instance is
783
available. This can be used in heuristics to prevent huge transactions
784
eating up the whole buffer pool for their locks.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
785
@return	TRUE if less than 25 % of buffer pool left */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
786
UNIV_INTERN
787
ibool
788
buf_LRU_buf_pool_running_out(void)
789
/*==============================*/
790
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
791
	ulint	i;
792
	ibool	ret = FALSE;
793
794
	for (i = 0; i < srv_buf_pool_instances && !ret; i++) {
795
		buf_pool_t*	buf_pool;
796
797
		buf_pool = buf_pool_from_array(i);
798
799
		buf_pool_mutex_enter(buf_pool);
800
801
		if (!recv_recovery_on
802
		    && UT_LIST_GET_LEN(buf_pool->free)
803
		       + UT_LIST_GET_LEN(buf_pool->LRU)
804
		       < buf_pool->curr_size / 4) {
805
806
			ret = TRUE;
807
		}
808
809
		buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
810
	}
811
812
	return(ret);
813
}
814
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
815
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
816
Returns a free block from the buf_pool.  The block is taken off the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
817
free list.  If it is empty, returns NULL.
818
@return	a free control block, or NULL if the buf_block->free list is empty */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
819
UNIV_INTERN
820
buf_block_t*
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
821
buf_LRU_get_free_only(
822
/*==================*/
823
	buf_pool_t*	buf_pool)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
824
{
825
	buf_block_t*	block;
826
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
827
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
828
829
	block = (buf_block_t*) UT_LIST_GET_FIRST(buf_pool->free);
830
831
	if (block) {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
832
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
833
		ut_ad(block->page.in_free_list);
834
		ut_d(block->page.in_free_list = FALSE);
835
		ut_ad(!block->page.in_flush_list);
836
		ut_ad(!block->page.in_LRU_list);
837
		ut_a(!buf_page_in_file(&block->page));
838
		UT_LIST_REMOVE(list, buf_pool->free, (&block->page));
839
840
		mutex_enter(&block->mutex);
841
842
		buf_block_set_state(block, BUF_BLOCK_READY_FOR_USE);
843
		UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
844
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
845
		ut_ad(buf_pool_from_block(block) == buf_pool);
846
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
847
		mutex_exit(&block->mutex);
848
	}
849
850
	return(block);
851
}
852
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
853
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
854
Returns a free block from the buf_pool. The block is taken off the
855
free list. If it is empty, blocks are moved from the end of the
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
856
LRU list to the free list.
857
@return	the free control block, in state BUF_BLOCK_READY_FOR_USE */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
858
UNIV_INTERN
859
buf_block_t*
860
buf_LRU_get_free_block(
861
/*===================*/
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
862
	buf_pool_t*	buf_pool,	/*!< in: buffer pool instance */
863
	ulint		zip_size)	/*!< in: compressed page size in bytes,
864
					or 0 if uncompressed tablespace */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
865
{
866
	buf_block_t*	block		= NULL;
867
	ibool		freed;
868
	ulint		n_iterations	= 1;
869
	ibool		mon_value_was	= FALSE;
870
	ibool		started_monitor	= FALSE;
871
loop:
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
872
	buf_pool_mutex_enter(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
873
874
	if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
875
	    + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->curr_size / 20) {
876
		ut_print_timestamp(stderr);
877
878
		fprintf(stderr,
879
			"  InnoDB: ERROR: over 95 percent of the buffer pool"
880
			" is occupied by\n"
881
			"InnoDB: lock heaps or the adaptive hash index!"
882
			" Check that your\n"
883
			"InnoDB: transactions do not set too many row locks.\n"
884
			"InnoDB: Your buffer pool size is %lu MB."
885
			" Maybe you should make\n"
886
			"InnoDB: the buffer pool bigger?\n"
887
			"InnoDB: We intentionally generate a seg fault"
888
			" to print a stack trace\n"
889
			"InnoDB: on Linux!\n",
890
			(ulong) (buf_pool->curr_size
891
				 / (1024 * 1024 / UNIV_PAGE_SIZE)));
892
893
		ut_error;
894
895
	} else if (!recv_recovery_on
896
		   && (UT_LIST_GET_LEN(buf_pool->free)
897
		       + UT_LIST_GET_LEN(buf_pool->LRU))
898
		   < buf_pool->curr_size / 3) {
899
900
		if (!buf_lru_switched_on_innodb_mon) {
901
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
902
			/* Over 67 % of the buffer pool is occupied by lock
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
903
			heaps or the adaptive hash index. This may be a memory
904
			leak! */
905
906
			ut_print_timestamp(stderr);
907
			fprintf(stderr,
908
				"  InnoDB: WARNING: over 67 percent of"
909
				" the buffer pool is occupied by\n"
910
				"InnoDB: lock heaps or the adaptive"
911
				" hash index! Check that your\n"
912
				"InnoDB: transactions do not set too many"
913
				" row locks.\n"
914
				"InnoDB: Your buffer pool size is %lu MB."
915
				" Maybe you should make\n"
916
				"InnoDB: the buffer pool bigger?\n"
917
				"InnoDB: Starting the InnoDB Monitor to print"
918
				" diagnostics, including\n"
919
				"InnoDB: lock heap and hash index sizes.\n",
920
				(ulong) (buf_pool->curr_size
921
					 / (1024 * 1024 / UNIV_PAGE_SIZE)));
922
923
			buf_lru_switched_on_innodb_mon = TRUE;
924
			srv_print_innodb_monitor = TRUE;
925
			os_event_set(srv_lock_timeout_thread_event);
926
		}
927
	} else if (buf_lru_switched_on_innodb_mon) {
928
929
		/* Switch off the InnoDB Monitor; this is a simple way
930
		to stop the monitor if the situation becomes less urgent,
931
		but may also surprise users if the user also switched on the
932
		monitor! */
933
934
		buf_lru_switched_on_innodb_mon = FALSE;
935
		srv_print_innodb_monitor = FALSE;
936
	}
937
938
	/* If there is a block in the free list, take it */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
939
	block = buf_LRU_get_free_only(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
940
	if (block) {
941
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
942
		ut_ad(buf_pool_from_block(block) == buf_pool);
943
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
944
#ifdef UNIV_DEBUG
945
		block->page.zip.m_start =
946
#endif /* UNIV_DEBUG */
947
			block->page.zip.m_end =
948
			block->page.zip.m_nonempty =
949
			block->page.zip.n_blobs = 0;
950
951
		if (UNIV_UNLIKELY(zip_size)) {
952
			ibool	lru;
953
			page_zip_set_size(&block->page.zip, zip_size);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
954
955
			block->page.zip.data = buf_buddy_alloc(
956
				buf_pool, zip_size, &lru);
957
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
958
			UNIV_MEM_DESC(block->page.zip.data, zip_size, block);
959
		} else {
960
			page_zip_set_size(&block->page.zip, 0);
961
			block->page.zip.data = NULL;
962
		}
963
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
964
		buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
965
966
		if (started_monitor) {
967
			srv_print_innodb_monitor = mon_value_was;
968
		}
969
970
		return(block);
971
	}
972
973
	/* If no block was in the free list, search from the end of the LRU
974
	list and try to free a block there */
975
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
976
	buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
977
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
978
	freed = buf_LRU_search_and_free_block(buf_pool, n_iterations);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
979
980
	if (freed > 0) {
981
		goto loop;
982
	}
983
984
	if (n_iterations > 30) {
985
		ut_print_timestamp(stderr);
986
		fprintf(stderr,
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
987
			"  InnoDB: Warning: difficult to find free blocks in\n"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
988
			"InnoDB: the buffer pool (%lu search iterations)!"
989
			" Consider\n"
990
			"InnoDB: increasing the buffer pool size.\n"
991
			"InnoDB: It is also possible that"
992
			" in your Unix version\n"
993
			"InnoDB: fsync is very slow, or"
994
			" completely frozen inside\n"
995
			"InnoDB: the OS kernel. Then upgrading to"
996
			" a newer version\n"
997
			"InnoDB: of your operating system may help."
998
			" Look at the\n"
999
			"InnoDB: number of fsyncs in diagnostic info below.\n"
1000
			"InnoDB: Pending flushes (fsync) log: %lu;"
1001
			" buffer pool: %lu\n"
1002
			"InnoDB: %lu OS file reads, %lu OS file writes,"
1003
			" %lu OS fsyncs\n"
1004
			"InnoDB: Starting InnoDB Monitor to print further\n"
1005
			"InnoDB: diagnostics to the standard output.\n",
1006
			(ulong) n_iterations,
1007
			(ulong) fil_n_pending_log_flushes,
1008
			(ulong) fil_n_pending_tablespace_flushes,
1009
			(ulong) os_n_file_reads, (ulong) os_n_file_writes,
1010
			(ulong) os_n_fsyncs);
1011
1012
		mon_value_was = srv_print_innodb_monitor;
1013
		started_monitor = TRUE;
1014
		srv_print_innodb_monitor = TRUE;
1015
		os_event_set(srv_lock_timeout_thread_event);
1016
	}
1017
1018
	/* No free block was found: try to flush the LRU list */
1019
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1020
	buf_flush_free_margin(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1021
	++srv_buf_pool_wait_free;
1022
1023
	os_aio_simulated_wake_handler_threads();
1024
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1025
	buf_pool_mutex_enter(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1026
1027
	if (buf_pool->LRU_flush_ended > 0) {
1028
		/* We have written pages in an LRU flush. To make the insert
1029
		buffer more efficient, we try to move these pages to the free
1030
		list. */
1031
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1032
		buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1033
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1034
		buf_LRU_try_free_flushed_blocks(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1035
	} else {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1036
		buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1037
	}
1038
1039
	if (n_iterations > 10) {
1040
1041
		os_thread_sleep(500000);
1042
	}
1043
1044
	n_iterations++;
1045
1046
	goto loop;
1047
}
1048
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1049
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1050
Moves the LRU_old pointer so that the length of the old blocks list
1051
is inside the allowed limits. */
1052
UNIV_INLINE
1053
void
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1054
buf_LRU_old_adjust_len(
1055
/*===================*/
1056
	buf_pool_t*	buf_pool)	/*!< in: buffer pool instance */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1057
{
1058
	ulint	old_len;
1059
	ulint	new_len;
1060
1061
	ut_a(buf_pool->LRU_old);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1062
	ut_ad(buf_pool_mutex_own(buf_pool));
1063
	ut_ad(buf_pool->LRU_old_ratio >= BUF_LRU_OLD_RATIO_MIN);
1064
	ut_ad(buf_pool->LRU_old_ratio <= BUF_LRU_OLD_RATIO_MAX);
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1065
#if BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)
1066
# error "BUF_LRU_OLD_RATIO_MIN * BUF_LRU_OLD_MIN_LEN <= BUF_LRU_OLD_RATIO_DIV * (BUF_LRU_OLD_TOLERANCE + 5)"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1067
#endif
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1068
#ifdef UNIV_LRU_DEBUG
1069
	/* buf_pool->LRU_old must be the first item in the LRU list
1070
	whose "old" flag is set. */
1071
	ut_a(buf_pool->LRU_old->old);
1072
	ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
1073
	     || !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
1074
	ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
1075
	     || UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
1076
#endif /* UNIV_LRU_DEBUG */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1077
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1078
	old_len = buf_pool->LRU_old_len;
1079
	new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1080
			 * buf_pool->LRU_old_ratio / BUF_LRU_OLD_RATIO_DIV,
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1081
			 UT_LIST_GET_LEN(buf_pool->LRU)
1082
			 - (BUF_LRU_OLD_TOLERANCE
1083
			    + BUF_LRU_NON_OLD_MIN_LEN));
1084
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1085
	for (;;) {
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1086
		buf_page_t*	LRU_old = buf_pool->LRU_old;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1087
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1088
		ut_a(LRU_old);
1089
		ut_ad(LRU_old->in_LRU_list);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1090
#ifdef UNIV_LRU_DEBUG
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1091
		ut_a(LRU_old->old);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1092
#endif /* UNIV_LRU_DEBUG */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1093
1094
		/* Update the LRU_old pointer if necessary */
1095
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1096
		if (old_len + BUF_LRU_OLD_TOLERANCE < new_len) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1097
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1098
			buf_pool->LRU_old = LRU_old = UT_LIST_GET_PREV(
1099
				LRU, LRU_old);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1100
#ifdef UNIV_LRU_DEBUG
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1101
			ut_a(!LRU_old->old);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1102
#endif /* UNIV_LRU_DEBUG */
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1103
			old_len = ++buf_pool->LRU_old_len;
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1104
			buf_page_set_old(LRU_old, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1105
1106
		} else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) {
1107
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1108
			buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old);
1109
			old_len = --buf_pool->LRU_old_len;
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1110
			buf_page_set_old(LRU_old, FALSE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1111
		} else {
1112
			return;
1113
		}
1114
	}
1115
}
1116
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1117
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1118
Initializes the old blocks pointer in the LRU list. This function should be
1119
called when the LRU list grows to BUF_LRU_OLD_MIN_LEN length. */
1120
static
1121
void
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1122
buf_LRU_old_init(
1123
/*=============*/
1124
	buf_pool_t*	buf_pool)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1125
{
1126
	buf_page_t*	bpage;
1127
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1128
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1129
	ut_a(UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN);
1130
1131
	/* We first initialize all blocks in the LRU list as old and then use
1132
	the adjust function to move the LRU_old pointer to the right
1133
	position */
1134
1819.5.99 by stewart at flamingspork
[patch 099/129] Merge patch for revision 1904 from InnoDB SVN:
1135
	for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage != NULL;
1136
	     bpage = UT_LIST_GET_PREV(LRU, bpage)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1137
		ut_ad(bpage->in_LRU_list);
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1138
		ut_ad(buf_page_in_file(bpage));
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1139
		/* This loop temporarily violates the
1140
		assertions of buf_page_set_old(). */
1141
		bpage->old = TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1142
	}
1143
1144
	buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU);
1145
	buf_pool->LRU_old_len = UT_LIST_GET_LEN(buf_pool->LRU);
1146
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1147
	buf_LRU_old_adjust_len(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1148
}
1149
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1150
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1151
Remove a block from the unzip_LRU list if it belonged to the list. */
1152
static
1153
void
1154
buf_unzip_LRU_remove_block_if_needed(
1155
/*=================================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1156
	buf_page_t*	bpage)	/*!< in/out: control block */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1157
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1158
	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
1159
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1160
	ut_ad(buf_pool);
1161
	ut_ad(bpage);
1162
	ut_ad(buf_page_in_file(bpage));
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1163
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1164
1165
	if (buf_page_belongs_to_unzip_LRU(bpage)) {
1166
		buf_block_t*	block = (buf_block_t*) bpage;
1167
1168
		ut_ad(block->in_unzip_LRU_list);
1169
		ut_d(block->in_unzip_LRU_list = FALSE);
1170
1171
		UT_LIST_REMOVE(unzip_LRU, buf_pool->unzip_LRU, block);
1172
	}
1173
}
1174
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1175
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1176
Removes a block from the LRU list. */
1177
UNIV_INLINE
1178
void
1179
buf_LRU_remove_block(
1180
/*=================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1181
	buf_page_t*	bpage)	/*!< in: control block */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1182
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1183
	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
1184
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1185
	ut_ad(buf_pool);
1186
	ut_ad(bpage);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1187
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1188
1189
	ut_a(buf_page_in_file(bpage));
1190
1191
	ut_ad(bpage->in_LRU_list);
1192
1193
	/* If the LRU_old pointer is defined and points to just this block,
1194
	move it backward one step */
1195
1196
	if (UNIV_UNLIKELY(bpage == buf_pool->LRU_old)) {
1197
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1198
		/* Below: the previous block is guaranteed to exist,
1199
		because the LRU_old pointer is only allowed to differ
1200
		by BUF_LRU_OLD_TOLERANCE from strict
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1201
		buf_pool->LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV of the LRU
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1202
		list length. */
1203
		buf_page_t*	prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1204
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1205
		ut_a(prev_bpage);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1206
#ifdef UNIV_LRU_DEBUG
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1207
		ut_a(!prev_bpage->old);
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1208
#endif /* UNIV_LRU_DEBUG */
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1209
		buf_pool->LRU_old = prev_bpage;
1210
		buf_page_set_old(prev_bpage, TRUE);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1211
1212
		buf_pool->LRU_old_len++;
1213
	}
1214
1215
	/* Remove the block from the LRU list */
1216
	UT_LIST_REMOVE(LRU, buf_pool->LRU, bpage);
1217
	ut_d(bpage->in_LRU_list = FALSE);
1218
1219
	buf_unzip_LRU_remove_block_if_needed(bpage);
1220
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1221
	/* If the LRU list is so short that LRU_old is not defined,
1222
	clear the "old" flags and return */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1223
	if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) {
1224
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1225
		for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage != NULL;
1226
		     bpage = UT_LIST_GET_NEXT(LRU, bpage)) {
1227
			/* This loop temporarily violates the
1228
			assertions of buf_page_set_old(). */
1229
			bpage->old = FALSE;
1230
		}
1231
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1232
		buf_pool->LRU_old = NULL;
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1233
		buf_pool->LRU_old_len = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1234
1235
		return;
1236
	}
1237
1238
	ut_ad(buf_pool->LRU_old);
1239
1240
	/* Update the LRU_old_len field if necessary */
1241
	if (buf_page_is_old(bpage)) {
1242
1243
		buf_pool->LRU_old_len--;
1244
	}
1245
1246
	/* Adjust the length of the old block list if necessary */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1247
	buf_LRU_old_adjust_len(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1248
}
1249
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1250
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1251
Adds a block to the LRU list of decompressed zip pages. */
1252
UNIV_INTERN
1253
void
1254
buf_unzip_LRU_add_block(
1255
/*====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1256
	buf_block_t*	block,	/*!< in: control block */
1257
	ibool		old)	/*!< in: TRUE if should be put to the end
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1258
				of the list, else put to the start */
1259
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1260
	buf_pool_t*	buf_pool = buf_pool_from_block(block);
1261
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1262
	ut_ad(buf_pool);
1263
	ut_ad(block);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1264
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1265
1266
	ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
1267
1268
	ut_ad(!block->in_unzip_LRU_list);
1269
	ut_d(block->in_unzip_LRU_list = TRUE);
1270
1271
	if (old) {
1272
		UT_LIST_ADD_LAST(unzip_LRU, buf_pool->unzip_LRU, block);
1273
	} else {
1274
		UT_LIST_ADD_FIRST(unzip_LRU, buf_pool->unzip_LRU, block);
1275
	}
1276
}
1277
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1278
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1279
Adds a block to the LRU list end. */
1280
UNIV_INLINE
1281
void
1282
buf_LRU_add_block_to_end_low(
1283
/*=========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1284
	buf_page_t*	bpage)	/*!< in: control block */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1285
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1286
	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
1287
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1288
	ut_ad(buf_pool);
1289
	ut_ad(bpage);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1290
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1291
1292
	ut_a(buf_page_in_file(bpage));
1293
1294
	ut_ad(!bpage->in_LRU_list);
1295
	UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
1296
	ut_d(bpage->in_LRU_list = TRUE);
1297
1298
	if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
1299
1300
		ut_ad(buf_pool->LRU_old);
1301
1302
		/* Adjust the length of the old block list if necessary */
1303
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1304
		buf_page_set_old(bpage, TRUE);
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1305
		buf_pool->LRU_old_len++;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1306
		buf_LRU_old_adjust_len(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1307
1308
	} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
1309
1310
		/* The LRU list is now long enough for LRU_old to become
1311
		defined: init it */
1312
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1313
		buf_LRU_old_init(buf_pool);
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1314
	} else {
1315
		buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1316
	}
1317
1318
	/* If this is a zipped block with decompressed frame as well
1319
	then put it on the unzip_LRU list */
1320
	if (buf_page_belongs_to_unzip_LRU(bpage)) {
1321
		buf_unzip_LRU_add_block((buf_block_t*) bpage, TRUE);
1322
	}
1323
}
1324
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1325
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1326
Adds a block to the LRU list. */
1327
UNIV_INLINE
1328
void
1329
buf_LRU_add_block_low(
1330
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1331
	buf_page_t*	bpage,	/*!< in: control block */
1332
	ibool		old)	/*!< in: TRUE if should be put to the old blocks
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1333
				in the LRU list, else put to the start; if the
1334
				LRU list is very short, the block is added to
1335
				the start, regardless of this parameter */
1336
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1337
	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
1338
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1339
	ut_ad(buf_pool);
1340
	ut_ad(bpage);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1341
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1342
1343
	ut_a(buf_page_in_file(bpage));
1344
	ut_ad(!bpage->in_LRU_list);
1345
1346
	if (!old || (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN)) {
1347
1348
		UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
1349
1350
		bpage->freed_page_clock = buf_pool->freed_page_clock;
1351
	} else {
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1352
#ifdef UNIV_LRU_DEBUG
1353
		/* buf_pool->LRU_old must be the first item in the LRU list
1354
		whose "old" flag is set. */
1355
		ut_a(buf_pool->LRU_old->old);
1356
		ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
1357
		     || !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
1358
		ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
1359
		     || UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
1360
#endif /* UNIV_LRU_DEBUG */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1361
		UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
1362
				     bpage);
1363
		buf_pool->LRU_old_len++;
1364
	}
1365
1366
	ut_d(bpage->in_LRU_list = TRUE);
1367
1368
	if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
1369
1370
		ut_ad(buf_pool->LRU_old);
1371
1372
		/* Adjust the length of the old block list if necessary */
1373
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1374
		buf_page_set_old(bpage, old);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1375
		buf_LRU_old_adjust_len(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1376
1377
	} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
1378
1379
		/* The LRU list is now long enough for LRU_old to become
1380
		defined: init it */
1381
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1382
		buf_LRU_old_init(buf_pool);
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1383
	} else {
1384
		buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1385
	}
1386
1387
	/* If this is a zipped block with decompressed frame as well
1388
	then put it on the unzip_LRU list */
1389
	if (buf_page_belongs_to_unzip_LRU(bpage)) {
1390
		buf_unzip_LRU_add_block((buf_block_t*) bpage, old);
1391
	}
1392
}
1393
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1394
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1395
Adds a block to the LRU list. */
1396
UNIV_INTERN
1397
void
1398
buf_LRU_add_block(
1399
/*==============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1400
	buf_page_t*	bpage,	/*!< in: control block */
1401
	ibool		old)	/*!< in: TRUE if should be put to the old
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1402
				blocks in the LRU list, else put to the start;
1403
				if the LRU list is very short, the block is
1404
				added to the start, regardless of this
1405
				parameter */
1406
{
1407
	buf_LRU_add_block_low(bpage, old);
1408
}
1409
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1410
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1411
Moves a block to the start of the LRU list. */
1412
UNIV_INTERN
1413
void
1414
buf_LRU_make_block_young(
1415
/*=====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1416
	buf_page_t*	bpage)	/*!< in: control block */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1417
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1418
	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
1419
1420
	ut_ad(buf_pool_mutex_own(buf_pool));
1819.5.57 by stewart at flamingspork
[patch 057/129] Merge patch for revision 1849 from InnoDB SVN:
1421
1422
	if (bpage->old) {
1423
		buf_pool->stat.n_pages_made_young++;
1424
	}
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1425
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1426
	buf_LRU_remove_block(bpage);
1427
	buf_LRU_add_block_low(bpage, FALSE);
1428
}
1429
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1430
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1431
Moves a block to the end of the LRU list. */
1432
UNIV_INTERN
1433
void
1434
buf_LRU_make_block_old(
1435
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1436
	buf_page_t*	bpage)	/*!< in: control block */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1437
{
1438
	buf_LRU_remove_block(bpage);
1439
	buf_LRU_add_block_to_end_low(bpage);
1440
}
1441
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1442
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1443
Try to free a block.  If bpage is a descriptor of a compressed-only
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1444
page, the descriptor object will be freed as well.
1445
1819.7.134 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100520131632-qvwrzeun5jbhv24d from MySQL InnoDB
1446
NOTE: If this function returns BUF_LRU_FREED, it will temporarily
1819.9.172 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20101020114628-ly1tyc8etgxr985x from MySQL InnoDB
1447
release buf_pool->mutex.  Furthermore, the page frame will no longer be
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1448
accessible via bpage.
1449
1819.9.172 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20101020114628-ly1tyc8etgxr985x from MySQL InnoDB
1450
The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1451
release these two mutexes after the call.  No other
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1452
buf_page_get_mutex() may be held when calling this function.
1453
@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
1454
BUF_LRU_NOT_FREED otherwise. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1455
UNIV_INTERN
1456
enum buf_lru_free_block_status
1457
buf_LRU_free_block(
1458
/*===============*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1459
	buf_page_t*	bpage,	/*!< in: block to be freed */
1460
	ibool		zip,	/*!< in: TRUE if should remove also the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1461
				compressed page of an uncompressed page */
1462
	ibool*		buf_pool_mutex_released)
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1463
				/*!< in: pointer to a variable that will
1819.7.134 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100520131632-qvwrzeun5jbhv24d from MySQL InnoDB
1464
				be assigned TRUE if buf_pool_mutex
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1465
				was temporarily released, or NULL */
1466
{
1467
	buf_page_t*	b = NULL;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1468
	buf_pool_t*	buf_pool = buf_pool_from_bpage(bpage);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1469
	mutex_t*	block_mutex = buf_page_get_mutex(bpage);
1470
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1471
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1472
	ut_ad(mutex_own(block_mutex));
1473
	ut_ad(buf_page_in_file(bpage));
1474
	ut_ad(bpage->in_LRU_list);
1475
	ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
1819.7.106 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100511154617-4ipeglopbpdiwzy0 from MySQL InnoDB
1476
#if UNIV_WORD_SIZE == 4
1477
	/* On 32-bit systems, there is no padding in buf_page_t.  On
1478
	other systems, Valgrind could complain about uninitialized pad
1479
	bytes. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1480
	UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
1819.7.106 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100511154617-4ipeglopbpdiwzy0 from MySQL InnoDB
1481
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1482
1483
	if (!buf_page_can_relocate(bpage)) {
1484
1485
		/* Do not free buffer-fixed or I/O-fixed blocks. */
1486
		return(BUF_LRU_NOT_FREED);
1487
	}
1488
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1489
#ifdef UNIV_IBUF_COUNT_DEBUG
1490
	ut_a(ibuf_count_get(bpage->space, bpage->offset) == 0);
1491
#endif /* UNIV_IBUF_COUNT_DEBUG */
1492
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1493
	if (zip || !bpage->zip.data) {
1494
		/* This would completely free the block. */
1495
		/* Do not completely free dirty blocks. */
1496
1497
		if (bpage->oldest_modification) {
1498
			return(BUF_LRU_NOT_FREED);
1499
		}
1500
	} else if (bpage->oldest_modification) {
1501
		/* Do not completely free dirty blocks. */
1502
1503
		if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
1504
			ut_ad(buf_page_get_state(bpage)
1505
			      == BUF_BLOCK_ZIP_DIRTY);
1506
			return(BUF_LRU_NOT_FREED);
1507
		}
1508
1509
		goto alloc;
1510
	} else if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
1511
		/* Allocate the control block for the compressed page.
1512
		If it cannot be allocated (without freeing a block
1513
		from the LRU list), refuse to free bpage. */
1514
alloc:
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1515
		buf_pool_mutex_exit_forbid(buf_pool);
1516
		b = buf_buddy_alloc(buf_pool, sizeof *b, NULL);
1517
		buf_pool_mutex_exit_allow(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1518
1519
		if (UNIV_UNLIKELY(!b)) {
1520
			return(BUF_LRU_CANNOT_RELOCATE);
1521
		}
1522
1523
		memcpy(b, bpage, sizeof *b);
1524
	}
1525
1526
#ifdef UNIV_DEBUG
1527
	if (buf_debug_prints) {
1528
		fprintf(stderr, "Putting space %lu page %lu to free list\n",
1529
			(ulong) buf_page_get_space(bpage),
1530
			(ulong) buf_page_get_page_no(bpage));
1531
	}
1532
#endif /* UNIV_DEBUG */
1533
1534
	if (buf_LRU_block_remove_hashed_page(bpage, zip)
1535
	    != BUF_BLOCK_ZIP_FREE) {
1536
		ut_a(bpage->buf_fix_count == 0);
1537
1538
		if (b) {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1539
			buf_page_t*	hash_b;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1540
			buf_page_t*	prev_b	= UT_LIST_GET_PREV(LRU, b);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1541
1542
			const ulint	fold = buf_page_address_fold(
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1543
				bpage->space, bpage->offset);
1544
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1545
			hash_b	= buf_page_hash_get_low(
1546
				buf_pool, bpage->space, bpage->offset, fold);
1547
1548
			ut_a(!hash_b);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1549
1550
			b->state = b->oldest_modification
1551
				? BUF_BLOCK_ZIP_DIRTY
1552
				: BUF_BLOCK_ZIP_PAGE;
1553
			UNIV_MEM_DESC(b->zip.data,
1554
				      page_zip_get_size(&b->zip), b);
1555
1556
			/* The fields in_page_hash and in_LRU_list of
1557
			the to-be-freed block descriptor should have
1558
			been cleared in
1559
			buf_LRU_block_remove_hashed_page(), which
1560
			invokes buf_LRU_remove_block(). */
1561
			ut_ad(!bpage->in_page_hash);
1562
			ut_ad(!bpage->in_LRU_list);
1563
			/* bpage->state was BUF_BLOCK_FILE_PAGE because
1564
			b != NULL. The type cast below is thus valid. */
1565
			ut_ad(!((buf_block_t*) bpage)->in_unzip_LRU_list);
1566
1567
			/* The fields of bpage were copied to b before
1568
			buf_LRU_block_remove_hashed_page() was invoked. */
1569
			ut_ad(!b->in_zip_hash);
1570
			ut_ad(b->in_page_hash);
1571
			ut_ad(b->in_LRU_list);
1572
1573
			HASH_INSERT(buf_page_t, hash,
1574
				    buf_pool->page_hash, fold, b);
1575
1576
			/* Insert b where bpage was in the LRU list. */
1577
			if (UNIV_LIKELY(prev_b != NULL)) {
1578
				ulint	lru_len;
1579
1580
				ut_ad(prev_b->in_LRU_list);
1581
				ut_ad(buf_page_in_file(prev_b));
1819.7.131 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100519093627-nasfm1bo837lyrkm from MySQL InnoDB
1582
#if UNIV_WORD_SIZE == 4
1583
				/* On 32-bit systems, there is no
1584
				padding in buf_page_t.  On other
1585
				systems, Valgrind could complain about
1586
				uninitialized pad bytes. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1587
				UNIV_MEM_ASSERT_RW(prev_b, sizeof *prev_b);
1819.7.131 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100519093627-nasfm1bo837lyrkm from MySQL InnoDB
1588
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1589
				UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU,
1590
						     prev_b, b);
1591
1592
				if (buf_page_is_old(b)) {
1593
					buf_pool->LRU_old_len++;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1594
					if (UNIV_UNLIKELY
1595
					    (buf_pool->LRU_old
1596
					     == UT_LIST_GET_NEXT(LRU, b))) {
1597
1598
						buf_pool->LRU_old = b;
1599
					}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1600
				}
1601
1602
				lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
1603
1604
				if (lru_len > BUF_LRU_OLD_MIN_LEN) {
1605
					ut_ad(buf_pool->LRU_old);
1606
					/* Adjust the length of the
1607
					old block list if necessary */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1608
					buf_LRU_old_adjust_len(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1609
				} else if (lru_len == BUF_LRU_OLD_MIN_LEN) {
1610
					/* The LRU list is now long
1611
					enough for LRU_old to become
1612
					defined: init it */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1613
					buf_LRU_old_init(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1614
				}
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
1615
#ifdef UNIV_LRU_DEBUG
1616
				/* Check that the "old" flag is consistent
1617
				in the block and its neighbours. */
1618
				buf_page_set_old(b, buf_page_is_old(b));
1619
#endif /* UNIV_LRU_DEBUG */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1620
			} else {
1621
				ut_d(b->in_LRU_list = FALSE);
1622
				buf_LRU_add_block_low(b, buf_page_is_old(b));
1623
			}
1624
1625
			if (b->state == BUF_BLOCK_ZIP_PAGE) {
1626
				buf_LRU_insert_zip_clean(b);
1627
			} else {
1819.5.251 by jyang
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6860 from MySQL InnoDB
1628
				/* Relocate on buf_pool->flush_list. */
1629
				buf_flush_relocate_on_flush_list(bpage, b);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1630
			}
1631
1632
			bpage->zip.data = NULL;
1633
			page_zip_set_size(&bpage->zip, 0);
1634
1635
			/* Prevent buf_page_get_gen() from
1636
			decompressing the block while we release
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1637
			buf_pool->mutex and block_mutex. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1638
			b->buf_fix_count++;
1639
			b->io_fix = BUF_IO_READ;
1640
		}
1641
1642
		if (buf_pool_mutex_released) {
1643
			*buf_pool_mutex_released = TRUE;
1644
		}
1645
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1646
		buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1647
		mutex_exit(block_mutex);
1648
1649
		/* Remove possible adaptive hash index on the page.
1650
		The page was declared uninitialized by
1651
		buf_LRU_block_remove_hashed_page().  We need to flag
1652
		the contents of the page valid (which it still is) in
1653
		order to avoid bogus Valgrind warnings.*/
1654
1655
		UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
1656
			       UNIV_PAGE_SIZE);
1657
		btr_search_drop_page_hash_index((buf_block_t*) bpage);
1658
		UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
1659
				 UNIV_PAGE_SIZE);
1660
1661
		if (b) {
1662
			/* Compute and stamp the compressed page
1663
			checksum while not holding any mutex.  The
1664
			block is already half-freed
1665
			(BUF_BLOCK_REMOVE_HASH) and removed from
1666
			buf_pool->page_hash, thus inaccessible by any
1667
			other thread. */
1668
1669
			mach_write_to_4(
1670
				b->zip.data + FIL_PAGE_SPACE_OR_CHKSUM,
1671
				UNIV_LIKELY(srv_use_checksums)
1672
				? page_zip_calc_checksum(
1673
					b->zip.data,
1674
					page_zip_get_size(&b->zip))
1675
				: BUF_NO_CHECKSUM_MAGIC);
1676
		}
1677
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1678
		buf_pool_mutex_enter(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1679
		mutex_enter(block_mutex);
1680
1681
		if (b) {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1682
			mutex_enter(&buf_pool->zip_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1683
			b->buf_fix_count--;
1684
			buf_page_set_io_fix(b, BUF_IO_NONE);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1685
			mutex_exit(&buf_pool->zip_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1686
		}
1687
1688
		buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
1689
	} else {
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1690
		/* The block_mutex should have been released by
1691
		buf_LRU_block_remove_hashed_page() when it returns
1692
		BUF_BLOCK_ZIP_FREE. */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1693
		ut_ad(block_mutex == &buf_pool->zip_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1694
		mutex_enter(block_mutex);
1695
	}
1696
1697
	return(BUF_LRU_FREED);
1698
}
1699
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1700
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1701
Puts a block back to the free list. */
1702
UNIV_INTERN
1703
void
1704
buf_LRU_block_free_non_file_page(
1705
/*=============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1706
	buf_block_t*	block)	/*!< in: block, must not contain a file page */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1707
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1708
	void*		data;
1709
	buf_pool_t*	buf_pool = buf_pool_from_block(block);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1710
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1711
	ut_ad(block);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1712
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1713
	ut_ad(mutex_own(&block->mutex));
1714
1715
	switch (buf_block_get_state(block)) {
1716
	case BUF_BLOCK_MEMORY:
1717
	case BUF_BLOCK_READY_FOR_USE:
1718
		break;
1719
	default:
1720
		ut_error;
1721
	}
1722
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1723
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
1724
	ut_a(block->n_pointers == 0);
1725
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1726
	ut_ad(!block->page.in_free_list);
1727
	ut_ad(!block->page.in_flush_list);
1728
	ut_ad(!block->page.in_LRU_list);
1729
1730
	buf_block_set_state(block, BUF_BLOCK_NOT_USED);
1731
1732
	UNIV_MEM_ALLOC(block->frame, UNIV_PAGE_SIZE);
1733
#ifdef UNIV_DEBUG
1734
	/* Wipe contents of page to reveal possible stale pointers to it */
1735
	memset(block->frame, '\0', UNIV_PAGE_SIZE);
1736
#else
1737
	/* Wipe page_no and space_id */
1738
	memset(block->frame + FIL_PAGE_OFFSET, 0xfe, 4);
1739
	memset(block->frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xfe, 4);
1740
#endif
1741
	data = block->page.zip.data;
1742
1743
	if (data) {
1744
		block->page.zip.data = NULL;
1745
		mutex_exit(&block->mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1746
		buf_pool_mutex_exit_forbid(buf_pool);
1747
1748
		buf_buddy_free(
1749
			buf_pool, data, page_zip_get_size(&block->page.zip));
1750
1751
		buf_pool_mutex_exit_allow(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1752
		mutex_enter(&block->mutex);
1753
		page_zip_set_size(&block->page.zip, 0);
1754
	}
1755
1756
	UT_LIST_ADD_FIRST(list, buf_pool->free, (&block->page));
1757
	ut_d(block->page.in_free_list = TRUE);
1758
1759
	UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
1760
}
1761
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1762
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1763
Takes a block out of the LRU list and page hash table.
1764
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1765
the object will be freed and buf_pool->zip_mutex will be released.
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1766
1767
If a compressed page or a compressed-only block descriptor is freed,
1768
other compressed pages or compressed-only block descriptors may be
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1769
relocated.
1770
@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
1771
was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1772
static
1773
enum buf_page_state
1774
buf_LRU_block_remove_hashed_page(
1775
/*=============================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1776
	buf_page_t*	bpage,	/*!< in: block, must contain a file page and
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1777
				be in a state where it can be freed; there
1778
				may or may not be a hash index to the page */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1779
	ibool		zip)	/*!< in: TRUE if should remove also the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1780
				compressed page of an uncompressed page */
1781
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1782
	ulint			fold;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1783
	const buf_page_t*	hashed_bpage;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1784
	buf_pool_t*		buf_pool = buf_pool_from_bpage(bpage);
1785
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1786
	ut_ad(bpage);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1787
	ut_ad(buf_pool_mutex_own(buf_pool));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1788
	ut_ad(mutex_own(buf_page_get_mutex(bpage)));
1789
1790
	ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
1791
	ut_a(bpage->buf_fix_count == 0);
1792
1819.7.106 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100511154617-4ipeglopbpdiwzy0 from MySQL InnoDB
1793
#if UNIV_WORD_SIZE == 4
1794
	/* On 32-bit systems, there is no padding in
1795
	buf_page_t.  On other systems, Valgrind could complain
1796
	about uninitialized pad bytes. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1797
	UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
1819.7.106 by Marko Mäkelä
Merge Revision revid:marko.makela@oracle.com-20100511154617-4ipeglopbpdiwzy0 from MySQL InnoDB
1798
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1799
1800
	buf_LRU_remove_block(bpage);
1801
1802
	buf_pool->freed_page_clock += 1;
1803
1804
	switch (buf_page_get_state(bpage)) {
1805
	case BUF_BLOCK_FILE_PAGE:
1806
		UNIV_MEM_ASSERT_W(bpage, sizeof(buf_block_t));
1807
		UNIV_MEM_ASSERT_W(((buf_block_t*) bpage)->frame,
1808
				  UNIV_PAGE_SIZE);
1809
		buf_block_modify_clock_inc((buf_block_t*) bpage);
1810
		if (bpage->zip.data) {
1811
			const page_t*	page = ((buf_block_t*) bpage)->frame;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1812
			const ulint	zip_size
1813
				= page_zip_get_size(&bpage->zip);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1814
1815
			ut_a(!zip || bpage->oldest_modification == 0);
1816
1817
			switch (UNIV_EXPECT(fil_page_get_type(page),
1818
					    FIL_PAGE_INDEX)) {
1819
			case FIL_PAGE_TYPE_ALLOCATED:
1820
			case FIL_PAGE_INODE:
1821
			case FIL_PAGE_IBUF_BITMAP:
1822
			case FIL_PAGE_TYPE_FSP_HDR:
1823
			case FIL_PAGE_TYPE_XDES:
1824
				/* These are essentially uncompressed pages. */
1825
				if (!zip) {
1826
					/* InnoDB writes the data to the
1827
					uncompressed page frame.  Copy it
1828
					to the compressed page, which will
1829
					be preserved. */
1830
					memcpy(bpage->zip.data, page,
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1831
					       zip_size);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1832
				}
1833
				break;
1834
			case FIL_PAGE_TYPE_ZBLOB:
1835
			case FIL_PAGE_TYPE_ZBLOB2:
1836
				break;
1837
			case FIL_PAGE_INDEX:
1838
#ifdef UNIV_ZIP_DEBUG
1839
				ut_a(page_zip_validate(&bpage->zip, page));
1840
#endif /* UNIV_ZIP_DEBUG */
1841
				break;
1842
			default:
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1843
				ut_print_timestamp(stderr);
1844
				fputs("  InnoDB: ERROR: The compressed page"
1845
				      " to be evicted seems corrupt:", stderr);
1846
				ut_print_buf(stderr, page, zip_size);
1847
				fputs("\nInnoDB: Possibly older version"
1848
				      " of the page:", stderr);
1849
				ut_print_buf(stderr, bpage->zip.data,
1850
					     zip_size);
1851
				putc('\n', stderr);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1852
				ut_error;
1853
			}
1854
1855
			break;
1856
		}
1857
		/* fall through */
1858
	case BUF_BLOCK_ZIP_PAGE:
1859
		ut_a(bpage->oldest_modification == 0);
1860
		UNIV_MEM_ASSERT_W(bpage->zip.data,
1861
				  page_zip_get_size(&bpage->zip));
1862
		break;
1863
	case BUF_BLOCK_ZIP_FREE:
1864
	case BUF_BLOCK_ZIP_DIRTY:
1865
	case BUF_BLOCK_NOT_USED:
1866
	case BUF_BLOCK_READY_FOR_USE:
1867
	case BUF_BLOCK_MEMORY:
1868
	case BUF_BLOCK_REMOVE_HASH:
1869
		ut_error;
1870
		break;
1871
	}
1872
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1873
	fold = buf_page_address_fold(bpage->space, bpage->offset);
1874
	hashed_bpage = buf_page_hash_get_low(
1875
		buf_pool, bpage->space, bpage->offset, fold);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1876
1877
	if (UNIV_UNLIKELY(bpage != hashed_bpage)) {
1878
		fprintf(stderr,
1879
			"InnoDB: Error: page %lu %lu not found"
1880
			" in the hash table\n",
1881
			(ulong) bpage->space,
1882
			(ulong) bpage->offset);
1883
		if (hashed_bpage) {
1884
			fprintf(stderr,
1885
				"InnoDB: In hash table we find block"
1886
				" %p of %lu %lu which is not %p\n",
1887
				(const void*) hashed_bpage,
1888
				(ulong) hashed_bpage->space,
1889
				(ulong) hashed_bpage->offset,
1890
				(const void*) bpage);
1891
		}
1892
1893
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1894
		mutex_exit(buf_page_get_mutex(bpage));
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1895
		buf_pool_mutex_exit(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1896
		buf_print();
1897
		buf_LRU_print();
1898
		buf_validate();
1899
		buf_LRU_validate();
1900
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
1901
		ut_error;
1902
	}
1903
1904
	ut_ad(!bpage->in_zip_hash);
1905
	ut_ad(bpage->in_page_hash);
1906
	ut_d(bpage->in_page_hash = FALSE);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1907
	HASH_DELETE(buf_page_t, hash, buf_pool->page_hash, fold, bpage);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1908
	switch (buf_page_get_state(bpage)) {
1909
	case BUF_BLOCK_ZIP_PAGE:
1910
		ut_ad(!bpage->in_free_list);
1911
		ut_ad(!bpage->in_flush_list);
1912
		ut_ad(!bpage->in_LRU_list);
1913
		ut_a(bpage->zip.data);
1914
		ut_a(buf_page_get_zip_size(bpage));
1915
1916
		UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
1917
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1918
		mutex_exit(&buf_pool->zip_mutex);
1919
		buf_pool_mutex_exit_forbid(buf_pool);
1920
1921
		buf_buddy_free(
1922
			buf_pool, bpage->zip.data,
1923
			page_zip_get_size(&bpage->zip));
1924
1925
		buf_buddy_free(buf_pool, bpage, sizeof(*bpage));
1926
		buf_pool_mutex_exit_allow(buf_pool);
1927
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1928
		UNIV_MEM_UNDESC(bpage);
1929
		return(BUF_BLOCK_ZIP_FREE);
1930
1931
	case BUF_BLOCK_FILE_PAGE:
1932
		memset(((buf_block_t*) bpage)->frame
1933
		       + FIL_PAGE_OFFSET, 0xff, 4);
1934
		memset(((buf_block_t*) bpage)->frame
1935
		       + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 0xff, 4);
1936
		UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
1937
				 UNIV_PAGE_SIZE);
1938
		buf_page_set_state(bpage, BUF_BLOCK_REMOVE_HASH);
1939
1940
		if (zip && bpage->zip.data) {
1941
			/* Free the compressed page. */
1942
			void*	data = bpage->zip.data;
1943
			bpage->zip.data = NULL;
1944
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1945
			ut_ad(!bpage->in_free_list);
1946
			ut_ad(!bpage->in_flush_list);
1947
			ut_ad(!bpage->in_LRU_list);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1948
			mutex_exit(&((buf_block_t*) bpage)->mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1949
			buf_pool_mutex_exit_forbid(buf_pool);
1950
1951
			buf_buddy_free(
1952
				buf_pool, data,
1953
				page_zip_get_size(&bpage->zip));
1954
1955
			buf_pool_mutex_exit_allow(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1956
			mutex_enter(&((buf_block_t*) bpage)->mutex);
1957
			page_zip_set_size(&bpage->zip, 0);
1958
		}
1959
1960
		return(BUF_BLOCK_REMOVE_HASH);
1961
1962
	case BUF_BLOCK_ZIP_FREE:
1963
	case BUF_BLOCK_ZIP_DIRTY:
1964
	case BUF_BLOCK_NOT_USED:
1965
	case BUF_BLOCK_READY_FOR_USE:
1966
	case BUF_BLOCK_MEMORY:
1967
	case BUF_BLOCK_REMOVE_HASH:
1968
		break;
1969
	}
1970
1971
	ut_error;
1972
	return(BUF_BLOCK_ZIP_FREE);
1973
}
1974
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1975
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1976
Puts a file page whose has no hash index to the free list. */
1977
static
1978
void
1979
buf_LRU_block_free_hashed_page(
1980
/*===========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1981
	buf_block_t*	block)	/*!< in: block, must contain a file page and
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1982
				be in a state where it can be freed */
1983
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1984
#ifdef UNIV_DEBUG
1985
	buf_pool_t*	buf_pool = buf_pool_from_block(block);
1986
	ut_ad(buf_pool_mutex_own(buf_pool));
1987
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1988
	ut_ad(mutex_own(&block->mutex));
1989
1990
	buf_block_set_state(block, BUF_BLOCK_MEMORY);
1991
1992
	buf_LRU_block_free_non_file_page(block);
1993
}
1994
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1995
/**********************************************************************//**
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1996
Updates buf_pool->LRU_old_ratio for one buffer pool instance.
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1997
@return	updated old_pct */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1998
static
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
1999
uint
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2000
buf_LRU_old_ratio_update_instance(
2001
/*==============================*/
2002
	buf_pool_t*	buf_pool,/*!< in: buffer pool instance */
2003
	uint		old_pct,/*!< in: Reserve this percentage of
2004
				the buffer pool for "old" blocks. */
2005
	ibool		adjust)	/*!< in: TRUE=adjust the LRU list;
2006
				FALSE=just assign buf_pool->LRU_old_ratio
2007
				during the initialization of InnoDB */
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2008
{
2009
	uint	ratio;
2010
2011
	ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100;
2012
	if (ratio < BUF_LRU_OLD_RATIO_MIN) {
2013
		ratio = BUF_LRU_OLD_RATIO_MIN;
2014
	} else if (ratio > BUF_LRU_OLD_RATIO_MAX) {
2015
		ratio = BUF_LRU_OLD_RATIO_MAX;
2016
	}
2017
2018
	if (adjust) {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2019
		buf_pool_mutex_enter(buf_pool);
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2020
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2021
		if (ratio != buf_pool->LRU_old_ratio) {
2022
			buf_pool->LRU_old_ratio = ratio;
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2023
2024
			if (UT_LIST_GET_LEN(buf_pool->LRU)
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2025
			   >= BUF_LRU_OLD_MIN_LEN) {
2026
2027
				buf_LRU_old_adjust_len(buf_pool);
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2028
			}
2029
		}
2030
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2031
		buf_pool_mutex_exit(buf_pool);
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2032
	} else {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2033
		buf_pool->LRU_old_ratio = ratio;
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2034
	}
1819.5.41 by stewart at flamingspork
[patch 041/129] Merge patch for revision 1829 from InnoDB SVN:
2035
	/* the reverse of 
2036
	ratio = old_pct * BUF_LRU_OLD_RATIO_DIV / 100 */
2037
	return((uint) (ratio * 100 / (double) BUF_LRU_OLD_RATIO_DIV + 0.5));
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2038
}
2039
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2040
/**********************************************************************//**
2041
Updates buf_pool->LRU_old_ratio.
2042
@return	updated old_pct */
2043
UNIV_INTERN
2044
ulint
2045
buf_LRU_old_ratio_update(
2046
/*=====================*/
2047
	uint	old_pct,/*!< in: Reserve this percentage of
2048
			the buffer pool for "old" blocks. */
2049
	ibool	adjust)	/*!< in: TRUE=adjust the LRU list;
2050
			FALSE=just assign buf_pool->LRU_old_ratio
2051
			during the initialization of InnoDB */
2052
{
2053
	ulint	i;
2054
	ulint	new_ratio = 0;
2055
2056
	for (i = 0; i < srv_buf_pool_instances; i++) {
2057
		buf_pool_t*	buf_pool;
2058
2059
		buf_pool = buf_pool_from_array(i);
2060
2061
		new_ratio = buf_LRU_old_ratio_update_instance(
2062
			buf_pool, old_pct, adjust);
2063
	}
2064
2065
	return(new_ratio);
2066
}
2067
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2068
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2069
Update the historical stats that we are collecting for LRU eviction
2070
policy at the end of each interval. */
2071
UNIV_INTERN
2072
void
2073
buf_LRU_stat_update(void)
2074
/*=====================*/
2075
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2076
	ulint		i;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2077
	buf_LRU_stat_t*	item;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2078
	buf_pool_t*	buf_pool;
2079
	ibool		evict_started = FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2080
2081
	/* If we haven't started eviction yet then don't update stats. */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2082
	for (i = 0; i < srv_buf_pool_instances; i++) {
2083
2084
		buf_pool = buf_pool_from_array(i);
2085
2086
		if (buf_pool->freed_page_clock != 0) {
2087
			evict_started = TRUE;
2088
			break;
2089
		}
2090
	}
2091
2092
	if (!evict_started) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2093
		goto func_exit;
2094
	}
2095
2096
	/* Update the index. */
2097
	item = &buf_LRU_stat_arr[buf_LRU_stat_arr_ind];
2098
	buf_LRU_stat_arr_ind++;
2099
	buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL;
2100
2101
	/* Add the current value and subtract the obsolete entry. */
2102
	buf_LRU_stat_sum.io += buf_LRU_stat_cur.io - item->io;
2103
	buf_LRU_stat_sum.unzip += buf_LRU_stat_cur.unzip - item->unzip;
2104
2105
	/* Put current entry in the array. */
2106
	memcpy(item, &buf_LRU_stat_cur, sizeof *item);
2107
2108
func_exit:
2109
	/* Clear the current entry. */
2110
	memset(&buf_LRU_stat_cur, 0, sizeof buf_LRU_stat_cur);
2111
}
2112
2113
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2114
/**********************************************************************//**
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2115
Validates the LRU list for one buffer pool instance. */
2116
static
2117
void
2118
buf_LRU_validate_instance(
2119
/*======================*/
2120
	buf_pool_t*	buf_pool)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2121
{
2122
	buf_page_t*	bpage;
2123
	buf_block_t*	block;
2124
	ulint		old_len;
2125
	ulint		new_len;
2126
2127
	ut_ad(buf_pool);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2128
	buf_pool_mutex_enter(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2129
2130
	if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
2131
2132
		ut_a(buf_pool->LRU_old);
2133
		old_len = buf_pool->LRU_old_len;
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2134
		new_len = ut_min(UT_LIST_GET_LEN(buf_pool->LRU)
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2135
				 * buf_pool->LRU_old_ratio
2136
				 / BUF_LRU_OLD_RATIO_DIV,
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2137
				 UT_LIST_GET_LEN(buf_pool->LRU)
2138
				 - (BUF_LRU_OLD_TOLERANCE
2139
				    + BUF_LRU_NON_OLD_MIN_LEN));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2140
		ut_a(old_len >= new_len - BUF_LRU_OLD_TOLERANCE);
2141
		ut_a(old_len <= new_len + BUF_LRU_OLD_TOLERANCE);
2142
	}
2143
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2144
	UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU,
2145
			 ut_ad(ut_list_node_313->in_LRU_list));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2146
2147
	bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
2148
2149
	old_len = 0;
2150
2151
	while (bpage != NULL) {
2152
2153
		switch (buf_page_get_state(bpage)) {
2154
		case BUF_BLOCK_ZIP_FREE:
2155
		case BUF_BLOCK_NOT_USED:
2156
		case BUF_BLOCK_READY_FOR_USE:
2157
		case BUF_BLOCK_MEMORY:
2158
		case BUF_BLOCK_REMOVE_HASH:
2159
			ut_error;
2160
			break;
2161
		case BUF_BLOCK_FILE_PAGE:
2162
			ut_ad(((buf_block_t*) bpage)->in_unzip_LRU_list
2163
			      == buf_page_belongs_to_unzip_LRU(bpage));
2164
		case BUF_BLOCK_ZIP_PAGE:
2165
		case BUF_BLOCK_ZIP_DIRTY:
2166
			break;
2167
		}
2168
2169
		if (buf_page_is_old(bpage)) {
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
2170
			const buf_page_t*	prev
2171
				= UT_LIST_GET_PREV(LRU, bpage);
2172
			const buf_page_t*	next
2173
				= UT_LIST_GET_NEXT(LRU, bpage);
2174
2175
			if (!old_len++) {
2176
				ut_a(buf_pool->LRU_old == bpage);
2177
			} else {
2178
				ut_a(!prev || buf_page_is_old(prev));
2179
			}
2180
2181
			ut_a(!next || buf_page_is_old(next));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2182
		}
2183
2184
		bpage = UT_LIST_GET_NEXT(LRU, bpage);
2185
	}
2186
1819.5.102 by stewart at flamingspork
[patch 102/129] Merge patch for revision 1908 from InnoDB SVN:
2187
	ut_a(buf_pool->LRU_old_len == old_len);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2188
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2189
	UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free,
2190
			 ut_ad(ut_list_node_313->in_free_list));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2191
2192
	for (bpage = UT_LIST_GET_FIRST(buf_pool->free);
2193
	     bpage != NULL;
2194
	     bpage = UT_LIST_GET_NEXT(list, bpage)) {
2195
2196
		ut_a(buf_page_get_state(bpage) == BUF_BLOCK_NOT_USED);
2197
	}
2198
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2199
	UT_LIST_VALIDATE(unzip_LRU, buf_block_t, buf_pool->unzip_LRU,
2200
			 ut_ad(ut_list_node_313->in_unzip_LRU_list
2201
			       && ut_list_node_313->page.in_LRU_list));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2202
2203
	for (block = UT_LIST_GET_FIRST(buf_pool->unzip_LRU);
2204
	     block;
2205
	     block = UT_LIST_GET_NEXT(unzip_LRU, block)) {
2206
2207
		ut_ad(block->in_unzip_LRU_list);
2208
		ut_ad(block->page.in_LRU_list);
2209
		ut_a(buf_page_belongs_to_unzip_LRU(&block->page));
2210
	}
2211
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2212
	buf_pool_mutex_exit(buf_pool);
2213
}
2214
2215
/**********************************************************************//**
2216
Validates the LRU list.
2217
@return	TRUE */
2218
UNIV_INTERN
2219
ibool
2220
buf_LRU_validate(void)
2221
/*==================*/
2222
{
2223
	ulint	i;
2224
2225
	for (i = 0; i < srv_buf_pool_instances; i++) {
2226
		buf_pool_t*	buf_pool;
2227
2228
		buf_pool = buf_pool_from_array(i);
2229
		buf_LRU_validate_instance(buf_pool);
2230
	}
2231
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2232
	return(TRUE);
2233
}
2234
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
2235
2236
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2237
/**********************************************************************//**
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2238
Prints the LRU list for one buffer pool instance. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2239
UNIV_INTERN
2240
void
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2241
buf_LRU_print_instance(
2242
/*===================*/
2243
	buf_pool_t*	buf_pool)
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2244
{
2245
	const buf_page_t*	bpage;
2246
2247
	ut_ad(buf_pool);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2248
	buf_pool_mutex_enter(buf_pool);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2249
2250
	bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
2251
2252
	while (bpage != NULL) {
2253
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2254
		mutex_enter(buf_page_get_mutex(bpage));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2255
		fprintf(stderr, "BLOCK space %lu page %lu ",
2256
			(ulong) buf_page_get_space(bpage),
2257
			(ulong) buf_page_get_page_no(bpage));
2258
2259
		if (buf_page_is_old(bpage)) {
2260
			fputs("old ", stderr);
2261
		}
2262
2263
		if (bpage->buf_fix_count) {
2264
			fprintf(stderr, "buffix count %lu ",
2265
				(ulong) bpage->buf_fix_count);
2266
		}
2267
2268
		if (buf_page_get_io_fix(bpage)) {
2269
			fprintf(stderr, "io_fix %lu ",
2270
				(ulong) buf_page_get_io_fix(bpage));
2271
		}
2272
2273
		if (bpage->oldest_modification) {
2274
			fputs("modif. ", stderr);
2275
		}
2276
2277
		switch (buf_page_get_state(bpage)) {
2278
			const byte*	frame;
2279
		case BUF_BLOCK_FILE_PAGE:
2280
			frame = buf_block_get_frame((buf_block_t*) bpage);
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2281
			fprintf(stderr, "\ntype %lu"
1819.9.31 by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB
2282
				" index id %llu\n",
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2283
				(ulong) fil_page_get_type(frame),
1819.9.31 by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB
2284
				(ullint) btr_page_get_index_id(frame));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2285
			break;
2286
		case BUF_BLOCK_ZIP_PAGE:
2287
			frame = bpage->zip.data;
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2288
			fprintf(stderr, "\ntype %lu size %lu"
1819.9.31 by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB
2289
				" index id %llu\n",
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2290
				(ulong) fil_page_get_type(frame),
2291
				(ulong) buf_page_get_zip_size(bpage),
1819.9.31 by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB
2292
				(ullint) btr_page_get_index_id(frame));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2293
			break;
2294
2295
		default:
1819.5.16 by stewart at flamingspork
[patch 016/129] Merge patch for revision 1802 from InnoDB SVN:
2296
			fprintf(stderr, "\n!state %lu!\n",
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2297
				(ulong) buf_page_get_state(bpage));
2298
			break;
2299
		}
2300
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2301
		mutex_exit(buf_page_get_mutex(bpage));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2302
		bpage = UT_LIST_GET_NEXT(LRU, bpage);
2303
	}
2304
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2305
	buf_pool_mutex_exit(buf_pool);
2306
}
2307
2308
/**********************************************************************//**
2309
Prints the LRU list. */
2310
UNIV_INTERN
2311
void
2312
buf_LRU_print(void)
2313
/*===============*/
2314
{
2315
	ulint		i;
2316
	buf_pool_t*	buf_pool;
2317
2318
	for (i = 0; i < srv_buf_pool_instances; i++) {
2319
		buf_pool = buf_pool_from_array(i);
2320
		buf_LRU_print_instance(buf_pool);
2321
	}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2322
}
2323
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */