buf0buf.h 52.6 KB
Newer Older
vasil's avatar
vasil committed
1
/*****************************************************************************
2

vasil's avatar
vasil committed
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4

vasil's avatar
vasil committed
5 6 7 8 9 10 11 12 13 14 15 16 17
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA

*****************************************************************************/
18

19 20
/**************************************************//**
@file include/buf0buf.h
osku's avatar
osku committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34
The database buffer pool high-level routines

Created 11/5/1995 Heikki Tuuri
*******************************************************/

#ifndef buf0buf_h
#define buf0buf_h

#include "univ.i"
#include "fil0fil.h"
#include "mtr0types.h"
#include "buf0types.h"
#include "hash0hash.h"
#include "ut0byte.h"
marko's avatar
marko committed
35
#include "page0types.h"
36 37
#ifndef UNIV_HOTBACKUP
#include "os0proc.h"
osku's avatar
osku committed
38

39
/** @name Modes for buf_page_get_gen */
40 41 42 43 44 45 46 47 48 49
/* @{ */
#define BUF_GET			10	/*!< get always */
#define	BUF_GET_IF_IN_POOL	11	/*!< get if in pool */
#define BUF_GET_NO_LATCH	14	/*!< get and bufferfix, but
					set no latch; we have
					separated this case, because
					it is error-prone programming
					not to set a latch, and it
					should be used with care */
/* @} */
50
/** @name Modes for buf_page_get_known_nowait */
51 52 53 54 55 56 57 58 59 60 61
/* @{ */
#define BUF_MAKE_YOUNG	51		/*!< Move the block to the
					start of the LRU list if there
					is a danger that the block
					would drift out of the buffer
					pool*/
#define BUF_KEEP_OLD	52		/*!< Preserve the current LRU
					position of the block. */
/* @} */

extern buf_pool_t*	buf_pool;	/*!< The buffer pool of the database */
osku's avatar
osku committed
62
#ifdef UNIV_DEBUG
63
extern ibool		buf_debug_prints;/*!< If this is set TRUE, the program
osku's avatar
osku committed
64 65 66
					prints info whenever read or flush
					occurs */
#endif /* UNIV_DEBUG */
67
extern ulint srv_buf_pool_write_requests; /*!< variable to count write request
68
					  issued */
69
#else /* !UNIV_HOTBACKUP */
70 71
extern buf_block_t*	back_block1;	/*!< first block, for --apply-log */
extern buf_block_t*	back_block2;	/*!< second block, for page reorganize */
72 73
#endif /* !UNIV_HOTBACKUP */

74
/** Magic value to use instead of checksums when they are disabled */
75
#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
osku's avatar
osku committed
76

77 78 79
/** @brief States of a control block
@see buf_page_struct

80
The enumeration values must be 0..7. */
81
enum buf_page_state {
82 83 84 85 86 87 88
	BUF_BLOCK_ZIP_FREE = 0,		/*!< contains a free
					compressed page */
	BUF_BLOCK_ZIP_PAGE,		/*!< contains a clean
					compressed page */
	BUF_BLOCK_ZIP_DIRTY,		/*!< contains a compressed
					page that is in the
					buf_pool->flush_list */
89

90 91 92 93 94 95 96 97 98 99
	BUF_BLOCK_NOT_USED,		/*!< is in the free list;
					must be after the BUF_BLOCK_ZIP_
					constants for compressed-only pages
					@see buf_block_state_valid() */
	BUF_BLOCK_READY_FOR_USE,	/*!< when buf_LRU_get_free_block
					returns a block, it is in this state */
	BUF_BLOCK_FILE_PAGE,		/*!< contains a buffered file page */
	BUF_BLOCK_MEMORY,		/*!< contains some main memory
					object */
	BUF_BLOCK_REMOVE_HASH		/*!< hash index should be removed
100 101 102
					before putting to the free list */
};

103
#ifndef UNIV_HOTBACKUP
104
/********************************************************************//**
105 106
Creates the buffer pool.
@return	own: buf_pool object, NULL if not enough memory or error */
107
UNIV_INTERN
osku's avatar
osku committed
108
buf_pool_t*
109 110
buf_pool_init(void);
/*===============*/
111
/********************************************************************//**
112 113
Frees the buffer pool at shutdown.  This must not be invoked before
freeing all mutexes. */
114
UNIV_INTERN
115 116 117 118
void
buf_pool_free(void);
/*===============*/

119
/********************************************************************//**
120 121 122 123 124 125 126 127
Drops the adaptive hash index.  To prevent a livelock, this function
is only to be called while holding btr_search_latch and while
btr_search_enabled == FALSE. */
UNIV_INTERN
void
buf_pool_drop_hash_index(void);
/*==========================*/

128
/********************************************************************//**
129
Relocate a buffer control block.  Relocates the block on the LRU list
130 131
and in buf_pool->page_hash.  Does not relocate bpage->list.
The caller must take care of relocating bpage->list. */
132
UNIV_INTERN
133 134 135
void
buf_relocate(
/*=========*/
136
	buf_page_t*	bpage,	/*!< in/out: control block being relocated;
137 138
				buf_page_get_state(bpage) must be
				BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
139
	buf_page_t*	dpage)	/*!< in/out: destination control block */
140
	__attribute__((nonnull));
141
/********************************************************************//**
142
Resizes the buffer pool. */
143
UNIV_INTERN
144 145 146
void
buf_pool_resize(void);
/*=================*/
147
/*********************************************************************//**
148 149
Gets the current size of buffer buf_pool in bytes.
@return	size in bytes */
osku's avatar
osku committed
150 151 152 153
UNIV_INLINE
ulint
buf_pool_get_curr_size(void);
/*========================*/
154
/********************************************************************//**
osku's avatar
osku committed
155
Gets the smallest oldest_modification lsn for any page in the pool. Returns
156 157
zero if all modified pages have been flushed to disk.
@return	oldest modification in pool, zero if none */
osku's avatar
osku committed
158
UNIV_INLINE
159
ib_uint64_t
osku's avatar
osku committed
160 161
buf_pool_get_oldest_modification(void);
/*==================================*/
162
/********************************************************************//**
163 164
Allocates a buffer block.
@return	own: the allocated block, in state BUF_BLOCK_MEMORY */
165 166 167 168
UNIV_INLINE
buf_block_t*
buf_block_alloc(
/*============*/
169
	ulint	zip_size);	/*!< in: compressed page size in bytes,
170
				or 0 if uncompressed tablespace */
171
/********************************************************************//**
172 173 174 175 176
Frees a buffer block which does not contain a file page. */
UNIV_INLINE
void
buf_block_free(
/*===========*/
177
	buf_block_t*	block);	/*!< in, own: block to be freed */
178
#endif /* !UNIV_HOTBACKUP */
179
/*********************************************************************//**
180 181
Copies contents of a buffer frame to a given buffer.
@return	buf */
osku's avatar
osku committed
182 183 184 185
UNIV_INLINE
byte*
buf_frame_copy(
/*===========*/
186 187
	byte*			buf,	/*!< in: buffer to copy to */
	const buf_frame_t*	frame);	/*!< in: buffer frame */
188
#ifndef UNIV_HOTBACKUP
189
/**************************************************************//**
osku's avatar
osku committed
190 191 192
NOTE! The following macros should be used instead of buf_page_get_gen,
to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed
in LA! */
193 194
#define buf_page_get(SP, ZS, OF, LA, MTR)	 buf_page_get_gen(\
				SP, ZS, OF, LA, NULL,\
osku's avatar
osku committed
195
				BUF_GET, __FILE__, __LINE__, MTR)
196
/**************************************************************//**
osku's avatar
osku committed
197 198 199 200 201
Use these macros to bufferfix a page with no latching. Remember not to
read the contents of the page unless you know it is safe. Do not modify
the contents of the page! We have separated this case, because it is
error-prone programming not to set a latch, and it should be used
with care. */
202 203
#define buf_page_get_with_no_latch(SP, ZS, OF, MTR)	   buf_page_get_gen(\
				SP, ZS, OF, RW_NO_LATCH, NULL,\
