1/***************************************************************************** 2 3Copyright (c) 1995, 2009, Oracle and/or its affiliates. All Rights Reserved. 4 5This program is free software; you can redistribute it and/or modify 6it under the terms of the GNU General Public License, version 2.0, 7as published by the Free Software Foundation. 8 9This program is also distributed with certain software (including 10but not limited to OpenSSL) that is licensed under separate terms, 11as designated in a particular file or component or in included license 12documentation. The authors of MySQL hereby grant you an additional 13permission to link the program and your derivative works with the 14separately licensed software that they have included with MySQL. 15 16This program is distributed in the hope that it will be useful, 17but WITHOUT ANY WARRANTY; without even the implied warranty of 18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19GNU General Public License, version 2.0, for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25*****************************************************************************/ 26 27/**************************************************//** 28@file include/buf0flu.ic 29The database buffer pool flush algorithm 30 31Created 11/5/1995 Heikki Tuuri 32*******************************************************/ 33 34#ifndef UNIV_HOTBACKUP 35#include "buf0buf.h" 36#include "mtr0mtr.h" 37#include "srv0srv.h" 38 39/********************************************************************//** 40Inserts a modified block into the flush list. */ 41UNIV_INTERN 42void 43buf_flush_insert_into_flush_list( 44/*=============================*/ 45 buf_pool_t* buf_pool, /*!< buffer pool instance */ 46 buf_block_t* block, /*!< in/out: block which is modified */ 47 lsn_t lsn); /*!< in: oldest modification */ 48/********************************************************************//** 49Inserts a modified block into the flush list in the right sorted position. 50This function is used by recovery, because there the modifications do not 51necessarily come in the order of lsn's. */ 52UNIV_INTERN 53void 54buf_flush_insert_sorted_into_flush_list( 55/*====================================*/ 56 buf_pool_t* buf_pool, /*!< buffer pool instance */ 57 buf_block_t* block, /*!< in/out: block which is modified */ 58 lsn_t lsn); /*!< in: oldest modification */ 59 60/********************************************************************//** 61This function should be called at a mini-transaction commit, if a page was 62modified in it. Puts the block to the list of modified blocks, if it is not 63already in it. */ 64UNIV_INLINE 65void 66buf_flush_note_modification( 67/*========================*/ 68 buf_block_t* block, /*!< in: block which is modified */ 69 mtr_t* mtr) /*!< in: mtr */ 70{ 71 buf_pool_t* buf_pool = buf_pool_from_block(block); 72 73 ut_ad(!srv_read_only_mode); 74 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); 75 ut_ad(block->page.buf_fix_count > 0); 76#ifdef UNIV_SYNC_DEBUG 77 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); 78#endif /* UNIV_SYNC_DEBUG */ 79 80 ut_ad(!buf_flush_list_mutex_own(buf_pool)); 81 ut_ad(!mtr->made_dirty || log_flush_order_mutex_own()); 82 83 ut_ad(mtr->start_lsn != 0); 84 ut_ad(mtr->modifications); 85 86 mutex_enter(&block->mutex); 87 ut_ad(block->page.newest_modification <= mtr->end_lsn); 88 89 block->page.newest_modification = mtr->end_lsn; 90 91 if (!block->page.oldest_modification) { 92 ut_a(mtr->made_dirty); 93 ut_ad(log_flush_order_mutex_own()); 94 buf_flush_insert_into_flush_list( 95 buf_pool, block, mtr->start_lsn); 96 } else { 97 ut_ad(block->page.oldest_modification <= mtr->start_lsn); 98 } 99 100 mutex_exit(&block->mutex); 101 102 srv_stats.buf_pool_write_requests.inc(); 103} 104 105/********************************************************************//** 106This function should be called when recovery has modified a buffer page. */ 107UNIV_INLINE 108void 109buf_flush_recv_note_modification( 110/*=============================*/ 111 buf_block_t* block, /*!< in: block which is modified */ 112 lsn_t start_lsn, /*!< in: start lsn of the first mtr in a 113 set of mtr's */ 114 lsn_t end_lsn) /*!< in: end lsn of the last mtr in the 115 set of mtr's */ 116{ 117 buf_pool_t* buf_pool = buf_pool_from_block(block); 118 119 ut_ad(!srv_read_only_mode); 120 ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE); 121 ut_ad(block->page.buf_fix_count > 0); 122#ifdef UNIV_SYNC_DEBUG 123 ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX)); 124#endif /* UNIV_SYNC_DEBUG */ 125 126 ut_ad(!buf_flush_list_mutex_own(buf_pool)); 127 ut_ad(log_flush_order_mutex_own()); 128 129 ut_ad(start_lsn != 0); 130 ut_ad(block->page.newest_modification <= end_lsn); 131 132 mutex_enter(&block->mutex); 133 block->page.newest_modification = end_lsn; 134 135 if (!block->page.oldest_modification) { 136 buf_flush_insert_sorted_into_flush_list( 137 buf_pool, block, start_lsn); 138 } else { 139 ut_ad(block->page.oldest_modification <= start_lsn); 140 } 141 142 mutex_exit(&block->mutex); 143 144} 145#endif /* !UNIV_HOTBACKUP */ 146 147/******************************************************************//** 148Check if a flush list flush is in progress for any buffer pool instance, or if 149all the instances are clean, for heuristic purposes. 150@return true if flush list flush is in progress or buffer pool is clean */ 151UNIV_INLINE 152bool 153buf_flush_flush_list_in_progress(void) 154/*==================================*/ 155{ 156 bool all_clean = true; 157 158 for (ulint i = 0; i < srv_buf_pool_instances; i++) { 159 160 const buf_pool_t* buf_pool = buf_pool_from_array(i); 161 if (buf_pool->init_flush[BUF_FLUSH_LIST] 162 || buf_pool->n_flush[BUF_FLUSH_LIST]) { 163 164 return(true); 165 } 166 167 if (all_clean) { 168 169 all_clean = (UT_LIST_GET_LEN(buf_pool->flush_list) 170 == 0); 171 } 172 173 } 174 return(all_clean); 175} 176