MySQL 8.4.1
Source Code Documentation
buf0flu.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1995, 2024, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is designed to work 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 either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
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 "buf0types.h"
38#include "univ.i"
39#include "ut0byte.h"
40
41#ifndef UNIV_HOTBACKUP
42/** Checks if the page_cleaner is in active state. */
44
45#ifdef UNIV_DEBUG
46
47/** Value of MySQL global variable used to disable page cleaner. */
49
50#endif /* UNIV_DEBUG */
51
52/** Event to synchronise with the flushing. */
54
55/** Event to wait for one flushing step */
57
58class Alter_stage;
59
60/** Remove a block from the flush list of modified blocks.
61@param[in] bpage pointer to the block in question */
62void buf_flush_remove(buf_page_t *bpage);
63
64/** Relocates a buffer control block on the flush_list.
65 Note that it is assumed that the contents of bpage has already been
66 copied to dpage. */
68 buf_page_t *bpage, /*!< in/out: control block being moved */
69 buf_page_t *dpage); /*!< in/out: destination block */
70
71/** Updates the flush system data structures when a write is completed.
72@param[in] bpage pointer to the block in question */
74
75#endif /* !UNIV_HOTBACKUP */
76
77/** Check if page type is uncompressed.
78@param[in] page page frame
79@return true if uncompressed page type. */
80bool page_is_uncompressed_type(const byte *page);
81
82/** Initialize a page for writing to the tablespace.
83@param[in] block buffer block; NULL if bypassing the buffer pool
84@param[in,out] page page frame
85@param[in,out] page_zip_ compressed page, or NULL if uncompressed
86@param[in] newest_lsn newest modification LSN to the page
87@param[in] skip_checksum whether to disable the page checksum
88@param[in] skip_lsn_check true to skip check for LSN (in DEBUG) */
89void buf_flush_init_for_writing(const buf_block_t *block, byte *page,
90 void *page_zip_, lsn_t newest_lsn,
91 bool skip_checksum, bool skip_lsn_check);
92
93#ifndef UNIV_HOTBACKUP
94#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
95/** Writes a flushable page asynchronously from the buffer pool to a file.
96NOTE: block and LRU list mutexes must be held upon entering this function, and
97they will be released by this function after flushing. This is loosely based on
98buf_flush_batch() and buf_flush_page().
99@param[in,out] buf_pool buffer pool instance
100@param[in,out] block buffer control block
101@return true if the page was flushed and the mutex released */
102[[nodiscard]] bool buf_flush_page_try(buf_pool_t *buf_pool, buf_block_t *block);
103#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
104
105/** Do flushing batch of a given type.
106NOTE: The calling thread is not allowed to own any latches on pages!
107@param[in,out] buf_pool buffer pool instance
108@param[in] type flush type
109@param[in] min_n wished minimum number of blocks flushed
110(it is not guaranteed that the actual number is that big, though)
111@param[in] lsn_limit in the case BUF_FLUSH_LIST all blocks whose
112oldest_modification is smaller than this should be flushed (if their number
113does not exceed min_n), otherwise ignored
114@param[out] n_processed the number of pages which were processed is
115passed back to caller. Ignored if NULL
116@retval true if a batch was queued successfully.
117@retval false if another batch of same type was already running. */
118bool buf_flush_do_batch(buf_pool_t *buf_pool, buf_flush_t type, ulint min_n,
119 lsn_t lsn_limit, ulint *n_processed);
120
121/** This utility flushes dirty blocks from the end of the flush list of all
122buffer pool instances.
123NOTE: The calling thread is not allowed to own any latches on pages!
124@param[in] min_n wished minimum number of blocks flushed (it is
125not guaranteed that the actual number is that big, though)
126@param[in] lsn_limit in the case BUF_FLUSH_LIST all blocks whose
127oldest_modification is smaller than this should be flushed (if their number
128does not exceed min_n), otherwise ignored
129@param[out] n_processed the number of pages which were processed is
130passed back to caller. Ignored if NULL.
131@return true if a batch was queued successfully for each buffer pool
132instance. false if another batch of same type was already running in
133at least one of the buffer pool instance */
134bool buf_flush_lists(ulint min_n, lsn_t lsn_limit, ulint *n_processed);
135
136/** This function picks up a single page from the tail of the LRU
137list, flushes it (if it is dirty), removes it from page_hash and LRU
138list and puts it on the free list. It is called from user threads when
139they are unable to find a replaceable page at the tail of the LRU
140list i.e.: when the background LRU flushing in the page_cleaner thread
141is not fast enough to keep pace with the workload.
142@param[in,out] buf_pool buffer pool instance
143@return true if success. */
145
146/** Waits until there's no flush of the given type from given BP instance.
147Note that in case of BUF_FLUSH_LIST and BUF_FLUSH_LRU we also make sure there's
148no ongoing batch initialization (which could lead to flushes).
149The BUF_FLUSH_SINGLE_PAGE does not have batch initialization.
150Note, that we return as soon as there is no flush, but in general a new one
151could start right after we've returned (it's up to the caller to prevent this).
152If buf_pool is nullptr, then it will await a moment with no flushes for each
153BP instance in turn, which in general doesn't imply there was a single moment
154when all instances were quiescent - it's up to the caller to ensure that.
155
156@param[in] buf_pool
157 The specific buffer pool instance to check.
158 Can be null, if we want to wait for each buf_pool in turn.
159@param[in] flush_type Flush type. */
161
162/** This function should be called at a mini-transaction commit, if a page was
163modified in it. Puts the block to the list of modified blocks, if it not
164already in it.
165@param[in] block block which is modified
166@param[in] start_lsn start lsn of the first mtr in a set of mtr's
167@param[in] end_lsn end lsn of the last mtr in the set of mtr's
168@param[in] observer flush observer */
169static inline void buf_flush_note_modification(buf_block_t *block,
170 lsn_t start_lsn, lsn_t end_lsn,
171 Flush_observer *observer);
172
173/** This function should be called when recovery has modified a buffer page.
174@param[in] block block which is modified
175@param[in] start_lsn start lsn of the first mtr in a set of mtr's
176@param[in] end_lsn end lsn of the last mtr in the set of mtr's */
178 lsn_t start_lsn,
179 lsn_t end_lsn);
180
181/** Returns true if the file page block is immediately suitable for replacement,
182i.e., the transition FILE_PAGE => NOT_USED allowed. The caller must hold the
183LRU list and block mutexes.
184@param[in] bpage buffer control block, must be buf_page_in_file() and
185 in the LRU list
186@return true if can replace immediately */
188
189#ifdef UNIV_DEBUG
190struct SYS_VAR;
191
192/** Disables page cleaner threads (coordinator and workers).
193It's used by: SET GLOBAL innodb_page_cleaner_disabled_debug = 1 (0).
194@param[in] thd thread handle
195@param[in] var pointer to system variable
196@param[out] var_ptr where the formal string goes
197@param[in] save immediate result from check function */
199 void *var_ptr,
200 const void *save);
201#endif /* UNIV_DEBUG */
202
203/** Initialize page_cleaner. */
205
206#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
207/** Validates the flush list.
208 @return true if ok */
209bool buf_flush_validate(buf_pool_t *buf_pool);
210#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
211
212/** Initialize the red-black tree to speed up insertions into the flush_list
213 during recovery process. Should be called at the start of recovery
214 process before any page has been read/written. */
215void buf_flush_init_flush_rbt(void);
216
217/** Frees up the red-black tree. */
218void buf_flush_free_flush_rbt(void);
219
220/** Writes a flushable page asynchronously from the buffer pool to a file.
221NOTE: 1. in simulated aio we must call os_aio_simulated_wake_handler_threads
222after we have posted a batch of writes! 2. buf_page_get_mutex(bpage) must be
223held upon entering this function. The LRU list mutex must be held if flush_type
224== BUF_FLUSH_SINGLE_PAGE. Both mutexes will be released by this function if it
225returns true.
226@param[in] buf_pool buffer pool instance
227@param[in] bpage buffer control block
228@param[in] flush_type type of flush
229@param[in] sync true if sync IO request
230@return true if page was flushed */
231bool buf_flush_page(buf_pool_t *buf_pool, buf_page_t *bpage,
232 buf_flush_t flush_type, bool sync);
233
234/** Check if the block is modified and ready for flushing.
235Requires buf_page_get_mutex(bpage).
236@param[in] bpage buffer control block, must be buf_page_in_file()
237@param[in] flush_type type of flush
238@return true if can flush immediately */
239[[nodiscard]] bool buf_flush_ready_for_flush(buf_page_t *bpage,
241
242/** Check if there are any dirty pages that belong to a space id in the flush
243 list in a particular buffer pool.
244 @return number of dirty pages present in a single buffer pool */
246 buf_pool_t *buf_pool, /*!< in: buffer pool */
247 space_id_t id, /*!< in: space id to check */
248 Flush_observer *observer); /*!< in: flush observer to check */
249
250/** Executes fsync for all tablespaces, to fsync all pages written to disk. */
251void buf_flush_fsync();
252
253/** Synchronously flush dirty blocks from the end of the flush list of all
254 buffer pool instances. NOTE: The calling thread is not allowed to own any
255 latches on pages! */
257
258/** Checks if all flush lists are empty. It is supposed to be used in
259single thread, during startup or shutdown. Hence it does not acquire
260lock and it is caller's responsibility to guarantee that flush lists
261are not changed in background.
262@return true if all flush lists were empty. */
264
265/** We use Flush_observer to track flushing of non-redo logged pages in bulk
266create index(btr0load.cc).Since we disable redo logging during a index build,
267we need to make sure that all dirty pages modified by the index build are
268flushed to disk before any redo logged operations go to the index. */
269
271 public:
272 /** Constructor
273 @param[in] space_id table space id
274 @param[in] trx trx instance
275 @param[in,out] stage PFS progress monitoring instance, it's used by
276 ALTER TABLE. It is passed to log_preflush_pool_modified_pages() for
277 accounting. */
278 Flush_observer(space_id_t space_id, trx_t *trx, Alter_stage *stage) noexcept;
279
280 /** Destructor */
281 ~Flush_observer() noexcept;
282
283 /** Print information about the current object.
284 @param[in,out] out output stream to be used.
285 @return the output stream. */
286 std::ostream &print(std::ostream &out) const;
287
288 /** Check pages have been flushed and removed from the flush list
289 in a buffer pool instance.
290 @param[in] instance_no buffer pool instance no
291 @return true if the pages were removed from the flush list */
292 bool is_complete(size_t instance_no) {
293 ut_ad(m_flushed[instance_no].load() >= 0);
294 ut_ad(m_removed[instance_no].load() >= 0);
295 return m_interrupted ||
296 (m_flushed[instance_no].load() == m_removed[instance_no].load());
297 }
298
299 /** Interrupt observer not to wait. */
300 void interrupted() { m_interrupted = true; }
301
302 /** Check whether trx is interrupted
303 @return true if trx is interrupted */
304 bool check_interrupted();
305
306 /** Flush dirty pages. */
307 void flush();
308
309 /** Notify observer of flushing a page
310 @param[in] buf_pool buffer pool instance
311 @param[in] bpage buffer page to flush */
312 void notify_flush(buf_pool_t *buf_pool, buf_page_t *bpage);
313
314 /** Notify observer of removing a page from flush list
315 @param[in] buf_pool buffer pool instance
316 @param[in] bpage buffer page flushed */
317 void notify_remove(buf_pool_t *buf_pool, buf_page_t *bpage);
318
319 private:
320 using Counter = std::atomic_int;
321 using Counters = std::vector<Counter, ut::allocator<Counter>>;
322
323#ifdef UNIV_DEBUG
324 [[nodiscard]] bool validate() const noexcept;
325#endif /* UNIV_DEBUG */
326
327 /** Tablespace ID. */
329
330 /** Trx instance */
332
333 /** Performance schema accounting object, used by ALTER TABLE.
334 If not nullptr, then stage->begin_phase_flush() will be called initially,
335 specifying the number of pages to be attempted to be flushed and
336 subsequently, stage->inc() will be called for each page we attempt to
337 flush. */
339
340 /** Flush request sent, per buffer pool. */
342
343 /** Flush request finished, per buffer pool. */
345
346 /** Number of pages using this instance. */
348
349 /** True if the operation was interrupted. */
351};
352
353lsn_t get_flush_sync_lsn() noexcept;
354#endif /* !UNIV_HOTBACKUP */
355
356#include "buf0flu.ic"
357
358#endif
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:47
void buf_flush_fsync()
Executes fsync for all tablespaces, to fsync all pages written to disk.
Definition: buf0flu.cc:3574
bool buf_flush_ready_for_replace(buf_page_t *bpage)
Returns true if the file page block is immediately suitable for replacement, i.e.,...
Definition: buf0flu.cc:684
ulint buf_pool_get_dirty_pages_count(buf_pool_t *buf_pool, space_id_t id, Flush_observer *observer)
Check if there are any dirty pages that belong to a space id in the flush list in a particular buffer...
Definition: buf0flu.cc:3706
void buf_flush_write_complete(buf_page_t *bpage)
Updates the flush system data structures when a write is completed.
Definition: buf0flu.cc:916
bool buf_flush_do_batch(buf_pool_t *buf_pool, buf_flush_t type, ulint min_n, lsn_t lsn_limit, ulint *n_processed)
Do flushing batch of a given type.
Definition: buf0flu.cc:2040
void buf_flush_sync_all_buf_pools()
Synchronously flush dirty blocks from the end of the flush list of all buffer pool instances.
Definition: buf0flu.cc:3602
bool buf_flush_single_page_from_LRU(buf_pool_t *buf_pool)
This function picks up a single page from the tail of the LRU list, flushes it (if it is dirty),...
Definition: buf0flu.cc:2125
bool buf_flush_validate(buf_pool_t *buf_pool)
Validates the flush list.
Definition: buf0flu.cc:3692
void buf_flush_init_flush_rbt(void)
Initialize the red-black tree to speed up insertions into the flush_list during recovery process.
Definition: buf0flu.cc:370
bool buf_flush_lists(ulint min_n, lsn_t lsn_limit, ulint *n_processed)
This utility flushes dirty blocks from the end of the flush list of all buffer pool instances.
Definition: buf0flu.cc:2063
static void buf_flush_recv_note_modification(buf_block_t *block, lsn_t start_lsn, lsn_t end_lsn)
This function should be called when recovery has modified a buffer page.
void buf_flush_page_cleaner_disabled_debug_update(THD *thd, SYS_VAR *var, void *var_ptr, const void *save)
Disables page cleaner threads (coordinator and workers).
Definition: buf0flu.cc:3066
bool buf_flush_page(buf_pool_t *buf_pool, buf_page_t *bpage, buf_flush_t flush_type, bool sync)
Writes a flushable page asynchronously from the buffer pool to a file.
Definition: buf0flu.cc:1275
void buf_flush_remove(buf_page_t *bpage)
Remove a block from the flush list of modified blocks.
Definition: buf0flu.cc:783
os_event_t buf_flush_tick_event
Event to wait for one flushing step.
Definition: buf0flu.cc:105
bool buf_flush_page_try(buf_pool_t *buf_pool, buf_block_t *block)
Writes a flushable page asynchronously from the buffer pool to a file.
Definition: buf0flu.cc:1401
os_event_t buf_flush_event
Event to synchronise with the flushing.
Definition: buf0flu.cc:102
void buf_flush_await_no_flushing(buf_pool_t *buf_pool, buf_flush_t flush_type)
Waits until there's no flush of the given type from given BP instance.
Definition: buf0flu.cc:2028
static void buf_flush_note_modification(buf_block_t *block, lsn_t start_lsn, lsn_t end_lsn, Flush_observer *observer)
This function should be called at a mini-transaction commit, if a page was modified in it.
void buf_flush_free_flush_rbt(void)
Frees up the red-black tree.
Definition: buf0flu.cc:390
void buf_flush_relocate_on_flush_list(buf_page_t *bpage, buf_page_t *dpage)
Relocates a buffer control block on the flush_list.
Definition: buf0flu.cc:859
void buf_flush_page_cleaner_init()
Initialize page_cleaner.
Definition: buf0flu.cc:2776
lsn_t get_flush_sync_lsn() noexcept
Get the lsn up to which data pages are to be synchronously flushed.
Definition: buf0flu.cc:93
bool buf_are_flush_lists_empty_validate()
Checks if all flush lists are empty.
Definition: buf0flu.cc:411
bool innodb_page_cleaner_disabled_debug
Value of MySQL global variable used to disable page cleaner.
Definition: buf0flu.cc:203
bool buf_flush_ready_for_flush(buf_page_t *bpage, buf_flush_t flush_type)
Check if the block is modified and ready for flushing.
Definition: buf0flu.cc:777
void buf_flush_init_for_writing(const buf_block_t *block, byte *page, void *page_zip_, lsn_t newest_lsn, bool skip_checksum, bool skip_lsn_check)
Initialize a page for writing to the tablespace.
Definition: buf0flu.cc:987
bool buf_flush_page_cleaner_is_active()
Checks if the page_cleaner is in active state.
Definition: buf0flu.cc:2772
bool page_is_uncompressed_type(const byte *page)
Check if page type is uncompressed.
Definition: buf0flu.cc:963
The database buffer pool flush algorithm.
The database buffer pool global types for the directory.
buf_flush_t
Flags for flush types.
Definition: buf0types.h:68
Class used to report ALTER TABLE progress via performance_schema.
Definition: ut0stage.h:81
We use Flush_observer to track flushing of non-redo logged pages in bulk create index(btr0load....
Definition: buf0flu.h:270
trx_t * m_trx
Trx instance.
Definition: buf0flu.h:331
Counters m_flushed
Flush request sent, per buffer pool.
Definition: buf0flu.h:341
space_id_t m_space_id
Tablespace ID.
Definition: buf0flu.h:328
Flush_observer(space_id_t space_id, trx_t *trx, Alter_stage *stage) noexcept
Constructor.
Definition: buf0flu.cc:3753
void flush()
Flush dirty pages.
Definition: buf0flu.cc:3809
Counters m_removed
Flush request finished, per buffer pool.
Definition: buf0flu.h:344
bool validate() const noexcept
Definition: buf0flu.cc:3845
void interrupted()
Interrupt observer not to wait.
Definition: buf0flu.h:300
std::ostream & print(std::ostream &out) const
Print information about the current object.
Definition: buf0flu.cc:3854
bool check_interrupted()
Check whether trx is interrupted.
Definition: buf0flu.cc:3783
~Flush_observer() noexcept
Destructor.
Definition: buf0flu.cc:3772
void notify_remove(buf_pool_t *buf_pool, buf_page_t *bpage)
Notify observer of removing a page from flush list.
Definition: buf0flu.cc:3803
bool m_interrupted
True if the operation was interrupted.
Definition: buf0flu.h:350
void notify_flush(buf_pool_t *buf_pool, buf_page_t *bpage)
Notify observer of flushing a page.
Definition: buf0flu.cc:3793
std::vector< Counter, ut::allocator< Counter > > Counters
Definition: buf0flu.h:321
Counter m_n_ref_count
Number of pages using this instance.
Definition: buf0flu.h:347
Alter_stage * m_stage
Performance schema accounting object, used by ALTER TABLE.
Definition: buf0flu.h:338
bool is_complete(size_t instance_no)
Check pages have been flushed and removed from the flush list in a buffer pool instance.
Definition: buf0flu.h:292
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Definition: buf0buf.h:1153
int page
Definition: ctype-mb.cc:1234
flush_type
Definition: my_sys.h:297
uint64_t lsn_t
Type used for all log sequence number storage and arithmetic.
Definition: log0types.h:63
Sharded atomic counter.
Definition: ut0counter.h:221
bool load(THD *, const dd::String_type &fname, dd::String_type *buf)
Read an sdi file from disk and store in a buffer.
Definition: sdi_file.cc:308
required string type
Definition: replication_group_member_actions.proto:34
Definition: plugin.h:69
The buffer control block structure.
Definition: buf0buf.h:1747
The buffer pool structure.
Definition: buf0buf.h:2275
InnoDB condition variable.
Definition: os0event.cc:63
Definition: trx0trx.h:684
Version control for database, common definitions, and include files.
unsigned long int ulint
Definition: univ.i:406
Utilities for byte operations.
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105