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