osku's avatar
osku committed
204
				BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
205
/**************************************************************//**
osku's avatar
osku committed
206 207 208
NOTE! The following macros should be used instead of
buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and
RW_X_LATCH are allowed as LA! */
209 210
#define buf_page_optimistic_get(LA, BL, MC, MTR)			     \
	buf_page_optimistic_get_func(LA, BL, MC, __FILE__, __LINE__, MTR)
211
/********************************************************************//**
osku's avatar
osku committed
212
This is the general function used to get optimistic access to a database
213 214
page.
@return	TRUE if success */
215
UNIV_INTERN
osku's avatar
osku committed
216 217 218
ibool
buf_page_optimistic_get_func(
/*=========================*/
219 220 221
	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
	buf_block_t*	block,	/*!< in: guessed block */
	ib_uint64_t	modify_clock,/*!< in: modify clock value if mode is
osku's avatar
osku committed
222
				..._GUESS_ON_CLOCK */
223 224 225
	const char*	file,	/*!< in: file name */
	ulint		line,	/*!< in: line where called */
	mtr_t*		mtr);	/*!< in: mini-transaction */
226
/********************************************************************//**
osku's avatar
osku committed
227
This is used to get access to a known database page, when no waiting can be
228 229
done.
@return	TRUE if success */
230
UNIV_INTERN
osku's avatar
osku committed
231 232 233
ibool
buf_page_get_known_nowait(
/*======================*/
234 235 236 237 238 239
	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
	buf_block_t*	block,	/*!< in: the known page */
	ulint		mode,	/*!< in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
	const char*	file,	/*!< in: file name */
	ulint		line,	/*!< in: line where called */
	mtr_t*		mtr);	/*!< in: mini-transaction */
vasil's avatar
vasil committed
240

241
/*******************************************************************//**
vasil's avatar
vasil committed
242 243 244
Given a tablespace id and page number tries to get that page. If the
page is not in the buffer pool it is not loaded and NULL is returned.
Suitable for using when holding the kernel mutex. */
245
UNIV_INTERN
246
const buf_block_t*
vasil's avatar
vasil committed
247 248
buf_page_try_get_func(
/*==================*/
249 250 251 252 253
	ulint		space_id,/*!< in: tablespace id */
	ulint		page_no,/*!< in: page number */
	const char*	file,	/*!< in: file name */
	ulint		line,	/*!< in: line where called */
	mtr_t*		mtr);	/*!< in: mini-transaction */
vasil's avatar
vasil committed
254

255 256 257 258 259 260
/** Tries to get a page. If the page is not in the buffer pool it is
not loaded.  Suitable for using when holding the kernel mutex.
@param space_id	in: tablespace id
@param page_no	in: page number
@param mtr	in: mini-transaction
@return		the page if in buffer pool, NULL if not */
vasil's avatar
vasil committed
261 262 263
#define buf_page_try_get(space_id, page_no, mtr)	\
	buf_page_try_get_func(space_id, page_no, __FILE__, __LINE__, mtr);

264
/********************************************************************//**
265 266
Get read access to a compressed page (usually of type
FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2).
267 268 269 270
The page must be released with buf_page_release_zip().
NOTE: the page is not protected by any latch.  Mutual exclusion has to
be implemented at a higher level.  In other words, all possible
accesses to a given page through this function must be protected by
271 272
the same set of mutexes or latches.
@return	pointer to the block, or NULL if not compressed */
273
UNIV_INTERN
274 275 276
buf_page_t*
buf_page_get_zip(
/*=============*/
277 278 279
	ulint		space,	/*!< in: space id */
	ulint		zip_size,/*!< in: compressed page size */
	ulint		offset);/*!< in: page number */
280
/********************************************************************//**
281 282
This is the general function used to get access to a database page.
@return	pointer to the block or NULL */
283
UNIV_INTERN
284
buf_block_t*
osku's avatar
osku committed
285 286
buf_page_get_gen(
/*=============*/
287 288
	ulint		space,	/*!< in: space id */
	ulint		zip_size,/*!< in: compressed page size in bytes
289
				or 0 for uncompressed pages */
290 291 292 293
	ulint		offset,	/*!< in: page number */
	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
	buf_block_t*	guess,	/*!< in: guessed block or NULL */
	ulint		mode,	/*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
osku's avatar
osku committed
294
				BUF_GET_NO_LATCH */
295 296 297
	const char*	file,	/*!< in: file name */
	ulint		line,	/*!< in: line where called */
	mtr_t*		mtr);	/*!< in: mini-transaction */
298
/********************************************************************//**
osku's avatar
osku committed
299 300 301
Initializes a page to the buffer buf_pool. The page is usually not read
from a file even if it cannot be found in the buffer buf_pool. This is one
of the functions which perform to a block a state transition NOT_USED =>
302 303
FILE_PAGE (the other is buf_page_get_gen).
@return	pointer to the block, page bufferfixed */
304
UNIV_INTERN
305
buf_block_t*
osku's avatar
osku committed
306 307
buf_page_create(
/*============*/
308 309
	ulint	space,	/*!< in: space id */
	ulint	offset,	/*!< in: offset of the page within space in units of
osku's avatar
osku committed
310
			a page */
311 312
	ulint	zip_size,/*!< in: compressed page size, or 0 */
	mtr_t*	mtr);	/*!< in: mini-transaction handle */
313
#else /* !UNIV_HOTBACKUP */
314
/********************************************************************//**
osku's avatar
osku committed
315
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
316
UNIV_INTERN
osku's avatar
osku committed
317 318 319
void
buf_page_init_for_backup_restore(
/*=============================*/
320 321
	ulint		space,	/*!< in: space id */
	ulint		offset,	/*!< in: offset of the page within space
osku's avatar
osku committed
322
				in units of a page */
323
	ulint		zip_size,/*!< in: compressed page size in bytes
324
				or 0 for uncompressed pages */
325
	buf_block_t*	block);	/*!< in: block to init */
326 327 328
#endif /* !UNIV_HOTBACKUP */

#ifndef UNIV_HOTBACKUP
329
/********************************************************************//**
330 331 332 333 334
Releases a compressed-only page acquired with buf_page_get_zip(). */
UNIV_INLINE
void
buf_page_release_zip(
/*=================*/
335
	buf_page_t*	bpage);		/*!< in: buffer block */
336
/********************************************************************//**
osku's avatar
osku committed
337 338 339 340 341 342
Decrements the bufferfix count of a buffer control block and releases
a latch, if specified. */
UNIV_INLINE
void
buf_page_release(
/*=============*/
343 344
	buf_block_t*	block,		/*!< in: buffer block */
	ulint		rw_latch,	/*!< in: RW_S_LATCH, RW_X_LATCH,
osku's avatar
osku committed
345
					RW_NO_LATCH */
346
	mtr_t*		mtr);		/*!< in: mtr */
347
/********************************************************************//**
osku's avatar
osku committed
348
Moves a page to the start of the buffer pool LRU list. This high-level
349
function can be used to prevent an important page from slipping out of
osku's avatar
osku committed
350
the buffer pool. */
351
UNIV_INTERN
osku's avatar
osku committed
352 353
void
buf_page_make_young(
354
/*================*/
355
	buf_page_t*	bpage);	/*!< in: buffer block of a file page */
356
/********************************************************************//**
357 358 359 360 361 362
Returns TRUE if the page can be found in the buffer pool hash table.

NOTE that it is possible that the page is not yet read from disk,
though.

@return	TRUE if found in the page hash table */
363
UNIV_INLINE
osku's avatar
osku committed
364 365 366
ibool
buf_page_peek(
/*==========*/
367 368
	ulint	space,	/*!< in: space id */
	ulint	offset);/*!< in: page number */
