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