1 /*****************************************************************************
2 
3 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file include/buf0buf.h
29 The database buffer pool high-level routines
30 
31 Created 11/5/1995 Heikki Tuuri
32 *******************************************************/
33 
34 #ifndef buf0buf_h
35 #define buf0buf_h
36 
37 #include "univ.i"
38 #include "fil0fil.h"
39 #include "mtr0types.h"
40 #include "buf0types.h"
41 #include "hash0hash.h"
42 #include "ut0byte.h"
43 #include "page0types.h"
44 #ifndef UNIV_HOTBACKUP
45 #include "ut0rbt.h"
46 #include "os0proc.h"
47 #include "log0log.h"
48 
49 /** @name Modes for buf_page_get_gen */
50 /* @{ */
51 #define BUF_GET			10	/*!< get always */
52 #define	BUF_GET_IF_IN_POOL	11	/*!< get if in pool */
53 #define BUF_PEEK_IF_IN_POOL	12	/*!< get if in pool, do not make
54 					the block young in the LRU list */
55 #define BUF_GET_NO_LATCH	14	/*!< get and bufferfix, but
56 					set no latch; we have
57 					separated this case, because
58 					it is error-prone programming
59 					not to set a latch, and it
60 					should be used with care */
61 #define BUF_GET_IF_IN_POOL_OR_WATCH	15
62 					/*!< Get the page only if it's in the
63 					buffer pool, if not then set a watch
64 					on the page. */
65 #define BUF_GET_POSSIBLY_FREED		16
66 					/*!< Like BUF_GET, but do not mind
67 					if the file page has been freed. */
68 /* @} */
69 /** @name Modes for buf_page_get_known_nowait */
70 /* @{ */
71 #define BUF_MAKE_YOUNG	51		/*!< Move the block to the
72 					start of the LRU list if there
73 					is a danger that the block
74 					would drift out of the buffer
75 					pool*/
76 #define BUF_KEEP_OLD	52		/*!< Preserve the current LRU
77 					position of the block. */
78 /* @} */
79 
80 #define MAX_BUFFER_POOLS_BITS	6	/*!< Number of bits to representing
81 					a buffer pool ID */
82 
83 #define MAX_BUFFER_POOLS 	(1 << MAX_BUFFER_POOLS_BITS)
84 					/*!< The maximum number of buffer
85 					pools that can be defined */
86 
87 #define BUF_POOL_WATCH_SIZE		(srv_n_purge_threads + 1)
88 					/*!< Maximum number of concurrent
89 					buffer pool watches */
90 #define MAX_PAGE_HASH_LOCKS	1024	/*!< The maximum number of
91 					page_hash locks */
92 
93 extern	buf_pool_t*	buf_pool_ptr;	/*!< The buffer pools
94 					of the database */
95 #ifdef UNIV_DEBUG
96 extern ibool		buf_debug_prints;/*!< If this is set TRUE, the program
97 					prints info whenever read or flush
98 					occurs */
99 #endif /* UNIV_DEBUG */
100 extern ulint srv_buf_pool_instances;
101 extern ulint srv_buf_pool_curr_size;
102 #else /* !UNIV_HOTBACKUP */
103 extern buf_block_t*	back_block1;	/*!< first block, for --apply-log */
104 extern buf_block_t*	back_block2;	/*!< second block, for page reorganize */
105 #endif /* !UNIV_HOTBACKUP */
106 
107 /** Magic value to use instead of checksums when they are disabled */
108 #define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL
109 
110 /** @brief States of a control block
111 @see buf_page_t
112 
113 The enumeration values must be 0..7. */
114 enum buf_page_state {
115 	BUF_BLOCK_POOL_WATCH,		/*!< a sentinel for the buffer pool
116 					watch, element of buf_pool->watch[] */
117 	BUF_BLOCK_ZIP_PAGE,		/*!< contains a clean
118 					compressed page */
119 	BUF_BLOCK_ZIP_DIRTY,		/*!< contains a compressed
120 					page that is in the
121 					buf_pool->flush_list */
122 
123 	BUF_BLOCK_NOT_USED,		/*!< is in the free list;
124 					must be after the BUF_BLOCK_ZIP_
125 					constants for compressed-only pages
126 					@see buf_block_state_valid() */
127 	BUF_BLOCK_READY_FOR_USE,	/*!< when buf_LRU_get_free_block
128 					returns a block, it is in this state */
129 	BUF_BLOCK_FILE_PAGE,		/*!< contains a buffered file page */
130 	BUF_BLOCK_MEMORY,		/*!< contains some main memory
131 					object */
132 	BUF_BLOCK_REMOVE_HASH		/*!< hash index should be removed
133 					before putting to the free list */
134 };
135 
136 
137 /** This structure defines information we will fetch from each buffer pool. It
138 will be used to print table IO stats */
139 struct buf_pool_info_t{
140 	/* General buffer pool info */
141 	ulint	pool_unique_id;		/*!< Buffer Pool ID */
142 	ulint	pool_size;		/*!< Buffer Pool size in pages */
143 	ulint	lru_len;		/*!< Length of buf_pool->LRU */
144 	ulint	old_lru_len;		/*!< buf_pool->LRU_old_len */
145 	ulint	free_list_len;		/*!< Length of buf_pool->free list */
146 	ulint	flush_list_len;		/*!< Length of buf_pool->flush_list */
147 	ulint	n_pend_unzip;		/*!< buf_pool->n_pend_unzip, pages
148 					pending decompress */
149 	ulint	n_pend_reads;		/*!< buf_pool->n_pend_reads, pages
150 					pending read */
151 	ulint	n_pending_flush_lru;	/*!< Pages pending flush in LRU */
152 	ulint	n_pending_flush_single_page;/*!< Pages pending to be
153 					flushed as part of single page
154 					flushes issued by various user
155 					threads */
156 	ulint	n_pending_flush_list;	/*!< Pages pending flush in FLUSH
157 					LIST */
158 	ulint	n_pages_made_young;	/*!< number of pages made young */
159 	ulint	n_pages_not_made_young;	/*!< number of pages not made young */
160 	ulint	n_pages_read;		/*!< buf_pool->n_pages_read */
161 	ulint	n_pages_created;	/*!< buf_pool->n_pages_created */
162 	ulint	n_pages_written;	/*!< buf_pool->n_pages_written */
163 	ulint	n_page_gets;		/*!< buf_pool->n_page_gets */
164 	ulint	n_ra_pages_read_rnd;	/*!< buf_pool->n_ra_pages_read_rnd,
165 					number of pages readahead */
166 	ulint	n_ra_pages_read;	/*!< buf_pool->n_ra_pages_read, number
167 					of pages readahead */
168 	ulint	n_ra_pages_evicted;	/*!< buf_pool->n_ra_pages_evicted,
169 					number of readahead pages evicted
170 					without access */
171 	ulint	n_page_get_delta;	/*!< num of buffer pool page gets since
172 					last printout */
173 
174 	/* Buffer pool access stats */
175 	double	page_made_young_rate;	/*!< page made young rate in pages
176 					per second */
177 	double	page_not_made_young_rate;/*!< page not made young rate
178 					in pages per second */
179 	double	pages_read_rate;	/*!< num of pages read per second */
180 	double	pages_created_rate;	/*!< num of pages create per second */
181 	double	pages_written_rate;	/*!< num of  pages written per second */
182 	ulint	page_read_delta;	/*!< num of pages read since last
183 					printout */
184 	ulint	young_making_delta;	/*!< num of pages made young since
185 					last printout */
186 	ulint	not_young_making_delta;	/*!< num of pages not make young since
187 					last printout */
188 
189 	/* Statistics about read ahead algorithm.  */
190 	double	pages_readahead_rnd_rate;/*!< random readahead rate in pages per
191 					second */
192 	double	pages_readahead_rate;	/*!< readahead rate in pages per
193 					second */
194 	double	pages_evicted_rate;	/*!< rate of readahead page evicted
195 					without access, in pages per second */
196 
197 	/* Stats about LRU eviction */
198 	ulint	unzip_lru_len;		/*!< length of buf_pool->unzip_LRU
199 					list */
200 	/* Counters for LRU policy */
201 	ulint	io_sum;			/*!< buf_LRU_stat_sum.io */
202 	ulint	io_cur;			/*!< buf_LRU_stat_cur.io, num of IO
203 					for current interval */
204 	ulint	unzip_sum;		/*!< buf_LRU_stat_sum.unzip */
205 	ulint	unzip_cur;		/*!< buf_LRU_stat_cur.unzip, num
206 					pages decompressed in current
207 					interval */
208 };
209 
210 /** The occupied bytes of lists in all buffer pools */
211 struct buf_pools_list_size_t {
212 	ulint	LRU_bytes;		/*!< LRU size in bytes */
213 	ulint	unzip_LRU_bytes;	/*!< unzip_LRU size in bytes */
214 	ulint	flush_list_bytes;	/*!< flush_list size in bytes */
215 };
216 
217 #ifndef UNIV_HOTBACKUP
218 /********************************************************************//**
219 Acquire mutex on all buffer pool instances */
220 UNIV_INLINE
221 void
222 buf_pool_mutex_enter_all(void);
223 /*===========================*/
224 
225 /********************************************************************//**
226 Release mutex on all buffer pool instances */
227 UNIV_INLINE
228 void
229 buf_pool_mutex_exit_all(void);
230 /*==========================*/
231 
232 /********************************************************************//**
233 Creates the buffer pool.
234 @return	DB_SUCCESS if success, DB_ERROR if not enough memory or error */
235 UNIV_INTERN
236 dberr_t
237 buf_pool_init(
238 /*=========*/
239 	ulint	size,		/*!< in: Size of the total pool in bytes */
240 	ulint	n_instances);	/*!< in: Number of instances */
241 /********************************************************************//**
242 Frees the buffer pool at shutdown.  This must not be invoked before
243 freeing all mutexes. */
244 UNIV_INTERN
245 void
246 buf_pool_free(
247 /*==========*/
248 	ulint	n_instances);	/*!< in: numbere of instances to free */
249 
250 /********************************************************************//**
251 Clears the adaptive hash index on all pages in the buffer pool. */
252 UNIV_INTERN
253 void
254 buf_pool_clear_hash_index(void);
255 /*===========================*/
256 
257 /********************************************************************//**
258 Relocate a buffer control block.  Relocates the block on the LRU list
259 and in buf_pool->page_hash.  Does not relocate bpage->list.
260 The caller must take care of relocating bpage->list. */
261 UNIV_INTERN
262 void
263 buf_relocate(
264 /*=========*/
265 	buf_page_t*	bpage,	/*!< in/out: control block being relocated;
266 				buf_page_get_state(bpage) must be
267 				BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */
268 	buf_page_t*	dpage)	/*!< in/out: destination control block */
269 	MY_ATTRIBUTE((nonnull));
270 /*********************************************************************//**
271 Gets the current size of buffer buf_pool in bytes.
272 @return	size in bytes */
273 UNIV_INLINE
274 ulint
275 buf_pool_get_curr_size(void);
276 /*========================*/
277 /*********************************************************************//**
278 Gets the current size of buffer buf_pool in frames.
279 @return	size in pages */
280 UNIV_INLINE
281 ulint
282 buf_pool_get_n_pages(void);
283 /*=======================*/
284 /********************************************************************//**
285 Gets the smallest oldest_modification lsn for any page in the pool. Returns
286 zero if all modified pages have been flushed to disk.
287 @return	oldest modification in pool, zero if none */
288 UNIV_INTERN
289 lsn_t
290 buf_pool_get_oldest_modification(void);
291 /*==================================*/
292 
293 /********************************************************************//**
294 Allocates a buf_page_t descriptor. This function must succeed. In case
295 of failure we assert in this function. */
296 UNIV_INLINE
297 buf_page_t*
298 buf_page_alloc_descriptor(void)
299 /*===========================*/
300 	MY_ATTRIBUTE((malloc));
301 /********************************************************************//**
302 Free a buf_page_t descriptor. */
303 UNIV_INLINE
304 void
305 buf_page_free_descriptor(
306 /*=====================*/
307 	buf_page_t*	bpage)	/*!< in: bpage descriptor to free. */
308 	MY_ATTRIBUTE((nonnull));
309 
310 /********************************************************************//**
311 Allocates a buffer block.
312 @return	own: the allocated block, in state BUF_BLOCK_MEMORY */
313 UNIV_INTERN
314 buf_block_t*
315 buf_block_alloc(
316 /*============*/
317 	buf_pool_t*	buf_pool);	/*!< in: buffer pool instance,
318 					or NULL for round-robin selection
319 					of the buffer pool */
320 /********************************************************************//**
321 Frees a buffer block which does not contain a file page. */
322 UNIV_INLINE
323 void
324 buf_block_free(
325 /*===========*/
326 	buf_block_t*	block);	/*!< in, own: block to be freed */
327 #endif /* !UNIV_HOTBACKUP */
328 /*********************************************************************//**
329 Copies contents of a buffer frame to a given buffer.
330 @return	buf */
331 UNIV_INLINE
332 byte*
333 buf_frame_copy(
334 /*===========*/
335 	byte*			buf,	/*!< in: buffer to copy to */
336 	const buf_frame_t*	frame);	/*!< in: buffer frame */
337 #ifndef UNIV_HOTBACKUP
338 /**************************************************************//**
339 NOTE! The following macros should be used instead of buf_page_get_gen,
340 to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed
341 in LA! */
342 #define buf_page_get(SP, ZS, OF, LA, MTR)	 buf_page_get_gen(\
343 				SP, ZS, OF, LA, NULL,\
344 				BUF_GET, __FILE__, __LINE__, MTR)
345 /**************************************************************//**
346 Use these macros to bufferfix a page with no latching. Remember not to
347 read the contents of the page unless you know it is safe. Do not modify
348 the contents of the page! We have separated this case, because it is
349 error-prone programming not to set a latch, and it should be used
350 with care. */
351 #define buf_page_get_with_no_latch(SP, ZS, OF, MTR)	   buf_page_get_gen(\
352 				SP, ZS, OF, RW_NO_LATCH, NULL,\
353 				BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR)
354 /********************************************************************//**
355 This is the general function used to get optimistic access to a database
356 page.
357 @return	TRUE if success */
358 UNIV_INTERN
359 ibool
360 buf_page_optimistic_get(
361 /*====================*/
362 	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
363 	buf_block_t*	block,	/*!< in: guessed block */
364 	ib_uint64_t	modify_clock,/*!< in: modify clock value */
365 	const char*	file,	/*!< in: file name */
366 	ulint		line,	/*!< in: line where called */
367 	mtr_t*		mtr);	/*!< in: mini-transaction */
368 /********************************************************************//**
369 This is used to get access to a known database page, when no waiting can be
370 done.
371 @return	TRUE if success */
372 UNIV_INTERN
373 ibool
374 buf_page_get_known_nowait(
375 /*======================*/
376 	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH */
377 	buf_block_t*	block,	/*!< in: the known page */
378 	ulint		mode,	/*!< in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */
379 	const char*	file,	/*!< in: file name */
380 	ulint		line,	/*!< in: line where called */
381 	mtr_t*		mtr);	/*!< in: mini-transaction */
382 
383 /*******************************************************************//**
384 Given a tablespace id and page number tries to get that page. If the
385 page is not in the buffer pool it is not loaded and NULL is returned.
386 Suitable for using when holding the lock_sys_t::mutex. */
387 UNIV_INTERN
388 const buf_block_t*
389 buf_page_try_get_func(
390 /*==================*/
391 	ulint		space_id,/*!< in: tablespace id */
392 	ulint		page_no,/*!< in: page number */
393 	const char*	file,	/*!< in: file name */
394 	ulint		line,	/*!< in: line where called */
395 	mtr_t*		mtr);	/*!< in: mini-transaction */
396 
397 /** Tries to get a page. If the page is not in the buffer pool it is
398 not loaded.  Suitable for using when holding the lock_sys_t::mutex.
399 @param space_id	in: tablespace id
400 @param page_no	in: page number
401 @param mtr	in: mini-transaction
402 @return		the page if in buffer pool, NULL if not */
403 #define buf_page_try_get(space_id, page_no, mtr)	\
404 	buf_page_try_get_func(space_id, page_no, __FILE__, __LINE__, mtr);
405 
406 /********************************************************************//**
407 Get read access to a compressed page (usually of type
408 FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2).
409 The page must be released with buf_page_release_zip().
410 NOTE: the page is not protected by any latch.  Mutual exclusion has to
411 be implemented at a higher level.  In other words, all possible
412 accesses to a given page through this function must be protected by
413 the same set of mutexes or latches.
414 @return	pointer to the block, or NULL if not compressed */
415 UNIV_INTERN
416 buf_page_t*
417 buf_page_get_zip(
418 /*=============*/
419 	ulint		space,	/*!< in: space id */
420 	ulint		zip_size,/*!< in: compressed page size */
421 	ulint		offset);/*!< in: page number */
422 /********************************************************************//**
423 This is the general function used to get access to a database page.
424 @return	pointer to the block or NULL */
425 UNIV_INTERN
426 buf_block_t*
427 buf_page_get_gen(
428 /*=============*/
429 	ulint		space,	/*!< in: space id */
430 	ulint		zip_size,/*!< in: compressed page size in bytes
431 				or 0 for uncompressed pages */
432 	ulint		offset,	/*!< in: page number */
433 	ulint		rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
434 	buf_block_t*	guess,	/*!< in: guessed block or NULL */
435 	ulint		mode,	/*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
436 				BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH or
437 				BUF_GET_IF_IN_POOL_OR_WATCH */
438 	const char*	file,	/*!< in: file name */
439 	ulint		line,	/*!< in: line where called */
440 	mtr_t*		mtr);	/*!< in: mini-transaction */
441 /********************************************************************//**
442 Initializes a page to the buffer buf_pool. The page is usually not read
443 from a file even if it cannot be found in the buffer buf_pool. This is one
444 of the functions which perform to a block a state transition NOT_USED =>
445 FILE_PAGE (the other is buf_page_get_gen).
446 @return	pointer to the block, page bufferfixed */
447 UNIV_INTERN
448 buf_block_t*
449 buf_page_create(
450 /*============*/
451 	ulint	space,	/*!< in: space id */
452 	ulint	offset,	/*!< in: offset of the page within space in units of
453 			a page */
454 	ulint	zip_size,/*!< in: compressed page size, or 0 */
455 	mtr_t*	mtr);	/*!< in: mini-transaction handle */
456 #else /* !UNIV_HOTBACKUP */
457 /********************************************************************//**
458 Inits a page to the buffer buf_pool, for use in mysqlbackup --restore. */
459 UNIV_INTERN
460 void
461 buf_page_init_for_backup_restore(
462 /*=============================*/
463 	ulint		space,	/*!< in: space id */
464 	ulint		offset,	/*!< in: offset of the page within space
465 				in units of a page */
466 	ulint		zip_size,/*!< in: compressed page size in bytes
467 				or 0 for uncompressed pages */
468 	buf_block_t*	block);	/*!< in: block to init */
469 #endif /* !UNIV_HOTBACKUP */
470 
471 #ifndef UNIV_HOTBACKUP
472 /********************************************************************//**
473 Releases a compressed-only page acquired with buf_page_get_zip(). */
474 UNIV_INLINE
475 void
476 buf_page_release_zip(
477 /*=================*/
478 	buf_page_t*	bpage);		/*!< in: buffer block */
479 /********************************************************************//**
480 Decrements the bufferfix count of a buffer control block and releases
481 a latch, if specified. */
482 UNIV_INLINE
483 void
484 buf_page_release(
485 /*=============*/
486 	buf_block_t*	block,		/*!< in: buffer block */
487 	ulint		rw_latch);	/*!< in: RW_S_LATCH, RW_X_LATCH,
488 					RW_NO_LATCH */
489 /********************************************************************//**
490 Moves a page to the start of the buffer pool LRU list. This high-level
491 function can be used to prevent an important page from slipping out of
492 the buffer pool. */
493 UNIV_INTERN
494 void
495 buf_page_make_young(
496 /*================*/
497 	buf_page_t*	bpage);	/*!< in: buffer block of a file page */
498 /********************************************************************//**
499 Returns TRUE if the page can be found in the buffer pool hash table.
500 
501 NOTE that it is possible that the page is not yet read from disk,
502 though.
503 
504 @return	TRUE if found in the page hash table */
505 UNIV_INLINE
506 ibool
507 buf_page_peek(
508 /*==========*/
509 	ulint	space,	/*!< in: space id */
510 	ulint	offset);/*!< in: page number */
511 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
512 /********************************************************************//**
513 Sets file_page_was_freed TRUE if the page is found in the buffer pool.
514 This function should be called when we free a file page and want the
515 debug version to check that it is not accessed any more unless
516 reallocated.
517 @return	control block if found in page hash table, otherwise NULL */
518 UNIV_INTERN
519 buf_page_t*
520 buf_page_set_file_page_was_freed(
521 /*=============================*/
522 	ulint	space,	/*!< in: space id */
523 	ulint	offset);/*!< in: page number */
524 /********************************************************************//**
525 Sets file_page_was_freed FALSE if the page is found in the buffer pool.
526 This function should be called when we free a file page and want the
527 debug version to check that it is not accessed any more unless
528 reallocated.
529 @return	control block if found in page hash table, otherwise NULL */
530 UNIV_INTERN
531 buf_page_t*
532 buf_page_reset_file_page_was_freed(
533 /*===============================*/
534 	ulint	space,	/*!< in: space id */
535 	ulint	offset);	/*!< in: page number */
536 #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
537 /********************************************************************//**
538 Reads the freed_page_clock of a buffer block.
539 @return	freed_page_clock */
540 UNIV_INLINE
541 ulint
542 buf_page_get_freed_page_clock(
543 /*==========================*/
544 	const buf_page_t*	bpage)	/*!< in: block */
545 	MY_ATTRIBUTE((pure));
546 /********************************************************************//**
547 Reads the freed_page_clock of a buffer block.
548 @return	freed_page_clock */
549 UNIV_INLINE
550 ulint
551 buf_block_get_freed_page_clock(
552 /*===========================*/
553 	const buf_block_t*	block)	/*!< in: block */
554 	MY_ATTRIBUTE((pure));
555 
556 /********************************************************************//**
557 Tells if a block is still close enough to the MRU end of the LRU list
558 meaning that it is not in danger of getting evicted and also implying
559 that it has been accessed recently.
560 Note that this is for heuristics only and does not reserve buffer pool
561 mutex.
562 @return	TRUE if block is close to MRU end of LRU */
563 UNIV_INLINE
564 ibool
565 buf_page_peek_if_young(
566 /*===================*/
567 	const buf_page_t*	bpage);	/*!< in: block */
568 /********************************************************************//**
569 Recommends a move of a block to the start of the LRU list if there is danger
570 of dropping from the buffer pool. NOTE: does not reserve the buffer pool
571 mutex.
572 @return	TRUE if should be made younger */
573 UNIV_INLINE
574 ibool
575 buf_page_peek_if_too_old(
576 /*=====================*/
577 	const buf_page_t*	bpage);	/*!< in: block to make younger */
578 /********************************************************************//**
579 Gets the youngest modification log sequence number for a frame.
580 Returns zero if not file page or no modification occurred yet.
581 @return	newest modification to page */
582 UNIV_INLINE
583 lsn_t
584 buf_page_get_newest_modification(
585 /*=============================*/
586 	const buf_page_t*	bpage);	/*!< in: block containing the
587 					page frame */
588 /********************************************************************//**
589 Increments the modify clock of a frame by 1. The caller must (1) own the
590 buf_pool->mutex and block bufferfix count has to be zero, (2) or own an x-lock
591 on the block. */
592 UNIV_INLINE
593 void
594 buf_block_modify_clock_inc(
595 /*=======================*/
596 	buf_block_t*	block);	/*!< in: block */
597 /********************************************************************//**
598 Returns the value of the modify clock. The caller must have an s-lock
599 or x-lock on the block.
600 @return	value */
601 UNIV_INLINE
602 ib_uint64_t
603 buf_block_get_modify_clock(
604 /*=======================*/
605 	buf_block_t*	block);	/*!< in: block */
606 /*******************************************************************//**
607 Increments the bufferfix count. */
608 UNIV_INLINE
609 void
610 buf_block_buf_fix_inc_func(
611 /*=======================*/
612 # ifdef UNIV_SYNC_DEBUG
613 	const char*	file,	/*!< in: file name */
614 	ulint		line,	/*!< in: line */
615 # endif /* UNIV_SYNC_DEBUG */
616 	buf_block_t*	block)	/*!< in/out: block to bufferfix */
617 	MY_ATTRIBUTE((nonnull));
618 
619 /*******************************************************************//**
620 Increments the bufferfix count. */
621 UNIV_INLINE
622 void
623 buf_block_fix(
624 /*===========*/
625 	buf_block_t*	block);	/*!< in/out: block to bufferfix */
626 
627 /*******************************************************************//**
628 Increments the bufferfix count. */
629 UNIV_INLINE
630 void
631 buf_block_unfix(
632 /*===========*/
633 	buf_block_t*	block);	/*!< in/out: block to bufferfix */
634 
635 # ifdef UNIV_SYNC_DEBUG
636 /** Increments the bufferfix count.
637 @param b	in/out: block to bufferfix
638 @param f	in: file name where requested
639 @param l	in: line number where requested */
640 # define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
641 # else /* UNIV_SYNC_DEBUG */
642 /** Increments the bufferfix count.
643 @param b	in/out: block to bufferfix
644 @param f	in: file name where requested
645 @param l	in: line number where requested */
646 # define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
647 # endif /* UNIV_SYNC_DEBUG */
648 #else /* !UNIV_HOTBACKUP */
649 # define buf_block_modify_clock_inc(block) ((void) 0)
650 #endif /* !UNIV_HOTBACKUP */
651 /********************************************************************//**
652 Checks if a page is corrupt.
653 @return	TRUE if corrupted */
654 UNIV_INTERN
655 ibool
656 buf_page_is_corrupted(
657 /*==================*/
658 	bool		check_lsn,	/*!< in: true if we need to check the
659 					and complain about the LSN */
660 	const byte*	read_buf,	/*!< in: a database page */
661 	ulint		zip_size)	/*!< in: size of compressed page;
662 					0 for uncompressed pages */
663 	MY_ATTRIBUTE((nonnull, warn_unused_result));
664 /********************************************************************//**
665 Checks if a page is all zeroes.
666 @return	TRUE if the page is all zeroes */
667 bool
668 buf_page_is_zeroes(
669 /*===============*/
670 	const byte*	read_buf,	/*!< in: a database page */
671 	const ulint	zip_size);	/*!< in: size of compressed page;
672 					0 for uncompressed pages */
673 #ifndef UNIV_HOTBACKUP
674 /**********************************************************************//**
675 Gets the space id, page offset, and byte offset within page of a
676 pointer pointing to a buffer frame containing a file page. */
677 UNIV_INLINE
678 void
679 buf_ptr_get_fsp_addr(
680 /*=================*/
681 	const void*	ptr,	/*!< in: pointer to a buffer frame */
682 	ulint*		space,	/*!< out: space id */
683 	fil_addr_t*	addr);	/*!< out: page offset and byte offset */
684 /**********************************************************************//**
685 Gets the hash value of a block. This can be used in searches in the
686 lock hash table.
687 @return	lock hash value */
688 UNIV_INLINE
689 ulint
690 buf_block_get_lock_hash_val(
691 /*========================*/
692 	const buf_block_t*	block)	/*!< in: block */
693 	MY_ATTRIBUTE((pure));
694 #ifdef UNIV_DEBUG
695 /*********************************************************************//**
696 Finds a block in the buffer pool that points to a
697 given compressed page.
698 @return	buffer block pointing to the compressed page, or NULL */
699 UNIV_INTERN
700 buf_block_t*
701 buf_pool_contains_zip(
702 /*==================*/
703 	buf_pool_t*	buf_pool,	/*!< in: buffer pool instance */
704 	const void*	data);		/*!< in: pointer to compressed page */
705 #endif /* UNIV_DEBUG */
706 
707 /***********************************************************************
708 FIXME_FTS: Gets the frame the pointer is pointing to. */
709 UNIV_INLINE
710 buf_frame_t*
711 buf_frame_align(
712 /*============*/
713                         /* out: pointer to frame */
714         byte*   ptr);   /* in: pointer to a frame */
715 
716 
717 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
718 /*********************************************************************//**
719 Validates the buffer pool data structure.
720 @return	TRUE */
721 UNIV_INTERN
722 ibool
723 buf_validate(void);
724 /*==============*/
725 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
726 #if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
727 /*********************************************************************//**
728 Prints info of the buffer pool data structure. */
729 UNIV_INTERN
730 void
731 buf_print(void);
732 /*============*/
733 #endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
734 #endif /* !UNIV_HOTBACKUP */
735 enum buf_page_print_flags {
736 	/** Do not crash at the end of buf_page_print(). */
737 	BUF_PAGE_PRINT_NO_CRASH	= 1,
738 	/** Do not print the full page dump. */
739 	BUF_PAGE_PRINT_NO_FULL = 2
740 };
741 
742 /********************************************************************//**
743 Prints a page to stderr. */
744 UNIV_INTERN
745 void
746 buf_page_print(
747 /*===========*/
748 	const byte*	read_buf,	/*!< in: a database page */
749 	ulint		zip_size,	/*!< in: compressed page size, or
750 					0 for uncompressed pages */
751 	ulint		flags)		/*!< in: 0 or
752 					BUF_PAGE_PRINT_NO_CRASH or
753 					BUF_PAGE_PRINT_NO_FULL */
754 	UNIV_COLD MY_ATTRIBUTE((nonnull));
755 /********************************************************************//**
756 Decompress a block.
757 @return	TRUE if successful */
758 UNIV_INTERN
759 ibool
760 buf_zip_decompress(
761 /*===============*/
762 	buf_block_t*	block,	/*!< in/out: block */
763 	ibool		check);	/*!< in: TRUE=verify the page checksum */
764 #ifndef UNIV_HOTBACKUP
765 #ifdef UNIV_DEBUG
766 /*********************************************************************//**
767 Returns the number of latched pages in the buffer pool.
768 @return	number of latched pages */
769 UNIV_INTERN
770 ulint
771 buf_get_latched_pages_number(void);
772 /*==============================*/
773 #endif /* UNIV_DEBUG */
774 /*********************************************************************//**
775 Returns the number of pending buf pool read ios.
776 @return	number of pending read I/O operations */
777 UNIV_INTERN
778 ulint
779 buf_get_n_pending_read_ios(void);
780 /*============================*/
781 /*********************************************************************//**
782 Prints info of the buffer i/o. */
783 UNIV_INTERN
784 void
785 buf_print_io(
786 /*=========*/
787 	FILE*	file);	/*!< in: file where to print */
788 /*******************************************************************//**
789 Collect buffer pool stats information for a buffer pool. Also
790 record aggregated stats if there are more than one buffer pool
791 in the server */
792 UNIV_INTERN
793 void
794 buf_stats_get_pool_info(
795 /*====================*/
796 	buf_pool_t*		buf_pool,	/*!< in: buffer pool */
797 	ulint			pool_id,	/*!< in: buffer pool ID */
798 	buf_pool_info_t*	all_pool_info);	/*!< in/out: buffer pool info
799 						to fill */
800 /*********************************************************************//**
801 Returns the ratio in percents of modified pages in the buffer pool /
802 database pages in the buffer pool.
803 @return	modified page percentage ratio */
804 UNIV_INTERN
805 ulint
806 buf_get_modified_ratio_pct(void);
807 /*============================*/
808 /**********************************************************************//**
809 Refreshes the statistics used to print per-second averages. */
810 UNIV_INTERN
811 void
812 buf_refresh_io_stats(
813 /*=================*/
814 	buf_pool_t*	buf_pool);	/*!< buffer pool instance */
815 /**********************************************************************//**
816 Refreshes the statistics used to print per-second averages. */
817 UNIV_INTERN
818 void
819 buf_refresh_io_stats_all(void);
820 /*=================*/
821 /*********************************************************************//**
822 Asserts that all file pages in the buffer are in a replaceable state.
823 @return	TRUE */
824 UNIV_INTERN
825 ibool
826 buf_all_freed(void);
827 /*===============*/
828 /*********************************************************************//**
829 Checks that there currently are no pending i/o-operations for the buffer
830 pool.
831 @return	number of pending i/o operations */
832 UNIV_INTERN
833 ulint
834 buf_pool_check_no_pending_io(void);
835 /*==============================*/
836 /*********************************************************************//**
837 Invalidates the file pages in the buffer pool when an archive recovery is
838 completed. All the file pages buffered must be in a replaceable state when
839 this function is called: not latched and not modified. */
840 UNIV_INTERN
841 void
842 buf_pool_invalidate(void);
843 /*=====================*/
844 #endif /* !UNIV_HOTBACKUP */
845 
846 /*========================================================================
847 --------------------------- LOWER LEVEL ROUTINES -------------------------
848 =========================================================================*/
849 
850 #ifdef UNIV_SYNC_DEBUG
851 /*********************************************************************//**
852 Adds latch level info for the rw-lock protecting the buffer frame. This
853 should be called in the debug version after a successful latching of a
854 page if we know the latching order level of the acquired latch. */
855 UNIV_INLINE
856 void
857 buf_block_dbg_add_level(
858 /*====================*/
859 	buf_block_t*	block,	/*!< in: buffer page
860 				where we have acquired latch */
861 	ulint		level);	/*!< in: latching order level */
862 #else /* UNIV_SYNC_DEBUG */
863 # define buf_block_dbg_add_level(block, level) /* nothing */
864 #endif /* UNIV_SYNC_DEBUG */
865 /*********************************************************************//**
866 Gets the state of a block.
867 @return	state */
868 UNIV_INLINE
869 enum buf_page_state
870 buf_page_get_state(
871 /*===============*/
872 	const buf_page_t*	bpage);	/*!< in: pointer to the control block */
873 /*********************************************************************//**
874 Gets the state of a block.
875 @return	state */
876 UNIV_INLINE
877 enum buf_page_state
878 buf_block_get_state(
879 /*================*/
880 	const buf_block_t*	block)	/*!< in: pointer to the control block */
881 	MY_ATTRIBUTE((pure));
882 /*********************************************************************//**
883 Sets the state of a block. */
884 UNIV_INLINE
885 void
886 buf_page_set_state(
887 /*===============*/
888 	buf_page_t*		bpage,	/*!< in/out: pointer to control block */
889 	enum buf_page_state	state);	/*!< in: state */
890 /*********************************************************************//**
891 Sets the state of a block. */
892 UNIV_INLINE
893 void
894 buf_block_set_state(
895 /*================*/
896 	buf_block_t*		block,	/*!< in/out: pointer to control block */
897 	enum buf_page_state	state);	/*!< in: state */
898 /*********************************************************************//**
899 Determines if a block is mapped to a tablespace.
900 @return	TRUE if mapped */
901 UNIV_INLINE
902 ibool
903 buf_page_in_file(
904 /*=============*/
905 	const buf_page_t*	bpage)	/*!< in: pointer to control block */
906 	MY_ATTRIBUTE((pure));
907 #ifndef UNIV_HOTBACKUP
908 /*********************************************************************//**
909 Determines if a block should be on unzip_LRU list.
910 @return	TRUE if block belongs to unzip_LRU */
911 UNIV_INLINE
912 ibool
913 buf_page_belongs_to_unzip_LRU(
914 /*==========================*/
915 	const buf_page_t*	bpage)	/*!< in: pointer to control block */
916 	MY_ATTRIBUTE((pure));
917 
918 /*********************************************************************//**
919 Gets the mutex of a block.
920 @return	pointer to mutex protecting bpage */
921 UNIV_INLINE
922 ib_mutex_t*
923 buf_page_get_mutex(
924 /*===============*/
925 	const buf_page_t*	bpage)	/*!< in: pointer to control block */
926 	MY_ATTRIBUTE((pure));
927 
928 /*********************************************************************//**
929 Get the flush type of a page.
930 @return	flush type */
931 UNIV_INLINE
932 buf_flush_t
933 buf_page_get_flush_type(
934 /*====================*/
935 	const buf_page_t*	bpage)	/*!< in: buffer page */
936 	MY_ATTRIBUTE((pure));
937 /*********************************************************************//**
938 Set the flush type of a page. */
939 UNIV_INLINE
940 void
941 buf_page_set_flush_type(
942 /*====================*/
943 	buf_page_t*	bpage,		/*!< in: buffer page */
944 	buf_flush_t	flush_type);	/*!< in: flush type */
945 /*********************************************************************//**
946 Map a block to a file page. */
947 UNIV_INLINE
948 void
949 buf_block_set_file_page(
950 /*====================*/
951 	buf_block_t*		block,	/*!< in/out: pointer to control block */
952 	ulint			space,	/*!< in: tablespace id */
953 	ulint			page_no);/*!< in: page number */
954 /*********************************************************************//**
955 Gets the io_fix state of a block.
956 @return	io_fix state */
957 UNIV_INLINE
958 enum buf_io_fix
959 buf_page_get_io_fix(
960 /*================*/
961 	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
962 	MY_ATTRIBUTE((pure));
963 /*********************************************************************//**
964 Gets the io_fix state of a block.
965 @return	io_fix state */
966 UNIV_INLINE
967 enum buf_io_fix
968 buf_block_get_io_fix(
969 /*================*/
970 	const buf_block_t*	block)	/*!< in: pointer to the control block */
971 	MY_ATTRIBUTE((pure));
972 /*********************************************************************//**
973 Sets the io_fix state of a block. */
974 UNIV_INLINE
975 void
976 buf_page_set_io_fix(
977 /*================*/
978 	buf_page_t*	bpage,	/*!< in/out: control block */
979 	enum buf_io_fix	io_fix);/*!< in: io_fix state */
980 /*********************************************************************//**
981 Sets the io_fix state of a block. */
982 UNIV_INLINE
983 void
984 buf_block_set_io_fix(
985 /*=================*/
986 	buf_block_t*	block,	/*!< in/out: control block */
987 	enum buf_io_fix	io_fix);/*!< in: io_fix state */
988 /*********************************************************************//**
989 Makes a block sticky. A sticky block implies that even after we release
990 the buf_pool->mutex and the block->mutex:
991 * it cannot be removed from the flush_list
992 * the block descriptor cannot be relocated
993 * it cannot be removed from the LRU list
994 Note that:
995 * the block can still change its position in the LRU list
996 * the next and previous pointers can change. */
997 UNIV_INLINE
998 void
999 buf_page_set_sticky(
1000 /*================*/
1001 	buf_page_t*	bpage);	/*!< in/out: control block */
1002 /*********************************************************************//**
1003 Removes stickiness of a block. */
1004 UNIV_INLINE
1005 void
1006 buf_page_unset_sticky(
1007 /*==================*/
1008 	buf_page_t*	bpage);	/*!< in/out: control block */
1009 /********************************************************************//**
1010 Determine if a buffer block can be relocated in memory.  The block
1011 can be dirty, but it must not be I/O-fixed or bufferfixed. */
1012 UNIV_INLINE
1013 ibool
1014 buf_page_can_relocate(
1015 /*==================*/
1016 	const buf_page_t*	bpage)	/*!< control block being relocated */
1017 	MY_ATTRIBUTE((pure));
1018 
1019 /*********************************************************************//**
1020 Determine if a block has been flagged old.
1021 @return	TRUE if old */
1022 UNIV_INLINE
1023 ibool
1024 buf_page_is_old(
1025 /*============*/
1026 	const buf_page_t*	bpage)	/*!< in: control block */
1027 	MY_ATTRIBUTE((pure));
1028 /*********************************************************************//**
1029 Flag a block old. */
1030 UNIV_INLINE
1031 void
1032 buf_page_set_old(
1033 /*=============*/
1034 	buf_page_t*	bpage,	/*!< in/out: control block */
1035 	ibool		old);	/*!< in: old */
1036 /*********************************************************************//**
1037 Determine the time of first access of a block in the buffer pool.
1038 @return	ut_time_ms() at the time of first access, 0 if not accessed */
1039 UNIV_INLINE
1040 unsigned
1041 buf_page_is_accessed(
1042 /*=================*/
1043 	const buf_page_t*	bpage)	/*!< in: control block */
1044 	MY_ATTRIBUTE((nonnull, pure));
1045 /*********************************************************************//**
1046 Flag a block accessed. */
1047 UNIV_INLINE
1048 void
1049 buf_page_set_accessed(
1050 /*==================*/
1051 	buf_page_t*	bpage)		/*!< in/out: control block */
1052 	MY_ATTRIBUTE((nonnull));
1053 /*********************************************************************//**
1054 Gets the buf_block_t handle of a buffered file block if an uncompressed
1055 page frame exists, or NULL. Note: even though bpage is not declared a
1056 const we don't update its value. It is safe to make this pure.
1057 @return	control block, or NULL */
1058 UNIV_INLINE
1059 buf_block_t*
1060 buf_page_get_block(
1061 /*===============*/
1062 	buf_page_t*	bpage)	/*!< in: control block, or NULL */
1063 	MY_ATTRIBUTE((pure));
1064 #endif /* !UNIV_HOTBACKUP */
1065 #ifdef UNIV_DEBUG
1066 /*********************************************************************//**
1067 Gets a pointer to the memory frame of a block.
1068 @return	pointer to the frame */
1069 UNIV_INLINE
1070 buf_frame_t*
1071 buf_block_get_frame(
1072 /*================*/
1073 	const buf_block_t*	block)	/*!< in: pointer to the control block */
1074 	MY_ATTRIBUTE((pure));
1075 #else /* UNIV_DEBUG */
1076 # define buf_block_get_frame(block) (block)->frame
1077 #endif /* UNIV_DEBUG */
1078 /*********************************************************************//**
1079 Gets the space id of a block.
1080 @return	space id */
1081 UNIV_INLINE
1082 ulint
1083 buf_page_get_space(
1084 /*===============*/
1085 	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
1086 	MY_ATTRIBUTE((pure));
1087 /*********************************************************************//**
1088 Gets the space id of a block.
1089 @return	space id */
1090 UNIV_INLINE
1091 ulint
1092 buf_block_get_space(
1093 /*================*/
1094 	const buf_block_t*	block)	/*!< in: pointer to the control block */
1095 	MY_ATTRIBUTE((pure));
1096 /*********************************************************************//**
1097 Gets the page number of a block.
1098 @return	page number */
1099 UNIV_INLINE
1100 ulint
1101 buf_page_get_page_no(
1102 /*=================*/
1103 	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
1104 	MY_ATTRIBUTE((pure));
1105 /*********************************************************************//**
1106 Gets the page number of a block.
1107 @return	page number */
1108 UNIV_INLINE
1109 ulint
1110 buf_block_get_page_no(
1111 /*==================*/
1112 	const buf_block_t*	block)	/*!< in: pointer to the control block */
1113 	MY_ATTRIBUTE((pure));
1114 /*********************************************************************//**
1115 Gets the compressed page size of a block.
1116 @return	compressed page size, or 0 */
1117 UNIV_INLINE
1118 ulint
1119 buf_page_get_zip_size(
1120 /*==================*/
1121 	const buf_page_t*	bpage)	/*!< in: pointer to the control block */
1122 	MY_ATTRIBUTE((pure));
1123 /*********************************************************************//**
1124 Gets the compressed page size of a block.
1125 @return	compressed page size, or 0 */
1126 UNIV_INLINE
1127 ulint
1128 buf_block_get_zip_size(
1129 /*===================*/
1130 	const buf_block_t*	block)	/*!< in: pointer to the control block */
1131 	MY_ATTRIBUTE((pure));
1132 /*********************************************************************//**
1133 Gets the compressed page descriptor corresponding to an uncompressed page
1134 if applicable. */
1135 #define buf_block_get_page_zip(block) \
1136 	((block)->page.zip.data ? &(block)->page.zip : NULL)
1137 #ifndef UNIV_HOTBACKUP
1138 /*******************************************************************//**
1139 Gets the block to whose frame the pointer is pointing to.
1140 @return	pointer to block, never NULL */
1141 UNIV_INTERN
1142 buf_block_t*
1143 buf_block_align(
1144 /*============*/
1145 	const byte*	ptr);	/*!< in: pointer to a frame */
1146 /********************************************************************//**
1147 Find out if a pointer belongs to a buf_block_t. It can be a pointer to
1148 the buf_block_t itself or a member of it
1149 @return	TRUE if ptr belongs to a buf_block_t struct */
1150 UNIV_INTERN
1151 ibool
1152 buf_pointer_is_block_field(
1153 /*=======================*/
1154 	const void*		ptr);	/*!< in: pointer not
1155 					dereferenced */
1156 /** Find out if a pointer corresponds to a buf_block_t::mutex.
1157 @param m	in: mutex candidate
1158 @return		TRUE if m is a buf_block_t::mutex */
1159 #define buf_pool_is_block_mutex(m)			\
1160 	buf_pointer_is_block_field((const void*)(m))
1161 /** Find out if a pointer corresponds to a buf_block_t::lock.
1162 @param l	in: rw-lock candidate
1163 @return		TRUE if l is a buf_block_t::lock */
1164 #define buf_pool_is_block_lock(l)			\
1165 	buf_pointer_is_block_field((const void*)(l))
1166 
1167 #if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
1168 /*********************************************************************//**
1169 Gets the compressed page descriptor corresponding to an uncompressed page
1170 if applicable.
1171 @return	compressed page descriptor, or NULL */
1172 UNIV_INLINE
1173 const page_zip_des_t*
1174 buf_frame_get_page_zip(
1175 /*===================*/
1176 	const byte*	ptr);	/*!< in: pointer to the page */
1177 #endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
1178 /********************************************************************//**
1179 Function which inits a page for read to the buffer buf_pool. If the page is
1180 (1) already in buf_pool, or
1181 (2) if we specify to read only ibuf pages and the page is not an ibuf page, or
1182 (3) if the space is deleted or being deleted,
1183 then this function does nothing.
1184 Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
1185 on the buffer frame. The io-handler must take care that the flag is cleared
1186 and the lock released later.
1187 @return	pointer to the block or NULL */
1188 UNIV_INTERN
1189 buf_page_t*
1190 buf_page_init_for_read(
1191 /*===================*/
1192 	dberr_t*	err,	/*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
1193 	ulint		mode,	/*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
1194 	ulint		space,	/*!< in: space id */
1195 	ulint		zip_size,/*!< in: compressed page size, or 0 */
1196 	ibool		unzip,	/*!< in: TRUE=request uncompressed page */
1197 	ib_int64_t	tablespace_version,/*!< in: prevents reading from a wrong
1198 				version of the tablespace in case we have done
1199 				DISCARD + IMPORT */
1200 	ulint		offset);/*!< in: page number */
1201 /********************************************************************//**
1202 Completes an asynchronous read or write request of a file page to or from
1203 the buffer pool.
1204 @return true if successful */
1205 UNIV_INTERN
1206 bool
1207 buf_page_io_complete(
1208 /*=================*/
1209 	buf_page_t*	bpage);	/*!< in: pointer to the block in question */
1210 /********************************************************************//**
1211 Calculates a folded value of a file page address to use in the page hash
1212 table.
1213 @return	the folded value */
1214 UNIV_INLINE
1215 ulint
1216 buf_page_address_fold(
1217 /*==================*/
1218 	ulint	space,	/*!< in: space id */
1219 	ulint	offset)	/*!< in: offset of the page within space */
1220 	MY_ATTRIBUTE((const));
1221 /********************************************************************//**
1222 Calculates the index of a buffer pool to the buf_pool[] array.
1223 @return	the position of the buffer pool in buf_pool[] */
1224 UNIV_INLINE
1225 ulint
1226 buf_pool_index(
1227 /*===========*/
1228 	const buf_pool_t*	buf_pool)	/*!< in: buffer pool */
1229 	MY_ATTRIBUTE((nonnull, const));
1230 /******************************************************************//**
1231 Returns the buffer pool instance given a page instance
1232 @return buf_pool */
1233 UNIV_INLINE
1234 buf_pool_t*
1235 buf_pool_from_bpage(
1236 /*================*/
1237 	const buf_page_t*	bpage); /*!< in: buffer pool page */
1238 /******************************************************************//**
1239 Returns the buffer pool instance given a block instance
1240 @return buf_pool */
1241 UNIV_INLINE
1242 buf_pool_t*
1243 buf_pool_from_block(
1244 /*================*/
1245 	const buf_block_t*	block); /*!< in: block */
1246 /******************************************************************//**
1247 Returns the buffer pool instance given space and offset of page
1248 @return buffer pool */
1249 UNIV_INLINE
1250 buf_pool_t*
1251 buf_pool_get(
1252 /*==========*/
1253 	ulint	space,	/*!< in: space id */
1254 	ulint	offset);/*!< in: offset of the page within space */
1255 /******************************************************************//**
1256 Returns the buffer pool instance given its array index
1257 @return buffer pool */
1258 UNIV_INLINE
1259 buf_pool_t*
1260 buf_pool_from_array(
1261 /*================*/
1262 	ulint	index);		/*!< in: array index to get
1263 				buffer pool instance from */
1264 /******************************************************************//**
1265 Returns the control block of a file page, NULL if not found.
1266 @return	block, NULL if not found */
1267 UNIV_INLINE
1268 buf_page_t*
1269 buf_page_hash_get_low(
1270 /*==================*/
1271 	buf_pool_t*	buf_pool,/*!< buffer pool instance */
1272 	ulint		space,	/*!< in: space id */
1273 	ulint		offset,	/*!< in: offset of the page within space */
1274 	ulint		fold);	/*!< in: buf_page_address_fold(space, offset) */
1275 /******************************************************************//**
1276 Returns the control block of a file page, NULL if not found.
1277 If the block is found and lock is not NULL then the appropriate
1278 page_hash lock is acquired in the specified lock mode. Otherwise,
1279 mode value is ignored. It is up to the caller to release the
1280 lock. If the block is found and the lock is NULL then the page_hash
1281 lock is released by this function.
1282 @return	block, NULL if not found, or watch sentinel (if watch is true) */
1283 UNIV_INLINE
1284 buf_page_t*
1285 buf_page_hash_get_locked(
1286 /*=====================*/
1287 					/*!< out: pointer to the bpage,
1288 					or NULL; if NULL, hash_lock
1289 					is also NULL. */
1290 	buf_pool_t*	buf_pool,	/*!< buffer pool instance */
1291 	ulint		space,		/*!< in: space id */
1292 	ulint		offset,		/*!< in: page number */
1293 	rw_lock_t**	lock,		/*!< in/out: lock of the page
1294 					hash acquired if bpage is
1295 					found. NULL otherwise. If NULL
1296 					is passed then the hash_lock
1297 					is released by this function */
1298 	ulint		lock_mode,	/*!< in: RW_LOCK_EX or
1299 					RW_LOCK_SHARED. Ignored if
1300 					lock == NULL */
1301 	bool		watch = false);	/*!< in: if true, return watch
1302 					sentinel also. */
1303 /******************************************************************//**
1304 Returns the control block of a file page, NULL if not found.
1305 If the block is found and lock is not NULL then the appropriate
1306 page_hash lock is acquired in the specified lock mode. Otherwise,
1307 mode value is ignored. It is up to the caller to release the
1308 lock. If the block is found and the lock is NULL then the page_hash
1309 lock is released by this function.
1310 @return	block, NULL if not found */
1311 UNIV_INLINE
1312 buf_block_t*
1313 buf_block_hash_get_locked(
1314 /*=====================*/
1315 					/*!< out: pointer to the bpage,
1316 					or NULL; if NULL, hash_lock
1317 					is also NULL. */
1318 	buf_pool_t*	buf_pool,	/*!< buffer pool instance */
1319 	ulint		space,		/*!< in: space id */
1320 	ulint		offset,		/*!< in: page number */
1321 	rw_lock_t**	lock,		/*!< in/out: lock of the page
1322 					hash acquired if bpage is
1323 					found. NULL otherwise. If NULL
1324 					is passed then the hash_lock
1325 					is released by this function */
1326 	ulint		lock_mode);	/*!< in: RW_LOCK_EX or
1327 					RW_LOCK_SHARED. Ignored if
1328 					lock == NULL */
1329 /* There are four different ways we can try to get a bpage or block
1330 from the page hash:
1331 1) Caller already holds the appropriate page hash lock: in the case call
1332 buf_page_hash_get_low() function.
1333 2) Caller wants to hold page hash lock in x-mode
1334 3) Caller wants to hold page hash lock in s-mode
1335 4) Caller doesn't want to hold page hash lock */
1336 #define buf_page_hash_get_s_locked(b, s, o, l)			\
1337 	buf_page_hash_get_locked(b, s, o, l, RW_LOCK_SHARED)
1338 #define buf_page_hash_get_x_locked(b, s, o, l)			\
1339 	buf_page_hash_get_locked(b, s, o, l, RW_LOCK_EX)
1340 #define buf_page_hash_get(b, s, o)				\
1341 	buf_page_hash_get_locked(b, s, o, NULL, 0)
1342 #define buf_page_get_also_watch(b, s, o)			\
1343 	buf_page_hash_get_locked(b, s, o, NULL, 0, true)
1344 
1345 #define buf_block_hash_get_s_locked(b, s, o, l)			\
1346 	buf_block_hash_get_locked(b, s, o, l, RW_LOCK_SHARED)
1347 #define buf_block_hash_get_x_locked(b, s, o, l)			\
1348 	buf_block_hash_get_locked(b, s, o, l, RW_LOCK_EX)
1349 #define buf_block_hash_get(b, s, o)				\
1350 	buf_block_hash_get_locked(b, s, o, NULL, 0)
1351 
1352 /*********************************************************************//**
1353 Gets the current length of the free list of buffer blocks.
1354 @return	length of the free list */
1355 UNIV_INTERN
1356 ulint
1357 buf_get_free_list_len(void);
1358 /*=======================*/
1359 
1360 /********************************************************************//**
1361 Determine if a block is a sentinel for a buffer pool watch.
1362 @return	TRUE if a sentinel for a buffer pool watch, FALSE if not */
1363 UNIV_INTERN
1364 ibool
1365 buf_pool_watch_is_sentinel(
1366 /*=======================*/
1367 	buf_pool_t*		buf_pool,	/*!< buffer pool instance */
1368 	const buf_page_t*	bpage)		/*!< in: block */
1369 	MY_ATTRIBUTE((nonnull, warn_unused_result));
1370 /****************************************************************//**
1371 Add watch for the given page to be read in. Caller must have the buffer pool
1372 @return NULL if watch set, block if the page is in the buffer pool */
1373 UNIV_INTERN
1374 buf_page_t*
1375 buf_pool_watch_set(
1376 /*===============*/
1377 	ulint	space,	/*!< in: space id */
1378 	ulint	offset,	/*!< in: page number */
1379 	ulint	fold)	/*!< in: buf_page_address_fold(space, offset) */
1380 	MY_ATTRIBUTE((warn_unused_result));
1381 /****************************************************************//**
1382 Stop watching if the page has been read in.
1383 buf_pool_watch_set(space,offset) must have returned NULL before. */
1384 UNIV_INTERN
1385 void
1386 buf_pool_watch_unset(
1387 /*=================*/
1388 	ulint	space,	/*!< in: space id */
1389 	ulint	offset);/*!< in: page number */
1390 /****************************************************************//**
1391 Check if the page has been read in.
1392 This may only be called after buf_pool_watch_set(space,offset)
1393 has returned NULL and before invoking buf_pool_watch_unset(space,offset).
1394 @return	FALSE if the given page was not read in, TRUE if it was */
1395 UNIV_INTERN
1396 ibool
1397 buf_pool_watch_occurred(
1398 /*====================*/
1399 	ulint	space,	/*!< in: space id */
1400 	ulint	offset)	/*!< in: page number */
1401 	MY_ATTRIBUTE((warn_unused_result));
1402 /********************************************************************//**
1403 Get total buffer pool statistics. */
1404 UNIV_INTERN
1405 void
1406 buf_get_total_list_len(
1407 /*===================*/
1408 	ulint*		LRU_len,	/*!< out: length of all LRU lists */
1409 	ulint*		free_len,	/*!< out: length of all free lists */
1410 	ulint*		flush_list_len);/*!< out: length of all flush lists */
1411 /********************************************************************//**
1412 Get total list size in bytes from all buffer pools. */
1413 UNIV_INTERN
1414 void
1415 buf_get_total_list_size_in_bytes(
1416 /*=============================*/
1417 	buf_pools_list_size_t*	buf_pools_list_size);	/*!< out: list sizes
1418 							in all buffer pools */
1419 /********************************************************************//**
1420 Get total buffer pool statistics. */
1421 UNIV_INTERN
1422 void
1423 buf_get_total_stat(
1424 /*===============*/
1425 	buf_pool_stat_t*tot_stat);	/*!< out: buffer pool stats */
1426 /*********************************************************************//**
1427 Get the nth chunk's buffer block in the specified buffer pool.
1428 @return the nth chunk's buffer block. */
1429 UNIV_INLINE
1430 buf_block_t*
1431 buf_get_nth_chunk_block(
1432 /*====================*/
1433 	const buf_pool_t* buf_pool,	/*!< in: buffer pool instance */
1434 	ulint		n,		/*!< in: nth chunk in the buffer pool */
1435 	ulint*		chunk_size);	/*!< in: chunk size */
1436 
1437 /********************************************************************//**
1438 Calculate the checksum of a page from compressed table and update the page. */
1439 UNIV_INTERN
1440 void
1441 buf_flush_update_zip_checksum(
1442 /*==========================*/
1443 	buf_frame_t*	page,		/*!< in/out: Page to update */
1444 	ulint		zip_size,	/*!< in: Compressed page size */
1445 	lsn_t		lsn);		/*!< in: Lsn to stamp on the page */
1446 
1447 #endif /* !UNIV_HOTBACKUP */
1448 
1449 /** The common buffer control block structure
1450 for compressed and uncompressed frames */
1451 
1452 /** Number of bits used for buffer page states. */
1453 #define BUF_PAGE_STATE_BITS	3
1454 
1455 struct buf_page_t{
1456 	/** @name General fields
1457 	None of these bit-fields must be modified without holding
1458 	buf_page_get_mutex() [buf_block_t::mutex or
1459 	buf_pool->zip_mutex], since they can be stored in the same
1460 	machine word.  Some of these fields are additionally protected
1461 	by buf_pool->mutex. */
1462 	/* @{ */
1463 
1464 	ib_uint32_t	space;		/*!< tablespace id; also protected
1465 					by buf_pool->mutex. */
1466 	ib_uint32_t	offset;		/*!< page number; also protected
1467 					by buf_pool->mutex. */
1468 	/** count of how manyfold this block is currently bufferfixed */
1469 #ifdef PAGE_ATOMIC_REF_COUNT
1470 	ib_uint32_t	buf_fix_count;
1471 
1472 	/** type of pending I/O operation; also protected by
1473 	buf_pool->mutex for writes only @see enum buf_io_fix */
1474 	byte		io_fix;
1475 
1476 	byte		state;
1477 #else
1478 	unsigned	buf_fix_count:19;
1479 
1480 	/** type of pending I/O operation; also protected by
1481 	buf_pool->mutex for writes only @see enum buf_io_fix */
1482 	unsigned	io_fix:2;
1483 
1484 	/*!< state of the control block; also protected by buf_pool->mutex.
1485 	State transitions from BUF_BLOCK_READY_FOR_USE to BUF_BLOCK_MEMORY
1486 	need not be protected by buf_page_get_mutex(). @see enum buf_page_state.
1487 	State changes that are relevant to page_hash are additionally protected
1488 	by the appropriate page_hash mutex i.e.: if a page is in page_hash or
1489 	is being added to/removed from page_hash then the corresponding changes
1490 	must also be protected by page_hash mutex. */
1491 	unsigned	state:BUF_PAGE_STATE_BITS;
1492 
1493 #endif /* PAGE_ATOMIC_REF_COUNT */
1494 
1495 #ifndef UNIV_HOTBACKUP
1496 	unsigned	flush_type:2;	/*!< if this block is currently being
1497 					flushed to disk, this tells the
1498 					flush_type.
1499 					@see buf_flush_t */
1500 	unsigned	buf_pool_index:6;/*!< index number of the buffer pool
1501 					that this block belongs to */
1502 # if MAX_BUFFER_POOLS > 64
1503 #  error "MAX_BUFFER_POOLS > 64; redefine buf_pool_index:6"
1504 # endif
1505 	/* @} */
1506 #endif /* !UNIV_HOTBACKUP */
1507 	page_zip_des_t	zip;		/*!< compressed page; zip.data
1508 					(but not the data it points to) is
1509 					also protected by buf_pool->mutex;
1510 					state == BUF_BLOCK_ZIP_PAGE and
1511 					zip.data == NULL means an active
1512 					buf_pool->watch */
1513 #ifndef UNIV_HOTBACKUP
1514 	buf_page_t*	hash;		/*!< node used in chaining to
1515 					buf_pool->page_hash or
1516 					buf_pool->zip_hash */
1517 #ifdef UNIV_DEBUG
1518 	ibool		in_page_hash;	/*!< TRUE if in buf_pool->page_hash */
1519 	ibool		in_zip_hash;	/*!< TRUE if in buf_pool->zip_hash */
1520 #endif /* UNIV_DEBUG */
1521 
1522 	/** @name Page flushing fields
1523 	All these are protected by buf_pool->mutex. */
1524 	/* @{ */
1525 
1526 	UT_LIST_NODE_T(buf_page_t) list;
1527 					/*!< based on state, this is a
1528 					list node, protected either by
1529 					buf_pool->mutex or by
1530 					buf_pool->flush_list_mutex,
1531 					in one of the following lists in
1532 					buf_pool:
1533 
1534 					- BUF_BLOCK_NOT_USED:	free
1535 					- BUF_BLOCK_FILE_PAGE:	flush_list
1536 					- BUF_BLOCK_ZIP_DIRTY:	flush_list
1537 					- BUF_BLOCK_ZIP_PAGE:	zip_clean
1538 
1539 					If bpage is part of flush_list
1540 					then the node pointers are
1541 					covered by buf_pool->flush_list_mutex.
1542 					Otherwise these pointers are
1543 					protected by buf_pool->mutex.
1544 
1545 					The contents of the list node
1546 					is undefined if !in_flush_list
1547 					&& state == BUF_BLOCK_FILE_PAGE,
1548 					or if state is one of
1549 					BUF_BLOCK_MEMORY,
1550 					BUF_BLOCK_REMOVE_HASH or
1551 					BUF_BLOCK_READY_IN_USE. */
1552 
1553 #ifdef UNIV_DEBUG
1554 	ibool		in_flush_list;	/*!< TRUE if in buf_pool->flush_list;
1555 					when buf_pool->flush_list_mutex is
1556 					free, the following should hold:
1557 					in_flush_list
1558 					== (state == BUF_BLOCK_FILE_PAGE
1559 					    || state == BUF_BLOCK_ZIP_DIRTY)
1560 					Writes to this field must be
1561 					covered by both block->mutex
1562 					and buf_pool->flush_list_mutex. Hence
1563 					reads can happen while holding
1564 					any one of the two mutexes */
1565 	ibool		in_free_list;	/*!< TRUE if in buf_pool->free; when
1566 					buf_pool->mutex is free, the following
1567 					should hold: in_free_list
1568 					== (state == BUF_BLOCK_NOT_USED) */
1569 #endif /* UNIV_DEBUG */
1570 	lsn_t		newest_modification;
1571 					/*!< log sequence number of
1572 					the youngest modification to
1573 					this block, zero if not
1574 					modified. Protected by block
1575 					mutex */
1576 	lsn_t		oldest_modification;
1577 					/*!< log sequence number of
1578 					the START of the log entry
1579 					written of the oldest
1580 					modification to this block
1581 					which has not yet been flushed
1582 					on disk; zero if all
1583 					modifications are on disk.
1584 					Writes to this field must be
1585 					covered by both block->mutex
1586 					and buf_pool->flush_list_mutex. Hence
1587 					reads can happen while holding
1588 					any one of the two mutexes */
1589 	/* @} */
1590 	/** @name LRU replacement algorithm fields
1591 	These fields are protected by buf_pool->mutex only (not
1592 	buf_pool->zip_mutex or buf_block_t::mutex). */
1593 	/* @{ */
1594 
1595 	UT_LIST_NODE_T(buf_page_t) LRU;
1596 					/*!< node of the LRU list */
1597 #ifdef UNIV_DEBUG
1598 	ibool		in_LRU_list;	/*!< TRUE if the page is in
1599 					the LRU list; used in
1600 					debugging */
1601 #endif /* UNIV_DEBUG */
1602 	unsigned	old:1;		/*!< TRUE if the block is in the old
1603 					blocks in buf_pool->LRU_old */
1604 	unsigned	freed_page_clock:31;/*!< the value of
1605 					buf_pool->freed_page_clock
1606 					when this block was the last
1607 					time put to the head of the
1608 					LRU list; a thread is allowed
1609 					to read this for heuristic
1610 					purposes without holding any
1611 					mutex or latch */
1612 	/* @} */
1613 	unsigned	access_time;	/*!< time of first access, or
1614 					0 if the block was never accessed
1615 					in the buffer pool. Protected by
1616 					block mutex */
1617 # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
1618 	ibool		file_page_was_freed;
1619 					/*!< this is set to TRUE when
1620 					fsp frees a page in buffer pool;
1621 					protected by buf_pool->zip_mutex
1622 					or buf_block_t::mutex. */
1623 # endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
1624 #endif /* !UNIV_HOTBACKUP */
1625 };
1626 
1627 /** The buffer control block structure */
1628 
1629 struct buf_block_t{
1630 
1631 	/** @name General fields */
1632 	/* @{ */
1633 
1634 	buf_page_t	page;		/*!< page information; this must
1635 					be the first field, so that
1636 					buf_pool->page_hash can point
1637 					to buf_page_t or buf_block_t */
1638 	byte*		frame;		/*!< pointer to buffer frame which
1639 					is of size UNIV_PAGE_SIZE, and
1640 					aligned to an address divisible by
1641 					UNIV_PAGE_SIZE */
1642 #ifndef UNIV_HOTBACKUP
1643 	UT_LIST_NODE_T(buf_block_t) unzip_LRU;
1644 					/*!< node of the decompressed LRU list;
1645 					a block is in the unzip_LRU list
1646 					if page.state == BUF_BLOCK_FILE_PAGE
1647 					and page.zip.data != NULL */
1648 #ifdef UNIV_DEBUG
1649 	ibool		in_unzip_LRU_list;/*!< TRUE if the page is in the
1650 					decompressed LRU list;
1651 					used in debugging */
1652 #endif /* UNIV_DEBUG */
1653 	ib_mutex_t	mutex;		/*!< mutex protecting this block:
1654 					state (also protected by the buffer
1655 					pool mutex), io_fix, buf_fix_count,
1656 					and accessed; we introduce this new
1657 					mutex in InnoDB-5.1 to relieve
1658 					contention on the buffer pool mutex */
1659 	rw_lock_t	lock;		/*!< read-write lock of the buffer
1660 					frame */
1661 	unsigned	lock_hash_val:32;/*!< hashed value of the page address
1662 					in the record lock hash table;
1663 					protected by buf_block_t::lock
1664 					(or buf_block_t::mutex, buf_pool->mutex
1665 				        in buf_page_get_gen(),
1666 					buf_page_init_for_read()
1667 					and buf_page_create()) */
1668 	ibool		check_index_page_at_flush;
1669 					/*!< TRUE if we know that this is
1670 					an index page, and want the database
1671 					to check its consistency before flush;
1672 					note that there may be pages in the
1673 					buffer pool which are index pages,
1674 					but this flag is not set because
1675 					we do not keep track of all pages;
1676 					NOT protected by any mutex */
1677 	/* @} */
1678 	/** @name Optimistic search field */
1679 	/* @{ */
1680 
1681 	ib_uint64_t	modify_clock;	/*!< this clock is incremented every
1682 					time a pointer to a record on the
1683 					page may become obsolete; this is
1684 					used in the optimistic cursor
1685 					positioning: if the modify clock has
1686 					not changed, we know that the pointer
1687 					is still valid; this field may be
1688 					changed if the thread (1) owns the
1689 					pool mutex and the page is not
1690 					bufferfixed, or (2) the thread has an
1691 					x-latch on the block */
1692 	/* @} */
1693 	/** @name Hash search fields (unprotected)
1694 	NOTE that these fields are NOT protected by any semaphore! */
1695 	/* @{ */
1696 
1697 	ulint		n_hash_helps;	/*!< counter which controls building
1698 					of a new hash index for the page */
1699 	ulint		n_fields;	/*!< recommended prefix length for hash
1700 					search: number of full fields */
1701 	ulint		n_bytes;	/*!< recommended prefix: number of bytes
1702 					in an incomplete field */
1703 	ibool		left_side;	/*!< TRUE or FALSE, depending on
1704 					whether the leftmost record of several
1705 					records with the same prefix should be
1706 					indexed in the hash index */
1707 	/* @} */
1708 
1709 	/** @name Hash search fields
1710 	These 5 fields may only be modified when we have
1711 	an x-latch on btr_search_latch AND
1712 	- we are holding an s-latch or x-latch on buf_block_t::lock or
1713 	- we know that buf_block_t::buf_fix_count == 0.
1714 
1715 	An exception to this is when we init or create a page
1716 	in the buffer pool in buf0buf.cc.
1717 
1718 	Another exception is that assigning block->index = NULL
1719 	is allowed whenever holding an x-latch on btr_search_latch. */
1720 
1721 	/* @{ */
1722 
1723 #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
1724 	ulint		n_pointers;	/*!< used in debugging: the number of
1725 					pointers in the adaptive hash index
1726 					pointing to this frame */
1727 #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
1728 	unsigned	curr_n_fields:10;/*!< prefix length for hash indexing:
1729 					number of full fields */
1730 	unsigned	curr_n_bytes:15;/*!< number of bytes in hash
1731 					indexing */
1732 	unsigned	curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
1733 	dict_index_t*	index;		/*!< Index for which the
1734 					adaptive hash index has been
1735 					created, or NULL if the page
1736 					does not exist in the
1737 					index. Note that it does not
1738 					guarantee that the index is
1739 					complete, though: there may
1740 					have been hash collisions,
1741 					record deletions, etc. */
1742 	/* @} */
1743 # ifdef UNIV_SYNC_DEBUG
1744 	/** @name Debug fields */
1745 	/* @{ */
1746 	rw_lock_t	debug_latch;	/*!< in the debug version, each thread
1747 					which bufferfixes the block acquires
1748 					an s-latch here; so we can use the
1749 					debug utilities in sync0rw */
1750 	/* @} */
1751 # endif
1752 #endif /* !UNIV_HOTBACKUP */
1753 };
1754 
1755 /** Check if a buf_block_t object is in a valid state
1756 @param block	buffer block
1757 @return		TRUE if valid */
1758 #define buf_block_state_valid(block)				\
1759 (buf_block_get_state(block) >= BUF_BLOCK_NOT_USED		\
1760  && (buf_block_get_state(block) <= BUF_BLOCK_REMOVE_HASH))
1761 
1762 #ifndef UNIV_HOTBACKUP
1763 /**********************************************************************//**
1764 Compute the hash fold value for blocks in buf_pool->zip_hash. */
1765 /* @{ */
1766 #define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE)
1767 #define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame)
1768 #define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b))
1769 /* @} */
1770 
1771 /** Struct that is embedded in the free zip blocks */
1772 struct buf_buddy_free_t {
1773 	union {
1774 		ulint	size;	/*!< size of the block */
1775 		byte	bytes[FIL_PAGE_DATA];
1776 				/*!< stamp[FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID]
1777 				== BUF_BUDDY_FREE_STAMP denotes a free
1778 				block. If the space_id field of buddy
1779 				block != BUF_BUDDY_FREE_STAMP, the block
1780 				is not in any zip_free list. If the
1781 				space_id is BUF_BUDDY_FREE_STAMP then
1782 				stamp[0] will contain the
1783 				buddy block size. */
1784 	} stamp;
1785 
1786 	buf_page_t	bpage;	/*!< Embedded bpage descriptor */
1787 	UT_LIST_NODE_T(buf_buddy_free_t) list;
1788 				/*!< Node of zip_free list */
1789 };
1790 
1791 /** @brief The buffer pool statistics structure. */
1792 struct buf_pool_stat_t{
1793 	ulint	n_page_gets;	/*!< number of page gets performed;
1794 				also successful searches through
1795 				the adaptive hash index are
1796 				counted as page gets; this field
1797 				is NOT protected by the buffer
1798 				pool mutex */
1799 	ulint	n_pages_read;	/*!< number read operations */
1800 	ulint	n_pages_written;/*!< number write operations */
1801 	ulint	n_pages_created;/*!< number of pages created
1802 				in the pool with no read */
1803 	ulint	n_ra_pages_read_rnd;/*!< number of pages read in
1804 				as part of random read ahead */
1805 	ulint	n_ra_pages_read;/*!< number of pages read in
1806 				as part of read ahead */
1807 	ulint	n_ra_pages_evicted;/*!< number of read ahead
1808 				pages that are evicted without
1809 				being accessed */
1810 	ulint	n_pages_made_young; /*!< number of pages made young, in
1811 				calls to buf_LRU_make_block_young() */
1812 	ulint	n_pages_not_made_young; /*!< number of pages not made
1813 				young because the first access
1814 				was not long enough ago, in
1815 				buf_page_peek_if_too_old() */
1816 	ulint	LRU_bytes;	/*!< LRU size in bytes */
1817 	ulint	flush_list_bytes;/*!< flush_list size in bytes */
1818 };
1819 
1820 /** Statistics of buddy blocks of a given size. */
1821 struct buf_buddy_stat_t {
1822 	/** Number of blocks allocated from the buddy system. */
1823 	ulint		used;
1824 	/** Number of blocks relocated by the buddy system. */
1825 	ib_uint64_t	relocated;
1826 	/** Total duration of block relocations, in microseconds. */
1827 	ib_uint64_t	relocated_usec;
1828 };
1829 
1830 /** @brief The buffer pool structure.
1831 
1832 NOTE! The definition appears here only for other modules of this
1833 directory (buf) to see it. Do not use from outside! */
1834 
1835 struct buf_pool_t{
1836 
1837 	/** @name General fields */
1838 	/* @{ */
1839 	ib_mutex_t	mutex;		/*!< Buffer pool mutex of this
1840 					instance */
1841 	ib_mutex_t	zip_mutex;	/*!< Zip mutex of this buffer
1842 					pool instance, protects compressed
1843 					only pages (of type buf_page_t, not
1844 					buf_block_t */
1845 	ulint		instance_no;	/*!< Array index of this buffer
1846 					pool instance */
1847 	ulint		old_pool_size;  /*!< Old pool size in bytes */
1848 	ulint		curr_pool_size;	/*!< Current pool size in bytes */
1849 	ulint		LRU_old_ratio;  /*!< Reserve this much of the buffer
1850 					pool for "old" blocks */
1851 #ifdef UNIV_DEBUG
1852 	ulint		buddy_n_frames; /*!< Number of frames allocated from
1853 					the buffer pool to the buddy system */
1854 #endif
1855 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1856 	ulint		mutex_exit_forbidden; /*!< Forbid release mutex */
1857 #endif
1858 	ulint		n_chunks;	/*!< number of buffer pool chunks */
1859 	buf_chunk_t*	chunks;		/*!< buffer pool chunks */
1860 	ulint		curr_size;	/*!< current pool size in pages */
1861 	hash_table_t*	page_hash;	/*!< hash table of buf_page_t or
1862 					buf_block_t file pages,
1863 					buf_page_in_file() == TRUE,
1864 					indexed by (space_id, offset).
1865 					page_hash is protected by an
1866 					array of mutexes.
1867 					Changes in page_hash are protected
1868 					by buf_pool->mutex and the relevant
1869 					page_hash mutex. Lookups can happen
1870 					while holding the buf_pool->mutex or
1871 					the relevant page_hash mutex. */
1872 	hash_table_t*	zip_hash;	/*!< hash table of buf_block_t blocks
1873 					whose frames are allocated to the
1874 					zip buddy system,
1875 					indexed by block->frame */
1876 	ulint		n_pend_reads;	/*!< number of pending read
1877 					operations */
1878 	ulint		n_pend_unzip;	/*!< number of pending decompressions */
1879 
1880 	time_t		last_printout_time;
1881 					/*!< when buf_print_io was last time
1882 					called */
1883 	buf_buddy_stat_t buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
1884 					/*!< Statistics of buddy system,
1885 					indexed by block size */
1886 	buf_pool_stat_t	stat;		/*!< current statistics */
1887 	buf_pool_stat_t	old_stat;	/*!< old statistics */
1888 
1889 	/* @} */
1890 
1891 	/** @name Page flushing algorithm fields */
1892 
1893 	/* @{ */
1894 
1895 	ib_mutex_t	flush_list_mutex;/*!< mutex protecting the
1896 					flush list access. This mutex
1897 					protects flush_list, flush_rbt
1898 					and bpage::list pointers when
1899 					the bpage is on flush_list. It
1900 					also protects writes to
1901 					bpage::oldest_modification and
1902 					flush_list_hp */
1903 	const buf_page_t*	flush_list_hp;/*!< "hazard pointer"
1904 					used during scan of flush_list
1905 					while doing flush list batch.
1906 					Protected by flush_list_mutex */
1907 	UT_LIST_BASE_NODE_T(buf_page_t) flush_list;
1908 					/*!< base node of the modified block
1909 					list */
1910 	ibool		init_flush[BUF_FLUSH_N_TYPES];
1911 					/*!< this is TRUE when a flush of the
1912 					given type is being initialized */
1913 	ulint		n_flush[BUF_FLUSH_N_TYPES];
1914 					/*!< this is the number of pending
1915 					writes in the given flush type */
1916 	os_event_t	no_flush[BUF_FLUSH_N_TYPES];
1917 					/*!< this is in the set state
1918 					when there is no flush batch
1919 					of the given type running */
1920 	ib_rbt_t*	flush_rbt;	/*!< a red-black tree is used
1921 					exclusively during recovery to
1922 					speed up insertions in the
1923 					flush_list. This tree contains
1924 					blocks in order of
1925 					oldest_modification LSN and is
1926 					kept in sync with the
1927 					flush_list.
1928 					Each member of the tree MUST
1929 					also be on the flush_list.
1930 					This tree is relevant only in
1931 					recovery and is set to NULL
1932 					once the recovery is over.
1933 					Protected by flush_list_mutex */
1934 	ulint		freed_page_clock;/*!< a sequence number used
1935 					to count the number of buffer
1936 					blocks removed from the end of
1937 					the LRU list; NOTE that this
1938 					counter may wrap around at 4
1939 					billion! A thread is allowed
1940 					to read this for heuristic
1941 					purposes without holding any
1942 					mutex or latch */
1943 	ibool		try_LRU_scan;	/*!< Set to FALSE when an LRU
1944 					scan for free block fails. This
1945 					flag is used to avoid repeated
1946 					scans of LRU list when we know
1947 					that there is no free block
1948 					available in the scan depth for
1949 					eviction. Set to TRUE whenever
1950 					we flush a batch from the
1951 					buffer pool. Protected by the
1952 					buf_pool->mutex */
1953 	/* @} */
1954 
1955 	/** @name LRU replacement algorithm fields */
1956 	/* @{ */
1957 
1958 	UT_LIST_BASE_NODE_T(buf_page_t) free;
1959 					/*!< base node of the free
1960 					block list */
1961 	UT_LIST_BASE_NODE_T(buf_page_t) LRU;
1962 					/*!< base node of the LRU list */
1963 	buf_page_t*	LRU_old;	/*!< pointer to the about
1964 					LRU_old_ratio/BUF_LRU_OLD_RATIO_DIV
1965 					oldest blocks in the LRU list;
1966 					NULL if LRU length less than
1967 					BUF_LRU_OLD_MIN_LEN;
1968 					NOTE: when LRU_old != NULL, its length
1969 					should always equal LRU_old_len */
1970 	ulint		LRU_old_len;	/*!< length of the LRU list from
1971 					the block to which LRU_old points
1972 					onward, including that block;
1973 					see buf0lru.cc for the restrictions
1974 					on this value; 0 if LRU_old == NULL;
1975 					NOTE: LRU_old_len must be adjusted
1976 					whenever LRU_old shrinks or grows! */
1977 
1978 	UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU;
1979 					/*!< base node of the
1980 					unzip_LRU list */
1981 
1982 	/* @} */
1983 	/** @name Buddy allocator fields
1984 	The buddy allocator is used for allocating compressed page
1985 	frames and buf_page_t descriptors of blocks that exist
1986 	in the buffer pool only in compressed form. */
1987 	/* @{ */
1988 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1989 	UT_LIST_BASE_NODE_T(buf_page_t)	zip_clean;
1990 					/*!< unmodified compressed pages */
1991 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
1992 	UT_LIST_BASE_NODE_T(buf_buddy_free_t) zip_free[BUF_BUDDY_SIZES_MAX];
1993 					/*!< buddy free lists */
1994 
1995 	buf_page_t*			watch;
1996 					/*!< Sentinel records for buffer
1997 					pool watches. Protected by
1998 					buf_pool->mutex. */
1999 
2000 #if BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN
2001 # error "BUF_BUDDY_LOW > UNIV_ZIP_SIZE_MIN"
2002 #endif
2003 	/* @} */
2004 };
2005 
2006 /** @name Accessors for buf_pool->mutex.
2007 Use these instead of accessing buf_pool->mutex directly. */
2008 /* @{ */
2009 
2010 /** Test if a buffer pool mutex is owned. */
2011 #define buf_pool_mutex_own(b) mutex_own(&b->mutex)
2012 /** Acquire a buffer pool mutex. */
2013 #define buf_pool_mutex_enter(b) do {			\
2014 	ut_ad(!mutex_own(&b->zip_mutex));		\
2015 	mutex_enter(&b->mutex);				\
2016 } while (0)
2017 
2018 /** Test if flush list mutex is owned. */
2019 #define buf_flush_list_mutex_own(b) mutex_own(&b->flush_list_mutex)
2020 
2021 /** Acquire the flush list mutex. */
2022 #define buf_flush_list_mutex_enter(b) do {		\
2023 	mutex_enter(&b->flush_list_mutex);		\
2024 } while (0)
2025 /** Release the flush list mutex. */
2026 # define buf_flush_list_mutex_exit(b) do {		\
2027 	mutex_exit(&b->flush_list_mutex);		\
2028 } while (0)
2029 
2030 /** Test if block->mutex is owned. */
2031 #define buf_block_mutex_own(b)	mutex_own(&(b)->mutex)
2032 
2033 /** Acquire the block->mutex. */
2034 #define buf_block_mutex_enter(b) do {			\
2035 	mutex_enter(&(b)->mutex);			\
2036 } while (0)
2037 
2038 /** Release the trx->mutex. */
2039 #define buf_block_mutex_exit(b) do {			\
2040 	mutex_exit(&(b)->mutex);				\
2041 } while (0)
2042 
2043 
2044 /** Get appropriate page_hash_lock. */
2045 # define buf_page_hash_lock_get(b, f)			\
2046 	hash_get_lock(b->page_hash, f)
2047 
2048 #ifdef UNIV_SYNC_DEBUG
2049 /** Test if page_hash lock is held in s-mode. */
2050 # define buf_page_hash_lock_held_s(b, p)		\
2051 	rw_lock_own(buf_page_hash_lock_get(b,		\
2052 		  buf_page_address_fold(p->space,	\
2053 					p->offset)),	\
2054 					RW_LOCK_SHARED)
2055 
2056 /** Test if page_hash lock is held in x-mode. */
2057 # define buf_page_hash_lock_held_x(b, p)		\
2058 	rw_lock_own(buf_page_hash_lock_get(b,		\
2059 		  buf_page_address_fold(p->space,	\
2060 					p->offset)),	\
2061 					RW_LOCK_EX)
2062 
2063 /** Test if page_hash lock is held in x or s-mode. */
2064 # define buf_page_hash_lock_held_s_or_x(b, p)		\
2065 	(buf_page_hash_lock_held_s(b, p)		\
2066 	 || buf_page_hash_lock_held_x(b, p))
2067 
2068 # define buf_block_hash_lock_held_s(b, p)		\
2069 	buf_page_hash_lock_held_s(b, &(p->page))
2070 
2071 # define buf_block_hash_lock_held_x(b, p)		\
2072 	buf_page_hash_lock_held_x(b, &(p->page))
2073 
2074 # define buf_block_hash_lock_held_s_or_x(b, p)		\
2075 	buf_page_hash_lock_held_s_or_x(b, &(p->page))
2076 #else /* UNIV_SYNC_DEBUG */
2077 # define buf_page_hash_lock_held_s(b, p)	(TRUE)
2078 # define buf_page_hash_lock_held_x(b, p)	(TRUE)
2079 # define buf_page_hash_lock_held_s_or_x(b, p)	(TRUE)
2080 # define buf_block_hash_lock_held_s(b, p)	(TRUE)
2081 # define buf_block_hash_lock_held_x(b, p)	(TRUE)
2082 # define buf_block_hash_lock_held_s_or_x(b, p)	(TRUE)
2083 #endif /* UNIV_SYNC_DEBUG */
2084 
2085 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2086 /** Forbid the release of the buffer pool mutex. */
2087 # define buf_pool_mutex_exit_forbid(b) do {	\
2088 	ut_ad(buf_pool_mutex_own(b));		\
2089 	b->mutex_exit_forbidden++;		\
2090 } while (0)
2091 /** Allow the release of the buffer pool mutex. */
2092 # define buf_pool_mutex_exit_allow(b) do {	\
2093 	ut_ad(buf_pool_mutex_own(b));		\
2094 	ut_a(b->mutex_exit_forbidden);	\
2095 	b->mutex_exit_forbidden--;		\
2096 } while (0)
2097 /** Release the buffer pool mutex. */
2098 # define buf_pool_mutex_exit(b) do {		\
2099 	ut_a(!b->mutex_exit_forbidden);		\
2100 	mutex_exit(&b->mutex);			\
2101 } while (0)
2102 #else
2103 /** Forbid the release of the buffer pool mutex. */
2104 # define buf_pool_mutex_exit_forbid(b) ((void) 0)
2105 /** Allow the release of the buffer pool mutex. */
2106 # define buf_pool_mutex_exit_allow(b) ((void) 0)
2107 /** Release the buffer pool mutex. */
2108 # define buf_pool_mutex_exit(b) mutex_exit(&b->mutex)
2109 #endif
2110 #endif /* !UNIV_HOTBACKUP */
2111 /* @} */
2112 
2113 /**********************************************************************
2114 Let us list the consistency conditions for different control block states.
2115 
2116 NOT_USED:	is in free list, not in LRU list, not in flush list, nor
2117 		page hash table
2118 READY_FOR_USE:	is not in free list, LRU list, or flush list, nor page
2119 		hash table
2120 MEMORY:		is not in free list, LRU list, or flush list, nor page
2121 		hash table
2122 FILE_PAGE:	space and offset are defined, is in page hash table
2123 		if io_fix == BUF_IO_WRITE,
2124 			pool: no_flush[flush_type] is in reset state,
2125 			pool: n_flush[flush_type] > 0
2126 
2127 		(1) if buf_fix_count == 0, then
2128 			is in LRU list, not in free list
2129 			is in flush list,
2130 				if and only if oldest_modification > 0
2131 			is x-locked,
2132 				if and only if io_fix == BUF_IO_READ
2133 			is s-locked,
2134 				if and only if io_fix == BUF_IO_WRITE
2135 
2136 		(2) if buf_fix_count > 0, then
2137 			is not in LRU list, not in free list
2138 			is in flush list,
2139 				if and only if oldest_modification > 0
2140 			if io_fix == BUF_IO_READ,
2141 				is x-locked
2142 			if io_fix == BUF_IO_WRITE,
2143 				is s-locked
2144 
2145 State transitions:
2146 
2147 NOT_USED => READY_FOR_USE
2148 READY_FOR_USE => MEMORY
2149 READY_FOR_USE => FILE_PAGE
2150 MEMORY => NOT_USED
2151 FILE_PAGE => NOT_USED	NOTE: This transition is allowed if and only if
2152 				(1) buf_fix_count == 0,
2153 				(2) oldest_modification == 0, and
2154 				(3) io_fix == 0.
2155 */
2156 
2157 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
2158 /** Functor to validate the LRU list. */
2159 struct	CheckInLRUList {
operatorCheckInLRUList2160 	void	operator()(const buf_page_t* elem) const
2161 	{
2162 		ut_a(elem->in_LRU_list);
2163 	}
2164 };
2165 
2166 /** Functor to validate the LRU list. */
2167 struct	CheckInFreeList {
operatorCheckInFreeList2168 	void	operator()(const buf_page_t* elem) const
2169 	{
2170 		ut_a(elem->in_free_list);
2171 	}
2172 };
2173 
2174 struct	CheckUnzipLRUAndLRUList {
operatorCheckUnzipLRUAndLRUList2175 	void	operator()(const buf_block_t* elem) const
2176 	{
2177                 ut_a(elem->page.in_LRU_list);
2178                 ut_a(elem->in_unzip_LRU_list);
2179 	}
2180 };
2181 #endif /* UNIV_DEBUG || defined UNIV_BUF_DEBUG */
2182 
2183 #ifndef UNIV_NONINL
2184 #include "buf0buf.ic"
2185 #endif
2186 
2187 #endif
2188