369
/********************************************************************//**
osku's avatar
osku committed
370 371
Resets the check_index_page_at_flush field of a page if found in the buffer
pool. */
372
UNIV_INTERN
osku's avatar
osku committed
373 374 375
void
buf_reset_check_index_page_at_flush(
/*================================*/
376 377
	ulint	space,	/*!< in: space id */
	ulint	offset);/*!< in: page number */
378
#ifdef UNIV_DEBUG_FILE_ACCESSES
379
/********************************************************************//**
osku's avatar
osku committed
380 381 382
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
383 384
reallocated.
@return	control block if found in page hash table, otherwise NULL */
385
UNIV_INTERN
386
buf_page_t*
osku's avatar
osku committed
387 388
buf_page_set_file_page_was_freed(
/*=============================*/
389 390
	ulint	space,	/*!< in: space id */
	ulint	offset);/*!< in: page number */
391
/********************************************************************//**
osku's avatar
osku committed
392 393 394
Sets file_page_was_freed FALSE if the page is found in the buffer pool.
This function should be called when we free a file page and want the
debug version to check that it is not accessed any more unless
395 396
reallocated.
@return	control block if found in page hash table, otherwise NULL */
397
UNIV_INTERN
398
buf_page_t*
osku's avatar
osku committed
399 400
buf_page_reset_file_page_was_freed(
/*===============================*/
401 402
	ulint	space,	/*!< in: space id */
	ulint	offset);	/*!< in: page number */
403
#endif /* UNIV_DEBUG_FILE_ACCESSES */
404
/********************************************************************//**
405 406
Reads the freed_page_clock of a buffer block.
@return	freed_page_clock */
407 408 409 410
UNIV_INLINE
ulint
buf_page_get_freed_page_clock(
/*==========================*/
411
	const buf_page_t*	bpage)	/*!< in: block */
412
	__attribute__((pure));
413
/********************************************************************//**
414 415
Reads the freed_page_clock of a buffer block.
@return	freed_page_clock */
416 417 418 419
UNIV_INLINE
ulint
buf_block_get_freed_page_clock(
/*===========================*/
420
	const buf_block_t*	block)	/*!< in: block */
421 422
	__attribute__((pure));

423
/********************************************************************//**
osku's avatar
osku committed
424 425
Recommends a move of a block to the start of the LRU list if there is danger
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
426 427
mutex.
@return	TRUE if should be made younger */
osku's avatar
osku committed
428 429
UNIV_INLINE
ibool
430 431
buf_page_peek_if_too_old(
/*=====================*/
432
	const buf_page_t*	bpage);	/*!< in: block to make younger */
433
/********************************************************************//**
osku's avatar
osku committed
434 435
Returns the current state of is_hashed of a page. FALSE if the page is
not in the pool. NOTE that this operation does not fix the page in the
436 437
pool if it is found there.
@return	TRUE if page hash index is built in search system */
438
UNIV_INTERN
osku's avatar
osku committed
439 440 441
ibool
buf_page_peek_if_search_hashed(
/*===========================*/
442 443
	ulint	space,	/*!< in: space id */
	ulint	offset);/*!< in: page number */
444
/********************************************************************//**
osku's avatar
osku committed
445
Gets the youngest modification log sequence number for a frame.
446 447
Returns zero if not file page or no modification occurred yet.
@return	newest modification to page */
osku's avatar
osku committed
448
UNIV_INLINE
449
ib_uint64_t
450 451
buf_page_get_newest_modification(
/*=============================*/
452
	const buf_page_t*	bpage);	/*!< in: block containing the
453
					page frame */
454
/********************************************************************//**
osku's avatar
osku committed
455 456 457 458
Increments the modify clock of a frame by 1. The caller must (1) own the
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
on the block. */
UNIV_INLINE
459
void
osku's avatar
osku committed
460 461
buf_block_modify_clock_inc(
/*=======================*/
462
	buf_block_t*	block);	/*!< in: block */
463
/********************************************************************//**
464
Returns the value of the modify clock. The caller must have an s-lock
465 466
or x-lock on the block.
@return	value */
osku's avatar
osku committed
467
UNIV_INLINE
468
ib_uint64_t
osku's avatar
osku committed
469 470
buf_block_get_modify_clock(
/*=======================*/
471
	buf_block_t*	block);	/*!< in: block */
472 473 474
#else /* !UNIV_HOTBACKUP */
# define buf_block_modify_clock_inc(block) ((void) 0)
#endif /* !UNIV_HOTBACKUP */
475
/********************************************************************//**
osku's avatar
osku committed
476 477
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value
478 479
on 32-bit and 64-bit architectures.
@return	checksum */
480
UNIV_INTERN
osku's avatar
osku committed
481 482 483
ulint
buf_calc_page_new_checksum(
/*=======================*/
484
	const byte*	page);	/*!< in: buffer page */
485
/********************************************************************//**
osku's avatar
osku committed
486 487
In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
looked at the first few bytes of the page. This calculates that old
488
checksum.
osku's avatar
osku committed
489 490
NOTE: we must first store the new formula checksum to
FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum
491 492
because this takes that field as an input!
@return	checksum */
493
UNIV_INTERN
osku's avatar
osku committed
494 495 496
ulint
buf_calc_page_old_checksum(
/*=======================*/
497
	const byte*	 page);	/*!< in: buffer page */
498
/********************************************************************//**
499 500
Checks if a page is corrupt.
@return	TRUE if corrupted */
501
UNIV_INTERN
osku's avatar
osku committed
502 503 504
ibool
buf_page_is_corrupted(
/*==================*/
505 506
	const byte*	read_buf,	/*!< in: a database page */
	ulint		zip_size);	/*!< in: size of compressed page;
marko's avatar
marko committed
507
					0 for uncompressed pages */
508
#ifndef UNIV_HOTBACKUP
509
/**********************************************************************//**
osku's avatar
osku committed
510 511 512 513 514 515
Gets the space id, page offset, and byte offset within page of a
pointer pointing to a buffer frame containing a file page. */
UNIV_INLINE
void
buf_ptr_get_fsp_addr(
/*=================*/
516 517 518
	const void*	ptr,	/*!< in: pointer to a buffer frame */
	ulint*		space,	/*!< out: space id */
	fil_addr_t*	addr);	/*!< out: page offset and byte offset */
519
/**********************************************************************//**
520
Gets the hash value of a block. This can be used in searches in the
521 522
lock hash table.
@return	lock hash value */
osku's avatar
osku committed
523 524
UNIV_INLINE
ulint
525
buf_block_get_lock_hash_val(
osku's avatar
osku committed
526
/*========================*/
527
	const buf_block_t*	block)	/*!< in: block */
528
	__attribute__((pure));
529
#ifdef UNIV_DEBUG
530
/*********************************************************************//**
531
Finds a block in the buffer pool that points to a
532 533
given compressed page.
@return	buffer block pointing to the compressed page, or NULL */
534
UNIV_INTERN
535 536 537
buf_block_t*
buf_pool_contains_zip(
/*==================*/
538
	const void*	data);	/*!< in: pointer to compressed page */
539
#endif /* UNIV_DEBUG */
540
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
541
/*********************************************************************//**
542 543
Validates the buffer pool data structure.
@return	TRUE */
544
UNIV_INTERN
osku's avatar
osku committed
545 546 547
ibool
buf_validate(void);
/*==============*/
548 549
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
550
/*********************************************************************//**
osku's avatar
osku committed
551
Prints info of the buffer pool data structure. */
552
UNIV_INTERN
osku's avatar
osku committed
553 554 555
void
buf_print(void);
/*============*/
556
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
557
#endif /* !UNIV_HOTBACKUP */
558
/********************************************************************//**
osku's avatar
osku committed
559
Prints a page to stderr. */
560
UNIV_INTERN
osku's avatar
osku committed
561 562 563
void
buf_page_print(
/*===========*/
564 565
	const byte*	read_buf,	/*!< in: a database page */
	ulint		zip_size);	/*!< in: compressed page size, or
marko's avatar
marko committed
566
					0 for uncompressed pages */
