diff options
author | unknown <knielsen@knielsen-hq.org> | 2009-06-09 13:16:11 +0200 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2009-06-09 13:16:11 +0200 |
commit | a6b7f71329ceb7d0188572f494b5d1a1f0461fc5 (patch) | |
tree | d7e62c1af5118cd3ec9346de436569e907fcc51d /storage/xtradb/include/buf0buf.h | |
parent | b125770aaadd09e839ad9211047e88095984308b (diff) | |
parent | 107072563d771422c9bbb9aeeedce8ae19c5b838 (diff) | |
download | mariadb-git-a6b7f71329ceb7d0188572f494b5d1a1f0461fc5.tar.gz |
Import Percona XtraDB into the MariaDB source tree.
Diffstat (limited to 'storage/xtradb/include/buf0buf.h')
-rw-r--r-- | storage/xtradb/include/buf0buf.h | 1417 |
1 files changed, 1417 insertions, 0 deletions
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h new file mode 100644 index 00000000000..9f94f72e293 --- /dev/null +++ b/storage/xtradb/include/buf0buf.h @@ -0,0 +1,1417 @@ +/***************************************************************************** + +Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA + +*****************************************************************************/ + +/****************************************************** +The database buffer pool high-level routines + +Created 11/5/1995 Heikki Tuuri +*******************************************************/ + +#ifndef buf0buf_h +#define buf0buf_h + +#include "univ.i" +#include "fil0fil.h" +#include "mtr0types.h" +#include "buf0types.h" +#include "sync0rw.h" +#include "hash0hash.h" +#include "ut0byte.h" +#include "os0proc.h" +#include "page0types.h" + +/* Modes for buf_page_get_gen */ +#define BUF_GET 10 /* get always */ +#define BUF_GET_IF_IN_POOL 11 /* get if in pool */ +#define BUF_GET_NO_LATCH 14 /* get and bufferfix, but set no latch; + we have separated this case, because + it is error-prone programming not to + set a latch, and it should be used + with care */ +/* Modes for buf_page_get_known_nowait */ +#define BUF_MAKE_YOUNG 51 +#define BUF_KEEP_OLD 52 +/* Magic value to use instead of checksums when they are disabled */ +#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL + +extern buf_pool_t* buf_pool; /* The buffer pool of the database */ +#ifdef UNIV_DEBUG +extern ibool buf_debug_prints;/* If this is set TRUE, the program + prints info whenever read or flush + occurs */ +#endif /* UNIV_DEBUG */ +extern ulint srv_buf_pool_write_requests; /* variable to count write request + issued */ + +/* States of a control block (@see buf_page_struct). +The enumeration values must be 0..7. */ +enum buf_page_state { + BUF_BLOCK_ZIP_FREE = 0, /* contains a free compressed page */ + BUF_BLOCK_ZIP_PAGE, /* contains a clean compressed page */ + BUF_BLOCK_ZIP_DIRTY, /* contains a compressed page that is + in the buf_pool->flush_list */ + + /* The constants for compressed-only pages must precede + BUF_BLOCK_NOT_USED; @see buf_block_state_valid() */ + + BUF_BLOCK_NOT_USED, /* is in the free list */ + BUF_BLOCK_READY_FOR_USE, /* when buf_LRU_get_free_block returns + a block, it is in this state */ + BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */ + BUF_BLOCK_MEMORY, /* contains some main memory object */ + BUF_BLOCK_REMOVE_HASH /* hash index should be removed + before putting to the free list */ +}; + +/************************************************************************ +Creates the buffer pool. */ +UNIV_INTERN +buf_pool_t* +buf_pool_init(void); +/*===============*/ + /* out, own: buf_pool object, NULL if not + enough memory or error */ +/************************************************************************ +Frees the buffer pool at shutdown. This must not be invoked before +freeing all mutexes. */ +UNIV_INTERN +void +buf_pool_free(void); +/*===============*/ + +/************************************************************************ +Drops the adaptive hash index. To prevent a livelock, this function +is only to be called while holding btr_search_latch and while +btr_search_enabled == FALSE. */ +UNIV_INTERN +void +buf_pool_drop_hash_index(void); +/*==========================*/ + +/************************************************************************ +Relocate a buffer control block. Relocates the block on the LRU list +and in buf_pool->page_hash. Does not relocate bpage->list. +The caller must take care of relocating bpage->list. */ +UNIV_INTERN +void +buf_relocate( +/*=========*/ + buf_page_t* bpage, /* in/out: control block being relocated; + buf_page_get_state(bpage) must be + BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_ZIP_PAGE */ + buf_page_t* dpage) /* in/out: destination control block */ + __attribute__((nonnull)); +/************************************************************************ +Resizes the buffer pool. */ +UNIV_INTERN +void +buf_pool_resize(void); +/*=================*/ +/************************************************************************* +Gets the current size of buffer buf_pool in bytes. */ +UNIV_INLINE +ulint +buf_pool_get_curr_size(void); +/*========================*/ + /* out: size in bytes */ +/************************************************************************ +Gets the smallest oldest_modification lsn for any page in the pool. Returns +zero if all modified pages have been flushed to disk. */ +UNIV_INLINE +ib_uint64_t +buf_pool_get_oldest_modification(void); +/*==================================*/ + /* out: oldest modification in pool, + zero if none */ +/************************************************************************ +Allocates a buffer block. */ +UNIV_INLINE +buf_block_t* +buf_block_alloc( +/*============*/ + /* out, own: the allocated block, + in state BUF_BLOCK_MEMORY */ + ulint zip_size); /* in: compressed page size in bytes, + or 0 if uncompressed tablespace */ +/************************************************************************ +Frees a buffer block which does not contain a file page. */ +UNIV_INLINE +void +buf_block_free( +/*===========*/ + buf_block_t* block); /* in, own: block to be freed */ +/************************************************************************* +Copies contents of a buffer frame to a given buffer. */ +UNIV_INLINE +byte* +buf_frame_copy( +/*===========*/ + /* out: buf */ + byte* buf, /* in: buffer to copy to */ + const buf_frame_t* frame); /* in: buffer frame */ +/****************************************************************** +NOTE! The following macros should be used instead of buf_page_get_gen, +to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed +in LA! */ +#define buf_page_get(SP, ZS, OF, LA, MTR) buf_page_get_gen(\ + SP, ZS, OF, LA, NULL,\ + BUF_GET, __FILE__, __LINE__, MTR) +/****************************************************************** +Use these macros to bufferfix a page with no latching. Remember not to +read the contents of the page unless you know it is safe. Do not modify +the contents of the page! We have separated this case, because it is +error-prone programming not to set a latch, and it should be used +with care. */ +#define buf_page_get_with_no_latch(SP, ZS, OF, MTR) buf_page_get_gen(\ + SP, ZS, OF, RW_NO_LATCH, NULL,\ + BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR) +/****************************************************************** +NOTE! The following macros should be used instead of +buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and +RW_X_LATCH are allowed as LA! */ +#define buf_page_optimistic_get(LA, BL, MC, MTR) \ + buf_page_optimistic_get_func(LA, BL, MC, __FILE__, __LINE__, MTR) +/************************************************************************ +This is the general function used to get optimistic access to a database +page. */ +UNIV_INTERN +ibool +buf_page_optimistic_get_func( +/*=========================*/ + /* out: TRUE if success */ + ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */ + buf_block_t* block, /* in: guessed block */ + ib_uint64_t modify_clock,/* in: modify clock value if mode is + ..._GUESS_ON_CLOCK */ + const char* file, /* in: file name */ + ulint line, /* in: line where called */ + mtr_t* mtr); /* in: mini-transaction */ +/************************************************************************ +This is used to get access to a known database page, when no waiting can be +done. */ +UNIV_INTERN +ibool +buf_page_get_known_nowait( +/*======================*/ + /* out: TRUE if success */ + ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */ + buf_block_t* block, /* in: the known page */ + ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */ + const char* file, /* in: file name */ + ulint line, /* in: line where called */ + mtr_t* mtr); /* in: mini-transaction */ + +/*********************************************************************** +Given a tablespace id and page number tries to get that page. If the +page is not in the buffer pool it is not loaded and NULL is returned. +Suitable for using when holding the kernel mutex. */ + +const buf_block_t* +buf_page_try_get_func( +/*==================*/ + ulint space_id,/* in: tablespace id */ + ulint page_no,/* in: page number */ + const char* file, /* in: file name */ + ulint line, /* in: line where called */ + mtr_t* mtr); /* in: mini-transaction */ + +#define buf_page_try_get(space_id, page_no, mtr) \ + buf_page_try_get_func(space_id, page_no, __FILE__, __LINE__, mtr); + +/************************************************************************ +Get read access to a compressed page (usually of type +FIL_PAGE_TYPE_ZBLOB or FIL_PAGE_TYPE_ZBLOB2). +The page must be released with buf_page_release_zip(). +NOTE: the page is not protected by any latch. Mutual exclusion has to +be implemented at a higher level. In other words, all possible +accesses to a given page through this function must be protected by +the same set of mutexes or latches. */ +UNIV_INTERN +buf_page_t* +buf_page_get_zip( +/*=============*/ + /* out: pointer to the block, + or NULL if not compressed */ + ulint space, /* in: space id */ + ulint zip_size,/* in: compressed page size */ + ulint offset);/* in: page number */ +/************************************************************************ +This is the general function used to get access to a database page. */ +UNIV_INTERN +buf_block_t* +buf_page_get_gen( +/*=============*/ + /* out: pointer to the block or NULL */ + ulint space, /* in: space id */ + ulint zip_size,/* in: compressed page size in bytes + or 0 for uncompressed pages */ + ulint offset, /* in: page number */ + ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */ + buf_block_t* guess, /* in: guessed block or NULL */ + ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL, + BUF_GET_NO_LATCH */ + const char* file, /* in: file name */ + ulint line, /* in: line where called */ + mtr_t* mtr); /* in: mini-transaction */ +/************************************************************************ +Initializes a page to the buffer buf_pool. The page is usually not read +from a file even if it cannot be found in the buffer buf_pool. This is one +of the functions which perform to a block a state transition NOT_USED => +FILE_PAGE (the other is buf_page_get_gen). */ +UNIV_INTERN +buf_block_t* +buf_page_create( +/*============*/ + /* out: pointer to the block, page bufferfixed */ + ulint space, /* in: space id */ + ulint offset, /* in: offset of the page within space in units of + a page */ + ulint zip_size,/* in: compressed page size, or 0 */ + mtr_t* mtr); /* in: mini-transaction handle */ +#ifdef UNIV_HOTBACKUP +/************************************************************************ +Inits a page to the buffer buf_pool, for use in ibbackup --restore. */ +UNIV_INTERN +void +buf_page_init_for_backup_restore( +/*=============================*/ + ulint space, /* in: space id */ + ulint offset, /* in: offset of the page within space + in units of a page */ + ulint zip_size,/* in: compressed page size in bytes + or 0 for uncompressed pages */ + buf_block_t* block); /* in: block to init */ +#endif /* UNIV_HOTBACKUP */ +/************************************************************************ +Releases a compressed-only page acquired with buf_page_get_zip(). */ +UNIV_INLINE +void +buf_page_release_zip( +/*=================*/ + buf_page_t* bpage); /* in: buffer block */ +/************************************************************************ +Decrements the bufferfix count of a buffer control block and releases +a latch, if specified. */ +UNIV_INLINE +void +buf_page_release( +/*=============*/ + buf_block_t* block, /* in: buffer block */ + ulint rw_latch, /* in: RW_S_LATCH, RW_X_LATCH, + RW_NO_LATCH */ + mtr_t* mtr); /* in: mtr */ +/************************************************************************ +Moves a page to the start of the buffer pool LRU list. This high-level +function can be used to prevent an important page from from slipping out of +the buffer pool. */ +UNIV_INTERN +void +buf_page_make_young( +/*================*/ + buf_page_t* bpage); /* in: buffer block of a file page */ +/************************************************************************ +Returns TRUE if the page can be found in the buffer pool hash table. NOTE +that it is possible that the page is not yet read from disk, though. */ +UNIV_INLINE +ibool +buf_page_peek( +/*==========*/ + /* out: TRUE if found from page hash table, + NOTE that the page is not necessarily yet read + from disk! */ + ulint space, /* in: space id */ + ulint offset);/* in: page number */ +/************************************************************************ +Resets the check_index_page_at_flush field of a page if found in the buffer +pool. */ +UNIV_INTERN +void +buf_reset_check_index_page_at_flush( +/*================================*/ + ulint space, /* in: space id */ + ulint offset);/* in: page number */ +#ifdef UNIV_DEBUG_FILE_ACCESSES +/************************************************************************ +Sets file_page_was_freed TRUE if the page is found in the buffer pool. +This function should be called when we free a file page and want the +debug version to check that it is not accessed any more unless +reallocated. */ +UNIV_INTERN +buf_page_t* +buf_page_set_file_page_was_freed( +/*=============================*/ + /* out: control block if found in page hash table, + otherwise NULL */ + ulint space, /* in: space id */ + ulint offset);/* in: page number */ +/************************************************************************ +Sets file_page_was_freed FALSE if the page is found in the buffer pool. +This function should be called when we free a file page and want the +debug version to check that it is not accessed any more unless +reallocated. */ +UNIV_INTERN +buf_page_t* +buf_page_reset_file_page_was_freed( +/*===============================*/ + /* out: control block if found in page hash table, + otherwise NULL */ + ulint space, /* in: space id */ + ulint offset); /* in: page number */ +#endif /* UNIV_DEBUG_FILE_ACCESSES */ +/************************************************************************ +Reads the freed_page_clock of a buffer block. */ +UNIV_INLINE +ulint +buf_page_get_freed_page_clock( +/*==========================*/ + /* out: freed_page_clock */ + const buf_page_t* bpage) /* in: block */ + __attribute__((pure)); +/************************************************************************ +Reads the freed_page_clock of a buffer block. */ +UNIV_INLINE +ulint +buf_block_get_freed_page_clock( +/*===========================*/ + /* out: freed_page_clock */ + const buf_block_t* block) /* in: block */ + __attribute__((pure)); + +/************************************************************************ +Recommends a move of a block to the start of the LRU list if there is danger +of dropping from the buffer pool. NOTE: does not reserve the buffer pool +mutex. */ +UNIV_INLINE +ibool +buf_page_peek_if_too_old( +/*=====================*/ + /* out: TRUE if should be made + younger */ + const buf_page_t* bpage); /* in: block to make younger */ +/************************************************************************ +Returns the current state of is_hashed of a page. FALSE if the page is +not in the pool. NOTE that this operation does not fix the page in the +pool if it is found there. */ +UNIV_INTERN +ibool +buf_page_peek_if_search_hashed( +/*===========================*/ + /* out: TRUE if page hash index is built in search + system */ + ulint space, /* in: space id */ + ulint offset);/* in: page number */ +/************************************************************************ +Gets the youngest modification log sequence number for a frame. +Returns zero if not file page or no modification occurred yet. */ +UNIV_INLINE +ib_uint64_t +buf_page_get_newest_modification( +/*=============================*/ + /* out: newest modification to page */ + const buf_page_t* bpage); /* in: block containing the + page frame */ +/************************************************************************ +Increments the modify clock of a frame by 1. The caller must (1) own the +buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock +on the block. */ +UNIV_INLINE +void +buf_block_modify_clock_inc( +/*=======================*/ + buf_block_t* block); /* in: block */ +/************************************************************************ +Returns the value of the modify clock. The caller must have an s-lock +or x-lock on the block. */ +UNIV_INLINE +ib_uint64_t +buf_block_get_modify_clock( +/*=======================*/ + /* out: value */ + buf_block_t* block); /* in: block */ +/************************************************************************ +Calculates a page checksum which is stored to the page when it is written +to a file. Note that we must be careful to calculate the same value +on 32-bit and 64-bit architectures. */ +UNIV_INTERN +ulint +buf_calc_page_new_checksum( +/*=======================*/ + /* out: checksum */ + const byte* page); /* in: buffer page */ +/************************************************************************ +In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only +looked at the first few bytes of the page. This calculates that old +checksum. +NOTE: we must first store the new formula checksum to +FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum +because this takes that field as an input! */ +UNIV_INTERN +ulint +buf_calc_page_old_checksum( +/*=======================*/ + /* out: checksum */ + const byte* page); /* in: buffer page */ +/************************************************************************ +Checks if a page is corrupt. */ +UNIV_INTERN +ibool +buf_page_is_corrupted( +/*==================*/ + /* out: TRUE if corrupted */ + const byte* read_buf, /* in: a database page */ + ulint zip_size); /* in: size of compressed page; + 0 for uncompressed pages */ +/************************************************************************** +Gets the space id, page offset, and byte offset within page of a +pointer pointing to a buffer frame containing a file page. */ +UNIV_INLINE +void +buf_ptr_get_fsp_addr( +/*=================*/ + const void* ptr, /* in: pointer to a buffer frame */ + ulint* space, /* out: space id */ + fil_addr_t* addr); /* out: page offset and byte offset */ +/************************************************************************** +Gets the hash value of a block. This can be used in searches in the +lock hash table. */ +UNIV_INLINE +ulint +buf_block_get_lock_hash_val( +/*========================*/ + /* out: lock hash value */ + const buf_block_t* block) /* in: block */ + __attribute__((pure)); +#ifdef UNIV_DEBUG +/************************************************************************* +Finds a block in the buffer pool that points to a +given compressed page. */ +UNIV_INTERN +buf_block_t* +buf_pool_contains_zip( +/*==================*/ + /* out: buffer block pointing to + the compressed page, or NULL */ + const void* data); /* in: pointer to compressed page */ +#endif /* UNIV_DEBUG */ +#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG +/************************************************************************* +Validates the buffer pool data structure. */ +UNIV_INTERN +ibool +buf_validate(void); +/*==============*/ +#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ +#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG +/************************************************************************* +Prints info of the buffer pool data structure. */ +UNIV_INTERN +void +buf_print(void); +/*============*/ +#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */ +/************************************************************************ +Prints a page to stderr. */ +UNIV_INTERN +void +buf_page_print( +/*===========*/ + const byte* read_buf, /* in: a database page */ + ulint zip_size); /* in: compressed page size, or + 0 for uncompressed pages */ +#ifdef UNIV_DEBUG +/************************************************************************* +Returns the number of latched pages in the buffer pool. */ +UNIV_INTERN +ulint +buf_get_latched_pages_number(void); +/*==============================*/ +#endif /* UNIV_DEBUG */ +/************************************************************************* +Returns the number of pending buf pool ios. */ +UNIV_INTERN +ulint +buf_get_n_pending_ios(void); +/*=======================*/ +/************************************************************************* +Prints info of the buffer i/o. */ +UNIV_INTERN +void +buf_print_io( +/*=========*/ + FILE* file); /* in: file where to print */ +/************************************************************************* +Returns the ratio in percents of modified pages in the buffer pool / +database pages in the buffer pool. */ +UNIV_INTERN +ulint +buf_get_modified_ratio_pct(void); +/*============================*/ +/************************************************************************** +Refreshes the statistics used to print per-second averages. */ +UNIV_INTERN +void +buf_refresh_io_stats(void); +/*======================*/ +/************************************************************************* +Checks that all file pages in the buffer are in a replaceable state. */ +UNIV_INTERN +ibool +buf_all_freed(void); +/*===============*/ +/************************************************************************* +Checks that there currently are no pending i/o-operations for the buffer +pool. */ +UNIV_INTERN +ibool +buf_pool_check_no_pending_io(void); +/*==============================*/ + /* out: TRUE if there is no pending i/o */ +/************************************************************************* +Invalidates the file pages in the buffer pool when an archive recovery is +completed. All the file pages buffered must be in a replaceable state when +this function is called: not latched and not modified. */ +UNIV_INTERN +void +buf_pool_invalidate(void); +/*=====================*/ + +/*======================================================================== +--------------------------- LOWER LEVEL ROUTINES ------------------------- +=========================================================================*/ + +#ifdef UNIV_SYNC_DEBUG +/************************************************************************* +Adds latch level info for the rw-lock protecting the buffer frame. This +should be called in the debug version after a successful latching of a +page if we know the latching order level of the acquired latch. */ +UNIV_INLINE +void +buf_block_dbg_add_level( +/*====================*/ + buf_block_t* block, /* in: buffer page + where we have acquired latch */ + ulint level); /* in: latching order level */ +#else /* UNIV_SYNC_DEBUG */ +# define buf_block_dbg_add_level(block, level) /* nothing */ +#endif /* UNIV_SYNC_DEBUG */ +/************************************************************************* +Gets the state of a block. */ +UNIV_INLINE +enum buf_page_state +buf_page_get_state( +/*===============*/ + /* out: state */ + const buf_page_t* bpage); /* in: pointer to the control block */ +/************************************************************************* +Gets the state of a block. */ +UNIV_INLINE +enum buf_page_state +buf_block_get_state( +/*================*/ + /* out: state */ + const buf_block_t* block) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Sets the state of a block. */ +UNIV_INLINE +void +buf_page_set_state( +/*===============*/ + buf_page_t* bpage, /* in/out: pointer to control block */ + enum buf_page_state state); /* in: state */ +/************************************************************************* +Sets the state of a block. */ +UNIV_INLINE +void +buf_block_set_state( +/*================*/ + buf_block_t* block, /* in/out: pointer to control block */ + enum buf_page_state state); /* in: state */ +/************************************************************************* +Determines if a block is mapped to a tablespace. */ +UNIV_INLINE +ibool +buf_page_in_file( +/*=============*/ + /* out: TRUE if mapped */ + const buf_page_t* bpage) /* in: pointer to control block */ + __attribute__((pure)); +/************************************************************************* +Determines if a block should be on unzip_LRU list. */ +UNIV_INLINE +ibool +buf_page_belongs_to_unzip_LRU( +/*==========================*/ + /* out: TRUE if block belongs + to unzip_LRU */ + const buf_page_t* bpage) /* in: pointer to control block */ + __attribute__((pure)); +/************************************************************************* +Determine the approximate LRU list position of a block. */ +UNIV_INLINE +ulint +buf_page_get_LRU_position( +/*======================*/ + /* out: LRU list position */ + const buf_page_t* bpage) /* in: control block */ + __attribute__((pure)); + +/************************************************************************* +Gets the mutex of a block. */ +UNIV_INLINE +mutex_t* +buf_page_get_mutex( +/*===============*/ + /* out: pointer to mutex + protecting bpage */ + const buf_page_t* bpage) /* in: pointer to control block */ + __attribute__((pure)); + +/************************************************************************* +Get the flush type of a page. */ +UNIV_INLINE +enum buf_flush +buf_page_get_flush_type( +/*====================*/ + /* out: flush type */ + const buf_page_t* bpage) /* in: buffer page */ + __attribute__((pure)); +/************************************************************************* +Set the flush type of a page. */ +UNIV_INLINE +void +buf_page_set_flush_type( +/*====================*/ + buf_page_t* bpage, /* in: buffer page */ + enum buf_flush flush_type); /* in: flush type */ +/************************************************************************* +Map a block to a file page. */ +UNIV_INLINE +void +buf_block_set_file_page( +/*====================*/ + buf_block_t* block, /* in/out: pointer to control block */ + ulint space, /* in: tablespace id */ + ulint page_no);/* in: page number */ +/************************************************************************* +Gets the io_fix state of a block. */ +UNIV_INLINE +enum buf_io_fix +buf_page_get_io_fix( +/*================*/ + /* out: io_fix state */ + const buf_page_t* bpage) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Gets the io_fix state of a block. */ +UNIV_INLINE +enum buf_io_fix +buf_block_get_io_fix( +/*================*/ + /* out: io_fix state */ + const buf_block_t* block) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Sets the io_fix state of a block. */ +UNIV_INLINE +void +buf_page_set_io_fix( +/*================*/ + buf_page_t* bpage, /* in/out: control block */ + enum buf_io_fix io_fix);/* in: io_fix state */ +/************************************************************************* +Sets the io_fix state of a block. */ +UNIV_INLINE +void +buf_block_set_io_fix( +/*=================*/ + buf_block_t* block, /* in/out: control block */ + enum buf_io_fix io_fix);/* in: io_fix state */ + +/************************************************************************ +Determine if a buffer block can be relocated in memory. The block +can be dirty, but it must not be I/O-fixed or bufferfixed. */ +UNIV_INLINE +ibool +buf_page_can_relocate( +/*==================*/ + const buf_page_t* bpage) /* control block being relocated */ + __attribute__((pure)); + +/************************************************************************* +Determine if a block has been flagged old. */ +UNIV_INLINE +ibool +buf_page_is_old( +/*============*/ + /* out: TRUE if old */ + const buf_page_t* bpage) /* in: control block */ + __attribute__((pure)); +/************************************************************************* +Flag a block old. */ +UNIV_INLINE +void +buf_page_set_old( +/*=============*/ + buf_page_t* bpage, /* in/out: control block */ + ibool old); /* in: old */ +/************************************************************************* +Determine if a block has been accessed in the buffer pool. */ +UNIV_INLINE +ibool +buf_page_is_accessed( +/*=================*/ + /* out: TRUE if accessed */ + const buf_page_t* bpage) /* in: control block */ + __attribute__((pure)); +/************************************************************************* +Flag a block accessed. */ +UNIV_INLINE +void +buf_page_set_accessed( +/*==================*/ + buf_page_t* bpage, /* in/out: control block */ + ibool accessed); /* in: accessed */ +/************************************************************************* +Gets the buf_block_t handle of a buffered file block if an uncompressed +page frame exists, or NULL. */ +UNIV_INLINE +buf_block_t* +buf_page_get_block( +/*===============*/ + /* out: control block, or NULL */ + buf_page_t* bpage) /* in: control block, or NULL */ + __attribute__((pure)); +#ifdef UNIV_DEBUG +/************************************************************************* +Gets a pointer to the memory frame of a block. */ +UNIV_INLINE +buf_frame_t* +buf_block_get_frame( +/*================*/ + /* out: pointer to the frame */ + const buf_block_t* block) /* in: pointer to the control block */ + __attribute__((pure)); +#else /* UNIV_DEBUG */ +# define buf_block_get_frame(block) (block)->frame +#endif /* UNIV_DEBUG */ +/************************************************************************* +Gets the space id of a block. */ +UNIV_INLINE +ulint +buf_page_get_space( +/*===============*/ + /* out: space id */ + const buf_page_t* bpage) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Gets the space id of a block. */ +UNIV_INLINE +ulint +buf_block_get_space( +/*================*/ + /* out: space id */ + const buf_block_t* block) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Gets the page number of a block. */ +UNIV_INLINE +ulint +buf_page_get_page_no( +/*=================*/ + /* out: page number */ + const buf_page_t* bpage) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Gets the page number of a block. */ +UNIV_INLINE +ulint +buf_block_get_page_no( +/*==================*/ + /* out: page number */ + const buf_block_t* block) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Gets the compressed page size of a block. */ +UNIV_INLINE +ulint +buf_page_get_zip_size( +/*==================*/ + /* out: compressed page size, or 0 */ + const buf_page_t* bpage) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Gets the compressed page size of a block. */ +UNIV_INLINE +ulint +buf_block_get_zip_size( +/*===================*/ + /* out: compressed page size, or 0 */ + const buf_block_t* block) /* in: pointer to the control block */ + __attribute__((pure)); +/************************************************************************* +Gets the compressed page descriptor corresponding to an uncompressed page +if applicable. */ +#define buf_block_get_page_zip(block) \ + (UNIV_LIKELY_NULL((block)->page.zip.data) ? &(block)->page.zip : NULL) +/*********************************************************************** +Gets the block to whose frame the pointer is pointing to. */ +UNIV_INTERN +buf_block_t* +buf_block_align( +/*============*/ + /* out: pointer to block, never NULL */ + const byte* ptr); /* in: pointer to a frame */ +#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG +/************************************************************************* +Gets the compressed page descriptor corresponding to an uncompressed page +if applicable. */ +UNIV_INLINE +const page_zip_des_t* +buf_frame_get_page_zip( +/*===================*/ + /* out: compressed page descriptor, or NULL */ + const byte* ptr); /* in: pointer to the page */ +#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */ +/************************************************************************ +This function is used to get info if there is an io operation +going on on a buffer page. */ +UNIV_INLINE +ibool +buf_page_io_query( +/*==============*/ + /* out: TRUE if io going on */ + buf_page_t* bpage); /* in: pool block, must be bufferfixed */ +/************************************************************************ +Function which inits a page for read to the buffer buf_pool. If the page is +(1) already in buf_pool, or +(2) if we specify to read only ibuf pages and the page is not an ibuf page, or +(3) if the space is deleted or being deleted, +then this function does nothing. +Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock +on the buffer frame. The io-handler must take care that the flag is cleared +and the lock released later. */ +UNIV_INTERN +buf_page_t* +buf_page_init_for_read( +/*===================*/ + /* out: pointer to the block or NULL */ + ulint* err, /* out: DB_SUCCESS or DB_TABLESPACE_DELETED */ + ulint mode, /* in: BUF_READ_IBUF_PAGES_ONLY, ... */ + ulint space, /* in: space id */ + ulint zip_size,/* in: compressed page size, or 0 */ + ibool unzip, /* in: TRUE=request uncompressed page */ + ib_int64_t tablespace_version,/* in: prevents reading from a wrong + version of the tablespace in case we have done + DISCARD + IMPORT */ + ulint offset);/* in: page number */ +/************************************************************************ +Completes an asynchronous read or write request of a file page to or from +the buffer pool. */ +UNIV_INTERN +void +buf_page_io_complete( +/*=================*/ + buf_page_t* bpage); /* in: pointer to the block in question */ +/************************************************************************ +Calculates a folded value of a file page address to use in the page hash +table. */ +UNIV_INLINE +ulint +buf_page_address_fold( +/*==================*/ + /* out: the folded value */ + ulint space, /* in: space id */ + ulint offset) /* in: offset of the page within space */ + __attribute__((const)); +/********************************************************************** +Returns the control block of a file page, NULL if not found. */ +UNIV_INLINE +buf_page_t* +buf_page_hash_get( +/*==============*/ + /* out: block, NULL if not found */ + ulint space, /* in: space id */ + ulint offset);/* in: offset of the page within space */ +/********************************************************************** +Returns the control block of a file page, NULL if not found +or an uncompressed page frame does not exist. */ +UNIV_INLINE +buf_block_t* +buf_block_hash_get( +/*===============*/ + /* out: block, NULL if not found */ + ulint space, /* in: space id */ + ulint offset);/* in: offset of the page within space */ +/*********************************************************************** +Increments the pool clock by one and returns its new value. Remember that +in the 32 bit version the clock wraps around at 4 billion! */ +UNIV_INLINE +ulint +buf_pool_clock_tic(void); +/*====================*/ + /* out: new clock value */ +/************************************************************************* +Gets the current length of the free list of buffer blocks. */ +UNIV_INTERN +ulint +buf_get_free_list_len(void); +/*=======================*/ + + + +/* The common buffer control block structure +for compressed and uncompressed frames */ + +struct buf_page_struct{ + /* None of the following bit-fields must be modified without + holding buf_page_get_mutex() [block->mutex or buf_pool_zip_mutex], + since they can be stored in the same machine word. Some of them are + additionally protected by buf_pool_mutex. */ + + unsigned space:32; /* tablespace id; also protected + by buf_pool_mutex. */ + unsigned offset:32; /* page number; also protected + by buf_pool_mutex. */ + + unsigned state:3; /* state of the control block + (@see enum buf_page_state); also + protected by buf_pool_mutex. + State transitions from + BUF_BLOCK_READY_FOR_USE to + BUF_BLOCK_MEMORY need not be + protected by buf_page_get_mutex(). */ + unsigned flush_type:2; /* if this block is currently being + flushed to disk, this tells the + flush_type (@see enum buf_flush) */ + unsigned accessed:1; /* TRUE if the page has been accessed + while in the buffer pool: read-ahead + may read in pages which have not been + accessed yet; a thread is allowed to + read this for heuristic purposes + without holding any mutex or latch */ + unsigned io_fix:2; /* type of pending I/O operation + (@see enum buf_io_fix); also + protected by buf_pool_mutex */ + unsigned buf_fix_count:24;/* count of how manyfold this block + is currently bufferfixed */ + + page_zip_des_t zip; /* compressed page; zip.data + (but not the data it points to) is + also protected by buf_pool_mutex */ + buf_page_t* hash; /* node used in chaining to + buf_pool->page_hash or + buf_pool->zip_hash */ +#ifdef UNIV_DEBUG + ibool in_page_hash; /* TRUE if in buf_pool->page_hash */ + ibool in_zip_hash; /* TRUE if in buf_pool->zip_hash */ +#endif /* UNIV_DEBUG */ + + /* 2. Page flushing fields; protected by buf_pool_mutex */ + + UT_LIST_NODE_T(buf_page_t) list; + /* based on state, this is a list + node in one of the following lists + in buf_pool: + + BUF_BLOCK_NOT_USED: free + BUF_BLOCK_FILE_PAGE: flush_list + BUF_BLOCK_ZIP_DIRTY: flush_list + BUF_BLOCK_ZIP_PAGE: zip_clean + BUF_BLOCK_ZIP_FREE: zip_free[] */ +#ifdef UNIV_DEBUG + ibool in_flush_list; /* TRUE if in buf_pool->flush_list; + when buf_pool_mutex is free, the + following should hold: in_flush_list + == (state == BUF_BLOCK_FILE_PAGE + || state == BUF_BLOCK_ZIP_DIRTY) */ + ibool in_free_list; /* TRUE if in buf_pool->free; when + buf_pool_mutex is free, the following + should hold: in_free_list + == (state == BUF_BLOCK_NOT_USED) */ +#endif /* UNIV_DEBUG */ + ib_uint64_t newest_modification; + /* log sequence number of the youngest + modification to this block, zero if + not modified */ + ib_uint64_t oldest_modification; + /* log sequence number of the START of + the log entry written of the oldest + modification to this block which has + not yet been flushed on disk; zero if + all modifications are on disk */ + + /* 3. LRU replacement algorithm fields; protected by + buf_pool_mutex only (not buf_pool_zip_mutex or block->mutex) */ + + UT_LIST_NODE_T(buf_page_t) LRU; + /* node of the LRU list */ +//#ifdef UNIV_DEBUG + ibool in_LRU_list; /* TRUE if the page is in the LRU list; + used in debugging */ +//#endif /* UNIV_DEBUG */ + unsigned old:1; /* TRUE if the block is in the old + blocks in the LRU list */ + unsigned LRU_position:31;/* value which monotonically decreases + (or may stay constant if old==TRUE) + toward the end of the LRU list, if + buf_pool->ulint_clock has not wrapped + around: NOTE that this value can only + be used in heuristic algorithms, + because of the possibility of a + wrap-around! */ + unsigned freed_page_clock:32;/* the value of + buf_pool->freed_page_clock when this + block was the last time put to the + head of the LRU list; a thread is + allowed to read this for heuristic + purposes without holding any mutex or + latch */ +#ifdef UNIV_DEBUG_FILE_ACCESSES + ibool file_page_was_freed; + /* this is set to TRUE when fsp + frees a page in buffer pool */ +#endif /* UNIV_DEBUG_FILE_ACCESSES */ +}; + +/* The buffer control block structure */ + +struct buf_block_struct{ + + /* 1. General fields */ + + buf_page_t page; /* page information; this must + be the first field, so that + buf_pool->page_hash can point + to buf_page_t or buf_block_t */ + UT_LIST_NODE_T(buf_block_t) unzip_LRU; + /* node of the decompressed LRU list; + a block is in the unzip_LRU list + if page.state == BUF_BLOCK_FILE_PAGE + and page.zip.data != NULL */ +//#ifdef UNIV_DEBUG + ibool in_unzip_LRU_list;/* TRUE if the page is in the + decompressed LRU list; + used in debugging */ +//#endif /* UNIV_DEBUG */ + byte* frame; /* pointer to buffer frame which + is of size UNIV_PAGE_SIZE, and + aligned to an address divisible by + UNIV_PAGE_SIZE */ + mutex_t mutex; /* mutex protecting this block: + state (also protected by the buffer + pool mutex), io_fix, buf_fix_count, + and accessed; we introduce this new + mutex in InnoDB-5.1 to relieve + contention on the buffer pool mutex */ + rw_lock_t lock; /* read-write lock of the buffer + frame */ + unsigned lock_hash_val:32;/* hashed value of the page address + in the record lock hash table */ + unsigned check_index_page_at_flush:1; + /* TRUE if we know that this is + an index page, and want the database + to check its consistency before flush; + note that there may be pages in the + buffer pool which are index pages, + but this flag is not set because + we do not keep track of all pages */ + + /* 2. Optimistic search field */ + + ib_uint64_t modify_clock; /* this clock is incremented every + time a pointer to a record on the + page may become obsolete; this is + used in the optimistic cursor + positioning: if the modify clock has + not changed, we know that the pointer + is still valid; this field may be + changed if the thread (1) owns the + pool mutex and the page is not + bufferfixed, or (2) the thread has an + x-latch on the block */ + + /* 3. Hash search fields: NOTE that the first 4 fields are NOT + protected by any semaphore! */ + + ulint n_hash_helps; /* counter which controls building + of a new hash index for the page */ + ulint n_fields; /* recommended prefix length for hash + search: number of full fields */ + ulint n_bytes; /* recommended prefix: number of bytes + in an incomplete field */ + ibool left_side; /* TRUE or FALSE, depending on + whether the leftmost record of several + records with the same prefix should be + indexed in the hash index */ + + /* These 6 fields may only be modified when we have + an x-latch on btr_search_latch AND + a) we are holding an s-latch or x-latch on block->lock or + b) we know that block->buf_fix_count == 0. + + An exception to this is when we init or create a page + in the buffer pool in buf0buf.c. */ + +#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG + ulint n_pointers; /* used in debugging: the number of + pointers in the adaptive hash index + pointing to this frame */ +#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ + unsigned is_hashed:1; /* TRUE if hash index has already been + built on this page; note that it does + not guarantee that the index is + complete, though: there may have been + hash collisions, record deletions, + etc. */ + unsigned curr_n_fields:10;/* prefix length for hash indexing: + number of full fields */ + unsigned curr_n_bytes:15;/* number of bytes in hash indexing */ + unsigned curr_left_side:1;/* TRUE or FALSE in hash indexing */ + dict_index_t* index; /* Index for which the adaptive + hash index has been created. */ + /* 4. Debug fields */ +#ifdef UNIV_SYNC_DEBUG + rw_lock_t debug_latch; /* in the debug version, each thread + which bufferfixes the block acquires + an s-latch here; so we can use the + debug utilities in sync0rw */ +#endif +}; + +/* Check if a buf_block_t object is in a valid state. */ +#define buf_block_state_valid(block) \ +(buf_block_get_state(block) >= BUF_BLOCK_NOT_USED \ + && (buf_block_get_state(block) <= BUF_BLOCK_REMOVE_HASH)) + +/************************************************************************** +Compute the hash fold value for blocks in buf_pool->zip_hash. */ +#define BUF_POOL_ZIP_FOLD_PTR(ptr) ((ulint) (ptr) / UNIV_PAGE_SIZE) +#define BUF_POOL_ZIP_FOLD(b) BUF_POOL_ZIP_FOLD_PTR((b)->frame) +#define BUF_POOL_ZIP_FOLD_BPAGE(b) BUF_POOL_ZIP_FOLD((buf_block_t*) (b)) + +/* The buffer pool structure. NOTE! The definition appears here only for +other modules of this directory (buf) to see it. Do not use from outside! */ + +struct buf_pool_struct{ + + /* 1. General fields */ + + ulint n_chunks; /* number of buffer pool chunks */ + buf_chunk_t* chunks; /* buffer pool chunks */ + ulint curr_size; /* current pool size in pages */ + hash_table_t* page_hash; /* hash table of buf_page_t or + buf_block_t file pages, + buf_page_in_file() == TRUE, + indexed by (space_id, offset) */ + hash_table_t* zip_hash; /* hash table of buf_block_t blocks + whose frames are allocated to the + zip buddy system, + indexed by block->frame */ + ulint n_pend_reads; /* number of pending read operations */ + ulint n_pend_unzip; /* number of pending decompressions */ + + time_t last_printout_time; /* when buf_print was last time + called */ + ulint n_pages_read; /* number read operations */ + ulint n_pages_written;/* number write operations */ + ulint n_pages_created;/* number of pages created in the pool + with no read */ + ulint n_page_gets; /* number of page gets performed; + also successful searches through + the adaptive hash index are + counted as page gets; this field + is NOT protected by the buffer + pool mutex */ + ulint n_page_gets_old;/* n_page_gets when buf_print was + last time called: used to calculate + hit rate */ + ulint n_pages_read_old;/* n_pages_read when buf_print was + last time called */ + ulint n_pages_written_old;/* number write operations */ + ulint n_pages_created_old;/* number of pages created in + the pool with no read */ + /* 2. Page flushing algorithm fields */ + + UT_LIST_BASE_NODE_T(buf_page_t) flush_list; + /* base node of the modified block + list */ + ibool init_flush[BUF_FLUSH_N_TYPES]; + /* this is TRUE when a flush of the + given type is being initialized */ + ulint n_flush[BUF_FLUSH_N_TYPES]; + /* this is the number of pending + writes in the given flush type */ + os_event_t no_flush[BUF_FLUSH_N_TYPES]; + /* this is in the set state when there + is no flush batch of the given type + running */ + ulint ulint_clock; /* a sequence number used to count + time. NOTE! This counter wraps + around at 4 billion (if ulint == + 32 bits)! */ + ulint freed_page_clock;/* a sequence number used to count the + number of buffer blocks removed from + the end of the LRU list; NOTE that + this counter may wrap around at 4 + billion! A thread is allowed to + read this for heuristic purposes + without holding any mutex or latch */ + ulint LRU_flush_ended;/* when an LRU flush ends for a page, + this is incremented by one; this is + set to zero when a buffer block is + allocated */ + + /* 3. LRU replacement algorithm fields */ + + UT_LIST_BASE_NODE_T(buf_page_t) free; + /* base node of the free block list */ + UT_LIST_BASE_NODE_T(buf_page_t) LRU; + /* base node of the LRU list */ + buf_page_t* LRU_old; /* pointer to the about 3/8 oldest + blocks in the LRU list; NULL if LRU + length less than BUF_LRU_OLD_MIN_LEN; + NOTE: when LRU_old != NULL, its length + should always equal LRU_old_len */ + ulint LRU_old_len; /* length of the LRU list from + the block to which LRU_old points + onward, including that block; + see buf0lru.c for the restrictions + on this value; not defined if + LRU_old == NULL; + NOTE: LRU_old_len must be adjusted + whenever LRU_old shrinks or grows! */ + + UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU; + /* base node of the unzip_LRU list */ + + /* 4. Fields for the buddy allocator of compressed pages */ + UT_LIST_BASE_NODE_T(buf_page_t) zip_clean; + /* unmodified compressed pages */ + UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES]; + /* buddy free lists */ +#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE +# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE" +#endif +#if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE +# error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE" +#endif +}; + +/* mutex protecting the buffer pool struct and control blocks, except the +read-write lock in them */ +extern mutex_t buf_pool_mutex; +extern mutex_t LRU_list_mutex; +extern mutex_t flush_list_mutex; +extern rw_lock_t page_hash_latch; +extern mutex_t free_list_mutex; +extern mutex_t zip_free_mutex; +extern mutex_t zip_hash_mutex; +/* mutex protecting the control blocks of compressed-only pages +(of type buf_page_t, not buf_block_t) */ +extern mutex_t buf_pool_zip_mutex; + +/* Accessors for buf_pool_mutex. Use these instead of accessing +buf_pool_mutex directly. */ + +/* Test if buf_pool_mutex is owned. */ +#define buf_pool_mutex_own() mutex_own(&buf_pool_mutex) +/* Acquire the buffer pool mutex. */ +#define buf_pool_mutex_enter() do { \ + ut_ad(!mutex_own(&buf_pool_zip_mutex)); \ + mutex_enter(&buf_pool_mutex); \ +} while (0) + +#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG +/** Flag to forbid the release of the buffer pool mutex. +Protected by buf_pool_mutex. */ +extern ulint buf_pool_mutex_exit_forbidden; +/* Forbid the release of the buffer pool mutex. */ +# define buf_pool_mutex_exit_forbid() do { \ + ut_ad(buf_pool_mutex_own()); \ + buf_pool_mutex_exit_forbidden++; \ +} while (0) +/* Allow the release of the buffer pool mutex. */ +# define buf_pool_mutex_exit_allow() do { \ + ut_ad(buf_pool_mutex_own()); \ + ut_a(buf_pool_mutex_exit_forbidden); \ + buf_pool_mutex_exit_forbidden--; \ +} while (0) +/* Release the buffer pool mutex. */ +# define buf_pool_mutex_exit() do { \ + ut_a(!buf_pool_mutex_exit_forbidden); \ + mutex_exit(&buf_pool_mutex); \ +} while (0) +#else +/* Forbid the release of the buffer pool mutex. */ +# define buf_pool_mutex_exit_forbid() ((void) 0) +/* Allow the release of the buffer pool mutex. */ +# define buf_pool_mutex_exit_allow() ((void) 0) +/* Release the buffer pool mutex. */ +# define buf_pool_mutex_exit() mutex_exit(&buf_pool_mutex) +#endif + +/************************************************************************ +Let us list the consistency conditions for different control block states. + +NOT_USED: is in free list, not in LRU list, not in flush list, nor + page hash table +READY_FOR_USE: is not in free list, LRU list, or flush list, nor page + hash table +MEMORY: is not in free list, LRU list, or flush list, nor page + hash table +FILE_PAGE: space and offset are defined, is in page hash table + if io_fix == BUF_IO_WRITE, + pool: no_flush[flush_type] is in reset state, + pool: n_flush[flush_type] > 0 + + (1) if buf_fix_count == 0, then + is in LRU list, not in free list + is in flush list, + if and only if oldest_modification > 0 + is x-locked, + if and only if io_fix == BUF_IO_READ + is s-locked, + if and only if io_fix == BUF_IO_WRITE + + (2) if buf_fix_count > 0, then + is not in LRU list, not in free list + is in flush list, + if and only if oldest_modification > 0 + if io_fix == BUF_IO_READ, + is x-locked + if io_fix == BUF_IO_WRITE, + is s-locked + +State transitions: + +NOT_USED => READY_FOR_USE +READY_FOR_USE => MEMORY +READY_FOR_USE => FILE_PAGE +MEMORY => NOT_USED +FILE_PAGE => NOT_USED NOTE: This transition is allowed if and only if + (1) buf_fix_count == 0, + (2) oldest_modification == 0, and + (3) io_fix == 0. +*/ + +#ifndef UNIV_NONINL +#include "buf0buf.ic" +#endif + +#endif |