MySQL  8.0.23
Source Code Documentation
buf0flu.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1995, 2020, Oracle and/or its affiliates.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 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 St, Fifth Floor, Boston, MA 02110-1301 USA
24 
25 *****************************************************************************/
26 
27 /** @file include/buf0flu.h
28  The database buffer pool flush algorithm
29 
30  Created 11/5/1995 Heikki Tuuri
31  *******************************************************/
32 
33 #ifndef buf0flu_h
34 #define buf0flu_h
35 
36 #include "buf0types.h"
37 #include "log0log.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 
58 class ut_stage_alter_t;
59 
60 /** Remove a block from the flush list of modified blocks.
61 @param[in] bpage pointer to the block in question */
62 void 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. */
80 bool 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) */
89 void 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.
96 NOTE: block and LRU list mutexes must be held upon entering this function, and
97 they will be released by this function after flushing. This is loosely based on
98 buf_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 bool buf_flush_page_try(buf_pool_t *buf_pool, buf_block_t *block)
103  MY_ATTRIBUTE((warn_unused_result));
104 #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
105 /** Do flushing batch of a given type.
106 NOTE: 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 mumber 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
112 oldest_modification is smaller than this should be flushed (if their number
113 does not exceed min_n), otherwise ignored
114 @param[out] n_processed the number of pages which were processed is
115 passed 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. */
118 bool 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
122 buffer pool instances.
123 NOTE: The calling thread is not allowed to own any latches on pages!
124 @param[in] min_n wished minimum mumber of blocks flushed (it is
125 not guaranteed that the actual number is that big, though)
126 @param[in] lsn_limit in the case BUF_FLUSH_LIST all blocks whose
127 oldest_modification is smaller than this should be flushed (if their number
128 does not exceed min_n), otherwise ignored
129 @param[out] n_processed the number of pages which were processed is
130 passed back to caller. Ignored if NULL.
131 @return true if a batch was queued successfully for each buffer pool
132 instance. false if another batch of same type was already running in
133 at least one of the buffer pool instance */
134 bool 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
137 list, flushes it (if it is dirty), removes it from page_hash and LRU
138 list and puts it on the free list. It is called from user threads when
139 they are unable to find a replaceable page at the tail of the LRU
140 list i.e.: when the background LRU flushing in the page_cleaner thread
141 is 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 a flush batch of the given type ends.
147 @param[in] buf_pool Buffer pool instance.
148 @param[in] flush_type Flush type. */
150 
151 /** Waits until a flush batch of the given type ends. This is called by a
152 thread that only wants to wait for a flush to end but doesn't do any flushing
153 itself.
154 @param[in] buf_pool buffer pool instance
155 @param[in] type BUF_FLUSH_LRU or BUF_FLUSH_LIST */
157 
158 /** This function should be called at a mini-transaction commit, if a page was
159 modified in it. Puts the block to the list of modified blocks, if it not
160 already in it.
161 @param[in] block block which is modified
162 @param[in] start_lsn start lsn of the first mtr in a set of mtr's
163 @param[in] end_lsn end lsn of the last mtr in the set of mtr's
164 @param[in] observer flush observer */
165 UNIV_INLINE
167  lsn_t end_lsn, FlushObserver *observer);
168 
169 /** This function should be called when recovery has modified a buffer page.
170 @param[in] block block which is modified
171 @param[in] start_lsn start lsn of the first mtr in a set of mtr's
172 @param[in] end_lsn end lsn of the last mtr in the set of mtr's */
173 UNIV_INLINE
175  lsn_t end_lsn);
176 
177 /** Returns TRUE if the file page block is immediately suitable for replacement,
178 i.e., the transition FILE_PAGE => NOT_USED allowed. The caller must hold the
179 LRU list and block mutexes.
180 @param[in] bpage buffer control block, must be buf_page_in_file() and
181  in the LRU list
182 @return true if can replace immediately */
184 
185 #ifdef UNIV_DEBUG
186 struct SYS_VAR;
187 
188 /** Disables page cleaner threads (coordinator and workers).
189 It's used by: SET GLOBAL innodb_page_cleaner_disabled_debug = 1 (0).
190 @param[in] thd thread handle
191 @param[in] var pointer to system variable
192 @param[out] var_ptr where the formal string goes
193 @param[in] save immediate result from check function */
195  void *var_ptr,
196  const void *save);
197 #endif /* UNIV_DEBUG */
198 
199 /** Initialize page_cleaner.
200 @param[in] n_page_cleaners Number of page cleaner threads to create */
201 void buf_flush_page_cleaner_init(size_t n_page_cleaners);
202 
203 /** Wait for any possible LRU flushes that are in progress to end. */
205 
206 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
207 /** Validates the flush list.
208  @return true if ok */
209 bool 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. */
215 void buf_flush_init_flush_rbt(void);
216 
217 /** Frees up the red-black tree. */
218 void buf_flush_free_flush_rbt(void);
219 
220 /** Writes a flushable page asynchronously from the buffer pool to a file.
221 NOTE: 1. in simulated aio we must call os_aio_simulated_wake_handler_threads
222 after we have posted a batch of writes! 2. buf_page_get_mutex(bpage) must be
223 held 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
225 returns 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 */
231 ibool 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.
235 @param[in] bpage buffer control block, must be buf_page_in_file()
236 @param[in] flush_type type of flush
237 @return true if can flush immediately */
239  MY_ATTRIBUTE((warn_unused_result));
240 
241 /** Check if there are any dirty pages that belong to a space id in the flush
242  list in a particular buffer pool.
243  @return number of dirty pages present in a single buffer pool */
245  buf_pool_t *buf_pool, /*!< in: buffer pool */
246  space_id_t id, /*!< in: space id to check */
247  FlushObserver *observer); /*!< in: flush observer to check */
248 
249 /** Synchronously flush dirty blocks from the end of the flush list of all
250  buffer pool instances. NOTE: The calling thread is not allowed to own any
251  latches on pages! */
253 
254 /** Checks if all flush lists are empty. It is supposed to be used in
255 single thread, during startup or shutdown. Hence it does not acquire
256 lock and it is caller's responsibility to guarantee that flush lists
257 are not changed in background.
258 @return true if all flush lists were empty. */
260 
261 /** We use FlushObserver to track flushing of non-redo logged pages in bulk
262 create index(BtrBulk.cc).Since we disable redo logging during a index build,
263 we need to make sure that all dirty pages modifed by the index build are
264 flushed to disk before any redo logged operations go to the index. */
265 
267  public:
268  /** Constructor
269  @param[in] space_id table space id
270  @param[in] trx trx instance
271  @param[in] stage performance schema accounting object,
272  used by ALTER TABLE. It is passed to log_preflush_pool_modified_pages()
273  for accounting. */
274  FlushObserver(space_id_t space_id, trx_t *trx,
275  ut_stage_alter_t *stage) noexcept;
276 
277  /** Destructor */
278  ~FlushObserver() noexcept;
279 
280  /** Check pages have been flushed and removed from the flush list
281  in a buffer pool instance.
282  @param[in] instance_no buffer pool instance no
283  @return true if the pages were removed from the flush list */
284  bool is_complete(size_t instance_no) {
285  return m_flushed[instance_no].fetch_add(0, std::memory_order_relaxed) ==
286  m_removed[instance_no].fetch_add(0, std::memory_order_relaxed) ||
288  }
289 
290  /** Interrupt observer not to wait. */
291  void interrupted() { m_interrupted = true; }
292 
293  /** Check whether trx is interrupted
294  @return true if trx is interrupted */
295  bool check_interrupted();
296 
297  /** Flush dirty pages. */
298  void flush();
299 
300  /** Notify observer of flushing a page
301  @param[in] buf_pool buffer pool instance
302  @param[in] bpage buffer page to flush */
303  void notify_flush(buf_pool_t *buf_pool, buf_page_t *bpage);
304 
305  /** Notify observer of removing a page from flush list
306  @param[in] buf_pool buffer pool instance
307  @param[in] bpage buffer page flushed */
308  void notify_remove(buf_pool_t *buf_pool, buf_page_t *bpage);
309 
310  private:
311  using Counter = std::atomic_int;
312  using Counters = std::vector<Counter, ut_allocator<Counter>>;
313 
314  /** Tablespace ID. */
316 
317  /** Trx instance */
319 
320  /** Performance schema accounting object, used by ALTER TABLE.
321  If not nullptr, then stage->begin_phase_flush() will be called initially,
322  specifying the number of pages to be attempted to be flushed and
323  subsequently, stage->inc() will be called for each page we attempt to
324  flush. */
326 
327  /** Flush request sent, per buffer pool. */
329 
330  /** Flush request finished, per buffer pool. */
332 
333  /** Number of pages using this instance. */
335 
336  /** True if the operation was interrupted. */
338 };
339 lsn_t get_flush_sync_lsn() noexcept;
340 #endif /* !UNIV_HOTBACKUP */
341 
342 #include "buf0flu.ic"
343 
344 #endif
lsn_t
uint64_t lsn_t
Type used for all log sequence number storage and arithmetics.
Definition: log0types.h:60
page_is_uncompressed_type
bool page_is_uncompressed_type(const byte *page)
Check if page type is uncompressed.
Definition: buf0flu.cc:941
buf_flush_remove
void buf_flush_remove(buf_page_t *bpage)
Remove a block from the flush list of modified blocks.
Definition: buf0flu.cc:752
buf_flush_page_cleaner_is_active
bool buf_flush_page_cleaner_is_active()
Checks if the page_cleaner is in active state.
Definition: buf0flu.cc:2813
THD
Definition: sql_class.h:807
buf_flush_wait_batch_end
void buf_flush_wait_batch_end(buf_pool_t *buf_pool, buf_flush_t flush_type)
Waits until a flush batch of the given type ends.
Definition: buf0flu.cc:2025
buf_flush_wait_batch_end_wait_only
void buf_flush_wait_batch_end_wait_only(buf_pool_t *buf_pool, buf_flush_t type)
Waits until a flush batch of the given type ends.
SYS_VAR
Definition: plugin.h:62
Counter
Sharded atomic counter.
Definition: ut0counter.h:220
FlushObserver::flush
void flush()
Flush dirty pages.
Definition: buf0flu.cc:3794
os_event
InnoDB condition variable.
Definition: os0event.cc:66
buf_flush_event
os_event_t buf_flush_event
Event to synchronise with the flushing.
Definition: buf0flu.cc:99
buf_flush_page
ibool 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:1251
buf_flush_page_cleaner_disabled_debug_update
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:3123
buf_pool_get_dirty_pages_count
ulint buf_pool_get_dirty_pages_count(buf_pool_t *buf_pool, space_id_t id, FlushObserver *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:3699
get_flush_sync_lsn
lsn_t get_flush_sync_lsn() noexcept
Get the lsn upto which data pages are to be synchronously flushed.
Definition: buf0flu.cc:90
FlushObserver::m_interrupted
bool m_interrupted
True if the operation was interrupted.
Definition: buf0flu.h:337
FlushObserver::m_n_ref_count
Counter m_n_ref_count
Number of pages using this instance.
Definition: buf0flu.h:334
buf_are_flush_lists_empty_validate
bool buf_are_flush_lists_empty_validate()
Checks if all flush lists are empty.
Definition: buf0flu.cc:412
buf_block_t
The buffer control block structure.
Definition: buf0buf.h:1544
FlushObserver::~FlushObserver
~FlushObserver() noexcept
Destructor.
Definition: buf0flu.cc:3761
buf_flush_init_flush_rbt
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:371
FlushObserver::notify_flush
void notify_flush(buf_pool_t *buf_pool, buf_page_t *bpage)
Notify observer of flushing a page.
Definition: buf0flu.cc:3782
buf_flush_ready_for_replace
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:686
buf_flush_t
buf_flush_t
Flags for flush types.
Definition: buf0types.h:65
buf_flush_note_modification
UNIV_INLINE void buf_flush_note_modification(buf_block_t *block, lsn_t start_lsn, lsn_t end_lsn, FlushObserver *observer)
This function should be called at a mini-transaction commit, if a page was modified in it.
buf_flush_init_for_writing
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:965
FlushObserver::m_trx
trx_t * m_trx
Trx instance.
Definition: buf0flu.h:318
FlushObserver::m_stage
ut_stage_alter_t * m_stage
Performance schema accounting object, used by ALTER TABLE.
Definition: buf0flu.h:325
FlushObserver::interrupted
void interrupted()
Interrupt observer not to wait.
Definition: buf0flu.h:291
buf_flush_validate
bool buf_flush_validate(buf_pool_t *buf_pool)
Validates the flush list.
Definition: buf0flu.cc:3685
FlushObserver::m_space_id
space_id_t m_space_id
Tablespace ID.
Definition: buf0flu.h:315
buf_flush_single_page_from_LRU
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:2159
innodb_page_cleaner_disabled_debug
bool innodb_page_cleaner_disabled_debug
Value of MySQL global variable used to disable page cleaner.
Definition: buf0flu.cc:200
buf_page_t
Definition: buf0buf.h:1202
buf_flush_wait_LRU_batch_end
void buf_flush_wait_LRU_batch_end()
Wait for any possible LRU flushes that are in progress to end.
Definition: buf0flu.cc:2271
buf_flush_relocate_on_flush_list
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:829
buf_flush_sync_all_buf_pools
void buf_flush_sync_all_buf_pools(void)
Synchronously flush dirty blocks from the end of the flush list of all buffer pool instances.
Definition: buf0flu.cc:3599
buf_flush_recv_note_modification
UNIV_INLINE 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.
buf_flush_lists
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:2097
buf_flush_write_complete
void buf_flush_write_complete(buf_page_t *bpage)
Updates the flush system data structures when a write is completed.
Definition: buf0flu.cc:886
FlushObserver::FlushObserver
FlushObserver(space_id_t space_id, trx_t *trx, ut_stage_alter_t *stage) noexcept
Constructor.
Definition: buf0flu.cc:3747
page
int page
Definition: ctype-mb.cc:1234
ut_stage_alter_t
Class used to report ALTER TABLE progress via performance_schema.
Definition: ut0stage.h:77
buf_flush_ready_for_flush
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:708
log0log.h
buf_flush_page_cleaner_init
void buf_flush_page_cleaner_init(size_t n_page_cleaners)
Initialize page_cleaner.
Definition: buf0flu.cc:2819
buf_flush_tick_event
os_event_t buf_flush_tick_event
Event to wait for one flushing step.
Definition: buf0flu.cc:102
flush_type
flush_type
Definition: my_sys.h:293
buf0types.h
FlushObserver::Counters
std::vector< Counter, ut_allocator< Counter > > Counters
Definition: buf0flu.h:312
buf_flush_do_batch
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:2058
FlushObserver::notify_remove
void notify_remove(buf_pool_t *buf_pool, buf_page_t *bpage)
Notify observer of removing a page from flush list.
Definition: buf0flu.cc:3790
FlushObserver::check_interrupted
bool check_interrupted()
Check whether trx is interrupted.
Definition: buf0flu.cc:3772
FlushObserver::m_removed
Counters m_removed
Flush request finished, per buffer pool.
Definition: buf0flu.h:331
space_id_t
uint32 space_id_t
Tablespace identifier.
Definition: api0api.h:59
buf_flush_page_try
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:1383
FlushObserver::m_flushed
Counters m_flushed
Flush request sent, per buffer pool.
Definition: buf0flu.h:328
FlushObserver
We use FlushObserver to track flushing of non-redo logged pages in bulk create index(BtrBulk....
Definition: buf0flu.h:266
buf_pool_t
The buffer pool structure.
Definition: buf0buf.h:2007
buf_flush_free_flush_rbt
void buf_flush_free_flush_rbt(void)
Frees up the red-black tree.
Definition: buf0flu.cc:391
binary_log::transaction::compression::type
type
Definition: base.h:36
FlushObserver::is_complete
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:284
trx_t
Definition: trx0trx.h:836
ut0byte.h