MySQL 9.7.2
Source Code Documentation
btr0mtib.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2023, 2026, 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/btr0mtib.h
29
30 Multi Threaded Index Build (MTIB) using BUF_BLOCK_MEMORY and dedicated
31 Bulk_flusher threads.
32
33 Created 09/Feb/2023 Annamalai Gurusami
34 *************************************************************************/
35
36#ifndef btr0mtib_h
37#define btr0mtib_h
38
39#include <cstddef>
40#include <vector>
41
42#include "api0api.h"
43#include "btr0load.h"
44#include "ddl0impl-compare.h"
45#include "dict0dict.h"
46#include "lob0bulk.h"
47#include "lob0lob.h"
48#include "page0cur.h"
49#include "row0mysql.h"
50#include "ut0class_life_cycle.h"
51#include "ut0new.h"
52#include "ut0object_cache.h"
53
54/* The Btree_multi namespace is used for multi-threaded parallel index build. */
55namespace Btree_multi {
56
57// Forward declaration.
58class Page_load;
59class Btree_load;
60struct Page_stat;
61
62using Blob_context = void *;
63
64namespace bulk {
65class Blob_inserter;
66} // namespace bulk
67
68/** Allocate, use, manage and flush one extent pages (FSP_EXTENT_SIZE). */
70 using Page_range_t = std::pair<page_no_t, page_no_t>;
71
72 /** Constructor.
73 @param[in] btree_load B-tree loader object.
74 @param[in] is_leaf true if this is part of leaf segment, false if this is
75 part of non-leaf (or top) segment. */
76 Page_extent(Btree_load *btree_load, const bool is_leaf);
77
78 /** Destructor. */
80
81 /** Next page number to be used. */
83
84 /** Page numbers of the pages that has been allocated in this extent.
85 The page range is [p1, p2), where p2 is not included. */
87
88 /** All the page loaders of the used pages. */
89 std::vector<Page_load *> m_page_loads;
90
91 bool is_btree_load_nullptr() const { return m_btree_load == nullptr; }
92
93 public:
94 /** Create an object of type Page_extent in the heap. */
95 static Page_extent *create(Btree_load *btree_load, const bool is_leaf,
96 const bool is_blob);
97
98 /** Release the page extent. Delete if not cached.
99 @param[in] extent extent to release */
100 static void drop(Page_extent *extent);
101
102 /** Number of pages in this extent. */
103 page_no_t page_count() const;
104
105 /** Reset the range with the given value.
106 @param[in] range new range value to be used. */
107 void reset_range(const Page_range_t &range);
108
109 /** Calculate the number of used pages.
110 return the number of used pages. */
111 size_t used_pages() const { return m_page_no - m_range.first; }
112
113 void get_page_numbers(std::vector<page_no_t> &page_numbers) const;
114
115 /** Get the index of the first unused page load.
116 @return index of the first unused page load. */
117 size_t last() const { return m_page_no - m_range.first; }
118
119 /** Check if the range is valid.
120 @return true if the range is valid, false otherwise. */
121 bool is_valid() const;
122
123 bool is_null() const {
124 return (m_range.first == FIL_NULL) && (m_range.second == FIL_NULL);
125 }
126
127 public:
128 /** Member of Page_extent. The index of page_load objects in the m_page_loads
129 corresponds to the page_no in the m_range. Here, check if a page_no already
130 has a Page_load object.
131 @param[in] page_no page_no for which we are looking for Page_load obj.
132 @return Page_load object if available, nullptr otherwise. */
134
135 /** Member of Page_extent. Associate the given page_no and the page load
136 object.
137 @param[in] page_no page number to associate.
138 @param[in] page_load page load object to associate. */
139 void set_page_load(page_no_t page_no, Page_load *page_load);
140
142
143 /** Initialize the next page number to be allocated. The page range should
144 have been already initialized. */
145 void init();
146
147 /** Check if no more pages are there to be used.
148 @return true if the page extent is completely used.
149 @return false if the page extent has more pages to be used. */
150 bool is_fully_used() const { return m_page_no == m_range.second; }
151
152 /** Check if there are any pages used.
153 @return true if at least one page is used.
154 @return false if no pages are used in this extent.*/
155 bool is_any_used() const {
156 ut_ad(m_page_no == m_range.first || m_page_loads.size() > 0);
157 return m_page_no > m_range.first;
158 }
159
160 public:
161 /** Allocate a page number. */
163
164 /** Save a page_load. */
165 void append(Page_load *page_load);
166
167 /** Flush the used pages to disk. It also frees the unused pages back to the
168 segment.
169 @param[in,out] node space file node
170 @param[in,out] iov vector IO array
171 @param[in] iov_size vector IO array size
172 @return On success, return DB_SUCCESS. */
173 dberr_t flush(fil_node_t *node, void *iov, size_t iov_size);
174
175 /** Flush one page at a time. This can be used when scatter/gather i/o is
176 not available for use.
177 @param[in,out] node space file node
178 @return On success, return DB_SUCCESS. */
180
181 /** Flush 1 extent pages at a time. Internally it will call OS dependent
182 API (either bulk_flush_win() on Windows or bulk_flush_linux() on other
183 operating systems.
184 @param[in,out] node space file node
185 @param[in,out] iov vector IO array
186 @param[in] iov_size vector IO array size
187 @return DB_SUCCESS on success, error code on failure. */
188 dberr_t bulk_flush(fil_node_t *node, void *iov [[maybe_unused]],
189 size_t iov_size [[maybe_unused]]);
190
191#ifdef UNIV_LINUX
192 /** Flush 1 extent pages at a time. Uses pwritev() i/o API.
193 @param[in,out] node space file node
194 @param[in,out] iov vector IO array
195 @param[in] iov_size vector IO array size
196 @return DB_SUCCESS on success, error code on failure. */
197 dberr_t bulk_flush_linux(fil_node_t *node, struct iovec *iov,
198 size_t iov_size);
199#endif /* UNIV_LINUX */
200
201 /** Free all resources. */
203
204 /** Free any cached page load entries. */
205 void destroy_cached();
206
207 space_id_t space() const;
208
209 /** Mark the extent as cached. Flush thread should not free this extent. */
210 void set_cached() { m_is_cached.store(true); }
211
212 /** Set and unset free state of a cached extent.
213 @param[in] free state to be set */
214 void set_state(bool free) { m_is_free.store(free); }
215
216 /** @return true iff the cached element is in free state. */
217 bool is_free() const { return m_is_free.load(); }
218
219 /** @return true iff it is a cached extent. */
220 bool is_cached() const { return m_is_cached.load(); }
221
222 /** Reset page load cache to free all. */
224
225 public:
226 std::ostream &print(std::ostream &out) const;
227
228 /** Mark that this extent is used for blobs. */
229 void set_blob() { m_is_blob = true; }
230
231 /** Check if this is a blob extent.
232 @return true if it is a blob extent. */
233 bool is_blob() const { return m_is_blob; }
234
235 /** Free the BUF_BLOCK_MEMORY blocks used by this extent. */
236 void free_memory_blocks();
237
238#ifdef UNIV_DEBUG
239 /** True if this extent has been handed over to the bulk flusher. */
240 std::atomic_bool m_is_owned_by_bulk_flusher{false};
241#endif /* UNIV_DEBUG */
242
243 private:
245
246 /** true if this extent belongs to leaf segment. */
247 bool m_is_leaf{true};
248
249 /** true iff the the extent is cached. */
250 std::atomic_bool m_is_cached{false};
251 /** true if the cached entry is free to be used. */
252 std::atomic_bool m_is_free{true};
253 /** Cached page loads. */
254 std::vector<Page_load *> m_cached_page_loads;
255 /** Next cached page load index. */
257
258 /** True if this extent is used for blobs. */
259 bool m_is_blob{false};
260
261 friend struct Level_ctx;
262};
263
265 std::vector<page_no_t> &page_numbers) const {
266 for (page_no_t i = m_range.first; i < m_page_no; ++i) {
267 page_numbers.push_back(i);
268 }
269}
270
272 Page_load *page_load) {
273 ut_ad(page_no >= m_range.first);
274 ut_ad(page_no < m_range.second);
275 const size_t idx = page_no - m_range.first;
276 if (idx == m_page_loads.size()) {
277 m_page_loads.push_back(page_load);
278 } else {
279 ut_ad(idx <= m_page_loads.size());
280 ut_ad(m_page_loads[idx] == nullptr);
281 m_page_loads[idx] = page_load;
282 }
283 ut_ad(m_page_loads.size() > 0);
284}
285
287 ut_ad(page_no >= m_range.first);
288 ut_ad(page_no < m_range.second);
289 const size_t idx = page_no - m_range.first;
290 if (m_page_loads.empty() || m_page_loads.size() <= idx) {
291 return nullptr;
292 }
293 return m_page_loads[idx];
294}
295
299 m_range.first = FIL_NULL;
300 m_range.second = FIL_NULL;
301 m_btree_load = nullptr;
302}
303
304inline bool Page_extent::is_valid() const {
305 ut_ad(m_range.first != 0);
306 ut_ad(m_range.second != 0);
307 if (is_null()) {
308 return true;
309 }
310 ut_ad(m_range.first < m_range.second);
311 ut_ad((m_range.second - m_range.first) <= FSP_EXTENT_SIZE);
312 return m_range.first < m_range.second;
313}
314
315inline std::ostream &Page_extent::print(std::ostream &out) const {
316 out << "[Page_extent: this=" << (void *)this
317 << ", m_range.first=" << m_range.first
318 << ", m_range.second=" << m_range.second
319 << ", page_loads=" << m_page_loads.size() << "]" << std::endl;
320 return out;
321}
322
323inline std::ostream &operator<<(std::ostream &out, const Page_extent &obj) {
324 return obj.print(out);
325}
326
328 ut_ad(range.first != 0);
329 ut_ad(range.second != 0);
330 ut_ad(range.first != FIL_NULL);
331 ut_ad(range.second != FIL_NULL);
332 m_range = range;
333 m_page_no = m_range.first;
334}
335
337 ut_ad(is_valid());
339
340 if (m_page_no == m_range.second) {
341 return FIL_NULL;
342 }
343 return m_page_no++;
344}
345
346inline void Page_extent::init() {
347 ut_ad(m_range.first != 0);
348 ut_ad(m_range.second != 0);
349 ut_ad(m_range.first != FIL_NULL);
350 ut_ad(m_range.second != FIL_NULL);
351 m_page_no = m_range.first;
352 m_page_loads.reserve(page_count());
353}
354
356 return m_range.second - m_range.first;
357}
358
359/** Context information for each level. */
360struct Level_ctx {
361 /** Static member function construct a Level_ctx object.
362 @param[in] index dictionary index object.
363 @param[in] level the B-tree level of this context object.
364 @param[in] btree_load a back pointer to the Btree_load object to which this
365 Level_ctx object is a part of.
366 @return level context object on success, nullptr on error. */
367 static Level_ctx *create(dict_index_t *index, size_t level,
368 Btree_load *btree_load);
369
370 /** Static member function to destroy a Level_ctx object.
371 @param[in] obj the Level_ctx object to destroy. */
372 static void destroy(Level_ctx *obj);
373
374 /** Constructor
375 @param[in] index dictionary index object.
376 @param[in] level the B-tree level of this context object.
377 @param[in] btree_load a back pointer to the Btree_load object to which this
378 Level_ctx object is a part of.*/
379 Level_ctx(dict_index_t *index, size_t level, Btree_load *btree_load)
380 : m_index(index),
381 m_level(level),
383 m_btree_load(btree_load) {}
384
385 /** Destructor. */
386 ~Level_ctx();
387
388 /** Initialize.
389 @return DB_SUCCESS on success, an error code on failure. */
390 dberr_t init();
391
392 /** Check if this is leaf level.
393 @return true if this is leaf level, false otherwise. */
394 bool is_leaf() const { return m_level == 0; }
395
397
398 /** Free the current page load. */
399 void free_page_load();
400
401 /** Allocate a page number. Subsequently a Page_load will be created with the
402 allocated page number.
403 @param[out] page_no page number that was allocated.
404 @return DB_SUCCESS on success, error code on failure.*/
406
407 /** Allocate one extent in the relevant file segment. No associated buffer
408 blocks are allocated.
409 @return DB_SUCCESS on success, error code on failure.*/
411
412 /** Allocate private memory buffer (BUF_BLOCK_MEMORY) block for given page
413 number. */
414 [[nodiscard]] buf_block_t *alloc(const page_no_t new_page_no) noexcept;
415
416 void set_current_page_load(Page_load *sibling);
417
418 Page_load *get_page_load() const;
419
420 trx_id_t get_trx_id() const;
421
422 /** The current extent that is being loaded. */
424
425 /** Build the extent cache. */
426 void build_extent_cache();
427
428 /** Load one extent from extent cache.
429 @return true iff successful. */
431
432 /** Build page loader cache for current exent. */
433 void build_page_cache();
434
435 /** Get a free page loader from cache
436 @return page loader or nullptr if not found. */
438
439 /** Pre allocated extents to prevent repeated allocation and free. */
440 std::vector<Page_extent *> m_cached_extents;
441
442 /** The page_no of the first page in this level. */
444
445 /** The page_no of the last page in this level. */
447
448 /** The index which is being built. */
450
451 /** The B-tree level whose context information is stored in this obj. */
452 const size_t m_level{};
453
454 /** The Page_load of the current page being loaded. */
456
457 /** A back pointer to conceptually higher level btree load object. */
459
460 /** Number of pages allocated at this level. */
462
463 /** Number of extents allocated at this level. */
465
466 /** True if the current extent is full. */
467 bool m_extent_full{true};
468
469#ifdef UNIV_DEBUG
470 bool is_page_tracked(const page_no_t &page_no) const;
471 std::vector<page_no_t> m_pages_allocated;
472#endif /* UNIV_DEBUG */
473};
474
476
478 m_page_load = sibling;
479}
480
482 public:
483 enum class Type {
484 /** Allocate by Page */
485 PAGE,
486 /** Allocate by extent. */
487 EXTENT
488 };
489
490 /** Destructor to ensure thread stop. */
492
493 /** Check size and set extent allocator size parameters
494 @param[in] table InnoDB dictionary table object
495 @param[in] index InnoDB index being built.
496 @param[in] trx transaction performing bulk load
497 @param[in] size total data size to be loaded
498 @param[in] num_threads number of concurrent threads
499 @param[in] in_pages if true, allocate in pages
500 @return tablespace extend size in bytes. */
501 uint64_t init(dict_table_t *table, dict_index_t *index, trx_t *trx,
502 size_t size, size_t num_threads, bool in_pages);
503
504 /* Start extent allocator thread. */
505 void start();
506
507 /** Stop extent allocator thread, if active. */
508 void stop();
509
510 /** Allocate a page range - currently ans Extent.
511 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
512 @param[in] alloc_page if true, allocate in pages otherwise allocate extent
513 @param[out] range page range
514 @param[in,out] fn_wait_begin begin callback if wait is needed
515 @param[in,out] fn_wait_end end callback if wait is needed
516 @return Innodb error code. */
517 dberr_t allocate(bool is_leaf, bool alloc_page, Page_range_t &range,
518 std::function<void()> &fn_wait_begin,
519 std::function<void()> &fn_wait_end);
520
521 private:
522 /** Upper bound for max ranges. */
523 static constexpr size_t S_MAX_RANGES = 2 * 1024;
524
525 /** Maximum size by which the tablespace is extended each time. */
526 static constexpr size_t S_BULK_EXTEND_SIZE_MAX = 64;
527
529 /** Initialize cache.
530 @param[in] max_range maximum number of extents to cache. */
531 void init(size_t max_range);
532
533 /** @return true if no available extent to consume. */
534 inline bool is_empty() const { return (m_num_allocated == m_num_consumed); }
535
536 /** @return true if cache is full and no more extents can be added. */
537 inline bool is_full() const {
539 }
540
541 /** Check for number of extents to be allocated and cached.
542 @param[out] num_alloc number of extents to allocate
543 @param[out] num_free number of free extents
544 @return true if succesful. */
545 bool check(size_t &num_alloc, size_t &num_free) const;
546
547 /** Get one page range from the cache.
548 @param[out] range the allocated page range
549 @param[out] alloc_trigger true, if need to trigger allocator
550 @return true if extent is successfully returned from cache. */
551 bool get_range(Page_range_t &range, bool &alloc_trigger);
552
553 /** Set allocated range(extent) in cache.
554 @param[in] index position of the range
555 @param[in] range page range to be set */
556 void set_range(size_t index, Page_range_t &range);
557
558 /** Cached page ranges already allocated to the segment. */
559 std::array<Page_range_t, S_MAX_RANGES> m_ranges;
560
561 /** Maximum number of ranges to pre-allocate. */
563
564 /** Total number of ranges allocated. */
565 std::atomic<size_t> m_num_allocated{0};
566
567 /** Total number of ranges allocated. */
568 std::atomic<size_t> m_num_consumed{0};
569 };
570
571 /** Extent thread executor.
572 @return innodb error code. */
573 dberr_t run();
574
575 /** Allocate extents and fill the cache.
576 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
577 @param[in] num_extents number of extents to allocate
578 @return innodb error code. */
579 dberr_t allocate_extents(bool is_leaf, size_t num_extents);
580
581 /** Allocator wait function. */
582 void allocator_wait() const;
583
584 /** Check if leaf and non-leaf extent cache needs to be filled.
585 @param[out] n_leaf number of leaf extents to allocate
586 @param[out] n_non_leaf number of non-leaf extents to allocate
587 @param[out] trigger true if consumers should be triggered
588 @return true if allocator should stop. */
589 bool check(size_t &n_leaf, size_t &n_non_leaf, bool &trigger);
590
591 /** Allocate one extent.
592 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
593 @param[in,out] mtr mini tranaction to be used for allocation
594 @param[out] range page rannge for the extent
595 @return innodb error code. */
596 dberr_t allocate_extent(bool is_leaf, mtr_t &mtr, Page_range_t &range);
597
598 /** Allocate one page.
599 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
600 @param[out] range page rannge for the page
601 @return innodb error code. */
602 dberr_t allocate_page(bool is_leaf, Page_range_t &range);
603
604 /** @return true if operation is interrupted. */
605 bool is_interrupted();
606
607 private:
608 /** Bulk extent allocator. */
609 std::thread m_thread;
610
611 /** Number of times consumer(s) had to wait. */
612 mutable size_t m_consumer_wait_count{};
613
614 /** Number of times allocator had to wait. */
615 mutable size_t m_allocator_wait_count{};
616
617 /** Total consumer wait time in micro seconds. */
618 mutable std::chrono::microseconds m_consumer_wait_time;
619
620 /** Total allocator wait time in micro seconds. */
621 mutable std::chrono::microseconds m_allocator_wait_time;
622
623 /** Page range type. */
625
626 /** Cached leaf extents. */
628
629 /** Cached non-leaf extents. */
631
632 /** This mutex protects the m_queue. */
633 mutable std::mutex m_mutex;
634
635 /** Condition variable for allocator thread. */
636 mutable std::condition_variable m_allocator_condition;
637
638 /** Condition variable for extent consumer threads. */
639 mutable std::condition_variable m_consumer_condition;
640
641 /** Flag to indicate if the bulk allocator thread should stop. */
642 bool m_stop{false};
643
644 /** Error code, protected by m_mutex */
646
647 /** Innodb dictionary table object. */
650
651 /** Innodb transaction - used for checking interrupt. */
653
654 /** Number of concurrent consumers. */
656};
657
659 public:
660 /** Thread main function.
661 @return innodb error code. */
662 dberr_t run();
663
664 /** Check if work is available for the bulk flusher thread.
665 @return true if work is available. */
666 bool is_work_available();
667
668 /** Start a new thread to do the flush work.
669 @param[in] space_id space for flushing pages to
670 @param[in] index loader index
671 @param[in] queue_size flusher queue size */
672 void start(space_id_t space_id, size_t index, size_t queue_size);
673
674 /** Add a page extent to the bulk flush queue.
675 @param[in,out] page_extent extent to be added to the queue
676 @param[in,out] fn_wait_begin begin callback if wait is needed
677 @param[in,out] fn_wait_end end callback if wait is needed */
678 void add(Page_extent *page_extent, std::function<void()> &fn_wait_begin,
679 std::function<void()> &fn_wait_end);
680
681 /** Check for flusher error and wake up flusher thread.
682 @return Innodb error code. */
684
685 /** Wait till the bulk flush thread stops. */
686 void wait_to_stop();
687
688 /** Get the maximum allowed queue size.
689 @return the maximum allowed queue size. */
690 size_t get_max_queue_size() const { return m_max_queue_size; }
691
692 /** Destructor. */
694
695 /** @return true iff error has occurred. */
696 bool is_error() const { return m_is_error.load(); }
697
698 /** @return error code */
699 dberr_t get_error() const;
700
701 void add_to_free_queue(Page_extent *page_extent);
702
704
705 private:
706 /** Do the actual work of flushing.
707 @param[in,out] node space file node
708 @param[in,out] iov vector IO array
709 @param[in] iov_size vector IO array size */
710 void do_work(fil_node_t *node, void *iov, size_t iov_size);
711
712 /** Check if the bulk flush thread should stop working. */
713 bool should_i_stop() const { return m_stop.load(); }
714
715 /** When no work is available, put the thread to sleep. */
716 void wait();
717
718 /** Print useful information to the server log file while exiting. */
719 void info();
720
721 /** This queue is protected by the m_mutex. */
722 std::vector<Page_extent *> m_queue;
723
724 /** This mutex protects the m_queue. */
725 mutable std::mutex m_mutex;
726
727 /** Condition variable to wait upon. */
728 mutable std::condition_variable m_condition;
729
730 /** This queue is protected by the m_free_mutex. It is used to cache the
731 Page_extent objects that have been flushed and ready for re-use. */
732 std::vector<Page_extent *> m_free_queue;
733
734 /** This mutex protects the m_free_queue. */
735 mutable std::mutex m_free_mutex;
736
737 /** Flag to indicate if the bulk flusher thread should stop. If true, the
738 bulk flusher thread will stop after emptying the queue. If false, the
739 bulk flusher thread will go to sleep after emptying the queue. */
740 std::atomic<bool> m_stop{false};
741
742 /** Set if error is encountered during flush. */
743 std::atomic<bool> m_is_error{false};
744
745 /** Error code, protected by m_mutex */
747
748 /** Set error code.
749 @param[in] error_code error code to set. It could be DB_SUCCESS.*/
750 void set_error(dberr_t error_code);
751
752 /** Private queue (private to the bulk flush thread) containing the extents to
753 flush. */
754 std::vector<Page_extent *> m_priv_queue;
755
756 /** Bulk flusher thread. */
757 std::thread m_flush_thread;
758
759 /** Number of times slept */
760 size_t m_n_sleep{};
761
762 /** Total sleep time in micro seconds. */
763 std::chrono::microseconds m_wait_time;
764
765 /** The sleep duration in milliseconds. */
767
768 /** Maximum queue size, defaults to 4 */
770
771 /** Number of pages flushed. */
773
774 /** Bulk flusher is specific to a tablespace for now. */
776
777 /** Flusher ID. */
778 size_t m_id{};
779
780#ifdef UNIV_DEBUG
781 public:
782 /** Vector of page numbers that are flushed by this Bulk_flusher object. */
783 std::vector<page_no_t> m_flushed_page_nos;
784#endif /* UNIV_DEBUG */
785};
786
787namespace bulk {
788
789class Blob_handle;
790
791/** Used to insert many blobs into InnoDB. */
793 public:
794 /** Constructor.
795 @param[in] btree_load the B-tree into which blobs are inserted. */
796 Blob_inserter(Btree_load &btree_load);
797
799
800 /** Initialize by allocating necessary resources.
801 @return DB_SUCCESS on success or a failure error code. */
802 dberr_t init();
803
804 void finish();
805
807 Blob_context blob_ctx;
808 dberr_t err = open_blob(blob_ctx, ref);
809 if (err != DB_SUCCESS) {
810 return err;
811 }
812 const byte *data = (const byte *)dfield->data;
813 err = write_blob(blob_ctx, ref, data, dfield->len);
814 if (err != DB_SUCCESS) {
815 return err;
816 }
817 return close_blob(blob_ctx, ref);
818 }
819
820 /** Create a blob.
821 @param[out] blob_ctx pointer to an opaque object representing a blob.
822 @param[out] ref blob reference to be placed in the record.
823 @return DB_SUCCESS on success or a failure error code. */
825
826 /** Write data into the blob.
827 @param[in] blob_ctx pointer to blob into which data is written.
828 @param[out] ref blob reference to be placed in the record.
829 @param[in] data buffer containing data to be written
830 @param[in] len length of the data to be written.
831 @return DB_SUCCESS on success or a failure error code. */
832 dberr_t write_blob(Blob_context blob_ctx, lob::ref_t &ref, const byte *data,
833 size_t len);
834
835 /** Indicate that the blob has been completed, so that resources can be
836 removed, and as necessary flushing can be done.
837 @param[in] blob_ctx pointer to blob which has been completely written.
838 @param[out] ref a blob ref object.
839 @return DB_SUCCESS on success or a failure error code. */
841
842 /** Allocate a LOB first page
843 @return a LOB first page. */
845
846 /** Allocate a data page
847 @return a LOB data page. */
849
850 /** Allocate a LOB index page.
851 @return a LOB index page. */
853
854 /** Get the current transaction id.
855 @return the current transaction id. */
856 trx_id_t get_trx_id() const;
857
859 return ctx == m_blob_handle.get();
860 }
861
862 private:
864
866
868
869 /** Page extent from which to allocate first pages of blobs.
870 @ref lob::bulk::first_page_t. */
872
874
875 /** Page extent from which to allocate data pages of blobs.
876 @ref lob::bulk::data_page_t. */
878
879 /** Page extent from which to allocate index pages of blobs.
880 @ref lob::bulk::node_page_t. */
881 std::list<Page_extent *> m_index_extents;
882
883 /** The current blob being inserted. */
885
886 /** Cache of Page_load objects. */
888
889 /** Cache of Page_extent objects. */
891
892 /** Only one blob handle per sub-tree */
894};
895
896} /* namespace bulk */
897
898/** @note We should call commit(false) for a Page_load object, which is not in
899m_page_loaders after page_commit, and we will commit or abort Page_load
900objects in function "finish". */
902 public:
903 /** Merge multiple Btree_load sub-trees together. */
904 class Merger;
905
906 /** Class used to read the target table when the table is not empty. We bulk
907 load into a duplicate and migrate the data into it. */
908 class Table_reader;
909
911 return m_full_blob_inserter.insert_blob(ref, dfield);
912 }
913
914 /** Create a blob.
915 @param[out] blob_ctx pointer to an opaque object representing a blob.
916 @param[out] ref blob reference to be placed in the record.
917 @return DB_SUCCESS on success or a failure error code. */
919 return m_blob_inserter.open_blob(blob_ctx, ref);
920 }
921
922 /** Write data into the blob.
923 @param[in] blob_ctx pointer to blob into which data is written.
924 @param[in,out] ref blob reference of the current blob
925 @param[in] data buffer containing data to be written
926 @param[in] len length of the data to be written.
927 @return DB_SUCCESS on success or a failure error code. */
928 dberr_t write_blob(Blob_context blob_ctx, lob::ref_t &ref, const byte *data,
929 size_t len) {
930 return m_blob_inserter.write_blob(blob_ctx, ref, data, len);
931 }
932
933 /** Indicate that the blob has been completed, so that resources can be
934 removed, and as necessary flushing can be done.
935 @param[in] blob_ctx pointer to blob which has been completely written.
936 @param[out] ref blob reference of the closed blob.
937 @return DB_SUCCESS on success or a failure error code. */
939 return m_blob_inserter.close_blob(blob_ctx, ref);
940 }
941
942 public:
945 std::vector<Page_loader_ptr, ut::allocator<Page_loader_ptr>>;
946 using Level_ctxs = std::vector<Level_ctx *, ut::allocator<Level_ctx *>>;
947
948 /** Helper to set wait callbacks for the current scope. */
950 public:
951 using Function = std::function<void()>;
952 friend class Btree_load;
953
955 : m_btree_load(btree_load) {
958 }
959
961 m_btree_load->m_fn_wait_begin = nullptr;
962 m_btree_load->m_fn_wait_end = nullptr;
963 }
964
965 private:
966 /** Btree Load for the wait callbacks. */
968 };
969
970 /** Constructor
971 @param[in] index B-tree index.
972 @param[in] trx Transaction object.
973 @param[in] loader_num loader index
974 @param[in] flush_queue_size bulk flusher queue size
975 @param[in] allocator extent allocator */
976 Btree_load(dict_index_t *index, trx_t *trx, size_t loader_num,
977 size_t flush_queue_size,
978 Bulk_extent_allocator &allocator) noexcept;
979
980 /** Destructor */
982
983 /** Initialize. Allocates the m_heap_order memory heap.
984 @return DB_SUCCESS on success or an error code on failure. */
985 dberr_t init();
986
987#ifdef UNIV_DEBUG
988 /** Save flushed page numbers for debugging purposes.
989 @param[in] page_no page number of the page that is flushed. */
991 m_bulk_flusher.m_flushed_page_nos.push_back(page_no);
992 }
993#endif /* UNIV_DEBUG */
994
995 /** Check if the index build operation has been interrupted.
996 @return true if the index build operation is interrupted, false otherwise.*/
997 bool is_interrupted() const;
998
999 /** Trigger flusher thread and check for error.
1000 @return Innodb error code. */
1002
1003 bool is_pk() const { return m_index->is_clustered(); }
1004
1005 /** Get the index object.
1006 @return index object. */
1007 dict_index_t *index() const { return m_index; }
1008
1009 const char *get_table_name() const { return m_index->table->name.m_name; }
1010
1011 /** Get the root page number of this tree/subtree.
1012 @return the root page number of this tree/subtree. */
1014
1015 /** Get the level of the root page.
1016 @return the level of the root page. */
1017 size_t get_root_level() const { return m_root_level; }
1018
1019 /** Get information about root page. */
1020 void get_root_page_stat(Page_stat &stat);
1021
1022 /** Get the transaction id.
1023 @return the transaction id. */
1024 trx_id_t get_trx_id() const;
1025
1026 /** Btree bulk load finish. We commit the last page in each level
1027 and copy the last page in top level to the root page of the index
1028 if no error occurs.
1029 @param[in] is_err Whether bulk load was successful until now
1030 @param[in] subtree true if a subtree is being built, false otherwise.
1031 @return error code */
1032 [[nodiscard]] dberr_t finish(bool is_err, const bool subtree) noexcept;
1033
1034 /** Insert a tuple to a page in a level
1035 @param[in] dtuple Tuple to insert
1036 @param[in] level B-tree level
1037 @return error code */
1038 [[nodiscard]] dberr_t insert(dtuple_t *dtuple, size_t level) noexcept;
1039
1040 /** Split the right most block of the tree at the given level.
1041 @param[in,out] block the right most block at the given level.
1042 @param[in] level level of the given block.
1043 @param[in] node_ptr node pointer to be inserted in the block after
1044 splitting.
1045 @param[in] mtr mini transaction context.
1046 @param[in,out] highest_level highest level among all the subtrees.*/
1047 void split_rightmost(buf_block_t *block, size_t level, dtuple_t *node_ptr,
1048 mtr_t *mtr, size_t &highest_level);
1049
1050 /** Split the left most block of the tree at the given level.
1051 @param[in,out] block the left most block at the given level. it will be
1052 updated with the new left most block.
1053 @param[in] level level of the given block.
1054 @param[in] node_ptr node pointer to be inserted in the block after
1055 splitting.
1056 @param[in] mtr mini transaction context.
1057 @param[in,out] highest_level highest level among all the subtrees.*/
1058 void split_leftmost(buf_block_t *&block, size_t level, dtuple_t *node_ptr,
1059 mtr_t *mtr, size_t &highest_level);
1060
1061 private:
1062 /** Set the root page on completion.
1063 @param[in] last_page_no Last page number (the new root).
1064 @return DB_SUCCESS or error code. */
1065 [[nodiscard]] dberr_t load_root_page(page_no_t last_page_no) noexcept;
1066
1067 public:
1068 /** Commit(finish) a page. We set next/prev page no, insert a node pointer to
1069 father page if needed, and commit mini-transaction.
1070 @param[in] page_load Page to commit
1071 @param[in] next_page_load Next page
1072 @param[in] insert_father Flag whether need to insert node ptr
1073 @return error code */
1074 [[nodiscard]] dberr_t page_commit(Page_load *page_load,
1075 Page_load *next_page_load,
1076 bool insert_father) noexcept;
1077
1078 /** Prepare space to insert a tuple.
1079 @param[in,out] page_load Page bulk that will be used to store the record.
1080 It may be replaced if there is not enough space
1081 to hold the record.
1082 @param[in] level B-tree level
1083 @param[in] rec_size Record size
1084 @return error code */
1085 [[nodiscard]] dberr_t prepare_space(Page_load *&page_load, size_t level,
1086 size_t rec_size) noexcept;
1087
1088 /** Insert a tuple to a page.
1089 @param[in] page_load Page bulk object
1090 @param[in] tuple Tuple to insert
1091 @param[in] big_rec Big record vector, maybe NULL if there is no
1092 Data to be stored externally.
1093 @param[in] rec_size Record size
1094 @return error code */
1095 [[nodiscard]] dberr_t insert(Page_load *page_load, dtuple_t *tuple,
1096 big_rec_t *big_rec, size_t rec_size) noexcept;
1097
1098 /** Btree page bulk load finish. Commits the last page in each level
1099 if no error occurs. Also releases all page bulks.
1100 @param[in] is_err Whether bulk load was successful until now
1101 @param[out] last_page_no Last page number
1102 @return error code */
1103 [[nodiscard]] dberr_t finalize_page_loads(bool is_err,
1104 page_no_t &last_page_no) noexcept;
1105
1106 public:
1107 /** Allocate an extent.
1108 @param[in,out] page_range the range of pages allocated.
1109 @param[in] level btree level for which pages are allocated.
1110 @return status code. */
1111 dberr_t alloc_extent(Page_range_t &page_range, size_t level);
1112
1113 /** Initiate a direct file write operation.
1114 @param[in] block block to be written to disk.
1115 @return error code. */
1116 [[nodiscard]] dberr_t fil_io(buf_block_t *block) noexcept;
1117
1118 /** Flush the blob pages.
1119 @return status code. */
1121
1122 /** Add the given block the internal cache of blocks.
1123 @param[in] block the block to be cached. */
1124 inline void block_put(buf_block_t *block);
1125
1126 /** Remove the given block from the internal cache of blocks.
1127 @param[in] page_no the page number of block to be removed from cache. */
1128 inline void block_remove(const page_no_t page_no);
1129
1130 /** Search for a BUF_BLOCK_MEMORY block with given page number in the local
1131 cache.
1132 @param[in] page_no the page number of block to be fetched.
1133 @return buffer block with given page number. */
1134 [[nodiscard]] inline buf_block_t *block_get(page_no_t page_no) const noexcept;
1135
1136 /** Evict all the pages in the given range from the buffer pool.
1137 @param[in] range range of page numbers.
1138 @param[in] dirty_is_ok it is OK for a page to be dirty. */
1139 void force_evict(const Page_range_t &range, const bool dirty_is_ok = true);
1140
1141 public:
1142 /** Check if a new level is needed. */
1143 bool is_new_level(size_t level) const { return level >= m_level_ctxs.size(); }
1144
1145 /** Last page numbers of each level. */
1146 std::vector<page_no_t, ut::allocator<page_no_t>> m_last_page_nos{};
1147
1148 /** First page numbers of each level. */
1149 std::vector<page_no_t, ut::allocator<page_no_t>> m_first_page_nos{};
1150
1151 /** Get the level context object.
1152 @param[in] level the level number. level 0 is leaf level.
1153 @return the level context object. */
1154 Level_ctx *get_level(size_t level) const;
1155
1156 /** Page numbers of the pages that has been allocated in the leaf level.
1157 The page range is [p1, p2), where p2 is not included. */
1159
1160 /** Page numbers of the pages that has been allocated in the non-leaf level.
1161 The page range is [p1, p2), where p2 is not included. */
1163
1166
1167 /** State of the index. Used for asserting at the end of a
1168 bulk load operation to ensure that the online status of the
1169 index does not change */
1171
1172 /** Number of extents allocated for this B-tree. */
1174
1175 /** Number of pages allocated for this B-tree. */
1177
1178 public:
1179 std::ostream &print_left_pages(std::ostream &out) const;
1180 std::ostream &print_right_pages(std::ostream &out) const;
1181
1182 dberr_t check_key_overlap(const Btree_load *r_btree) const;
1183
1184#ifdef UNIV_DEBUG
1185 void print_tree_pages() const;
1186 std::string print_pages_in_level(const size_t level) const;
1187 /** Check size and validate index of limited size.
1188 @param[in] index Index to validate
1189 @return true if successful. */
1190 static bool validate_index(dict_index_t *index);
1191#endif /* UNIV_DEBUG */
1192
1193 /** All allocated extents registers with Btree_load. */
1194 void track_extent(Page_extent *page_extent);
1195
1196 /** Add fully used extents to the bulk flusher. Call this whenever a new
1197 Page_load is allocated, with finish set to false. Only in
1198 Btree_load::finish(), the finish argument will be true.
1199 @param[in] finish if true, add all the tracked extents to the bulk flusher,
1200 irrespective of whether it is fully used or not. */
1201 void add_to_bulk_flusher(bool finish = false);
1202
1203 /** Add blob extents to the bulk flusher and wait till they are flushed. */
1205
1206 /** Add the given page extent object to the bulk flusher.
1207 @param[in] page_extent the extent to be flushed. */
1208 void add_to_bulk_flusher(Page_extent *page_extent);
1209
1210 /** Check if transparent page compression (TPC) is enabled.
1211 @return true if TPC is enabled. */
1212 bool is_tpc_enabled() const;
1213
1214 /** Check if transparent page encryption (TPE) is enabled.
1215 @return true if TPE is enabled. */
1216 bool is_tpe_enabled() const;
1217
1218 /** @return get flush queue size limit. */
1221 }
1222
1223 /** If the data is already sorted and checked for duplicates, then we can
1224 disable doing it again. */
1226
1228
1231 }
1232
1233 private:
1234 /** Page allocation type. We allocate in extents by default. */
1237
1238 /** Number of records inserted. */
1239 uint64_t m_n_recs{};
1240
1241 /** B-tree index */
1243
1245
1246 /** Transaction id */
1248
1249 /** Root page level */
1251
1252 /** Context information for each level of the B-tree. The leaf level is at
1253 m_level_ctxs[0]. */
1255
1256 /** Reference to global extent allocator. */
1258
1259 /** Extents that are being tracked. */
1260 std::list<Page_extent *> m_extents_tracked;
1261
1262 /** If true, check if data is inserted in sorted order. */
1263 bool m_check_order{true};
1264
1265 /** Memory heap to be used for sort order checks. */
1267
1268 /** Function object to compare two tuples. */
1270
1271 /** The previous tuple that has been inserted. */
1273
1274 bool is_extent_tracked(const Page_extent *page_extent) const;
1275
1276 /** Loader number. */
1278
1280
1281 /* Begin wait callback function. */
1283
1284 /* End wait callback function. */
1286
1287 /** Blob inserter to handle the externally stored fields of InnoDB. This
1288 is used when blobs are inserted using multiple calls like open_blob(),
1289 write_blob() and close_blob(). */
1291
1292 /** Need another blob inserter to store blobs with a single call using
1293 insert_blob() */
1295
1296 /* Dedicated thread to flush pages. */
1298
1300};
1301
1303 public:
1304 using Btree_loads = std::vector<Btree_load *, ut::allocator<Btree_load *>>;
1305
1306 Merger(const size_t n_threads, Btree_loads &loads, dict_index_t *index,
1307 const trx_t *trx)
1308 : m_n_threads(n_threads),
1309 m_btree_loads(loads),
1310 m_index(index),
1311 m_trx(trx),
1313
1314 dberr_t merge(bool sort);
1315
1316 private:
1317 /** Get the maximum free space available in an empty page in bytes.
1318 @return the maximum free space available in an empty page. */
1319 size_t get_max_free() const {
1321 }
1322
1323 /** Remove any empty sub-trees with no records. */
1324 void remove_empty_subtrees();
1325
1326#ifdef UNIV_DEBUG
1327 /** Validate sub-tree boundaries. */
1328 void validate_boundaries();
1329
1330#endif /* UNIV_DEBUG */
1331
1332 /** Stich sub-trees together to form a tree with one or multiple
1333 nodes at highest leve.
1334 @param[out] highest_level highest level of the merged tree.
1335 @return innodb error code. */
1336 dberr_t subtree_link_levels(size_t &highest_level);
1337
1338 /** Create root node for the stiched sub-trees by combining the nodes
1339 at highest level creating another level if required.
1340 @param[in] highest_level highest level of the merged tree.
1341 @return innodb error code. */
1342 dberr_t add_root_for_subtrees(const size_t highest_level);
1343
1344 /** Insert the given list of node pointers into pages at the given level.
1345 @param[in,out] all_node_ptrs list of node pointers
1346 @param[in,out] total_node_ptrs_size total space in bytes needed to insert
1347 all the node pointers.
1348 @param[in] level the level at which the node pointers are inserted.
1349 @return DB_SUCCESS if successful.
1350 @return error code on failure. */
1351 dberr_t insert_node_ptrs(std::vector<dtuple_t *> &all_node_ptrs,
1352 size_t &total_node_ptrs_size, size_t level);
1353
1354 /** Load the left page and update its FIL_PAGE_NEXT.
1355 @param[in] l_page_no left page number
1356 @param[in] r_page_no right page number. */
1357 void link_right_sibling(const page_no_t l_page_no, const page_no_t r_page_no);
1358
1359 private:
1360 /** Number of loader threads. */
1361 const size_t m_n_threads;
1362
1363 /** Refernce to the subtrees to be merged. */
1365
1366 /** Index which is being built. */
1368
1369 /** Transaction making the changes. */
1370 const trx_t *m_trx{};
1371
1372 /** Memory heap to store node pointers. */
1374};
1375
1377 const Page_extent *page_extent) const {
1378 for (auto e : m_extents_tracked) {
1379 if (page_extent == e) {
1380 return true;
1381 }
1382 }
1383 return false;
1384}
1385
1386/** The proper function call sequence of Page_load is as below:
1387-- Page_load::init
1388-- Page_load::insert
1389-- Page_load::finish
1390-- Page_load::commit */
1392 public:
1394
1395 /** Ctor.
1396 @param[in] index B-tree index
1397 @param[in] btree_load btree object to which this page belongs. */
1398 Page_load(dict_index_t *index, Btree_load *btree_load);
1399
1400 /** Destructor. */
1402
1403 /** Check if page is corrupted.
1404 @return true if corrupted, false otherwise. */
1405 bool is_corrupted() const;
1406
1407 /** Print the child page numbers. */
1409
1410 /** Check if state of this page is BUF_BLOCK_MEMORY.
1411 @return true if page state is BUF_BLOCK_MEMORY, false otherwise.*/
1412 bool is_memory() const { return m_block->is_memory(); }
1413
1414 /** A static member function to create this object.
1415 @param[in] btree_load the bulk load object to which this Page_load belongs.
1416 @param[in] page_extent page extent to which this page belongs. */
1417 static Page_load *create(Btree_load *btree_load, Page_extent *page_extent);
1418
1419 /** Release the page loader. Delete if not cached.
1420 @param[in] page_load page loader to delete. */
1421 static void drop(Page_load *page_load);
1422
1423 /** Constructor
1424 @param[in] index B-tree index
1425 @param[in] trx_id Transaction id
1426 @param[in] page_no Page number
1427 @param[in] level Page level
1428 @param[in] observer Flush observer
1429 @param[in] btree_load btree object to which this page belongs. */
1431 size_t level, Flush_observer *observer,
1432 Btree_load *btree_load = nullptr) noexcept
1433 : m_index(index),
1434 m_trx_id(trx_id),
1435 m_page_no(page_no),
1436 m_level(level),
1438 m_flush_observer(observer),
1439 m_btree_load(btree_load) {
1441 }
1442
1443 /** Set the transaction id.
1444 @param[in] trx_id the transaction id to used. */
1445 void set_trx_id(const trx_id_t trx_id) { m_trx_id = trx_id; }
1446
1447 /** Get the current transaction identifier.
1448 @return the current transaction identifier.*/
1449 trx_id_t get_trx_id() const { return m_trx_id; }
1450
1451 /** Set the flush observer.
1452 @param[in] observer the flush observer object to use. */
1454 m_flush_observer = observer;
1455 }
1456
1457 bool is_leaf() const { return m_level == 0; }
1458
1459 /** Set the page number of this object. */
1460 void set_page_no(const page_no_t page_no);
1461
1462 void set_leaf_seg(const fseg_header_t *hdr) {
1464 }
1465 void set_top_seg(const fseg_header_t *hdr) {
1467 }
1468
1469 /** Initialize members and allocate page if needed and start mtr.
1470 @note Must be called and only once right after constructor.
1471 @return error code */
1472 [[nodiscard]] dberr_t init() noexcept;
1473 [[nodiscard]] dberr_t init_mem(const page_no_t new_page_no,
1474 Page_extent *page_extent) noexcept;
1475
1476 /** Initialize a memory block to be used for storing blobs.
1477 @param[in] page_no the page number to be set in the memory block.
1478 @param[in] page_extent extent to which this page belongs.
1479 @return DB_SUCCESS on success, error code on failure.*/
1480 [[nodiscard]] dberr_t init_mem_blob(const page_no_t page_no,
1481 Page_extent *page_extent) noexcept;
1482
1483 /** Allocate a page for this Page_load object.
1484 @return DB_SUCCESS on success, error code on failure. */
1486
1487 /** Re-initialize this page. */
1488 [[nodiscard]] dberr_t reinit() noexcept;
1489
1490 /** Reset this object so that Page_load::init() can be called again on this
1491 object. */
1492 void reset() noexcept;
1493
1494 /** Insert a tuple in the page.
1495 @param[in] tuple Tuple to insert
1496 @param[in] big_rec External record
1497 @param[in] rec_size Record size
1498 @return error code */
1499 [[nodiscard]] dberr_t insert(const dtuple_t *tuple, const big_rec_t *big_rec,
1500 size_t rec_size) noexcept;
1501
1502 /** Mark end of insertion to the page. Scan records to set page dirs,
1503 and set page header members. The scan is incremental (slots and records
1504 which assignment could be "finalized" are not checked again. Check the
1505 m_slotted_rec_no usage, note it could be reset in some cases like
1506 during split.
1507 Note: we refer to page_copy_rec_list_end_to_created_page.*/
1508 void finish() noexcept;
1509
1510 /** Commit mtr for a page
1511 @return DB_SUCCESS on success, error code on failure. */
1513
1514 /** Commit mtr for a page */
1515 void rollback() noexcept;
1516
1517 /** Check whether the record needs to be stored externally.
1518 @return false if the entire record can be stored locally on the page */
1519 [[nodiscard]] bool need_ext(const dtuple_t *tuple,
1520 size_t rec_size) const noexcept;
1521
1522 /** Store externally the first possible field of the given tuple.
1523 @return true if a field was stored externally, false if it was not possible
1524 to store any of the fields externally. */
1525 [[nodiscard]] bool make_ext(dtuple_t *tuple);
1526
1527 /** Get node pointer
1528 @return node pointer */
1529 [[nodiscard]] dtuple_t *get_node_ptr() noexcept;
1530
1531 /** Get node pointer
1532 @param[in] heap allocate node pointer in the given heap.
1533 @return node pointer */
1534 [[nodiscard]] dtuple_t *get_node_ptr(mem_heap_t *heap) noexcept;
1535
1536 /** Copy all records from page.
1537 @param[in] src_page Page with records to copy. */
1538 size_t copy_all(const page_t *src_page) noexcept;
1539
1540 /** Distribute all records from this page to the given pages.
1541 @param[in,out] to_pages array of Page_load objects.
1542 return total number of records processed. */
1543 size_t copy_to(std::vector<Page_load *> &to_pages);
1544
1545 /** Set next page
1546 @param[in] next_page_no Next page no */
1547 void set_next(page_no_t next_page_no) noexcept;
1548
1549 /** Set previous page
1550 @param[in] prev_page_no Previous page no */
1551 void set_prev(page_no_t prev_page_no) noexcept;
1552
1553 /** Get previous page (FIL_PAGE_PREV). */
1555
1556 /** Start mtr and latch block */
1558
1559 /** Check if required space is available in the page for the rec
1560 to be inserted. We check fill factor & padding here.
1561 @param[in] rec_size Required space
1562 @return true if space is available */
1563 [[nodiscard]] inline bool is_space_available(size_t rec_size) const noexcept;
1564
1565 /** Get the page number of this page load object.
1566 @return the page number of this page load object. */
1567 [[nodiscard]] page_no_t get_page_no() const noexcept { return m_page_no; }
1568
1569 [[nodiscard]] page_id_t get_page_id() const noexcept {
1570 return m_block->page.id;
1571 }
1572
1573 /** Get the physical page size of the underlying tablespace.
1574 @return the physical page size of the tablespace. */
1575 size_t get_page_size() const noexcept;
1576
1577 /** Get the table space ID.
1578 @return the table space ID. */
1579 space_id_t space() const noexcept;
1580
1581#ifdef UNIV_DEBUG
1582 /** Obtain tablespace id from the frame and the buffer block and ensure that
1583 they are the same.
1584 @return true if space id is same in both places. */
1585 bool verify_space_id() const;
1586#endif /* UNIV_DEBUG */
1587
1588 /** Get page level */
1589 [[nodiscard]] size_t get_level() const noexcept { return m_level; }
1590
1591 /** Set the level of this page. */
1592 void set_level(size_t level) noexcept { m_level = level; }
1593
1594 /** Get record no */
1595 [[nodiscard]] size_t get_rec_no() const { return m_rec_no; }
1596
1597 /** Get page */
1598 [[nodiscard]] const page_t *get_page() const noexcept {
1600 }
1601
1602 [[nodiscard]] page_t *get_page() noexcept {
1604 }
1605
1606 public:
1607 void init_for_writing();
1608 size_t get_data_size() const { return page_get_data_size(m_page); }
1609
1610#ifdef UNIV_DEBUG
1611 /** Check if index is X locked
1612 @return true if index is locked. */
1614#endif /* UNIV_DEBUG */
1615
1616 /** Copy given and all following records.
1617 @param[in] first_rec First record to copy */
1618 size_t copy_records(const rec_t *first_rec) noexcept;
1619
1620 /** Insert a record in the page, check for duplicates too.
1621 @param[in] rec Record
1622 @param[in] offsets Record offsets
1623 @return DB_SUCCESS or error code. */
1624 dberr_t insert(const rec_t *rec, Rec_offsets offsets) noexcept;
1625
1626 public:
1627 /** Store external record
1628 Since the record is not logged yet, so we don't log update to the record.
1629 the blob data is logged first, then the record is logged in bulk mode.
1630 @param[in] big_rec External record
1631 @param[in] offsets Record offsets
1632 @return error code */
1633 [[nodiscard]] dberr_t store_ext(const big_rec_t *big_rec,
1634 Rec_offsets offsets) noexcept;
1635
1636 /** Set the REC_INFO_MIN_REC_FLAG on the first user record in this page.
1637 @param[in] mtr mini transaction context. */
1638 void set_min_rec_flag(mtr_t *mtr);
1639
1640 /** Set the REC_INFO_MIN_REC_FLAG on the first user record in this page. */
1641 void set_min_rec_flag();
1642 bool is_min_rec_flag() const;
1643
1644 /** Set the level context object for this page load
1645 @param[in] level_ctx the level context object. */
1646 void set_level_ctx(Level_ctx *level_ctx) { m_level_ctx = level_ctx; }
1647
1648 /** Check if this page load object contains a level context object.
1649 @return true if the page load contains a level context object.
1650 @return false if the page load does NOT contain a level context object.*/
1651 bool has_level_ctx() const { return m_level_ctx != nullptr; }
1652
1653 /** Free the memory block. */
1654 void free();
1655
1657
1659
1660 void set_page_extent(Page_extent *page_extent) {
1661 m_page_extent = page_extent;
1662 }
1663
1664 /** Mark the Page load as cached. Flush thread should not free this Page. */
1665 void set_cached() { m_is_cached.store(true); }
1666
1667 /** @return true iff it is a cached Page Load. */
1668 bool is_cached() const { return m_is_cached.load(); }
1669
1670 private:
1671 /** Memory heap for internal allocation */
1673
1674 /** The index B-tree */
1676
1677 /** The min-transaction */
1679
1680 /** The transaction id */
1682
1683 /** The buffer block */
1685
1686 /** The page */
1688
1689 /** The current rec, just before the next insert rec */
1691
1692 /** The page no */
1694
1695 /** The page level in B-tree */
1696 size_t m_level{};
1697
1698 /** Flag: is page in compact format */
1699 const bool m_is_comp{};
1700
1701 /** The heap top in page for next insert */
1702 byte *m_heap_top{};
1703
1704 /** User record no */
1705 size_t m_rec_no{};
1706
1707 /** The free space left in the page */
1709
1710 /** The reserved space for fill factor */
1712
1713 /** Total data in the page */
1715
1716 /** The modify clock value of the buffer block
1717 when the block is re-pinned */
1718 uint64_t m_modify_clock{};
1719
1720 /** Flush observer */
1722
1723 /** Last record assigned to a slot. */
1725
1726 /** Number of records assigned to slots. */
1728
1729 /** Page modified flag. */
1731
1733
1735
1737
1738 /** true iff the the Page load is cached. */
1739 std::atomic_bool m_is_cached{false};
1740
1741 friend class Btree_load;
1742};
1743
1745 return get_node_ptr(m_heap);
1746}
1747
1749
1750inline size_t Page_load::get_page_size() const noexcept {
1751 const page_size_t page_size = m_index->get_page_size();
1752 return page_size.physical();
1753}
1754
1755inline Level_ctx *Btree_load::get_level(size_t level) const {
1756 ut_a(m_level_ctxs.size() > level);
1757 return m_level_ctxs[level];
1758}
1759
1760/** Information about a buffer page. */
1762 /** Number of user records in the page. */
1763 size_t m_n_recs;
1764
1765 /** Number of bytes of data. */
1767};
1768
1769inline void Page_extent::append(Page_load *page_load) {
1770 ut_ad(page_load->get_block() != nullptr);
1771 ut_ad(page_load->is_memory());
1772 ut_ad(page_load->get_page_no() >= m_range.first);
1773 ut_ad(page_load->get_page_no() < m_range.second);
1774 for (auto &iter : m_page_loads) {
1775 if (iter->get_page_no() == page_load->get_page_no()) {
1776 /* Page already appended. Don't append again. */
1777 return;
1778 }
1779 }
1781 m_page_loads.push_back(page_load);
1782}
1783
1785 return m_btree_load->get_trx_id();
1786}
1787
1789 return m_btree_load->index()->space;
1790}
1791
1792inline Page_extent::Page_extent(Btree_load *btree_load, const bool is_leaf)
1793 : m_page_no(FIL_NULL),
1794 m_range(FIL_NULL, FIL_NULL),
1795 m_btree_load(btree_load),
1796 m_is_leaf(is_leaf) {
1798}
1799
1801 const bool is_leaf, bool skip_track) {
1802 Page_extent *p = ut::new_withkey<Page_extent>(UT_NEW_THIS_FILE_PSI_KEY,
1803 btree_load, is_leaf);
1804 if (!skip_track) {
1805 btree_load->track_extent(p);
1806 }
1807 p->m_is_cached.store(false);
1808 return p;
1809}
1810
1811inline void Page_extent::drop(Page_extent *extent) {
1812 if (extent == nullptr) {
1813 return;
1814 }
1815 if (extent->is_cached()) {
1816 ut_a(!extent->is_free());
1817 bool free = true;
1818 extent->set_state(free);
1819 return;
1820 }
1821 ut::delete_(extent);
1822}
1823
1824/** Function object to compare two Btree_load objects. */
1827 bool operator()(const Btree_load *l_btree, const Btree_load *r_btree);
1829};
1830
1831#ifdef UNIV_DEBUG
1834#endif /* UNIV_DEBUG */
1835
1837 for (auto page_load : m_page_loads) {
1838 page_load->free();
1839 }
1840}
1841
1842namespace bulk {
1844 return m_btree_load.get_trx_id();
1845}
1846} /* namespace bulk */
1847
1848} /* namespace Btree_multi */
1849
1850#endif /* btr0mtib_h */
InnoDB Native API.
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:49
uint32_t page_no_t
Page number.
Definition: api0api.h:47
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:247
std::pair< page_no_t, page_no_t > Page_range_t
Definition: btr0btr.h:131
The B-tree bulk load.
static buf_frame_t * buf_block_get_frame(const buf_block_t *block)
Gets a pointer to the memory frame of a block.
Definition: btr0load.h:51
Definition: btr0mtib.h:1302
Merger(const size_t n_threads, Btree_loads &loads, dict_index_t *index, const trx_t *trx)
Definition: btr0mtib.h:1306
Btree_loads & m_btree_loads
Refernce to the subtrees to be merged.
Definition: btr0mtib.h:1364
std::vector< Btree_load *, ut::allocator< Btree_load * > > Btree_loads
Definition: btr0mtib.h:1304
const trx_t * m_trx
Transaction making the changes.
Definition: btr0mtib.h:1370
dict_index_t * m_index
Index which is being built.
Definition: btr0mtib.h:1367
void validate_boundaries()
Validate sub-tree boundaries.
Definition: btr0mtib.cc:2745
dberr_t insert_node_ptrs(std::vector< dtuple_t * > &all_node_ptrs, size_t &total_node_ptrs_size, size_t level)
Insert the given list of node pointers into pages at the given level.
Definition: btr0mtib.cc:3211
size_t get_max_free() const
Get the maximum free space available in an empty page in bytes.
Definition: btr0mtib.h:1319
void remove_empty_subtrees()
Remove any empty sub-trees with no records.
Definition: btr0mtib.cc:2732
dberr_t add_root_for_subtrees(const size_t highest_level)
Create root node for the stiched sub-trees by combining the nodes at highest level creating another l...
Definition: btr0mtib.cc:3053
Scoped_heap m_tuple_heap
Memory heap to store node pointers.
Definition: btr0mtib.h:1373
dberr_t merge(bool sort)
Definition: btr0mtib.cc:2671
const size_t m_n_threads
Number of loader threads.
Definition: btr0mtib.h:1361
void link_right_sibling(const page_no_t l_page_no, const page_no_t r_page_no)
Load the left page and update its FIL_PAGE_NEXT.
Definition: btr0mtib.cc:3183
dberr_t subtree_link_levels(size_t &highest_level)
Stich sub-trees together to form a tree with one or multiple nodes at highest leve.
Definition: btr0mtib.cc:2755
Helper to set wait callbacks for the current scope.
Definition: btr0mtib.h:949
~Wait_callbacks()
Definition: btr0mtib.h:960
Wait_callbacks(Btree_load *btree_load, Function &begin, Function &end)
Definition: btr0mtib.h:954
Btree_load * m_btree_load
Btree Load for the wait callbacks.
Definition: btr0mtib.h:967
std::function< void()> Function
Definition: btr0mtib.h:951
Definition: btr0mtib.h:901
~Btree_load() noexcept
Destructor.
Definition: btr0mtib.cc:1659
bulk::Blob_inserter m_full_blob_inserter
Need another blob inserter to store blobs with a single call using insert_blob()
Definition: btr0mtib.h:1294
dict_index_t * m_index
B-tree index.
Definition: btr0mtib.h:1242
Bulk_flusher m_bulk_flusher
Definition: btr0mtib.h:1297
dberr_t finish(bool is_err, const bool subtree) noexcept
Btree bulk load finish.
Definition: btr0mtib.cc:2014
dberr_t load_root_page(page_no_t last_page_no) noexcept
Set the root page on completion.
Definition: btr0mtib.cc:1890
dberr_t trigger_flusher() const
Trigger flusher thread and check for error.
Definition: btr0mtib.h:1001
bool is_tpe_enabled() const
Check if transparent page encryption (TPE) is enabled.
Definition: btr0mtib.cc:2663
Bulk_extent_allocator & m_allocator
Reference to global extent allocator.
Definition: btr0mtib.h:1257
bool is_new_level(size_t level) const
Check if a new level is needed.
Definition: btr0mtib.h:1143
bool is_pk() const
Definition: btr0mtib.h:1003
dberr_t check_key_overlap(const Btree_load *r_btree) const
Definition: btr0mtib.cc:3311
Btree_load(dict_index_t *index, trx_t *trx, size_t loader_num, size_t flush_queue_size, Bulk_extent_allocator &allocator) noexcept
Constructor.
Definition: btr0mtib.cc:1639
dict_index_t * index() const
Get the index object.
Definition: btr0mtib.h:1007
size_t get_max_flush_queue_size() const
Definition: btr0mtib.h:1219
void block_remove(const page_no_t page_no)
Remove the given block from the internal cache of blocks.
dberr_t insert(dtuple_t *dtuple, size_t level) noexcept
Insert a tuple to a page in a level.
Definition: btr0mtib.cc:1786
dtuple_t * m_prev_tuple
The previous tuple that has been inserted.
Definition: btr0mtib.h:1272
void force_evict(const Page_range_t &range, const bool dirty_is_ok=true)
Evict all the pages in the given range from the buffer pool.
Definition: btr0mtib.cc:2113
std::ostream & print_right_pages(std::ostream &out) const
Definition: btr0mtib.cc:2074
size_t m_root_level
Root page level.
Definition: btr0mtib.h:1250
std::vector< page_no_t, ut::allocator< page_no_t > > m_first_page_nos
First page numbers of each level.
Definition: btr0mtib.h:1149
byte m_fseg_hdr_leaf[FSEG_HEADER_SIZE]
Definition: btr0mtib.h:1164
void block_put(buf_block_t *block)
Add the given block the internal cache of blocks.
dberr_t init()
Initialize.
Definition: btr0mtib.cc:2206
void add_blobs_to_bulk_flusher()
Add blob extents to the bulk flusher and wait till they are flushed.
Definition: btr0mtib.cc:1746
Bulk_extent_allocator::Type m_alloc_type
Page allocation type.
Definition: btr0mtib.h:1235
Page_range_t m_page_range_leaf
Page numbers of the pages that has been allocated in the leaf level.
Definition: btr0mtib.h:1158
void get_root_page_stat(Page_stat &stat)
Get information about root page.
Definition: btr0mtib.cc:2124
size_t m_loader_num
Loader number.
Definition: btr0mtib.h:1277
Level_ctxs m_level_ctxs
Context information for each level of the B-tree.
Definition: btr0mtib.h:1254
page_no_t get_subtree_root() const
Get the root page number of this tree/subtree.
Definition: btr0mtib.h:1013
size_t m_stat_n_pages
Number of pages allocated for this B-tree.
Definition: btr0mtib.h:1176
trx_t * m_trx
Transaction id.
Definition: btr0mtib.h:1247
dberr_t flush_blobs() noexcept
Flush the blob pages.
dberr_t open_blob(Blob_context &blob_ctx, lob::ref_t &ref)
Create a blob.
Definition: btr0mtib.h:918
mem_heap_t * m_heap_order
Memory heap to be used for sort order checks.
Definition: btr0mtib.h:1266
dberr_t prepare_space(Page_load *&page_load, size_t level, size_t rec_size) noexcept
Prepare space to insert a tuple.
Definition: btr0mtib.cc:1667
std::list< Page_extent * > m_extents_tracked
Extents that are being tracked.
Definition: btr0mtib.h:1260
void track_page_flush(page_no_t page_no)
Save flushed page numbers for debugging purposes.
Definition: btr0mtib.h:990
std::ostream & print_left_pages(std::ostream &out) const
Definition: btr0mtib.cc:2065
ddl::Compare_key m_compare_key
Function object to compare two tuples.
Definition: btr0mtib.h:1269
bulk::Blob_inserter m_blob_inserter
Blob inserter to handle the externally stored fields of InnoDB.
Definition: btr0mtib.h:1290
size_t get_root_level() const
Get the level of the root page.
Definition: btr0mtib.h:1017
dberr_t alloc_extent(Page_range_t &page_range, size_t level)
Allocate an extent.
Definition: btr0mtib.cc:743
bool is_extent_tracked(const Page_extent *page_extent) const
Definition: btr0mtib.h:1376
dberr_t insert_blob(lob::ref_t &ref, const dfield_t *dfield)
Definition: btr0mtib.h:910
bool m_check_order
If true, check if data is inserted in sorted order.
Definition: btr0mtib.h:1263
bool is_tpc_enabled() const
Check if transparent page compression (TPC) is enabled.
Definition: btr0mtib.cc:2653
static bool validate_index(dict_index_t *index)
Check size and validate index of limited size.
Definition: btr0mtib.cc:1994
trx_id_t get_trx_id() const
Get the transaction id.
Definition: btr0mtib.cc:1657
void disable_check_order()
If the data is already sorted and checked for duplicates, then we can disable doing it again.
Definition: btr0mtib.h:1225
bool is_interrupted() const
Check if the index build operation has been interrupted.
Definition: btr0mtib.cc:3376
uint64_t m_n_recs
Number of records inserted.
Definition: btr0mtib.h:1239
Wait_callbacks::Function m_fn_wait_begin
Definition: btr0mtib.h:1282
ut::unique_ptr< Page_load > Page_loader_ptr
Definition: btr0mtib.h:943
const char * get_table_name() const
Definition: btr0mtib.h:1009
void track_extent(Page_extent *page_extent)
All allocated extents registers with Btree_load.
Definition: btr0mtib.cc:2150
void split_rightmost(buf_block_t *block, size_t level, dtuple_t *node_ptr, mtr_t *mtr, size_t &highest_level)
Split the right most block of the tree at the given level.
Definition: btr0mtib.cc:3393
fil_space_t * m_space
Definition: btr0mtib.h:1244
Page_range_t m_page_range_top
Page numbers of the pages that has been allocated in the non-leaf level.
Definition: btr0mtib.h:1162
Wait_callbacks::Function m_fn_wait_end
Definition: btr0mtib.h:1285
void add_to_bulk_flusher(bool finish=false)
Add fully used extents to the bulk flusher.
Definition: btr0mtib.cc:1762
unsigned m_index_online
State of the index.
Definition: btr0mtib.h:1170
byte m_fseg_hdr_top[FSEG_HEADER_SIZE]
Definition: btr0mtib.h:1165
dberr_t page_commit(Page_load *page_load, Page_load *next_page_load, bool insert_father) noexcept
Commit(finish) a page.
Definition: btr0mtib.cc:1598
void split_leftmost(buf_block_t *&block, size_t level, dtuple_t *node_ptr, mtr_t *mtr, size_t &highest_level)
Split the left most block of the tree at the given level.
Definition: btr0mtib.cc:3492
dberr_t fil_io(buf_block_t *block) noexcept
Initiate a direct file write operation.
dberr_t finalize_page_loads(bool is_err, page_no_t &last_page_no) noexcept
Btree page bulk load finish.
Definition: btr0mtib.cc:1858
std::string print_pages_in_level(const size_t level) const
Definition: btr0mtib.cc:1941
void print_tree_pages() const
Definition: btr0mtib.cc:2084
Level_ctx * get_level(size_t level) const
Get the level context object.
Definition: btr0mtib.h:1755
dberr_t close_blob(Blob_context blob_ctx, lob::ref_t &ref)
Indicate that the blob has been completed, so that resources can be removed, and as necessary flushin...
Definition: btr0mtib.h:938
const page_size_t m_page_size
Definition: btr0mtib.h:1279
Bulk_extent_allocator & get_extent_allocator()
Definition: btr0mtib.h:1227
std::vector< Level_ctx *, ut::allocator< Level_ctx * > > Level_ctxs
Definition: btr0mtib.h:946
buf_block_t * block_get(page_no_t page_no) const noexcept
Search for a BUF_BLOCK_MEMORY block with given page number in the local cache.
std::vector< page_no_t, ut::allocator< page_no_t > > m_last_page_nos
Last page numbers of each level.
Definition: btr0mtib.h:1146
bool verify_blob_context(Blob_context ctx) const
Definition: btr0mtib.h:1229
std::vector< Page_loader_ptr, ut::allocator< Page_loader_ptr > > Page_loaders
Definition: btr0mtib.h:945
size_t m_stat_n_extents
Number of extents allocated for this B-tree.
Definition: btr0mtib.h:1173
dberr_t write_blob(Blob_context blob_ctx, lob::ref_t &ref, const byte *data, size_t len)
Write data into the blob.
Definition: btr0mtib.h:928
Definition: btr0mtib.h:481
~Bulk_extent_allocator()
Destructor to ensure thread stop.
Definition: btr0mtib.h:491
Extent_cache m_leaf_extents
Cached leaf extents.
Definition: btr0mtib.h:627
dict_table_t * m_table
Innodb dictionary table object.
Definition: btr0mtib.h:648
std::chrono::microseconds m_allocator_wait_time
Total allocator wait time in micro seconds.
Definition: btr0mtib.h:621
size_t m_allocator_wait_count
Number of times allocator had to wait.
Definition: btr0mtib.h:615
size_t m_concurrency
Number of concurrent consumers.
Definition: btr0mtib.h:655
uint64_t init(dict_table_t *table, dict_index_t *index, trx_t *trx, size_t size, size_t num_threads, bool in_pages)
Check size and set extent allocator size parameters.
Definition: btr0mtib.cc:2238
std::condition_variable m_consumer_condition
Condition variable for extent consumer threads.
Definition: btr0mtib.h:639
bool check(size_t &n_leaf, size_t &n_non_leaf, bool &trigger)
Check if leaf and non-leaf extent cache needs to be filled.
Definition: btr0mtib.cc:2512
std::thread m_thread
Bulk extent allocator.
Definition: btr0mtib.h:609
size_t m_consumer_wait_count
Number of times consumer(s) had to wait.
Definition: btr0mtib.h:612
static constexpr size_t S_BULK_EXTEND_SIZE_MAX
Maximum size by which the tablespace is extended each time.
Definition: btr0mtib.h:526
dberr_t allocate(bool is_leaf, bool alloc_page, Page_range_t &range, std::function< void()> &fn_wait_begin, std::function< void()> &fn_wait_end)
Allocate a page range - currently ans Extent.
Definition: btr0mtib.cc:2396
dberr_t m_error
Error code, protected by m_mutex.
Definition: btr0mtib.h:645
static constexpr size_t S_MAX_RANGES
Upper bound for max ranges.
Definition: btr0mtib.h:523
dict_index_t * m_index
Definition: btr0mtib.h:649
trx_t * m_trx
Innodb transaction - used for checking interrupt.
Definition: btr0mtib.h:652
Extent_cache m_non_leaf_extents
Cached non-leaf extents.
Definition: btr0mtib.h:630
void allocator_wait() const
Allocator wait function.
Definition: btr0mtib.cc:2532
dberr_t allocate_extent(bool is_leaf, mtr_t &mtr, Page_range_t &range)
Allocate one extent.
Definition: btr0mtib.cc:2391
bool is_interrupted()
Definition: btr0mtib.cc:2342
dberr_t allocate_page(bool is_leaf, Page_range_t &range)
Allocate one page.
Definition: btr0mtib.cc:2346
dberr_t run()
Extent thread executor.
Definition: btr0mtib.cc:2599
void start()
Definition: btr0mtib.cc:2309
std::mutex m_mutex
This mutex protects the m_queue.
Definition: btr0mtib.h:633
Type m_type
Page range type.
Definition: btr0mtib.h:624
Type
Definition: btr0mtib.h:483
bool m_stop
Flag to indicate if the bulk allocator thread should stop.
Definition: btr0mtib.h:642
std::chrono::microseconds m_consumer_wait_time
Total consumer wait time in micro seconds.
Definition: btr0mtib.h:618
dberr_t allocate_extents(bool is_leaf, size_t num_extents)
Allocate extents and fill the cache.
Definition: btr0mtib.cc:2551
void stop()
Stop extent allocator thread, if active.
Definition: btr0mtib.cc:2317
std::condition_variable m_allocator_condition
Condition variable for allocator thread.
Definition: btr0mtib.h:636
Definition: btr0mtib.h:658
void do_work(fil_node_t *node, void *iov, size_t iov_size)
Do the actual work of flushing.
Definition: btr0mtib.cc:122
dberr_t check_and_notify() const
Check for flusher error and wake up flusher thread.
Definition: btr0mtib.cc:149
dberr_t m_error
Error code, protected by m_mutex.
Definition: btr0mtib.h:746
void add_to_free_queue(Page_extent *page_extent)
Definition: btr0mtib.cc:170
size_t m_pages_flushed
Number of pages flushed.
Definition: btr0mtib.h:772
space_id_t m_space_id
Bulk flusher is specific to a tablespace for now.
Definition: btr0mtib.h:775
std::atomic< bool > m_is_error
Set if error is encountered during flush.
Definition: btr0mtib.h:743
std::atomic< bool > m_stop
Flag to indicate if the bulk flusher thread should stop.
Definition: btr0mtib.h:740
dberr_t get_error() const
Definition: btr0mtib.cc:84
std::vector< Page_extent * > m_free_queue
This queue is protected by the m_free_mutex.
Definition: btr0mtib.h:732
dberr_t run()
Thread main function.
Definition: btr0mtib.cc:221
size_t m_id
Flusher ID.
Definition: btr0mtib.h:778
bool is_error() const
Definition: btr0mtib.h:696
Page_extent * get_free_extent()
Definition: btr0mtib.cc:160
std::mutex m_free_mutex
This mutex protects the m_free_queue.
Definition: btr0mtib.h:735
bool should_i_stop() const
Check if the bulk flush thread should stop working.
Definition: btr0mtib.h:713
size_t m_n_sleep
Number of times slept.
Definition: btr0mtib.h:760
std::mutex m_mutex
This mutex protects the m_queue.
Definition: btr0mtib.h:725
~Bulk_flusher()
Destructor.
Definition: btr0mtib.cc:98
void set_error(dberr_t error_code)
Set error code.
Definition: btr0mtib.cc:89
std::vector< Page_extent * > m_queue
This queue is protected by the m_mutex.
Definition: btr0mtib.h:722
std::thread m_flush_thread
Bulk flusher thread.
Definition: btr0mtib.h:757
size_t m_max_queue_size
Maximum queue size, defaults to 4.
Definition: btr0mtib.h:769
void start(space_id_t space_id, size_t index, size_t queue_size)
Start a new thread to do the flush work.
Definition: btr0mtib.cc:70
std::chrono::microseconds m_wait_time
Total sleep time in micro seconds.
Definition: btr0mtib.h:763
bool is_work_available()
Check if work is available for the bulk flusher thread.
Definition: btr0mtib.cc:205
std::vector< Page_extent * > m_priv_queue
Private queue (private to the bulk flush thread) containing the extents to flush.
Definition: btr0mtib.h:754
void wait_to_stop()
Wait till the bulk flush thread stops.
Definition: btr0mtib.cc:109
std::vector< page_no_t > m_flushed_page_nos
Vector of page numbers that are flushed by this Bulk_flusher object.
Definition: btr0mtib.h:783
size_t get_max_queue_size() const
Get the maximum allowed queue size.
Definition: btr0mtib.h:690
std::condition_variable m_condition
Condition variable to wait upon.
Definition: btr0mtib.h:728
void info()
Print useful information to the server log file while exiting.
Definition: btr0mtib.cc:2223
void wait()
When no work is available, put the thread to sleep.
Definition: btr0mtib.cc:282
void add(Page_extent *page_extent, std::function< void()> &fn_wait_begin, std::function< void()> &fn_wait_end)
Add a page extent to the bulk flush queue.
Definition: btr0mtib.cc:175
static constexpr std::chrono::milliseconds s_sleep_duration
The sleep duration in milliseconds.
Definition: btr0mtib.h:766
The proper function call sequence of Page_load is as below: – Page_load::init – Page_load::insert – P...
Definition: btr0mtib.h:1391
dberr_t init_mem(const page_no_t new_page_no, Page_extent *page_extent) noexcept
Definition: btr0mtib.cc:1005
dberr_t store_ext(const big_rec_t *big_rec, Rec_offsets offsets) noexcept
Store external record Since the record is not logged yet, so we don't log update to the record.
void set_level(size_t level) noexcept
Set the level of this page.
Definition: btr0mtib.h:1592
buf_block_t * get_block()
Definition: btr0mtib.h:1658
space_id_t space() const noexcept
Get the table space ID.
Definition: btr0mtib.h:1748
void rollback() noexcept
Commit mtr for a page.
Definition: btr0mtib.cc:1440
dberr_t init_mem_blob(const page_no_t page_no, Page_extent *page_extent) noexcept
Initialize a memory block to be used for storing blobs.
Definition: btr0mtib.cc:968
bool is_corrupted() const
Check if page is corrupted.
Definition: btr0mtib.cc:327
trx_id_t m_trx_id
The transaction id.
Definition: btr0mtib.h:1681
byte * m_heap_top
The heap top in page for next insert.
Definition: btr0mtib.h:1702
size_t get_level() const noexcept
Get page level.
Definition: btr0mtib.h:1589
rec_t * m_last_slotted_rec
Last record assigned to a slot.
Definition: btr0mtib.h:1724
bool make_ext(dtuple_t *tuple)
Store externally the first possible field of the given tuple.
Definition: btr0mtib.cc:1564
dict_index_t * index()
Definition: btr0mtib.h:1656
void set_level_ctx(Level_ctx *level_ctx)
Set the level context object for this page load.
Definition: btr0mtib.h:1646
void set_trx_id(const trx_id_t trx_id)
Set the transaction id.
Definition: btr0mtib.h:1445
size_t copy_to(std::vector< Page_load * > &to_pages)
Distribute all records from this page to the given pages.
Definition: btr0mtib.cc:1478
size_t copy_records(const rec_t *first_rec) noexcept
Copy given and all following records.
Definition: btr0mtib.cc:1509
void set_flush_observer(Flush_observer *observer)
Set the flush observer.
Definition: btr0mtib.h:1453
void set_page_extent(Page_extent *page_extent)
Definition: btr0mtib.h:1660
size_t get_rec_no() const
Get record no.
Definition: btr0mtib.h:1595
trx_id_t get_trx_id() const
Get the current transaction identifier.
Definition: btr0mtib.h:1449
void set_min_rec_flag()
Set the REC_INFO_MIN_REC_FLAG on the first user record in this page.
Definition: btr0mtib.cc:2094
page_no_t get_page_no() const noexcept
Get the page number of this page load object.
Definition: btr0mtib.h:1567
void set_next(page_no_t next_page_no) noexcept
Set next page.
Definition: btr0mtib.cc:1528
size_t get_page_size() const noexcept
Get the physical page size of the underlying tablespace.
Definition: btr0mtib.h:1750
dict_index_t * m_index
The index B-tree.
Definition: btr0mtib.h:1675
size_t m_slotted_rec_no
Number of records assigned to slots.
Definition: btr0mtib.h:1727
dberr_t insert(const dtuple_t *tuple, const big_rec_t *big_rec, size_t rec_size) noexcept
Insert a tuple in the page.
Definition: btr0mtib.cc:1310
Flush_observer * m_flush_observer
Flush observer.
Definition: btr0mtib.h:1721
bool verify_space_id() const
Obtain tablespace id from the frame and the buffer block and ensure that they are the same.
Definition: btr0mtib.cc:3381
void free()
Free the memory block.
Definition: btr0mtib.cc:2142
uint64_t m_modify_clock
The modify clock value of the buffer block when the block is re-pinned.
Definition: btr0mtib.h:1718
void set_prev(page_no_t prev_page_no) noexcept
Set previous page.
Definition: btr0mtib.cc:1532
bool has_level_ctx() const
Check if this page load object contains a level context object.
Definition: btr0mtib.h:1651
Page_load(dict_index_t *index, Btree_load *btree_load)
Ctor.
Definition: btr0mtib.cc:936
size_t m_rec_no
User record no.
Definition: btr0mtib.h:1705
std::atomic_bool m_is_cached
true iff the the Page load is cached.
Definition: btr0mtib.h:1739
static void drop(Page_load *page_load)
Release the page loader.
Definition: btr0mtib.cc:717
bool is_memory() const
Check if state of this page is BUF_BLOCK_MEMORY.
Definition: btr0mtib.h:1412
bool is_leaf() const
Definition: btr0mtib.h:1457
bool is_space_available(size_t rec_size) const noexcept
Check if required space is available in the page for the rec to be inserted.
Definition: btr0mtib.cc:1540
void reset() noexcept
Reset this object so that Page_load::init() can be called again on this object.
Definition: btr0mtib.cc:1145
size_t get_data_size() const
Definition: btr0mtib.h:1608
bool need_ext(const dtuple_t *tuple, size_t rec_size) const noexcept
Check whether the record needs to be stored externally.
Definition: btr0mtib.cc:1582
size_t m_level
The page level in B-tree.
Definition: btr0mtib.h:1696
rec_t * m_cur_rec
The current rec, just before the next insert rec.
Definition: btr0mtib.h:1690
dberr_t alloc() noexcept
Allocate a page for this Page_load object.
Definition: btr0mtib.cc:1098
void set_page_no(const page_no_t page_no)
Set the page number of this object.
Definition: btr0mtib.cc:927
size_t m_reserved_space
The reserved space for fill factor.
Definition: btr0mtib.h:1711
mem_heap_t * m_heap
Memory heap for internal allocation.
Definition: btr0mtib.h:1672
static Page_load * create(Btree_load *btree_load, Page_extent *page_extent)
A static member function to create this object.
Definition: btr0mtib.cc:707
page_id_t get_page_id() const noexcept
Definition: btr0mtib.h:1569
void latch() noexcept
Start mtr and latch block.
Page_extent * m_page_extent
Definition: btr0mtib.h:1736
bool is_cached() const
Definition: btr0mtib.h:1668
page_t * get_page() noexcept
Definition: btr0mtib.h:1602
bool is_index_locked() noexcept
Check if index is X locked.
Definition: btr0mtib.cc:1589
Page_load(dict_index_t *index, trx_id_t trx_id, page_no_t page_no, size_t level, Flush_observer *observer, Btree_load *btree_load=nullptr) noexcept
Constructor.
Definition: btr0mtib.h:1430
void set_top_seg(const fseg_header_t *hdr)
Definition: btr0mtib.h:1465
dberr_t reinit() noexcept
Re-initialize this page.
Definition: btr0mtib.cc:1077
~Page_load() noexcept
Destructor.
Definition: btr0mtib.cc:3365
void set_leaf_seg(const fseg_header_t *hdr)
Definition: btr0mtib.h:1462
bool is_min_rec_flag() const
Definition: btr0mtib.cc:2096
dberr_t commit() noexcept
Commit mtr for a page.
Definition: btr0mtib.cc:1406
size_t copy_all(const page_t *src_page) noexcept
Copy all records from page.
Definition: btr0mtib.cc:1469
size_t m_free_space
The free space left in the page.
Definition: btr0mtib.h:1708
void set_cached()
Mark the Page load as cached.
Definition: btr0mtib.h:1665
const bool m_is_comp
Flag: is page in compact format.
Definition: btr0mtib.h:1699
Btree_load * m_btree_load
Definition: btr0mtib.h:1732
page_no_t get_prev() noexcept
Get previous page (FIL_PAGE_PREV).
Definition: btr0mtib.cc:1536
mtr_t * m_mtr
The min-transaction.
Definition: btr0mtib.h:1678
const page_t * get_page() const noexcept
Get page.
Definition: btr0mtib.h:1598
bool m_modified
Page modified flag.
Definition: btr0mtib.h:1730
buf_block_t * m_block
The buffer block.
Definition: btr0mtib.h:1684
void print_child_page_nos() noexcept
Print the child page numbers.
Definition: btr0mtib.cc:1453
page_no_t m_page_no
The page no.
Definition: btr0mtib.h:1693
Level_ctx * m_level_ctx
Definition: btr0mtib.h:1734
dberr_t init() noexcept
Initialize members and allocate page if needed and start mtr.
Definition: btr0mtib.cc:1177
size_t m_total_data
Total data in the page.
Definition: btr0mtib.h:1714
void init_for_writing()
Definition: btr0mtib.cc:342
void finish() noexcept
Mark end of insertion to the page.
Definition: btr0mtib.cc:1347
page_t * m_page
The page.
Definition: btr0mtib.h:1687
dtuple_t * get_node_ptr() noexcept
Get node pointer.
Definition: btr0mtib.h:1744
Used to insert many blobs into InnoDB.
Definition: btr0mtib.h:792
Page_load * alloc_data_page()
Allocate a data page.
Definition: btr0mtib.cc:3959
Page_range_t m_page_range_first
Definition: btr0mtib.h:873
Page_load * alloc_first_page()
Allocate a LOB first page.
Definition: btr0mtib.cc:3939
Page_load * alloc_index_page()
Allocate a LOB index page.
Definition: btr0mtib.cc:3943
ut::Object_cache< Page_load > m_page_load_cache
Cache of Page_load objects.
Definition: btr0mtib.h:887
Page_extent * alloc_free_extent()
Definition: btr0mtib.cc:3898
Blob_inserter(Btree_load &btree_load)
Constructor.
Definition: btr0mtib.cc:3737
Page_load * alloc_page_from_extent(Page_extent *&m_page_extent)
Definition: btr0mtib.cc:3907
trx_id_t get_trx_id() const
Get the current transaction id.
Definition: btr0mtib.h:1843
~Blob_inserter()
Definition: btr0mtib.cc:3986
Page_extent * m_page_extent_first
Page extent from which to allocate first pages of blobs.
Definition: btr0mtib.h:871
dberr_t write_blob(Blob_context blob_ctx, lob::ref_t &ref, const byte *data, size_t len)
Write data into the blob.
Definition: btr0mtib.cc:3864
ut::Object_cache< Page_extent > m_page_extent_cache
Cache of Page_extent objects.
Definition: btr0mtib.h:890
dberr_t close_blob(Blob_context blob_ctx, lob::ref_t &ref)
Indicate that the blob has been completed, so that resources can be removed, and as necessary flushin...
Definition: btr0mtib.cc:3870
void finish()
Definition: btr0mtib.cc:3967
bool verify_blob_context(Blob_context ctx) const
Definition: btr0mtib.h:858
std::list< Page_extent * > m_index_extents
Page extent from which to allocate index pages of blobs.
Definition: btr0mtib.h:881
Blob_context m_blob
The current blob being inserted.
Definition: btr0mtib.h:884
dberr_t insert_blob(lob::ref_t &ref, const dfield_t *dfield)
Definition: btr0mtib.h:806
dberr_t open_blob(Blob_context &blob_ctx, lob::ref_t &ref)
Create a blob.
Definition: btr0mtib.cc:3859
dberr_t init()
Initialize by allocating necessary resources.
Definition: btr0mtib.cc:3744
Btree_load & m_btree_load
Definition: btr0mtib.h:867
ut::unique_ptr< Blob_handle > m_blob_handle
Only one blob handle per sub-tree.
Definition: btr0mtib.h:893
Page_extent * m_page_extent_data
Page extent from which to allocate data pages of blobs.
Definition: btr0mtib.h:877
We use Flush_observer to track flushing of non-redo logged pages in bulk create index(btr0load....
Definition: buf0flu.h:258
The proper function call sequence of Page_load is as below: – Page_load::init – Page_load::insert – P...
Definition: btr0load.cc:54
A helper RAII wrapper for otherwise difficult to use sequence of:
Definition: rem0rec.h:292
page_id_t id
Page id.
Definition: buf0buf.h:1387
Page identifier.
Definition: buf0types.h:207
Page size descriptor.
Definition: page0size.h:50
size_t physical() const
Retrieve the physical page size (on-disk).
Definition: page0size.h:121
A utility class which, if inherited from, prevents the descendant class from being copied,...
Definition: ut0class_life_cycle.h:41
A class to manage objects of type T.
Definition: ut0object_cache.h:40
const char * p
Definition: ctype-mb.cc:1227
dberr_t
Definition: db0err.h:39
@ DB_SUCCESS
Definition: db0err.h:43
DDL key comparison.
Data dictionary system.
static bool dict_table_is_comp(const dict_table_t *table)
Check whether the table uses the compact page format.
static ulint dict_index_is_spatial(const dict_index_t *index)
Check whether the index is a Spatial Index.
constexpr page_no_t FIL_NULL
'null' (undefined) page offset in the context of file spaces
Definition: fil0fil.h:1182
#define FSP_EXTENT_SIZE
File space extent size in pages page size | file space extent size -------—+--------------------— 4 K...
Definition: fsp0types.h:64
constexpr uint32_t FSEG_HEADER_SIZE
Length of the file system header, in bytes.
Definition: fsp0types.h:94
byte fseg_header_t
Data type for file segment header.
Definition: fsp0types.h:85
#define free(A)
Definition: lexyy.cc:915
For bulk loading large objects.
Implements the large objects (LOB) module.
Definition: btr0mtib.cc:56
void * Blob_context
Definition: btr0mtib.h:62
void bulk_load_enable_slow_io_debug()
Definition: btr0mtib.cc:61
void bulk_load_disable_slow_io_debug()
Definition: btr0mtib.cc:62
std::ostream & operator<<(std::ostream &out, const Page_extent &obj)
Definition: btr0mtib.h:323
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
Used for bulk load of data.
Definition: fut0lst.cc:411
PT & ref(PT *tp)
Definition: tablespace_impl.cc:359
bool index(const std::string &value, const String &search_for, uint32_t *idx)
Definition: contains.h:76
static Value err()
Create a Value object that represents an error condition.
Definition: json_binary.cc:943
std::chrono::milliseconds milliseconds
Definition: authorize_manager.cc:69
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
const char * begin(const char *const c)
Definition: base64.h:44
size_t size(const char *const c)
Definition: base64.h:46
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
Define std::hash<Gtid>.
Definition: gtid.h:355
std::vector< T, ut::allocator< T > > vector
Specialization of vector which uses allocator.
Definition: ut0new.h:2880
void delete_(T *ptr) noexcept
Releases storage which has been dynamically allocated through any of the ut::new*() variants.
Definition: ut0new.h:811
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2444
The page cursor.
static ulint page_get_free_space_of_empty(bool comp)
Calculates free space if a page is emptied.
static ulint page_get_data_size(const page_t *page)
Returns the sum of the sizes of the records in the record list excluding the infimum and supremum rec...
constexpr uint32_t PAGE_HEADER
index page header starts at this offset
Definition: page0types.h:53
constexpr uint32_t PAGE_BTR_SEG_LEAF
file segment header for the leaf pages in a B-tree: defined only on the root page of a B-tree,...
Definition: page0types.h:90
constexpr uint32_t PAGE_BTR_SEG_TOP
Definition: page0types.h:98
byte page_t
Type of the index page.
Definition: page0types.h:152
byte rec_t
Definition: rem0types.h:41
Interface between Innobase row operations and MySQL.
Function object to compare two Btree_load objects.
Definition: btr0mtib.h:1825
dict_index_t * m_index
Definition: btr0mtib.h:1828
bool operator()(const Btree_load *l_btree, const Btree_load *r_btree)
Definition: btr0mtib.cc:2161
Btree_load_compare(dict_index_t *index)
Definition: btr0mtib.h:1826
bool is_empty() const
Definition: btr0mtib.h:534
size_t m_max_range
Maximum number of ranges to pre-allocate.
Definition: btr0mtib.h:562
void init(size_t max_range)
Initialize cache.
Definition: btr0mtib.cc:2230
bool check(size_t &num_alloc, size_t &num_free) const
Check for number of extents to be allocated and cached.
Definition: btr0mtib.cc:2493
std::array< Page_range_t, S_MAX_RANGES > m_ranges
Cached page ranges already allocated to the segment.
Definition: btr0mtib.h:559
std::atomic< size_t > m_num_consumed
Total number of ranges allocated.
Definition: btr0mtib.h:568
void set_range(size_t index, Page_range_t &range)
Set allocated range(extent) in cache.
Definition: btr0mtib.cc:2484
std::atomic< size_t > m_num_allocated
Total number of ranges allocated.
Definition: btr0mtib.h:565
bool is_full() const
Definition: btr0mtib.h:537
bool get_range(Page_range_t &range, bool &alloc_trigger)
Get one page range from the cache.
Definition: btr0mtib.cc:2464
Context information for each level.
Definition: btr0mtib.h:360
size_t m_stat_n_extents
Number of extents allocated at this level.
Definition: btr0mtib.h:464
buf_block_t * alloc(const page_no_t new_page_no) noexcept
Allocate private memory buffer (BUF_BLOCK_MEMORY) block for given page number.
Definition: btr0mtib.cc:897
dict_index_t * m_index
The index which is being built.
Definition: btr0mtib.h:449
void build_page_cache()
Build page loader cache for current exent.
Definition: btr0mtib.cc:810
bool load_extent_from_cache()
Load one extent from extent cache.
Definition: btr0mtib.cc:757
dberr_t init()
Initialize.
Definition: btr0mtib.cc:850
Btree_load * m_btree_load
A back pointer to conceptually higher level btree load object.
Definition: btr0mtib.h:458
void set_current_page_load(Page_load *sibling)
Definition: btr0mtib.h:477
page_no_t m_last_page
The page_no of the last page in this level.
Definition: btr0mtib.h:446
~Level_ctx()
Destructor.
Definition: btr0mtib.cc:3363
const size_t m_level
The B-tree level whose context information is stored in this obj.
Definition: btr0mtib.h:452
void build_extent_cache()
Build the extent cache.
Definition: btr0mtib.cc:824
void free_page_load()
Free the current page load.
Definition: btr0mtib.cc:738
Page_load * create_page_load()
Definition: btr0mtib.cc:724
std::vector< page_no_t > m_pages_allocated
Definition: btr0mtib.h:471
trx_id_t get_trx_id() const
Definition: btr0mtib.h:1784
static void destroy(Level_ctx *obj)
Static member function to destroy a Level_ctx object.
Definition: btr0mtib.cc:693
std::vector< Page_extent * > m_cached_extents
Pre allocated extents to prevent repeated allocation and free.
Definition: btr0mtib.h:440
dberr_t alloc_page_num(page_no_t &page_no)
Allocate a page number.
Definition: btr0mtib.cc:626
Level_ctx(dict_index_t *index, size_t level, Btree_load *btree_load)
Constructor.
Definition: btr0mtib.h:379
bool m_extent_full
True if the current extent is full.
Definition: btr0mtib.h:467
dberr_t alloc_extent()
Allocate one extent in the relevant file segment.
Definition: btr0mtib.cc:663
size_t m_stat_n_pages
Number of pages allocated at this level.
Definition: btr0mtib.h:461
bool is_page_tracked(const page_no_t &page_no) const
Definition: btr0mtib.cc:657
Page_load * m_page_load
The Page_load of the current page being loaded.
Definition: btr0mtib.h:455
Page_load * get_page_load_from_cache()
Get a free page loader from cache.
Definition: btr0mtib.cc:792
Page_extent * m_page_extent
The current extent that is being loaded.
Definition: btr0mtib.h:423
page_no_t m_first_page
The page_no of the first page in this level.
Definition: btr0mtib.h:443
Page_load * get_page_load() const
Definition: btr0mtib.h:475
bool is_leaf() const
Check if this is leaf level.
Definition: btr0mtib.h:394
static Level_ctx * create(dict_index_t *index, size_t level, Btree_load *btree_load)
Static member function construct a Level_ctx object.
Definition: btr0mtib.cc:685
Allocate, use, manage and flush one extent pages (FSP_EXTENT_SIZE).
Definition: btr0mtib.h:69
Page_extent(Btree_load *btree_load, const bool is_leaf)
Constructor.
Definition: btr0mtib.h:1792
static void drop(Page_extent *extent)
Release the page extent.
Definition: btr0mtib.h:1811
bool is_blob() const
Check if this is a blob extent.
Definition: btr0mtib.h:233
void set_cached()
Mark the extent as cached.
Definition: btr0mtib.h:210
size_t m_next_cached_page_load_index
Next cached page load index.
Definition: btr0mtib.h:256
void get_page_numbers(std::vector< page_no_t > &page_numbers) const
Definition: btr0mtib.h:264
std::atomic_bool m_is_free
true if the cached entry is free to be used.
Definition: btr0mtib.h:252
std::vector< Page_load * > m_page_loads
All the page loaders of the used pages.
Definition: btr0mtib.h:89
bool is_null() const
Definition: btr0mtib.h:123
bool is_valid() const
Check if the range is valid.
Definition: btr0mtib.h:304
bool m_is_blob
True if this extent is used for blobs.
Definition: btr0mtib.h:259
dberr_t flush(fil_node_t *node, void *iov, size_t iov_size)
Flush the used pages to disk.
Definition: btr0mtib.cc:545
bool is_any_used() const
Check if there are any pages used.
Definition: btr0mtib.h:155
page_no_t alloc()
Allocate a page number.
Definition: btr0mtib.h:336
void init()
Initialize the next page number to be allocated.
Definition: btr0mtib.h:346
std::ostream & print(std::ostream &out) const
Definition: btr0mtib.h:315
dberr_t destroy()
Free all resources.
Definition: btr0mtib.cc:616
std::pair< page_no_t, page_no_t > Page_range_t
Definition: btr0mtib.h:70
std::vector< Page_load * > m_cached_page_loads
Cached page loads.
Definition: btr0mtib.h:254
size_t used_pages() const
Calculate the number of used pages.
Definition: btr0mtib.h:111
void set_page_load(page_no_t page_no, Page_load *page_load)
Member of Page_extent.
Definition: btr0mtib.h:271
page_no_t page_count() const
Number of pages in this extent.
Definition: btr0mtib.h:355
dberr_t flush_one_by_one(fil_node_t *node)
Flush one page at a time.
Definition: btr0mtib.cc:422
dberr_t bulk_flush(fil_node_t *node, void *iov, size_t iov_size)
Flush 1 extent pages at a time.
Definition: btr0mtib.cc:530
page_no_t m_page_no
Next page number to be used.
Definition: btr0mtib.h:82
void set_blob()
Mark that this extent is used for blobs.
Definition: btr0mtib.h:229
void reset_range(const Page_range_t &range)
Reset the range with the given value.
Definition: btr0mtib.h:327
std::atomic_bool m_is_owned_by_bulk_flusher
True if this extent has been handed over to the bulk flusher.
Definition: btr0mtib.h:240
Page_range_t m_range
Page numbers of the pages that has been allocated in this extent.
Definition: btr0mtib.h:86
bool is_fully_used() const
Check if no more pages are there to be used.
Definition: btr0mtib.h:150
bool is_free() const
Definition: btr0mtib.h:217
void destroy_cached()
Free any cached page load entries.
Definition: btr0mtib.cc:608
void append(Page_load *page_load)
Save a page_load.
Definition: btr0mtib.h:1769
Page_range_t pages_to_free() const
size_t last() const
Get the index of the first unused page load.
Definition: btr0mtib.h:117
void set_state(bool free)
Set and unset free state of a cached extent.
Definition: btr0mtib.h:214
std::atomic_bool m_is_cached
true iff the the extent is cached.
Definition: btr0mtib.h:250
void free_memory_blocks()
Free the BUF_BLOCK_MEMORY blocks used by this extent.
Definition: btr0mtib.h:1836
bool is_btree_load_nullptr() const
Definition: btr0mtib.h:91
bool is_cached() const
Definition: btr0mtib.h:220
void reset_cached_page_loads()
Reset page load cache to free all.
Definition: btr0mtib.h:223
space_id_t space() const
Definition: btr0mtib.h:1788
static Page_extent * create(Btree_load *btree_load, const bool is_leaf, const bool is_blob)
Create an object of type Page_extent in the heap.
Definition: btr0mtib.h:1800
Page_load * get_page_load(page_no_t page_no)
Member of Page_extent.
Definition: btr0mtib.h:286
~Page_extent()
Destructor.
Definition: btr0mtib.h:296
Btree_load * m_btree_load
Definition: btr0mtib.h:244
bool m_is_leaf
true if this extent belongs to leaf segment.
Definition: btr0mtib.h:247
Information about a buffer page.
Definition: btr0mtib.h:1761
size_t m_n_recs
Number of user records in the page.
Definition: btr0mtib.h:1763
size_t m_data_size
Number of bytes of data.
Definition: btr0mtib.h:1766
Heap wrapper that destroys the heap instance when it goes out of scope.
Definition: mem0mem.h:439
Storage format for overflow data in a big record, that is, a clustered index record which needs exter...
Definition: data0data.h:859
The buffer control block structure.
Definition: buf0buf.h:1764
buf_page_t page
page information; this must be the first field, so that buf_pool->page_hash can point to buf_page_t o...
Definition: buf0buf.h:1770
bool is_memory() const noexcept
Definition: buf0buf.h:2011
Compare the keys of an index.
Definition: ddl0impl-compare.h:41
Structure for an SQL data field.
Definition: data0data.h:617
unsigned len
data length; UNIV_SQL_NULL if SQL null
Definition: data0data.h:623
void * data
pointer to data
Definition: data0data.h:618
Data structure for an index.
Definition: dict0mem.h:1067
unsigned space
space where the index tree is placed
Definition: dict0mem.h:1084
bool is_clustered() const
Definition: dict0mem.h:1314
dict_table_t * table
back pointer to table
Definition: dict0mem.h:1081
page_size_t get_page_size() const
Get the page size of the tablespace to which this index belongs.
Definition: dict0mem.cc:917
Data structure for a database table.
Definition: dict0mem.h:1925
table_name_t name
Table name.
Definition: dict0mem.h:2000
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:696
File node of a tablespace or the log data space.
Definition: fil0fil.h:181
Tablespace or log data space.
Definition: fil0fil.h:261
The struct 'lob::ref_t' represents an external field reference.
Definition: lob0lob.h:198
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:302
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:177
Definition: gen_lex_token.cc:149
char * m_name
The name in internal representation.
Definition: dict0mem.h:468
Definition: trx0trx.h:675
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:138
#define IF_DEBUG(...)
Definition: univ.i:674
unsigned long int ulint
Definition: univ.i:406
Utilities related to class lifecycle.
#define UT_LOCATION_HERE
Definition: ut0core.h:73
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:93
Dynamic memory allocation routines and custom allocators specifically crafted to support memory instr...
#define UT_NEW_THIS_FILE_PSI_KEY
Definition: ut0new.h:566
Manage a cache of objects.