567
/********************************************************************//**
568 569
Decompress a block.
@return	TRUE if successful */
570 571 572 573
UNIV_INTERN
ibool
buf_zip_decompress(
/*===============*/
574 575
	buf_block_t*	block,	/*!< in/out: block */
	ibool		check);	/*!< in: TRUE=verify the page checksum */
576
#ifndef UNIV_HOTBACKUP
577
#ifdef UNIV_DEBUG
578
/*********************************************************************//**
579 580
Returns the number of latched pages in the buffer pool.
@return	number of latched pages */
581
UNIV_INTERN
osku's avatar
osku committed
582 583 584
ulint
buf_get_latched_pages_number(void);
/*==============================*/
585
#endif /* UNIV_DEBUG */
586
/*********************************************************************//**
587 588
Returns the number of pending buf pool ios.
@return	number of pending I/O operations */
589
UNIV_INTERN
osku's avatar
osku committed
590 591 592
ulint
buf_get_n_pending_ios(void);
/*=======================*/
593
/*********************************************************************//**
osku's avatar
osku committed
594
Prints info of the buffer i/o. */
595
UNIV_INTERN
osku's avatar
osku committed
596 597 598
void
buf_print_io(
/*=========*/
599
	FILE*	file);	/*!< in: file where to print */
600
/*********************************************************************//**
osku's avatar
osku committed
601
Returns the ratio in percents of modified pages in the buffer pool /
602 603
database pages in the buffer pool.
@return	modified page percentage ratio */
604
UNIV_INTERN
osku's avatar
osku committed
605 606 607
ulint
buf_get_modified_ratio_pct(void);
/*============================*/
608
/**********************************************************************//**
osku's avatar
osku committed
609
Refreshes the statistics used to print per-second averages. */
610
UNIV_INTERN
osku's avatar
osku committed
611 612 613
void
buf_refresh_io_stats(void);
/*======================*/
614
/*********************************************************************//**
615 616
Asserts that all file pages in the buffer are in a replaceable state.
@return	TRUE */
617
UNIV_INTERN
osku's avatar
osku committed
618 619 620
ibool
buf_all_freed(void);
/*===============*/
621
/*********************************************************************//**
osku's avatar
osku committed
622
Checks that there currently are no pending i/o-operations for the buffer
623 624
pool.
@return	TRUE if there is no pending i/o */
625
UNIV_INTERN
osku's avatar
osku committed
626 627 628
ibool
buf_pool_check_no_pending_io(void);
/*==============================*/
629
/*********************************************************************//**
osku's avatar
osku committed
630 631 632
Invalidates the file pages in the buffer pool when an archive recovery is
completed. All the file pages buffered must be in a replaceable state when
this function is called: not latched and not modified. */
633
UNIV_INTERN
osku's avatar
osku committed
634 635 636
void
buf_pool_invalidate(void);
/*=====================*/
637
#endif /* !UNIV_HOTBACKUP */
osku's avatar
osku committed
638 639 640 641 642 643

/*========================================================================
--------------------------- LOWER LEVEL ROUTINES -------------------------
=========================================================================*/

#ifdef UNIV_SYNC_DEBUG
644
/*********************************************************************//**
osku's avatar
osku committed
645 646 647 648 649
Adds latch level info for the rw-lock protecting the buffer frame. This
should be called in the debug version after a successful latching of a
page if we know the latching order level of the acquired latch. */
UNIV_INLINE
void
650 651
buf_block_dbg_add_level(
/*====================*/
652
	buf_block_t*	block,	/*!< in: buffer page
653
				where we have acquired latch */
654
	ulint		level);	/*!< in: latching order level */
marko's avatar
marko committed
655 656
#else /* UNIV_SYNC_DEBUG */
# define buf_block_dbg_add_level(block, level) /* nothing */
osku's avatar
osku committed
657
#endif /* UNIV_SYNC_DEBUG */
658
/*********************************************************************//**
659 660
Gets the state of a block.
@return	state */
661
UNIV_INLINE
662
enum buf_page_state
663 664
buf_page_get_state(
/*===============*/
665
	const buf_page_t*	bpage);	/*!< in: pointer to the control block */
666
/*********************************************************************//**
667 668
Gets the state of a block.
@return	state */
669 670
UNIV_INLINE
enum buf_page_state
671 672
buf_block_get_state(
/*================*/
673
	const buf_block_t*	block)	/*!< in: pointer to the control block */
674
	__attribute__((pure));
675
/*********************************************************************//**
676 677 678
Sets the state of a block. */
UNIV_INLINE
void
679 680
buf_page_set_state(
/*===============*/
681 682
	buf_page_t*		bpage,	/*!< in/out: pointer to control block */
	enum buf_page_state	state);	/*!< in: state */
683
/*********************************************************************//**
684 685 686
Sets the state of a block. */
UNIV_INLINE
void
687 688
buf_block_set_state(
/*================*/
689 690
	buf_block_t*		block,	/*!< in/out: pointer to control block */
	enum buf_page_state	state);	/*!< in: state */
691
/*********************************************************************//**
692 693
Determines if a block is mapped to a tablespace.
@return	TRUE if mapped */
694 695 696 697
UNIV_INLINE
ibool
buf_page_in_file(
/*=============*/
698
	const buf_page_t*	bpage)	/*!< in: pointer to control block */
699
	__attribute__((pure));
700
#ifndef UNIV_HOTBACKUP
701
/*********************************************************************//**
702 703
Determines if a block should be on unzip_LRU list.
@return	TRUE if block belongs to unzip_LRU */
704 705 706 707
UNIV_INLINE
ibool
buf_page_belongs_to_unzip_LRU(
/*==========================*/
708
	const buf_page_t*	bpage)	/*!< in: pointer to control block */
709
	__attribute__((pure));
710

711
/*********************************************************************//**
712 713
Gets the mutex of a block.
@return	pointer to mutex protecting bpage */
714 715 716
UNIV_INLINE
mutex_t*
buf_page_get_mutex(
717
/*===============*/
718
	const buf_page_t*	bpage)	/*!< in: pointer to control block */
719 720
	__attribute__((pure));

721
/*********************************************************************//**
722 723
Get the flush type of a page.
@return	flush type */
724 725 726 727
UNIV_INLINE
enum buf_flush
buf_page_get_flush_type(
/*====================*/
728
	const buf_page_t*	bpage)	/*!< in: buffer page */
729
	__attribute__((pure));
730
/*********************************************************************//**
731 732 733 734 735
Set the flush type of a page. */
UNIV_INLINE
void
buf_page_set_flush_type(
/*====================*/
736 737
	buf_page_t*	bpage,		/*!< in: buffer page */
	enum buf_flush	flush_type);	/*!< in: flush type */
738
/*********************************************************************//**
739 740 741 742 743
Map a block to a file page. */
UNIV_INLINE
void
buf_block_set_file_page(
/*====================*/
744 745 746
	buf_block_t*		block,	/*!< in/out: pointer to control block */
	ulint			space,	/*!< in: tablespace id */
	ulint			page_no);/*!< in: page number */
747
/*********************************************************************//**
748 749
Gets the io_fix state of a block.
@return	io_fix state */
750 751 752 753
UNIV_INLINE
enum buf_io_fix
buf_page_get_io_fix(
/*================*/
754
	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
755
	__attribute__((pure));
756
/*********************************************************************//**
757 758
Gets the io_fix state of a block.
@return	io_fix state */
759 760 761 762
UNIV_INLINE
enum buf_io_fix
buf_block_get_io_fix(
/*================*/
763
	const buf_block_t*	block)	/*!< in: pointer to the control block */
764
	__attribute__((pure));
765
/*********************************************************************//**
766 767 768 769 770
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_page_set_io_fix(
/*================*/
771 772
	buf_page_t*	bpage,	/*!< in/out: control block */
	enum buf_io_fix	io_fix);/*!< in: io_fix state */
