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/buf0flu.h 29 The database buffer pool flush algorithm 30 31 Created 11/5/1995 Heikki Tuuri 32 *******************************************************/ 33 34 #ifndef buf0flu_h 35 #define buf0flu_h 36 37 #include "univ.i" 38 #include "ut0byte.h" 39 #include "log0log.h" 40 #ifndef UNIV_HOTBACKUP 41 #include "mtr0types.h" 42 #include "buf0types.h" 43 44 /** Flag indicating if the page_cleaner is in active state. */ 45 extern ibool buf_page_cleaner_is_active; 46 47 /** Flag indicating if the lru_manager is in active state. */ 48 extern bool buf_lru_manager_is_active; 49 50 /********************************************************************//** 51 Remove a block from the flush list of modified blocks. */ 52 UNIV_INTERN 53 void 54 buf_flush_remove( 55 /*=============*/ 56 buf_page_t* bpage); /*!< in: pointer to the block in question */ 57 /*******************************************************************//** 58 Relocates a buffer control block on the flush_list. 59 Note that it is assumed that the contents of bpage has already been 60 copied to dpage. */ 61 UNIV_INTERN 62 void 63 buf_flush_relocate_on_flush_list( 64 /*=============================*/ 65 buf_page_t* bpage, /*!< in/out: control block being moved */ 66 buf_page_t* dpage); /*!< in/out: destination block */ 67 /********************************************************************//** 68 Updates the flush system data structures when a write is completed. */ 69 UNIV_INTERN 70 void 71 buf_flush_write_complete( 72 /*=====================*/ 73 buf_page_t* bpage); /*!< in: pointer to the block in question */ 74 #endif /* !UNIV_HOTBACKUP */ 75 /********************************************************************//** 76 Initializes a page for writing to the tablespace. */ 77 UNIV_INTERN 78 void 79 buf_flush_init_for_writing( 80 /*=======================*/ 81 byte* page, /*!< in/out: page */ 82 void* page_zip_, /*!< in/out: compressed page, or NULL */ 83 lsn_t newest_lsn); /*!< in: newest modification lsn 84 to the page */ 85 #ifndef UNIV_HOTBACKUP 86 # if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG 87 /********************************************************************//** 88 Writes a flushable page asynchronously from the buffer pool to a file. 89 NOTE: block and LRU list mutexes must be held upon entering this function, and 90 they will be released by this function after flushing. This is loosely based on 91 buf_flush_batch() and buf_flush_page(). 92 @return TRUE if the page was flushed and the mutexes released */ 93 UNIV_INTERN 94 ibool 95 buf_flush_page_try( 96 /*===============*/ 97 buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */ 98 buf_block_t* block) /*!< in/out: buffer control block */ 99 MY_ATTRIBUTE((nonnull, warn_unused_result)); 100 # endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ 101 /*******************************************************************//** 102 This utility flushes dirty blocks from the end of the flush list of 103 all buffer pool instances. 104 NOTE: The calling thread is not allowed to own any latches on pages! 105 @return true if a batch was queued successfully for each buffer pool 106 instance. false if another batch of same type was already running in 107 at least one of the buffer pool instance */ 108 UNIV_INTERN 109 bool 110 buf_flush_list( 111 /*===========*/ 112 ulint min_n, /*!< in: wished minimum mumber of blocks 113 flushed (it is not guaranteed that the 114 actual number is that big, though) */ 115 lsn_t lsn_limit, /*!< in the case BUF_FLUSH_LIST all 116 blocks whose oldest_modification is 117 smaller than this should be flushed 118 (if their number does not exceed 119 min_n), otherwise ignored */ 120 ulint* n_processed); /*!< out: the number of pages 121 which were processed is passed 122 back to caller. Ignored if NULL */ 123 /******************************************************************//** 124 This function picks up a single dirty page from the tail of the LRU 125 list, flushes it, removes it from page_hash and LRU list and puts 126 it on the free list. It is called from user threads when they are 127 unable to find a replacable page at the tail of the LRU list i.e.: 128 when the background LRU flushing in the page_cleaner thread is not 129 fast enough to keep pace with the workload. 130 @return TRUE if success. */ 131 UNIV_INTERN 132 ibool 133 buf_flush_single_page_from_LRU( 134 /*===========================*/ 135 buf_pool_t* buf_pool); /*!< in/out: buffer pool instance */ 136 /******************************************************************//** 137 Waits until a flush batch of the given type ends */ 138 UNIV_INTERN 139 void 140 buf_flush_wait_batch_end( 141 /*=====================*/ 142 buf_pool_t* buf_pool, /*!< in: buffer pool instance */ 143 buf_flush_t type); /*!< in: BUF_FLUSH_LRU 144 or BUF_FLUSH_LIST */ 145 /******************************************************************//** 146 Waits until a flush batch of the given type ends. This is called by 147 a thread that only wants to wait for a flush to end but doesn't do 148 any flushing itself. */ 149 UNIV_INTERN 150 void 151 buf_flush_wait_batch_end_wait_only( 152 /*===============================*/ 153 buf_pool_t* buf_pool, /*!< in: buffer pool instance */ 154 buf_flush_t type); /*!< in: BUF_FLUSH_LRU 155 or BUF_FLUSH_LIST */ 156 /********************************************************************//** 157 This function should be called at a mini-transaction commit, if a page was 158 modified in it. Puts the block to the list of modified blocks, if it not 159 already in it. */ 160 UNIV_INLINE 161 void 162 buf_flush_note_modification( 163 /*========================*/ 164 buf_block_t* block, /*!< in: block which is modified */ 165 mtr_t* mtr); /*!< in: mtr */ 166 /********************************************************************//** 167 This function should be called when recovery has modified a buffer page. */ 168 UNIV_INLINE 169 void 170 buf_flush_recv_note_modification( 171 /*=============================*/ 172 buf_block_t* block, /*!< in: block which is modified */ 173 lsn_t start_lsn, /*!< in: start lsn of the first mtr in a 174 set of mtr's */ 175 lsn_t end_lsn); /*!< in: end lsn of the last mtr in the 176 set of mtr's */ 177 /********************************************************************//** 178 Returns TRUE if the file page block is immediately suitable for replacement, 179 i.e., transition FILE_PAGE => NOT_USED allowed. 180 @return TRUE if can replace immediately */ 181 UNIV_INTERN 182 ibool 183 buf_flush_ready_for_replace( 184 /*========================*/ 185 buf_page_t* bpage); /*!< in: buffer control block, must be 186 buf_page_in_file(bpage) and in the LRU list */ 187 /******************************************************************//** 188 page_cleaner thread tasked with flushing dirty pages from the buffer 189 pool flush lists. As of now we'll have only one instance of this thread. 190 @return a dummy parameter */ 191 extern "C" UNIV_INTERN 192 os_thread_ret_t 193 DECLARE_THREAD(buf_flush_page_cleaner_thread)( 194 /*==========================================*/ 195 void* arg); /*!< in: a dummy parameter required by 196 os_thread_create */ 197 /******************************************************************//** 198 lru_manager thread tasked with performing LRU flushes and evictions to refill 199 the buffer pool free lists. As of now we'll have only one instance of this 200 thread. 201 @return a dummy parameter */ 202 extern "C" UNIV_INTERN 203 os_thread_ret_t 204 DECLARE_THREAD(buf_flush_lru_manager_thread)( 205 /*=========================================*/ 206 void* arg); /*!< in: a dummy parameter required by 207 os_thread_create */ 208 /*********************************************************************//** 209 Clears up tail of the LRU lists: 210 * Put replaceable pages at the tail of LRU to the free list 211 * Flush dirty pages at the tail of LRU to the disk 212 The depth to which we scan each buffer pool is controlled by dynamic 213 config parameter innodb_LRU_scan_depth. 214 @return number of pages flushed */ 215 UNIV_INTERN 216 ulint 217 buf_flush_LRU_tail(void); 218 /*====================*/ 219 /*********************************************************************//** 220 Wait for any possible LRU flushes that are in progress to end. */ 221 UNIV_INTERN 222 void 223 buf_flush_wait_LRU_batch_end(void); 224 /*==============================*/ 225 226 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG 227 /******************************************************************//** 228 Validates the flush list. 229 @return TRUE if ok */ 230 UNIV_INTERN 231 ibool 232 buf_flush_validate( 233 /*===============*/ 234 buf_pool_t* buf_pool); 235 #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ 236 237 /********************************************************************//** 238 Initialize the red-black tree to speed up insertions into the flush_list 239 during recovery process. Should be called at the start of recovery 240 process before any page has been read/written. */ 241 UNIV_INTERN 242 void 243 buf_flush_init_flush_rbt(void); 244 /*==========================*/ 245 246 /********************************************************************//** 247 Frees up the red-black tree. */ 248 UNIV_INTERN 249 void 250 buf_flush_free_flush_rbt(void); 251 /*==========================*/ 252 253 /********************************************************************//** 254 Writes a flushable page asynchronously from the buffer pool to a file. 255 NOTE: in simulated aio we must call 256 os_aio_simulated_wake_handler_threads after we have posted a batch of 257 writes! NOTE: buf_page_get_mutex(bpage) must be held upon entering this 258 function, and they will be released by this function if it returns true. 259 LRU_list_mutex must be held iff performing a single page flush and will be 260 released by the function if it returns true. 261 @return TRUE if the page was flushed */ 262 UNIV_INTERN 263 bool 264 buf_flush_page( 265 /*===========*/ 266 buf_pool_t* buf_pool, /*!< in: buffer pool instance */ 267 buf_page_t* bpage, /*!< in: buffer control block */ 268 buf_flush_t flush_type, /*!< in: type of flush */ 269 bool sync); /*!< in: true if sync IO request */ 270 /********************************************************************//** 271 Returns true if the block is modified and ready for flushing. 272 @return true if can flush immediately */ 273 UNIV_INTERN 274 bool 275 buf_flush_ready_for_flush( 276 /*======================*/ 277 buf_page_t* bpage, /*!< in: buffer control block, must be 278 buf_page_in_file(bpage) */ 279 buf_flush_t flush_type)/*!< in: type of flush */ 280 MY_ATTRIBUTE((warn_unused_result)); 281 282 #ifdef UNIV_DEBUG 283 /******************************************************************//** 284 Check if there are any dirty pages that belong to a space id in the flush 285 list in a particular buffer pool. 286 @return number of dirty pages present in a single buffer pool */ 287 UNIV_INTERN 288 ulint 289 buf_pool_get_dirty_pages_count( 290 /*===========================*/ 291 buf_pool_t* buf_pool, /*!< in: buffer pool */ 292 ulint id); /*!< in: space id to check */ 293 /******************************************************************//** 294 Check if there are any dirty pages that belong to a space id in the flush list. 295 @return count of dirty pages present in all the buffer pools */ 296 UNIV_INTERN 297 ulint 298 buf_flush_get_dirty_pages_count( 299 /*============================*/ 300 ulint id); /*!< in: space id to check */ 301 #endif /* UNIV_DEBUG */ 302 303 #endif /* !UNIV_HOTBACKUP */ 304 305 /******************************************************************//** 306 Check if a flush list flush is in progress for any buffer pool instance, or if 307 all the instances are clean, for heuristic purposes. 308 @return true if flush list flush is in progress or buffer pool is clean */ 309 UNIV_INLINE 310 bool 311 buf_flush_flush_list_in_progress(void) 312 /*==================================*/ 313 MY_ATTRIBUTE((warn_unused_result)); 314 315 /** If LRU list of a buf_pool is less than this size then LRU eviction 316 should not happen. This is because when we do LRU flushing we also put 317 the blocks on free list. If LRU list is very small then we can end up 318 in thrashing. */ 319 #define BUF_LRU_MIN_LEN 256 320 321 #ifndef UNIV_NONINL 322 #include "buf0flu.ic" 323 #endif 324 325 #endif 326