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