773
/*********************************************************************//**
774 775 776 777 778
Sets the io_fix state of a block. */
UNIV_INLINE
void
buf_block_set_io_fix(
/*=================*/
779 780
	buf_block_t*	block,	/*!< in/out: control block */
	enum buf_io_fix	io_fix);/*!< in: io_fix state */
781

782
/********************************************************************//**
783 784 785 786 787 788
Determine if a buffer block can be relocated in memory.  The block
can be dirty, but it must not be I/O-fixed or bufferfixed. */
UNIV_INLINE
ibool
buf_page_can_relocate(
/*==================*/
789
	const buf_page_t*	bpage)	/*!< control block being relocated */
790
	__attribute__((pure));
791

792
/*********************************************************************//**
793 794
Determine if a block has been flagged old.
@return	TRUE if old */
795 796 797 798
UNIV_INLINE
ibool
buf_page_is_old(
/*============*/
799
	const buf_page_t*	bpage)	/*!< in: control block */
800
	__attribute__((pure));
801
/*********************************************************************//**
802 803 804 805 806
Flag a block old. */
UNIV_INLINE
void
buf_page_set_old(
/*=============*/
807 808
	buf_page_t*	bpage,	/*!< in/out: control block */
	ibool		old);	/*!< in: old */
809
/*********************************************************************//**
810 811
Determine the time of first access of a block in the buffer pool.
@return	ut_time_ms() at the time of first access, 0 if not accessed */
812
UNIV_INLINE
813
unsigned
814 815
buf_page_is_accessed(
/*=================*/
816
	const buf_page_t*	bpage)	/*!< in: control block */
817
	__attribute__((nonnull, pure));
818
/*********************************************************************//**
819 820 821 822 823
Flag a block accessed. */
UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
824 825
	buf_page_t*	bpage,		/*!< in/out: control block */
	ulint		time_ms)	/*!< in: ut_time_ms() */
826
	__attribute__((nonnull));
827
/*********************************************************************//**
828
Gets the buf_block_t handle of a buffered file block if an uncompressed
829 830
page frame exists, or NULL.
@return	control block, or NULL */
831
UNIV_INLINE
832
buf_block_t*
833 834
buf_page_get_block(
/*===============*/
835
	buf_page_t*	bpage)	/*!< in: control block, or NULL */
836
	__attribute__((pure));
837
#endif /* !UNIV_HOTBACKUP */
838
#ifdef UNIV_DEBUG
839
/*********************************************************************//**
840 841
Gets a pointer to the memory frame of a block.
@return	pointer to the frame */
osku's avatar
osku committed
842 843 844 845
UNIV_INLINE
buf_frame_t*
buf_block_get_frame(
/*================*/
846
	const buf_block_t*	block)	/*!< in: pointer to the control block */
847
	__attribute__((pure));
848
#else /* UNIV_DEBUG */
849
# define buf_block_get_frame(block) (block)->frame
850
#endif /* UNIV_DEBUG */
851
/*********************************************************************//**
852 853
Gets the space id of a block.
@return	space id */
854 855 856 857
UNIV_INLINE
ulint
buf_page_get_space(
/*===============*/
858
	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
859
	__attribute__((pure));
860
/*********************************************************************//**
861 862
Gets the space id of a block.
@return	space id */
osku's avatar
osku committed
863 864 865 866
UNIV_INLINE
ulint
buf_block_get_space(
/*================*/
867
	const buf_block_t*	block)	/*!< in: pointer to the control block */
868
	__attribute__((pure));
869
/*********************************************************************//**
870 871
Gets the page number of a block.
@return	page number */
872 873 874 875
UNIV_INLINE
ulint
buf_page_get_page_no(
/*=================*/
876
	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
877
	__attribute__((pure));
878
/*********************************************************************//**
879 880
Gets the page number of a block.
@return	page number */
osku's avatar
osku committed
881 882 883 884
UNIV_INLINE
ulint
buf_block_get_page_no(
/*==================*/
885
	const buf_block_t*	block)	/*!< in: pointer to the control block */
886
	__attribute__((pure));
887
/*********************************************************************//**
888 889
Gets the compressed page size of a block.
@return	compressed page size, or 0 */
890 891 892 893
UNIV_INLINE
ulint
buf_page_get_zip_size(
/*==================*/
894
	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
895
	__attribute__((pure));
896
/*********************************************************************//**
897 898
Gets the compressed page size of a block.
@return	compressed page size, or 0 */
899 900 901 902
UNIV_INLINE
ulint
buf_block_get_zip_size(
/*===================*/
903
	const buf_block_t*	block)	/*!< in: pointer to the control block */
904
	__attribute__((pure));
905
/*********************************************************************//**
906 907
Gets the compressed page descriptor corresponding to an uncompressed page
if applicable. */
908 909
#define buf_block_get_page_zip(block) \
	(UNIV_LIKELY_NULL((block)->page.zip.data) ? &(block)->page.zip : NULL)
910
#ifndef UNIV_HOTBACKUP
911
/*******************************************************************//**
912 913
Gets the block to whose frame the pointer is pointing to.
@return	pointer to block, never NULL */
914 915
UNIV_INTERN
buf_block_t*
osku's avatar
osku committed
916 917
buf_block_align(
/*============*/
918
	const byte*	ptr);	/*!< in: pointer to a frame */
919
/********************************************************************//**
inaam's avatar
inaam committed
920
Find out if a pointer belongs to a buf_block_t. It can be a pointer to
921 922
the buf_block_t itself or a member of it
@return	TRUE if ptr belongs to a buf_block_t struct */
inaam's avatar
inaam committed
923 924 925 926
UNIV_INTERN
ibool
buf_pointer_is_block_field(
/*=======================*/
927
	const void*		ptr);	/*!< in: pointer not
inaam's avatar
inaam committed
928
					dereferenced */
929 930 931 932 933 934 935 936 937 938
/** Find out if a pointer corresponds to a buf_block_t::mutex.
@param m	in: mutex candidate
@return		TRUE if m is a buf_block_t::mutex */
#define buf_pool_is_block_mutex(m)			\
	buf_pointer_is_block_field((const void*)(m))
/** Find out if a pointer corresponds to a buf_block_t::lock.
@param l	in: rw-lock candidate
@return		TRUE if l is a buf_block_t::lock */
#define buf_pool_is_block_lock(l)			\
	buf_pointer_is_block_field((const void*)(l))
inaam's avatar
inaam committed
939

940
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
941
/*********************************************************************//**
942
Gets the compressed page descriptor corresponding to an uncompressed page
943 944
if applicable.
@return	compressed page descriptor, or NULL */
945
UNIV_INLINE
946
const page_zip_des_t*
947 948
buf_frame_get_page_zip(
/*===================*/
949
	const byte*	ptr);	/*!< in: pointer to the page */
950
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
951
/********************************************************************//**
osku's avatar
osku committed
952 953 954 955 956 957 958
Function which inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
(3) if the space is deleted or being deleted,
then this function does nothing.
Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
on the buffer frame. The io-handler must take care that the flag is cleared
959 960
and the lock released later.
@return	pointer to the block or NULL */
961
UNIV_INTERN
962
buf_page_t*
osku's avatar
osku committed
963 964
buf_page_init_for_read(
/*===================*/
965 966 967 968 969 970
	ulint*		err,	/*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
	ulint		mode,	/*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
	ulint		space,	/*!< in: space id */
	ulint		zip_size,/*!< in: compressed page size, or 0 */
	ibool		unzip,	/*!< in: TRUE=request uncompressed page */
	ib_int64_t	tablespace_version,/*!< in: prevents reading from a wrong
osku's avatar
osku committed
971 972
				version of the tablespace in case we have done
				DISCARD + IMPORT */
973
	ulint		offset);/*!< in: page number */
974
/********************************************************************//**
osku's avatar
osku committed
975 976
Completes an asynchronous read or write request of a file page to or from
the buffer pool. */
977
UNIV_INTERN
osku's avatar
osku committed
978 979 980
void
buf_page_io_complete(
/*=================*/
981
	buf_page_t*	bpage);	/*!< in: pointer to the block in question */
982
/********************************************************************//**
osku's avatar
osku committed
983
Calculates a folded value of a file page address to use in the page hash
984 985
table.
@return	the folded value */
osku's avatar
osku committed
986 987 988 989
UNIV_INLINE
ulint
buf_page_address_fold(
/*==================*/
990 991
	ulint	space,	/*!< in: space id */
	ulint	offset)	/*!< in: offset of the page within space */
992
	__attribute__((const));
993
/******************************************************************//**
994 995
Returns the control block of a file page, NULL if not found.
@return	block, NULL if not found */
osku's avatar
osku committed
996
UNIV_INLINE
997
buf_page_t*
osku's avatar
osku committed
998 999
buf_page_hash_get(
/*==============*/
1000 1001
	ulint	space,	/*!< in: space id */
	ulint	offset);/*!< in: offset of the page within space */
1002
/******************************************************************//**
1003
Returns the control block of a file page, NULL if not found
1004 1005
or an uncompressed page frame does not exist.
@return	block, NULL if not found */
1006 1007 1008 1009
UNIV_INLINE
buf_block_t*
buf_block_hash_get(
/*===============*/
1010 1011
	ulint	space,	/*!< in: space id */
	ulint	offset);/*!< in: offset of the page within space */
1012
/*********************************************************************//**
1013 1014
Gets the current length of the free list of buffer blocks.
@return	length of the free list */
1015
UNIV_INTERN
osku's avatar
osku committed
1016 1017 1018
ulint
buf_get_free_list_len(void);
/*=======================*/
1019
#endif /* !UNIV_HOTBACKUP */
osku's avatar
osku committed
1020

1021

1022
/** The common buffer control block structure
1023 1024 1025
for compressed and uncompressed frames */

struct buf_page_struct{
1026 1027 1028 1029 1030 1031
	/** @name General fields
	None of these bit-fields must be modified without holding
	buf_page_get_mutex() [buf_block_struct::mutex or
	buf_pool_zip_mutex], since they can be stored in the same
	machine word.  Some of these fields are additionally protected
	by buf_pool_mutex. */
1032
	/* @{ */
1033

1034
	unsigned	space:32;	/*!< tablespace id; also protected
1035
					by buf_pool_mutex. */
1036
	unsigned	offset:32;	/*!< page number; also protected
1037
					by buf_pool_mutex. */
1038

1039
	unsigned	state:3;	/*!< state of the control block; also
1040
					protected by buf_pool_mutex.
1041 1042 1043
					State transitions from
					BUF_BLOCK_READY_FOR_USE to
					BUF_BLOCK_MEMORY need not be
1044 1045
					protected by buf_page_get_mutex().
					@see enum buf_page_state */
1046
#ifndef UNIV_HOTBACKUP
1047
	unsigned	flush_type:2;	/*!< if this block is currently being
1048
					flushed to disk, this tells the
1049 1050 1051 1052 1053
					flush_type.
					@see enum buf_flush */
	unsigned	io_fix:2;	/*!< type of pending I/O operation;
					also protected by buf_pool_mutex
					@see enum buf_io_fix */
1054
	unsigned	buf_fix_count:25;/*!< count of how manyfold this block
1055
					is currently bufferfixed */
1056
	/* @} */
1057
#endif /* !UNIV_HOTBACKUP */
1058
	page_zip_des_t	zip;		/*!< compressed page; zip.data
1059
					(but not the data it points to) is
1060
					also protected by buf_pool_mutex */
1061
#ifndef UNIV_HOTBACKUP
1062
	buf_page_t*	hash;		/*!< node used in chaining to
1063 1064
					buf_pool->page_hash or
					buf_pool->zip_hash */
1065
#ifdef UNIV_DEBUG
1066 1067
	ibool		in_page_hash;	/*!< TRUE if in buf_pool->page_hash */
	ibool		in_zip_hash;	/*!< TRUE if in buf_pool->zip_hash */
1068
#endif /* UNIV_DEBUG */
1069

1070 1071
	/** @name Page flushing fields
	All these are protected by buf_pool_mutex. */
1072
	/* @{ */
1073

1074
	UT_LIST_NODE_T(buf_page_t) list;
1075
					/*!< based on state, this is a
1076 1077 1078
					list node, protected only by
					buf_pool_mutex, in one of the
					following lists in buf_pool:
1079

1080 1081 1082 1083
					- BUF_BLOCK_NOT_USED:	free
					- BUF_BLOCK_FILE_PAGE:	flush_list
					- BUF_BLOCK_ZIP_DIRTY:	flush_list
					- BUF_BLOCK_ZIP_PAGE:	zip_clean
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
					- BUF_BLOCK_ZIP_FREE:	zip_free[]

					The contents of the list node
					is undefined if !in_flush_list
					&& state == BUF_BLOCK_FILE_PAGE,
					or if state is one of
					BUF_BLOCK_MEMORY,
					BUF_BLOCK_REMOVE_HASH or
					BUF_BLOCK_READY_IN_USE. */

1094
#ifdef UNIV_DEBUG
1095
	ibool		in_flush_list;	/*!< TRUE if in buf_pool->flush_list;
1096
					when buf_pool_mutex is free, the
1097 1098 1099
					following should hold: in_flush_list
					== (state == BUF_BLOCK_FILE_PAGE
					    || state == BUF_BLOCK_ZIP_DIRTY) */
1100
	ibool		in_free_list;	/*!< TRUE if in buf_pool->free; when
1101
					buf_pool_mutex is free, the following
1102 1103
					should hold: in_free_list
					== (state == BUF_BLOCK_NOT_USED) */
1104
#endif /* UNIV_DEBUG */
1105
	ib_uint64_t	newest_modification;
1106 1107 1108 1109
					/*!< log sequence number of
					the youngest modification to
					this block, zero if not
					modified */
1110
	ib_uint64_t	oldest_modification;
1111 1112 1113 1114 1115 1116 1117 1118
					/*!< log sequence number of
					the START of the log entry
					written of the oldest
					modification to this block
					which has not yet been flushed
					on disk; zero if all
					modifications are on disk */
	/* @} */
1119 1120 1121
	/** @name LRU replacement algorithm fields
	These fields are protected by buf_pool_mutex only (not
	buf_pool_zip_mutex or buf_block_struct::mutex). */
1122
	/* @{ */
1123 1124

	UT_LIST_NODE_T(buf_page_t) LRU;
1125
					/*!< node of the LRU list */
1126
#ifdef UNIV_DEBUG
1127 1128 1129
	ibool		in_LRU_list;	/*!< TRUE if the page is in
					the LRU list; used in
					debugging */
1130
#endif /* UNIV_DEBUG */
1131
	unsigned	old:1;		/*!< TRUE if the block is in the old
1132
					blocks in buf_pool->LRU_old */
1133
	unsigned	freed_page_clock:31;/*!< the value of
1134 1135 1136 1137 1138 1139 1140
					buf_pool->freed_page_clock
					when this block was the last
					time put to the head of the
					LRU list; a thread is allowed
					to read this for heuristic
					purposes without holding any
					mutex or latch */
1141 1142 1143
	unsigned	access_time:32;	/*!< time of first access, or
					0 if the block was never accessed
					in the buffer pool */
1144
	/* @} */
1145
# ifdef UNIV_DEBUG_FILE_ACCESSES
1146
	ibool		file_page_was_freed;
1147
					/*!< this is set to TRUE when fsp
1148
					frees a page in buffer pool */
1149
# endif /* UNIV_DEBUG_FILE_ACCESSES */
1150
#endif /* !UNIV_HOTBACKUP */
1151 1152
};

1153
/** The buffer control block structure */
osku's avatar
osku committed
1154 1155 1156

struct buf_block_struct{

1157
	/** @name General fields */
1158
	/* @{ */
osku's avatar
osku committed
1159

1160
	buf_page_t	page;		/*!< page information; this must
1161 1162 1163
					be the first field, so that
					buf_pool->page_hash can point
					to buf_page_t or buf_block_t */
1164
	byte*		frame;		/*!< pointer to buffer frame which
1165 1166 1167 1168
					is of size UNIV_PAGE_SIZE, and
					aligned to an address divisible by
					UNIV_PAGE_SIZE */
#ifndef UNIV_HOTBACKUP
1169
	UT_LIST_NODE_T(buf_block_t) unzip_LRU;
1170
					/*!< node of the decompressed LRU list;
1171 1172 1173 1174
					a block is in the unzip_LRU list
					if page.state == BUF_BLOCK_FILE_PAGE
					and page.zip.data != NULL */
#ifdef UNIV_DEBUG
1175
	ibool		in_unzip_LRU_list;/*!< TRUE if the page is in the
1176 1177 1178
					decompressed LRU list;
					used in debugging */
#endif /* UNIV_DEBUG */
1179
	mutex_t		mutex;		/*!< mutex protecting this block:
1180 1181 1182 1183 1184
					state (also protected by the buffer
					pool mutex), io_fix, buf_fix_count,
					and accessed; we introduce this new
					mutex in InnoDB-5.1 to relieve
					contention on the buffer pool mutex */
1185
	rw_lock_t	lock;		/*!< read-write lock of the buffer
osku's avatar
osku committed
1186
					frame */
1187
	unsigned	lock_hash_val:32;/*!< hashed value of the page address
1188
					in the record lock hash table */
1189
	unsigned	check_index_page_at_flush:1;
1190
					/*!< TRUE if we know that this is
osku's avatar
osku committed
1191 1192 1193 1194 1195 1196
					an index page, and want the database
					to check its consistency before flush;
					note that there may be pages in the
					buffer pool which are index pages,
					but this flag is not set because
					we do not keep track of all pages */
1197
	/* @} */
1198
	/** @name Optimistic search field */
1199
	/* @{ */
osku's avatar
osku committed
1200

1201
	ib_uint64_t	modify_clock;	/*!< this clock is incremented every
osku's avatar
osku committed
1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
					time a pointer to a record on the
					page may become obsolete; this is
					used in the optimistic cursor
					positioning: if the modify clock has
					not changed, we know that the pointer
					is still valid; this field may be
					changed if the thread (1) owns the
					pool mutex and the page is not
					bufferfixed, or (2) the thread has an
					x-latch on the block */
1212
	/* @} */
1213 1214
	/** @name Hash search fields (unprotected)
	NOTE that these fields are NOT protected by any semaphore! */
1215
	/* @{ */
osku's avatar
osku committed
1216

1217
	ulint		n_hash_helps;	/*!< counter which controls building
osku's avatar
osku committed
1218
					of a new hash index for the page */
1219
	ulint		n_fields;	/*!< recommended prefix length for hash
osku's avatar
osku committed
1220
					search: number of full fields */
1221
	ulint		n_bytes;	/*!< recommended prefix: number of bytes
osku's avatar
osku committed
1222
					in an incomplete field */
1223
	ibool		left_side;	/*!< TRUE or FALSE, depending on
osku's avatar
osku committed
1224 1225 1226
					whether the leftmost record of several
					records with the same prefix should be
					indexed in the hash index */
1227
	/* @} */
1228

1229
	/** @name Hash search fields
1230
	These 6 fields may only be modified when we have
1231
	an x-latch on btr_search_latch AND
1232 1233
	- we are holding an s-latch or x-latch on buf_block_struct::lock or
	- we know that buf_block_struct::buf_fix_count == 0.
1234 1235 1236

	An exception to this is when we init or create a page
	in the buffer pool in buf0buf.c. */
osku's avatar
osku committed
1237

1238 1239
	/* @{ */

1240
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
1241
	ulint		n_pointers;	/*!< used in debugging: the number of
osku's avatar
osku committed
1242 1243
					pointers in the adaptive hash index
					pointing to this frame */
1244
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1245 1246 1247 1248 1249 1250 1251 1252
	unsigned	is_hashed:1;	/*!< TRUE if hash index has
					already been built on this
					page; note that it does not
					guarantee that the index is
					complete, though: there may
					have been hash collisions,
					record deletions, etc. */
	unsigned	curr_n_fields:10;/*!< prefix length for hash indexing:
osku's avatar
osku committed
1253
					number of full fields */
1254 1255 1256 1257
	unsigned	curr_n_bytes:15;/*!< number of bytes in hash
					indexing */
	unsigned	curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
	dict_index_t*	index;		/*!< Index for which the adaptive
1258
					hash index has been created. */
1259
	/* @} */
1260 1261
# ifdef UNIV_SYNC_DEBUG
	/** @name Debug fields */
1262 1263
	/* @{ */
	rw_lock_t	debug_latch;	/*!< in the debug version, each thread
osku's avatar
osku committed
1264 1265 1266
					which bufferfixes the block acquires
					an s-latch here; so we can use the
					debug utilities in sync0rw */
1267
	/* @} */
1268
# endif
1269
#endif /* !UNIV_HOTBACKUP */
osku's avatar
osku committed
1270 1271
};

1272 1273 1274
/** Check if a buf_block_t object is in a valid state
@param block	buffer block
@return		TRUE if valid */
1275
#define buf_block_state_valid(block)				\
1276 1277
(buf_block_get_state(block) >= BUF_BLOCK_NOT_USED		\
 && (buf_block_get_state(block) <= BUF_BLOCK_REMOVE_HASH))
osku's avatar
osku committed
1278

1279
#ifndef UNIV_HOTBACKUP
1280
/**********************************************************************//**
1281
Compute the hash fold value for blocks in buf_pool->zip_hash. */
1282
/* @{ */
1283 1284 1285
#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
#define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
1286
/* @} */
1287

inaam's avatar
inaam committed
1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
/** @brief The buffer pool statistics structure. */
struct buf_pool_stat_struct{
	ulint	n_page_gets;	/*!< number of page gets performed;
				also successful searches through
				the adaptive hash index are
				counted as page gets; this field
				is NOT protected by the buffer
				pool mutex */
	ulint	n_pages_read;	/*!< number read operations */
	ulint	n_pages_written;/*!< number write operations */
	ulint	n_pages_created;/*!< number of pages created
				in the pool with no read */
	ulint	n_ra_pages_read;/*!< number of pages read in
				as part of read ahead */
	ulint	n_ra_pages_evicted;/*!< number of read ahead
				pages that are evicted without
				being accessed */
	ulint	n_pages_made_young; /*!< number of pages made young, in
				calls to buf_LRU_make_block_young() */
	ulint	n_pages_not_made_young; /*!< number of pages not made
				young because the first access
				was not long enough ago, in
				buf_page_peek_if_too_old() */
};

1313 1314 1315 1316
/** @brief The buffer pool structure.

NOTE! The definition appears here only for other modules of this
directory (buf) to see it. Do not use from outside! */
osku's avatar
osku committed
1317 1318 1319

struct buf_pool_struct{

1320
	/** @name General fields */
1321
	/* @{ */
osku's avatar
osku committed
1322

1323 1324 1325 1326
	ulint		n_chunks;	/*!< number of buffer pool chunks */
	buf_chunk_t*	chunks;		/*!< buffer pool chunks */
	ulint		curr_size;	/*!< current pool size in pages */
	hash_table_t*	page_hash;	/*!< hash table of buf_page_t or
1327 1328 1329
					buf_block_t file pages,
					buf_page_in_file() == TRUE,
					indexed by (space_id, offset) */
1330
	hash_table_t*	zip_hash;	/*!< hash table of buf_block_t blocks
1331 1332 1333
					whose frames are allocated to the
					zip buddy system,
					indexed by block->frame */
1334 1335
	ulint		n_pend_reads;	/*!< number of pending read operations */
	ulint		n_pend_unzip;	/*!< number of pending decompressions */
osku's avatar
osku committed
1336

1337 1338
	time_t		last_printout_time;
					/*!< when buf_print_io was last time
osku's avatar
osku committed
1339
					called */
inaam's avatar
inaam committed
1340 1341 1342
	buf_pool_stat_t	stat;		/*!< current statistics */
	buf_pool_stat_t	old_stat;	/*!< old statistics */

1343
	/* @} */
inaam's avatar
inaam committed
1344

1345
	/** @name Page flushing algorithm fields */
inaam's avatar
inaam committed
1346

1347
	/* @{ */
osku's avatar
osku committed
1348

1349
	UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
1350
					/*!< base node of the modified block
osku's avatar
osku committed
1351
					list */
1352
	ibool		init_flush[BUF_FLUSH_N_TYPES];
1353
					/*!< this is TRUE when a flush of the
osku's avatar
osku committed
1354
					given type is being initialized */
1355
	ulint		n_flush[BUF_FLUSH_N_TYPES];
1356
					/*!< this is the number of pending
osku's avatar
osku committed
1357
					writes in the given flush type */
1358
	os_event_t	no_flush[BUF_FLUSH_N_TYPES];
1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371
					/*!< this is in the set state
					when there is no flush batch
					of the given type running */
	ulint		freed_page_clock;/*!< a sequence number used
					to count the number of buffer
					blocks removed from the end of
					the LRU list; NOTE that this
					counter may wrap around at 4
					billion! A thread is allowed
					to read this for heuristic
					purposes without holding any
					mutex or latch */
	ulint		LRU_flush_ended;/*!< when an LRU flush ends for a page,
osku's avatar
osku committed
1372 1373 1374 1375
					this is incremented by one; this is
					set to zero when a buffer block is
					allocated */

1376
	/* @} */
1377
	/** @name LRU replacement algorithm fields */
1378
	/* @{ */
osku's avatar
osku committed
1379

1380
	UT_LIST_BASE_NODE_T(buf_page_t) free;
1381 1382
					/*!< base node of the free
					block list */
1383
	UT_LIST_BASE_NODE_T(buf_page_t) LRU;
1384
					/*!< base node of the LRU list */
1385 1386 1387 1388 1389
	buf_page_t*	LRU_old;	/*!< pointer to the about
					buf_LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
					oldest blocks in the LRU list;
					NULL if LRU length less than
					BUF_LRU_OLD_MIN_LEN;
1390 1391
					NOTE: when LRU_old != NULL, its length
					should always equal LRU_old_len */
1392
	ulint		LRU_old_len;	/*!< length of the LRU list from
osku's avatar
osku committed
1393 1394 1395
					the block to which LRU_old points
					onward, including that block;
					see buf0lru.c for the restrictions
1396
					on this value; 0 if LRU_old == NULL;
1397 1398
					NOTE: LRU_old_len must be adjusted
					whenever LRU_old shrinks or grows! */
1399

1400
	UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU;
1401 1402
					/*!< base node of the
					unzip_LRU list */
1403

1404
	/* @} */
1405 1406 1407 1408
	/** @name Buddy allocator fields
	The buddy allocator is used for allocating compressed page
	frames and buf_page_t descriptors of blocks that exist
	in the buffer pool only in compressed form. */
1409
	/* @{ */
1410
	UT_LIST_BASE_NODE_T(buf_page_t)	zip_clean;
1411
					/*!< unmodified compressed pages */
1412
	UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
1413
					/*!< buddy free lists */
1414 1415
#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
1416 1417 1418 1419
#endif
#if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
# error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
#endif
1420
	/* @} */
osku's avatar
osku committed
1421 1422
};

1423
/** mutex protecting the buffer pool struct and control blocks, except the
1424 1425
read-write lock in them */
extern mutex_t	buf_pool_mutex;
1426
/** mutex protecting the control blocks of compressed-only pages
1427 1428 1429
(of type buf_page_t, not buf_block_t) */
extern mutex_t	buf_pool_zip_mutex;

1430 1431
/** @name Accessors for buf_pool_mutex.
Use these instead of accessing buf_pool_mutex directly. */
1432
/* @{ */
1433

1434
/** Test if buf_pool_mutex is owned. */
1435
#define buf_pool_mutex_own() mutex_own(&buf_pool_mutex)
1436
/** Acquire the buffer pool mutex. */
1437 1438 1439 1440
#define buf_pool_mutex_enter() do {		\
	ut_ad(!mutex_own(&buf_pool_zip_mutex));	\
	mutex_enter(&buf_pool_mutex);		\
} while (0)
1441 1442 1443 1444 1445

#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/** Flag to forbid the release of the buffer pool mutex.
Protected by buf_pool_mutex. */
extern ulint	buf_pool_mutex_exit_forbidden;
1446
/** Forbid the release of the buffer pool mutex. */
1447 1448 1449 1450
# define buf_pool_mutex_exit_forbid() do {	\
	ut_ad(buf_pool_mutex_own());		\
	buf_pool_mutex_exit_forbidden++;	\
} while (0)
1451
/** Allow the release of the buffer pool mutex. */
1452 1453 1454 1455 1456
# define buf_pool_mutex_exit_allow() do {	\
	ut_ad(buf_pool_mutex_own());		\
	ut_a(buf_pool_mutex_exit_forbidden);	\
	buf_pool_mutex_exit_forbidden--;	\
} while (0)
1457
/** Release the buffer pool mutex. */
1458 1459 1460 1461 1462
# define buf_pool_mutex_exit() do {		\
	ut_a(!buf_pool_mutex_exit_forbidden);	\
	mutex_exit(&buf_pool_mutex);		\
} while (0)
#else
1463
/** Forbid the release of the buffer pool mutex. */
1464
# define buf_pool_mutex_exit_forbid() ((void) 0)
1465
/** Allow the release of the buffer pool mutex. */
1466
# define buf_pool_mutex_exit_allow() ((void) 0)
1467
/** Release the buffer pool mutex. */
1468 1469
# define buf_pool_mutex_exit() mutex_exit(&buf_pool_mutex)
#endif
1470
#endif /* !UNIV_HOTBACKUP */
1471
/* @} */
1472

1473
/**********************************************************************
osku's avatar
osku committed
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
Let us list the consistency conditions for different control block states.

NOT_USED:	is in free list, not in LRU list, not in flush list, nor
		page hash table
READY_FOR_USE:	is not in free list, LRU list, or flush list, nor page
		hash table
MEMORY:		is not in free list, LRU list, or flush list, nor page
		hash table
FILE_PAGE:	space and offset are defined, is in page hash table
		if io_fix == BUF_IO_WRITE,
1484 1485
			pool: no_flush[flush_type] is in reset state,
			pool: n_flush[flush_type] > 0
1486

osku's avatar
osku committed
1487 1488 1489 1490 1491 1492 1493 1494
		(1) if buf_fix_count == 0, then
			is in LRU list, not in free list
			is in flush list,
				if and only if oldest_modification > 0
			is x-locked,
				if and only if io_fix == BUF_IO_READ
			is s-locked,
				if and only if io_fix == BUF_IO_WRITE
1495

osku's avatar
osku committed
1496 1497 1498 1499
		(2) if buf_fix_count > 0, then
			is not in LRU list, not in free list
			is in flush list,
				if and only if oldest_modification > 0
1500
			if io_fix == BUF_IO_READ,
osku's avatar
osku committed
1501 1502 1503
				is x-locked
			if io_fix == BUF_IO_WRITE,
				is s-locked
1504

osku's avatar
osku committed
1505 1506 1507 1508 1509 1510
State transitions:

NOT_USED => READY_FOR_USE
READY_FOR_USE => MEMORY
READY_FOR_USE => FILE_PAGE
MEMORY => NOT_USED
1511
FILE_PAGE => NOT_USED	NOTE: This transition is allowed if and only if
osku's avatar
osku committed
1512 1513 1514
				(1) buf_fix_count == 0,
				(2) oldest_modification == 0, and
				(3) io_fix == 0.
1515
*/
osku's avatar
osku committed
1516 1517 1518 1519 1520 1521

#ifndef UNIV_NONINL
#include "buf0buf.ic"
#endif

#endif