MySQL 8.3.0
Source Code Documentation
btr0mtib.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2023, 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 also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/btr0mtib.h
28
29 Multi Threaded Index Build (MTIB) using BUF_BLOCK_MEMORY and dedicated
30 Bulk_flusher threads.
31
32 Created 09/Feb/2023 Annamalai Gurusami
33 *************************************************************************/
34
35#ifndef btr0mtib_h
36#define btr0mtib_h
37
38#include <stddef.h>
39#include <vector>
40
41#include "btr0load.h"
42#include "ddl0impl-compare.h"
43#include "dict0dict.h"
44#include "page0cur.h"
45#include "ut0class_life_cycle.h"
46#include "ut0new.h"
47
48/* The Btree_multi namespace is used for multi-threaded parallel index build. */
49namespace Btree_multi {
50
51// Forward declaration.
52class Page_load;
53class Btree_load;
54struct Page_stat;
55
56/** Allocate, use, manage and flush one extent pages (FSP_EXTENT_SIZE). */
58 using Page_range_t = std::pair<page_no_t, page_no_t>;
59
60 /** Constructor.
61 @param[in] btree_load B-tree loader object.
62 @param[in] is_leaf true if this is part of leaf segment, false if this is
63 part of non-leaf (or top) segment. */
64 Page_extent(Btree_load *btree_load, const bool is_leaf);
65
66 /** Destructor. */
68
69 /** Next page number to be used. */
71
72 /** Page numbers of the pages that has been allocated in this extent.
73 The page range is [p1, p2), where p2 is not included. */
75
76 /** All the page loaders of the used pages. */
77 std::vector<Page_load *> m_page_loads;
78
79 public:
80 /** Create an object of type Page_extent in the heap. */
81 static Page_extent *create(Btree_load *btree_load, const bool is_leaf,
82 const bool is_blob);
83
84 /** Release the page extent. Delete if not cached.
85 @param[in] extent extent to release */
86 static void drop(Page_extent *extent);
87
88 /** Number of pages in this extent. */
89 page_no_t page_count() const;
90
91 /** Reset the range with the given value.
92 @param[in] range new range value to be used. */
93 void reset_range(const Page_range_t &range);
94
95 /** Calculate the number of used pages.
96 return the number of used pages. */
97 size_t used_pages() const { return m_page_loads.size(); }
98
99 /** Check if the range is valid.
100 @return true if the range is valid, false otherwise. */
101 bool is_valid() const;
102
103 bool is_null() const {
104 return (m_range.first == FIL_NULL) && (m_range.second == FIL_NULL);
105 }
106
108
109 /** Initialize the next page number to be allocated. The page range should
110 have been already initialized. */
111 void init();
112
113 /** Check if no more pages are there to be used.
114 @return true if the page extent is completed used.
115 @return false if the page extent has more pages to be used. */
116 bool is_fully_used() const { return m_page_no == m_range.second; }
117 bool is_page_loads_full() const {
118 return m_page_loads.size() == (m_range.second - m_range.first);
119 }
120
121 public:
122 /** Allocate a page number. */
124
125 /** Save a page_load. */
126 void append(Page_load *page_load);
127
128 /** Flush the used pages to disk. It also frees the unused pages back to the
129 segment.
130 @param[in,out] node space file node
131 @param[in,out] iov vector IO array
132 @param[in] iov_size vector IO array size
133 @return On success, return DB_SUCCESS. */
134 dberr_t flush(fil_node_t *node, void *iov, size_t iov_size);
135
136 /** Flush one page at a time. This can be used when scatter/gather i/o is
137 not available for use.
138 @param[in,out] node space file node
139 @return On success, return DB_SUCCESS. */
141
142 /** Flush 1 extent pages at a time. Internally it will call OS dependent
143 API (either bulk_flush_win() on Windows or bulk_flush_linux() on other
144 operating systems.
145 @param[in,out] node space file node
146 @param[in,out] iov vector IO array
147 @param[in] iov_size vector IO array size
148 @return DB_SUCCESS on success, error code on failure. */
149 dberr_t bulk_flush(fil_node_t *node, void *iov [[maybe_unused]],
150 size_t iov_size [[maybe_unused]]);
151
152#ifdef UNIV_LINUX
153 /** Flush 1 extent pages at a time. Uses pwritev() i/o API.
154 @param[in,out] node space file node
155 @param[in,out] iov vector IO array
156 @param[in] iov_size vector IO array size
157 @return DB_SUCCESS on success, error code on failure. */
158 dberr_t bulk_flush_linux(fil_node_t *node, struct iovec *iov,
159 size_t iov_size);
160#endif /* UNIV_LINUX */
161
162 /** Free all resources. */
164
165 /** Free any cached page load entries. */
166 void destroy_cached();
167
168 space_id_t space() const;
169
170 /** Mark the extent as cached. Flush thread should not free this extent. */
171 void set_cached() { m_is_cached.store(true); }
172
173 /** Set and unset free state of a cached extent.
174 @param[in] free state to be set */
175 void set_state(bool free) { m_is_free.store(free); }
176
177 /** @return true iff the cached element is in free state. */
178 bool is_free() const { return m_is_free.load(); }
179
180 /** @return true iff it is a cached extent. */
181 bool is_cached() const { return m_is_cached.load(); }
182
183 /** Reaset page load cache to free all. */
185
186 public:
187 std::ostream &print(std::ostream &out) const;
188
189 private:
191 const bool m_is_leaf; /* true if this extent belongs to leaf segment. */
192 /** true iff the the extent is cached. */
193 std::atomic_bool m_is_cached{false};
194 /** true if the cached entry is free to be used. */
195 std::atomic_bool m_is_free{true};
196 /** Cached page loads. */
197 std::vector<Page_load *> m_cached_page_loads;
198 /** Next cached page load index. */
200
201 friend struct Level_ctx;
202};
203
206 m_range.first = FIL_NULL;
207 m_range.second = FIL_NULL;
208 m_btree_load = nullptr;
209}
210
211inline bool Page_extent::is_valid() const {
212 ut_ad(m_range.first != 0);
213 ut_ad(m_range.second != 0);
214 if (is_null()) {
215 return true;
216 }
217 ut_ad(m_range.first < m_range.second);
218 ut_ad((m_range.second - m_range.first) <= FSP_EXTENT_SIZE);
219 return m_range.first < m_range.second;
220}
221
222inline std::ostream &Page_extent::print(std::ostream &out) const {
223 out << "[Page_extent: this=" << (void *)this
224 << ", m_range.first=" << m_range.first
225 << ", m_range.second=" << m_range.second
226 << ", page_loads=" << m_page_loads.size() << "]" << std::endl;
227 return out;
228}
229
230inline std::ostream &operator<<(std::ostream &out, const Page_extent &obj) {
231 return obj.print(out);
232}
233
235 ut_ad(range.first != 0);
236 ut_ad(range.second != 0);
237 ut_ad(range.first != FIL_NULL);
238 ut_ad(range.second != FIL_NULL);
239 m_range = range;
240 m_page_no = m_range.first;
241}
242
244 ut_ad(is_valid());
245 if (m_page_no == m_range.second) {
246 return FIL_NULL;
247 }
248 return m_page_no++;
249}
250
251inline void Page_extent::init() {
252 ut_ad(m_range.first != 0);
253 ut_ad(m_range.second != 0);
254 ut_ad(m_range.first != FIL_NULL);
255 ut_ad(m_range.second != FIL_NULL);
256 m_page_no = m_range.first;
257}
258
260 return m_range.second - m_range.first;
261}
262
263/** Context information for each level. */
264struct Level_ctx {
265 /** Static member function construct a Level_ctx object.
266 @param[in] index dictionary index object.
267 @param[in] level the B-tree level of this context object.
268 @param[in] btree_load a back pointer to the Btree_load object to which this
269 Level_ctx object is a part of.
270 @return level context object on success, nullptr on error. */
271 static Level_ctx *create(dict_index_t *index, size_t level,
272 Btree_load *btree_load);
273
274 /** Static member function to destroy a Level_ctx object.
275 @param[in] obj the Level_ctx object to destroy. */
276 static void destroy(Level_ctx *obj);
277
278 /** Constructor
279 @param[in] index dictionary index object.
280 @param[in] level the B-tree level of this context object.
281 @param[in] btree_load a back pointer to the Btree_load object to which this
282 Level_ctx object is a part of.*/
283 Level_ctx(dict_index_t *index, size_t level, Btree_load *btree_load)
284 : m_index(index),
285 m_level(level),
287 m_btree_load(btree_load) {}
288
289 /** Destructor. */
290 ~Level_ctx();
291
292 /** Initialize.
293 @return DB_SUCCESS on success, an error code on failure. */
294 dberr_t init();
295
296 /** Check if this is leaf level.
297 @return true if this is leaf level, false otherwise. */
298 bool is_leaf() const { return m_level == 0; }
299
301
302 /** Free the current page load. */
303 void free_page_load();
304
305 /** Allocate a page number. Subsequently a Page_load will be created with the
306 allocated page number.
307 @param[out] page_no page number that was allocated.
308 @return DB_SUCCESS on success, error code on failure.*/
310
311 /** Allocate one extent in the relevant file segment. No associated buffer
312 blocks are allocated.
313 @return DB_SUCCESS on success, error code on failure.*/
315
316 /** Allocate private memory buffer (BUF_BLOCK_MEMORY) block for given page
317 number. */
318 [[nodiscard]] buf_block_t *alloc(const page_no_t new_page_no) noexcept;
319
320 void set_current_page_load(Page_load *sibling);
321
322 Page_load *get_page_load() const;
323
324 trx_id_t get_trx_id() const;
325
326 /** The current extent that is being loaded. */
328
329 /** Build the extent cache. */
330 void build_extent_cache();
331
332 /** Load one extent from extent cache.
333 @return true iff successful. */
335
336 /** Build page loader cache for current exent. */
337 void build_page_cache();
338
339 /** Get a free page loader from cache
340 @return page loader or nullptr if not found. */
342
343 /** Pre allocated extents to prevent repeated allocation and free. */
344 std::vector<Page_extent *> m_cached_extents;
345
346 /** The page_no of the first page in this level. */
348
349 /** The page_no of the last page in this level. */
351
352 /** The index which is being built. */
354
355 /** The B-tree level whose context information is stored in this obj. */
356 const size_t m_level{};
357
358 /** The Page_load of the current page being loaded. */
360
361 /** A back pointer to conceptually higher level btree load object. */
363
364 /** Number of pages allocated at this level. */
366
367 /** Number of extents allocated at this level. */
369
370 /** True if the current extent is full. */
371 bool m_extent_full{true};
372
373#ifdef UNIV_DEBUG
374 bool is_page_tracked(const page_no_t &page_no) const;
375 std::vector<page_no_t> m_pages_allocated;
376#endif /* UNIV_DEBUG */
377};
378
380
382 m_page_load = sibling;
383}
384
386 public:
387 enum class Type {
388 /** Allocate by Page */
389 PAGE,
390 /** Allocate by extent. */
391 EXTENT
392 };
393
394 /** Destructor to ensure thread stop. */
396
397 /** Check size and set extent allocator size parameters
398 @param[in] table Innodb dictionary table object
399 @param[in] trx transaction performing bulk load
400 @param[in] size total data size to be loaded
401 @param[in] num_threads number of concurrent threads
402 @param[in] in_pages if true, allocate in pages
403 @return tablespace extend size in bytes. */
404 uint64_t init(dict_table_t *table, trx_t *trx, size_t size,
405 size_t num_threads, bool in_pages);
406
407 /* Start extent allocator thread. */
408 void start();
409
410 /** Stop extent allocator thread, if active. */
411 void stop();
412
413 /** Allocate a page range - currently ans Extent.
414 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
415 @param[in] alloc_page if true, allocate in pages otherwise allocate extent
416 @param[out] range page range
417 @param[in,out] fn_wait_begin begin callback if wait is needed
418 @param[in,out] fn_wait_end end callback if wait is needed
419 @return Innodb error code. */
420 dberr_t allocate(bool is_leaf, bool alloc_page, Page_range_t &range,
421 std::function<void()> &fn_wait_begin,
422 std::function<void()> &fn_wait_end);
423
424 private:
425 /** Upper bound for max ranges. */
426 static constexpr size_t S_MAX_RANGES = 2 * 1024;
427
428 /** Maximum size by which the tablespace is extended each time. */
429 static constexpr size_t S_BULK_EXTEND_SIZE_MAX = 64;
430
432 /** Initialize cache.
433 @param[in] max_range miaximum number of extents to cache. */
434 void init(size_t max_range);
435
436 /** @return true if no available extent to consume. */
437 inline bool is_empty() const { return (m_num_allocated == m_num_consumed); }
438
439 /** @return true if cache is full and no more extents can be added. */
440 inline bool is_full() const {
442 }
443
444 /** Check for number of extents to be allocated and cached.
445 @param[out] num_alloc number of extents to allocate
446 @param[out] num_free number of free extents
447 @return true if succesful. */
448 bool check(size_t &num_alloc, size_t &num_free) const;
449
450 /** Get one page range from the cache.
451 @param[out] range the allocated page range
452 @param[out] alloc_trigger true, if need to trigger allocator
453 @return true if extent is successfully returned from cache. */
454 bool get_range(Page_range_t &range, bool &alloc_trigger);
455
456 /** Set allocated range(extent) in cache.
457 @param[in] index position of the range
458 @param[in] range page range to be set */
459 void set_range(size_t index, Page_range_t &range);
460
461 /** Cached page ranges already allocated to the segment. */
462 std::array<Page_range_t, S_MAX_RANGES> m_ranges;
463
464 /** Maximum number of ranges to pre-allocate. */
466
467 /** Total number of ranges allocated. */
468 std::atomic<size_t> m_num_allocated{0};
469
470 /** Total number of ranges allocated. */
471 std::atomic<size_t> m_num_consumed{0};
472 };
473
474 /** Exetent thread executor.
475 @return innodb error code. */
476 dberr_t run();
477
478 /** Allocate extents and fill the cache.
479 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
480 @param[in] num_extents number of extents to allocate
481 @return innodb error code. */
482 dberr_t allocate_extents(bool is_leaf, size_t num_extents);
483
484 /** Allocator wait function. */
485 void allocator_wait() const;
486
487 /** Check if leaf and non-leaf extent cache needs to be filled.
488 @param[out] n_leaf number of leaf extents to allocate
489 @param[out] n_non_leaf number of non-leaf extents to allocate
490 @param[out] trigger true if consumers should be triggered
491 @return true if allocator should stop. */
492 bool check(size_t &n_leaf, size_t &n_non_leaf, bool &trigger);
493
494 /** Allocate one extent.
495 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
496 @param[in,out] mtr mini tranaction to be used for allocation
497 @param[out] range page rannge for the extent
498 @return innodb error code. */
499 dberr_t allocate_extent(bool is_leaf, mtr_t &mtr, Page_range_t &range);
500
501 /** Allocate one page.
502 @param[in] is_leaf true if leaf segment, otherwise non-leaf segment
503 @param[out] range page rannge for the page
504 @return innodb error code. */
505 dberr_t allocate_page(bool is_leaf, Page_range_t &range);
506
507 /** @return true if operation is interrupted. */
508 bool is_interrupted();
509
510 private:
511 /** Bulk extent allocator. */
512 std::thread m_thread;
513
514 /** Number of times consumer(s) had to wait. */
515 mutable size_t m_consumer_wait_count{};
516
517 /** Number of times allocator had to wait. */
518 mutable size_t m_allocator_wait_count{};
519
520 /** Total consumer wait time in micro seconds. */
521 mutable std::chrono::microseconds m_consumer_wait_time;
522
523 /** Total allocator wait time in micro seconds. */
524 mutable std::chrono::microseconds m_allocator_wait_time;
525
526 /** Page range type. */
528
529 /** Cached leaf extents. */
531
532 /** Cached non-leaf extents. */
534
535 /** This mutex protects the m_queue. */
536 mutable std::mutex m_mutex;
537
538 /** Condition variable for allocator thread. */
539 mutable std::condition_variable m_allocator_condition;
540
541 /** Condition variable for extent consumer threads. */
542 mutable std::condition_variable m_consumer_condition;
543
544 /** Flag to indicate if the bulk allocator thread should stop. */
545 bool m_stop{false};
546
547 /** Error code, protected by m_mutex */
549
550 /** Innodb dictionary table object. */
552
553 /** Innodb transaction - used for checking interrupt. */
555
556 /** Number of concurrent consumers. */
558};
559
561 public:
562 /** Thread main function.
563 @return innodb error code. */
564 dberr_t run();
565
566 /** Check if work is available for the bulk flusher thread.
567 @return true if work is available. */
568 bool is_work_available();
569
570 /** Start a new thread to do the flush work.
571 @param[in] space_id space for flushing pages to
572 @param[in] index loader index
573 @param[in] queue_size flusher queue size */
574 void start(space_id_t space_id, size_t index, size_t queue_size);
575
576 /** Add a page extent to the bulk flush queue.
577 @param[in,out] page_extent extent to be added to the queue
578 @param[in,out] fn_wait_begin begin callback if wait is needed
579 @param[in,out] fn_wait_end end callback if wait is needed */
580 void add(Page_extent *page_extent, std::function<void()> &fn_wait_begin,
581 std::function<void()> &fn_wait_end);
582
583 /** Check for flusher error and wake up flusher thread.
584 @return Innodb error code. */
586
587 /** Wait till the bulk flush thread stops. */
588 void wait_to_stop();
589
590 /** Get the maximum allowed queue size.
591 @return the maximum allowed queue size. */
592 size_t get_max_queue_size() const { return m_max_queue_size; }
593
594 /** Destructor. */
596
597 /** @return true iff error has occurred. */
598 bool is_error() const { return m_is_error.load(); }
599
600 /** @return error code */
601 dberr_t get_error() const;
602
603 private:
604 /** Do the actual work of flushing.
605 @param[in,out] node space file node
606 @param[in,out] iov vector IO array
607 @param[in] iov_size vector IO array size */
608 void do_work(fil_node_t *node, void *iov, size_t iov_size);
609
610 /** Check if the bulk flush thread should stop working. */
611 bool should_i_stop() const { return m_stop.load(); }
612
613 /** When no work is available, put the thread to sleep. */
614 void wait();
615
616 /** Print useful information to the server log file while exiting. */
617 void info();
618
619 /** This queue is protected by the m_mutex. */
620 std::vector<Page_extent *> m_queue;
621
622 /** This mutex protects the m_queue. */
623 mutable std::mutex m_mutex;
624
625 /** Condition variable to wait upon. */
626 mutable std::condition_variable m_condition;
627
628 /** Flag to indicate if the bulk flusher thread should stop. If true, the
629 bulk flusher thread will stop after emptying the queue. If false, the
630 bulk flusher thread will go to sleep after emptying the queue. */
631 std::atomic<bool> m_stop{false};
632
633 /** Set if error is encountered during flush. */
634 std::atomic<bool> m_is_error{false};
635
636 /** Error code, protected by m_mutex */
638
639 /** Set error code.
640 @param[in] error_code error code to set. It could be DB_SUCCESS.*/
641 void set_error(dberr_t error_code);
642
643 /** Private queue (private to the bulk flush thread) containing the extents to
644 flush. */
645 std::vector<Page_extent *> m_priv_queue;
646
647 /** Bulk flusher thread. */
648 std::thread m_flush_thread;
649
650 /** Number of times slept */
651 size_t m_n_sleep{};
652
653 /** Total sleep time in micro seconds. */
654 std::chrono::microseconds m_wait_time;
655
656 /** The sleep duration in milliseconds. */
657 static constexpr std::chrono::milliseconds s_sleep_duration{100};
658
659 /** Maximum queue size, defaults to 4 */
661
662 /** Number of pages flushed. */
664
665 /** Bulk flusher is specific to a tablespace for now. */
667
668 /** Flusher ID. */
669 size_t m_id{};
670
671#ifdef UNIV_DEBUG
672 public:
673 /** Vector of page numbers that are flushed by this Bulk_flusher object. */
674 std::vector<page_no_t> m_flushed_page_nos;
675#endif /* UNIV_DEBUG */
676};
677
678/** @note We should call commit(false) for a Page_load object, which is not in
679m_page_loaders after page_commit, and we will commit or abort Page_load
680objects in function "finish". */
682 public:
683 /** Merge multiple Btree_load sub-trees together. */
684 class Merger;
685
686 public:
687 using Page_loaders = std::vector<Page_load *, ut::allocator<Page_load *>>;
688 using Level_ctxs = std::vector<Level_ctx *, ut::allocator<Level_ctx *>>;
689
690 /** Helper to set wait callbacks for the current scope. */
692 public:
693 using Function = std::function<void()>;
694 friend class Btree_load;
695
697 : m_btree_load(btree_load) {
700 }
701
703 m_btree_load->m_fn_wait_begin = nullptr;
704 m_btree_load->m_fn_wait_end = nullptr;
705 }
706
707 private:
708 /** Btree Load for the wait callbacks. */
710 };
711
712 /** Constructor
713 @param[in] index B-tree index.
714 @param[in] trx Transaction object.
715 @param[in] loader_num loader index
716 @param[in] flush_queue_size bulk flusher queue size
717 @param[in] allocator extent allocator */
718 Btree_load(dict_index_t *index, trx_t *trx, size_t loader_num,
719 size_t flush_queue_size,
720 Bulk_extent_allocator &allocator) noexcept;
721
722 /** Destructor */
723 ~Btree_load() noexcept;
724
725 /** Initialize. Allocates the m_heap_order memory heap.
726 @return DB_SUCCESS on success or an error code on failure. */
727 dberr_t init();
728
729#ifdef UNIV_DEBUG
730 /** Save flushed page numbers for debugging purposes.
731 @param[in] page_no page number of the page that is flushed. */
733 m_bulk_flusher.m_flushed_page_nos.push_back(page_no);
734 }
735#endif /* UNIV_DEBUG */
736
737 /** Check if the index build operation has been interrupted.
738 @return true if the index build operation is interrupted, false otherwise.*/
739 bool is_interrupted() const;
740
741 /** Trigger flusher thread and check for error.
742 @return Innodb error code. */
744
745 /** Get the index object.
746 @return index object. */
747 dict_index_t *index() const { return m_index; }
748
749 const char *get_table_name() const { return m_index->table->name.m_name; }
750
751 /** Get the root page number of this tree/subtree.
752 @return the root page number of this tree/subtree. */
753 page_no_t get_subtree_root() const { return m_first_page_nos.back(); }
754
755 /** Get the level of the root page.
756 @return the level of the root page. */
757 size_t get_root_level() const { return m_root_level; }
758
759 /** Get information about root page. */
760 void get_root_page_stat(Page_stat &stat);
761
762 /** Get the transaction id.
763 @return the transaction id. */
764 trx_id_t get_trx_id() const;
765
766 /** Btree bulk load finish. We commit the last page in each level
767 and copy the last page in top level to the root page of the index
768 if no error occurs.
769 @param[in] is_err Whether bulk load was successful until now
770 @param[in] subtree true if a subtree is being built, false otherwise.
771 @return error code */
772 [[nodiscard]] dberr_t finish(bool is_err, const bool subtree) noexcept;
773
774 /** Insert a tuple to a page in a level
775 @param[in] dtuple Tuple to insert
776 @param[in] level B-tree level
777 @return error code */
778 [[nodiscard]] dberr_t insert(dtuple_t *dtuple, size_t level) noexcept;
779
780 /** Split the right most block of the tree at the given level.
781 @param[in,out] block the right most block at the given level.
782 @param[in] level level of the given block.
783 @param[in] node_ptr node pointer to be inserted in the block after
784 splitting.
785 @param[in] mtr mini transaction context.
786 @param[in,out] highest_level highest level among all the subtrees.*/
787 void split_rightmost(buf_block_t *block, size_t level, dtuple_t *node_ptr,
788 mtr_t *mtr, size_t &highest_level);
789
790 /** Split the left most block of the tree at the given level.
791 @param[in,out] block the left most block at the given level. it will be
792 updated with the new left most block.
793 @param[in] level level of the given block.
794 @param[in] node_ptr node pointer to be inserted in the block after
795 splitting.
796 @param[in] mtr mini transaction context.
797 @param[in,out] highest_level highest level among all the subtrees.*/
798 void split_leftmost(buf_block_t *&block, size_t level, dtuple_t *node_ptr,
799 mtr_t *mtr, size_t &highest_level);
800
801 private:
802 /** Set the root page on completion.
803 @param[in] last_page_no Last page number (the new root).
804 @return DB_SUCCESS or error code. */
805 [[nodiscard]] dberr_t load_root_page(page_no_t last_page_no) noexcept;
806
807 public:
808 /** Commit(finish) a page. We set next/prev page no, insert a node pointer to
809 father page if needed, and commit mini-transaction.
810 @param[in] page_load Page to commit
811 @param[in] next_page_load Next page
812 @param[in] insert_father Flag whether need to insert node ptr
813 @return error code */
814 [[nodiscard]] dberr_t page_commit(Page_load *page_load,
815 Page_load *next_page_load,
816 bool insert_father) noexcept;
817
818 /** Prepare space to insert a tuple.
819 @param[in,out] page_load Page bulk that will be used to store the record.
820 It may be replaced if there is not enough space
821 to hold the record.
822 @param[in] level B-tree level
823 @param[in] rec_size Record size
824 @return error code */
825 [[nodiscard]] dberr_t prepare_space(Page_load *&page_load, size_t level,
826 size_t rec_size) noexcept;
827
828 /** Insert a tuple to a page.
829 @param[in] page_load Page bulk object
830 @param[in] tuple Tuple to insert
831 @param[in] big_rec Big record vector, maybe NULL if there is no
832 Data to be stored externally.
833 @param[in] rec_size Record size
834 @return error code */
835 [[nodiscard]] dberr_t insert(Page_load *page_load, dtuple_t *tuple,
836 big_rec_t *big_rec, size_t rec_size) noexcept;
837
838 /** Btree page bulk load finish. Commits the last page in each level
839 if no error occurs. Also releases all page bulks.
840 @param[in] is_err Whether bulk load was successful until now
841 @param[out] last_page_no Last page number
842 @return error code */
843 [[nodiscard]] dberr_t finalize_page_loads(bool is_err,
844 page_no_t &last_page_no) noexcept;
845
846 public:
847 /** Allocate an extent.
848 @param[in,out] page_range the range of pages allocated.
849 @param[in] level btree level for which pages are allocated.
850 @return status code. */
851 dberr_t alloc_extent(Page_range_t &page_range, size_t level);
852
853 /** Initiate a direct file write operation.
854 @param[in] block block to be written to disk.
855 @return error code. */
856 [[nodiscard]] dberr_t fil_io(buf_block_t *block) noexcept;
857
858 /** Flush the blob pages.
859 @return status code. */
860 [[nodiscard]] dberr_t flush_blobs() noexcept;
861
862 /** Add the given block the internal cache of blocks.
863 @param[in] block the block to be cached. */
864 inline void block_put(buf_block_t *block);
865
866 /** Remove the given block from the internal cache of blocks.
867 @param[in] page_no the page number of block to be removed from cache. */
868 inline void block_remove(const page_no_t page_no);
869
870 /** Search for a BUF_BLOCK_MEMORY block with given page number in the local
871 cache.
872 @param[in] page_no the page number of block to be fetched.
873 @return buffer block with given page number. */
874 [[nodiscard]] inline buf_block_t *block_get(page_no_t page_no) const noexcept;
875
876 /** Evict all the pages in the given range from the buffer pool.
877 @param[in] range range of page numbers.
878 @param[in] dirty_is_ok it is OK for a page to be dirty. */
879 void force_evict(const Page_range_t &range, const bool dirty_is_ok = true);
880
881 public:
882 /** Check if a new level is needed. */
883 bool is_new_level(size_t level) const { return level >= m_level_ctxs.size(); }
884
885 /** Last page numbers of each level. */
886 std::vector<page_no_t, ut::allocator<page_no_t>> m_last_page_nos{};
887
888 /** First page numbers of each level. */
889 std::vector<page_no_t, ut::allocator<page_no_t>> m_first_page_nos{};
890
891 /** Get the level context object.
892 @param[in] level the level number. level 0 is leaf level.
893 @return the level context object. */
894 Level_ctx *get_level(size_t level) const;
895
896 /** Page numbers of the pages that has been allocated in the leaf level.
897 The page range is [p1, p2), where p2 is not included. */
899
900 /** Page numbers of the pages that has been allocated in the non-leaf level.
901 The page range is [p1, p2), where p2 is not included. */
903
906
907 /** State of the index. Used for asserting at the end of a
908 bulk load operation to ensure that the online status of the
909 index does not change */
911
912 /** Number of extents allocated for this B-tree. */
914
915 /** Number of pages allocated for this B-tree. */
916 size_t m_stat_n_pages{0};
917
918 public:
919 std::ostream &print_left_pages(std::ostream &out) const;
920 std::ostream &print_right_pages(std::ostream &out) const;
921
922 dberr_t check_key_overlap(const Btree_load *r_btree) const;
923
924#ifdef UNIV_DEBUG
925 void print_tree_pages() const;
926 std::string print_pages_in_level(const size_t level) const;
927 /** Check size and validate index of limited size.
928 @param[in] index Index to validate
929 @return true if successful. */
930 static bool validate_index(dict_index_t *index);
931#endif /* UNIV_DEBUG */
932
933 /** All allocated extents registers with Btree_load. */
934 void track_extent(Page_extent *page_extent);
935
936 /** Add fully used extents to the bulk flusher. Call this whenever a new
937 Page_load is allocated, with finish set to false. Only in
938 Btree_load::finish(), the finish argument will be true.
939 @param[in] finish if true, add all the tracked extents to the bulk flusher,
940 irrespective of whether it is fully used or not. */
941 void add_to_bulk_flusher(bool finish = false);
942
943 /** Add the given page extent object to the bulk flusher.
944 @param[in] page_extent the extent to be flushed. */
945 void add_to_bulk_flusher(Page_extent *page_extent);
946
947 /** Check if transparent page compression (TPC) is enabled.
948 @return true if TPC is enabled. */
949 bool is_tpc_enabled() const;
950
951 /** Check if transparent page encryption (TPE) is enabled.
952 @return true if TPE is enabled. */
953 bool is_tpe_enabled() const;
954
955 /** @return get flush queue size limit. */
958 }
959
960 /** If the data is already sorted and checked for duplicates, then we can
961 disable doing it again. */
963
964 private:
965 /** Page allocation type. We allocate in extents by default. */
968
969 /** Number of records inserted. */
970 uint64_t m_n_recs{};
971
972 /** B-tree index */
974
976
977 /** Transaction id */
979
980 /** Root page level */
981 size_t m_root_level{};
982
983 private:
984 /** Context information for each level of the B-tree. The leaf level is at
985 m_level_ctxs[0]. */
987
988 /* Dedicated thread to flush pages. */
990
991 /** Reference to global extent allocator. */
993
994 /** Extents that are being tracked. */
995 std::list<Page_extent *> m_extents_tracked;
996
997 /** If true, check if data is inserted in sorted order. */
998 bool m_check_order{true};
999
1000 /** Memory heap to be used for sort order checks. */
1002
1003 /** Function object to compare two tuples. */
1005
1006 /** The previous tuple that has been inserted. */
1008
1009 bool is_extent_tracked(const Page_extent *page_extent) const;
1010
1011 /** Loader number. */
1013
1015
1016 /* Begin wait callback function. */
1018
1019 /* End wait callback function. */
1021};
1022
1024 public:
1025 using Btree_loads = std::vector<Btree_load *, ut::allocator<Btree_load *>>;
1026
1028 : m_btree_loads(loads),
1029 m_index(index),
1030 m_trx(trx),
1032
1033 dberr_t merge(bool sort);
1034
1035 private:
1036 /** Get the maximum free space available in an empty page in bytes.
1037 @return the maximum free space available in an empty page. */
1038 size_t get_max_free() const {
1040 }
1041
1042 /** Remove any empty sub-trees with no records. */
1043 void remove_empty_subtrees();
1044
1045#ifdef UNIV_DEBUG
1046 /** Validate sub-tree boundaries. */
1047 void validate_boundaries();
1048
1049#endif /* UNIV_DEBUG */
1050
1051 /** Stich sub-trees together to form a tree with one or multiple
1052 nodes at highest leve.
1053 @param[out] highest_level highest level of the merged tree.
1054 @return innodb error code. */
1055 dberr_t subtree_link_levels(size_t &highest_level);
1056
1057 /** Create root node for the stiched sub-trees by combining the nodes
1058 at highest level creating another level if required.
1059 @param[in] highest_level highest level of the merged tree.
1060 @return innodb error code. */
1061 dberr_t add_root_for_subtrees(const size_t highest_level);
1062
1063 /** Insert the given list of node pointers into pages at the given level.
1064 @param[in,out] all_node_ptrs list of node pointers
1065 @param[in,out] total_node_ptrs_size total space in bytes needed to insert
1066 all the node pointers.
1067 @param[in] level the level at which the node pointers are inserted.
1068 @return DB_SUCCESS if successful.
1069 @return error code on failure. */
1070 dberr_t insert_node_ptrs(std::vector<dtuple_t *> &all_node_ptrs,
1071 size_t &total_node_ptrs_size, size_t level);
1072
1073 /** Load the left page and update its FIL_PAGE_NEXT.
1074 @param[in] l_page_no left page number
1075 @param[in] r_page_no right page number. */
1076 void link_right_sibling(const page_no_t l_page_no, const page_no_t r_page_no);
1077
1078 private:
1079 /** Refernce to the subtrees to be merged. */
1081
1082 /** Index which is being built. */
1084
1085 /** Transaction making the changes. */
1087
1088 /** Memory heap to store node pointers. */
1090};
1091
1093 const Page_extent *page_extent) const {
1094 for (auto e : m_extents_tracked) {
1095 if (page_extent == e) {
1096 return true;
1097 }
1098 }
1099 return false;
1100}
1101
1102/** The proper function call sequence of Page_load is as below:
1103-- Page_load::init
1104-- Page_load::insert
1105-- Page_load::finish
1106-- Page_load::commit */
1108 public:
1110
1111 /** Ctor.
1112 @param[in] index B-tree index
1113 @param[in] btree_load btree object to which this page belongs. */
1114 Page_load(dict_index_t *index, Btree_load *btree_load);
1115
1116 /** Destructor. */
1117 ~Page_load() noexcept;
1118
1119 /** Check if page is corrupted.
1120 @return true if corrupted, false otherwise. */
1121 bool is_corrupted() const;
1122
1123 /** Print the child page numbers. */
1124 void print_child_page_nos() noexcept;
1125
1126 /** Check if state of this page is BUF_BLOCK_MEMORY.
1127 @return true if page state is BUF_BLOCK_MEMORY, false otherwise.*/
1128 bool is_memory() const { return m_block->is_memory(); }
1129
1130 /** A static member function to create this object.
1131 @param[in] btree_load the bulk load object to which this Page_load belongs.
1132 @param[in] page_extent page extent to which this page belongs. */
1133 static Page_load *create(Btree_load *btree_load, Page_extent *page_extent);
1134
1135 /** Release the page loader. Delete if not cached.
1136 @param[in] page_load page loader to delete. */
1137 static void drop(Page_load *page_load);
1138
1139 /** Constructor
1140 @param[in] index B-tree index
1141 @param[in] trx_id Transaction id
1142 @param[in] page_no Page number
1143 @param[in] level Page level
1144 @param[in] observer Flush observer
1145 @param[in] btree_load btree object to which this page belongs. */
1147 size_t level, Flush_observer *observer,
1148 Btree_load *btree_load = nullptr) noexcept
1149 : m_index(index),
1150 m_trx_id(trx_id),
1151 m_page_no(page_no),
1152 m_level(level),
1154 m_flush_observer(observer),
1155 m_btree_load(btree_load) {
1157 }
1158
1159 /** Set the transaction id.
1160 @param[in] trx_id the transaction id to used. */
1161 void set_trx_id(const trx_id_t trx_id) { m_trx_id = trx_id; }
1162
1163 /** Set the flush observer.
1164 @param[in] observer the flush observer object to use. */
1166 m_flush_observer = observer;
1167 }
1168
1169 bool is_leaf() const { return m_level == 0; }
1170
1171 /** Set the page number of this object. */
1172 void set_page_no(const page_no_t page_no);
1173
1174 void set_leaf_seg(const fseg_header_t *hdr) {
1176 }
1177 void set_top_seg(const fseg_header_t *hdr) {
1179 }
1180
1181 /** Initialize members and allocate page if needed and start mtr.
1182 @note Must be called and only once right after constructor.
1183 @return error code */
1184 [[nodiscard]] dberr_t init() noexcept;
1185 [[nodiscard]] dberr_t init_mem(const page_no_t new_page_no,
1186 Page_extent *page_extent) noexcept;
1187
1188 /** Allocate a page for this Page_load object.
1189 @return DB_SUCCESS on success, error code on failure. */
1190 dberr_t alloc() noexcept;
1191
1192 /** Re-initialize this page. */
1193 [[nodiscard]] dberr_t reinit() noexcept;
1194
1195 /** Reset this object so that Page_load::init() can be called again on this
1196 object. */
1197 void reset() noexcept;
1198
1199 /** Insert a tuple in the page.
1200 @param[in] tuple Tuple to insert
1201 @param[in] big_rec External record
1202 @param[in] rec_size Record size
1203 @return error code */
1204 [[nodiscard]] dberr_t insert(const dtuple_t *tuple, const big_rec_t *big_rec,
1205 size_t rec_size) noexcept;
1206
1207 /** Mark end of insertion to the page. Scan records to set page dirs,
1208 and set page header members. The scan is incremental (slots and records
1209 which assignment could be "finalized" are not checked again. Check the
1210 m_slotted_rec_no usage, note it could be reset in some cases like
1211 during split.
1212 Note: we refer to page_copy_rec_list_end_to_created_page.*/
1213 void finish() noexcept;
1214
1215 /** Commit mtr for a page
1216 @return DB_SUCCESS on success, error code on failure. */
1217 dberr_t commit() noexcept;
1218
1219 /** Commit mtr for a page */
1220 void rollback() noexcept;
1221
1222 /** Check whether the record needs to be stored externally.
1223 @return false if the entire record can be stored locally on the page */
1224 [[nodiscard]] bool need_ext(const dtuple_t *tuple,
1225 size_t rec_size) const noexcept;
1226
1227 /** Get node pointer
1228 @return node pointer */
1229 [[nodiscard]] dtuple_t *get_node_ptr() noexcept;
1230
1231 /** Get node pointer
1232 @param[in] heap allocate node pointer in the given heap.
1233 @return node pointer */
1234 [[nodiscard]] dtuple_t *get_node_ptr(mem_heap_t *heap) noexcept;
1235
1236 /** Copy all records from page.
1237 @param[in] src_page Page with records to copy. */
1238 size_t copy_all(const page_t *src_page) noexcept;
1239
1240 /** Distribute all records from this page to the given pages.
1241 @param[in,out] to_pages array of Page_load objects.
1242 return total number of records processed. */
1243 size_t copy_to(std::vector<Page_load *> &to_pages);
1244
1245 /** Set next page
1246 @param[in] next_page_no Next page no */
1247 void set_next(page_no_t next_page_no) noexcept;
1248
1249 /** Set previous page
1250 @param[in] prev_page_no Previous page no */
1251 void set_prev(page_no_t prev_page_no) noexcept;
1252
1253 /** Get previous page (FIL_PAGE_PREV). */
1254 page_no_t get_prev() noexcept;
1255
1256 /** Start mtr and latch block */
1257 void latch() noexcept;
1258
1259 /** Check if required space is available in the page for the rec
1260 to be inserted. We check fill factor & padding here.
1261 @param[in] rec_size Required space
1262 @return true if space is available */
1263 [[nodiscard]] inline bool is_space_available(size_t rec_size) const noexcept;
1264
1265 /** Get page no */
1266 [[nodiscard]] page_no_t get_page_no() const noexcept { return m_page_no; }
1267 [[nodiscard]] page_id_t get_page_id() const noexcept {
1268 return m_block->page.id;
1269 }
1270
1271 /** Get the physical page size of the underlying tablespace.
1272 @return the physical page size of the tablespace. */
1273 size_t get_page_size() const noexcept;
1274
1275 /** Get the table space ID.
1276 @return the table space ID. */
1277 space_id_t space() const noexcept;
1278
1279#ifdef UNIV_DEBUG
1280 /** Obtain tablespace id from the frame and the buffer block and ensure that
1281 they are the same.
1282 @return true if space id is same in both places. */
1283 bool verify_space_id() const;
1284#endif /* UNIV_DEBUG */
1285
1286 /** Get page level */
1287 [[nodiscard]] size_t get_level() const noexcept { return m_level; }
1288
1289 /** Set the level of this page. */
1290 void set_level(size_t level) noexcept { m_level = level; }
1291
1292 /** Get record no */
1293 [[nodiscard]] size_t get_rec_no() const { return m_rec_no; }
1294
1295 /** Get page */
1296 [[nodiscard]] const page_t *get_page() const noexcept {
1298 }
1299
1300 [[nodiscard]] page_t *get_page() noexcept {
1302 }
1303
1304 public:
1305 void init_for_writing();
1306 size_t get_data_size() const { return page_get_data_size(m_page); }
1307
1308#ifdef UNIV_DEBUG
1309 /** Check if index is X locked
1310 @return true if index is locked. */
1311 bool is_index_locked() noexcept;
1312#endif /* UNIV_DEBUG */
1313
1314 /** Copy given and all following records.
1315 @param[in] first_rec First record to copy */
1316 size_t copy_records(const rec_t *first_rec) noexcept;
1317
1318 /** Insert a record in the page, check for duplicates too.
1319 @param[in] rec Record
1320 @param[in] offsets Record offsets
1321 @return DB_SUCCESS or error code. */
1322 dberr_t insert(const rec_t *rec, Rec_offsets offsets) noexcept;
1323
1324 public:
1325 /** Store external record
1326 Since the record is not logged yet, so we don't log update to the record.
1327 the blob data is logged first, then the record is logged in bulk mode.
1328 @param[in] big_rec External record
1329 @param[in] offsets Record offsets
1330 @return error code */
1331 [[nodiscard]] dberr_t store_ext(const big_rec_t *big_rec,
1332 Rec_offsets offsets) noexcept;
1333
1334 /** Set the REC_INFO_MIN_REC_FLAG on the first user record in this page.
1335 @param[in] mtr mini transaction context. */
1336 void set_min_rec_flag(mtr_t *mtr);
1337
1338 /** Set the REC_INFO_MIN_REC_FLAG on the first user record in this page. */
1339 void set_min_rec_flag();
1340 bool is_min_rec_flag() const;
1341
1342 /** Set the level context object for this page load
1343 @param[in] level_ctx the level context object. */
1344 void set_level_ctx(Level_ctx *level_ctx) { m_level_ctx = level_ctx; }
1345
1346 /** Check if this page load object contains a level context object.
1347 @return true if the page load contains a level context object.
1348 @return false if the page load does NOT contain a level context object.*/
1349 bool has_level_ctx() const { return m_level_ctx != nullptr; }
1350
1351 /** Free the memory block. */
1352 void free();
1353
1355
1357
1358 void set_page_extent(Page_extent *page_extent) {
1359 m_page_extent = page_extent;
1360 }
1361
1362 /** Mark the Page load as cached. Flush thread should not free this Page. */
1363 void set_cached() { m_is_cached.store(true); }
1364
1365 /** @return true iff it is a cached Page Load. */
1366 bool is_cached() const { return m_is_cached.load(); }
1367
1368 private:
1369 /** Memory heap for internal allocation */
1371
1372 /** The index B-tree */
1374
1375 /** The min-transaction */
1377
1378 /** The transaction id */
1380
1381 /** The buffer block */
1383
1384 /** The page */
1386
1387 /** The current rec, just before the next insert rec */
1389
1390 /** The page no */
1392
1393 /** The page level in B-tree */
1394 size_t m_level{};
1395
1396 /** Flag: is page in compact format */
1397 const bool m_is_comp{};
1398
1399 /** The heap top in page for next insert */
1400 byte *m_heap_top{};
1401
1402 /** User record no */
1403 size_t m_rec_no{};
1404
1405 /** The free space left in the page */
1407
1408 /** The reserved space for fill factor */
1410
1411 /** Total data in the page */
1413
1414 /** The modify clock value of the buffer block
1415 when the block is re-pinned */
1416 uint64_t m_modify_clock{};
1417
1418 /** Flush observer */
1420
1421 /** Last record assigned to a slot. */
1423
1424 /** Number of records assigned to slots. */
1426
1427 /** Page modified flag. */
1429
1431
1433
1435
1436 /** true iff the the Page load is cached. */
1437 std::atomic_bool m_is_cached{false};
1438
1439 friend class Btree_load;
1440};
1441
1443 return get_node_ptr(m_heap);
1444}
1445
1446inline space_id_t Page_load::space() const noexcept { return m_index->space; }
1447
1448inline size_t Page_load::get_page_size() const noexcept {
1449 const page_size_t page_size = m_index->get_page_size();
1450 return page_size.physical();
1451}
1452
1453inline Level_ctx *Btree_load::get_level(size_t level) const {
1454 ut_a(m_level_ctxs.size() > level);
1455 return m_level_ctxs[level];
1456}
1457
1458/** Information about a buffer page. */
1460 /** Number of user records in the page. */
1461 size_t m_n_recs;
1462
1463 /** Number of bytes of data. */
1465};
1466
1467inline void Page_extent::append(Page_load *page_load) {
1468 ut_ad(page_load->get_block() != nullptr);
1469 ut_ad(page_load->is_memory());
1470 ut_ad(page_load->get_page_no() >= m_range.first);
1471 ut_ad(page_load->get_page_no() < m_range.second);
1473 for (auto &iter : m_page_loads) {
1474 if (iter->get_page_no() == page_load->get_page_no()) {
1475 /* Page already appended. Don't append again. */
1476 return;
1477 }
1478 }
1479 m_page_loads.push_back(page_load);
1480}
1481
1483 return m_btree_load->get_trx_id();
1484}
1485
1487 return m_btree_load->index()->space;
1488}
1489
1490inline Page_extent::Page_extent(Btree_load *btree_load, const bool is_leaf)
1491 : m_page_no(FIL_NULL),
1492 m_range(FIL_NULL, FIL_NULL),
1493 m_btree_load(btree_load),
1494 m_is_leaf(is_leaf) {}
1495
1497 const bool is_leaf, bool skip_track) {
1498 Page_extent *p = ut::new_withkey<Page_extent>(UT_NEW_THIS_FILE_PSI_KEY,
1499 btree_load, is_leaf);
1500 if (!skip_track) {
1501 btree_load->track_extent(p);
1502 }
1503 p->m_is_cached.store(false);
1504 return p;
1505}
1506
1507inline void Page_extent::drop(Page_extent *extent) {
1508 if (extent == nullptr) {
1509 return;
1510 }
1511 if (extent->is_cached()) {
1512 ut_a(!extent->is_free());
1513 bool free = true;
1514 extent->set_state(free);
1515 return;
1516 }
1517 ut::delete_(extent);
1518}
1519
1520/** Function object to compare two Btree_load objects. */
1523 bool operator()(const Btree_load *l_btree, const Btree_load *r_btree);
1525};
1526
1527#ifdef UNIV_DEBUG
1530#endif /* UNIV_DEBUG */
1531
1532} /* namespace Btree_multi */
1533
1534#endif /* btr0mtib_h */
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:46
uint32_t page_no_t
Page number.
Definition: api0api.h:44
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:250
std::pair< page_no_t, page_no_t > Page_range_t
Definition: btr0btr.h:130
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:50
Definition: btr0mtib.h:1023
Btree_loads & m_btree_loads
Refernce to the subtrees to be merged.
Definition: btr0mtib.h:1080
std::vector< Btree_load *, ut::allocator< Btree_load * > > Btree_loads
Definition: btr0mtib.h:1025
dict_index_t * m_index
Index which is being built.
Definition: btr0mtib.h:1083
void validate_boundaries()
Validate sub-tree boundaries.
Definition: btr0mtib.cc:2549
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:3015
size_t get_max_free() const
Get the maximum free space available in an empty page in bytes.
Definition: btr0mtib.h:1038
Merger(Btree_loads &loads, dict_index_t *index, trx_t *trx)
Definition: btr0mtib.h:1027
void remove_empty_subtrees()
Remove any empty sub-trees with no records.
Definition: btr0mtib.cc:2536
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:2857
Scoped_heap m_tuple_heap
Memory heap to store node pointers.
Definition: btr0mtib.h:1089
dberr_t merge(bool sort)
Definition: btr0mtib.cc:2482
trx_t * m_trx
Transaction making the changes.
Definition: btr0mtib.h:1086
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:2987
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:2559
Helper to set wait callbacks for the current scope.
Definition: btr0mtib.h:691
~Wait_callbacks()
Definition: btr0mtib.h:702
Wait_callbacks(Btree_load *btree_load, Function &begin, Function &end)
Definition: btr0mtib.h:696
Btree_load * m_btree_load
Btree Load for the wait callbacks.
Definition: btr0mtib.h:709
std::function< void()> Function
Definition: btr0mtib.h:693
Definition: btr0mtib.h:681
~Btree_load() noexcept
Destructor.
Definition: btr0mtib.cc:1504
dict_index_t * m_index
B-tree index.
Definition: btr0mtib.h:973
Bulk_flusher m_bulk_flusher
Definition: btr0mtib.h:989
dberr_t finish(bool is_err, const bool subtree) noexcept
Btree bulk load finish.
Definition: btr0mtib.cc:1835
dberr_t load_root_page(page_no_t last_page_no) noexcept
Set the root page on completion.
Definition: btr0mtib.cc:1711
dberr_t trigger_flusher() const
Trigger flusher thread and check for error.
Definition: btr0mtib.h:743
bool is_tpe_enabled() const
Check if transparent page encryption (TPE) is enabled.
Definition: btr0mtib.cc:2474
Bulk_extent_allocator & m_allocator
Reference to global extent allocator.
Definition: btr0mtib.h:992
bool is_new_level(size_t level) const
Check if a new level is needed.
Definition: btr0mtib.h:883
dberr_t check_key_overlap(const Btree_load *r_btree) const
Definition: btr0mtib.cc:3115
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:1488
dict_index_t * index() const
Get the index object.
Definition: btr0mtib.h:747
size_t get_max_flush_queue_size() const
Definition: btr0mtib.h:956
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:1608
dtuple_t * m_prev_tuple
The previous tuple that has been inserted.
Definition: btr0mtib.h:1007
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:1932
std::ostream & print_right_pages(std::ostream &out) const
Definition: btr0mtib.cc:1893
size_t m_root_level
Root page level.
Definition: btr0mtib.h:981
std::vector< page_no_t, ut::allocator< page_no_t > > m_first_page_nos
First page numbers of each level.
Definition: btr0mtib.h:889
byte m_fseg_hdr_leaf[FSEG_HEADER_SIZE]
Definition: btr0mtib.h:904
void block_put(buf_block_t *block)
Add the given block the internal cache of blocks.
dberr_t init()
Initialize.
Definition: btr0mtib.cc:2023
Bulk_extent_allocator::Type m_alloc_type
Page allocation type.
Definition: btr0mtib.h:966
Page_range_t m_page_range_leaf
Page numbers of the pages that has been allocated in the leaf level.
Definition: btr0mtib.h:898
void get_root_page_stat(Page_stat &stat)
Get information about root page.
Definition: btr0mtib.cc:1943
size_t m_loader_num
Loader number.
Definition: btr0mtib.h:1012
Level_ctxs m_level_ctxs
Context information for each level of the B-tree.
Definition: btr0mtib.h:986
page_no_t get_subtree_root() const
Get the root page number of this tree/subtree.
Definition: btr0mtib.h:753
size_t m_stat_n_pages
Number of pages allocated for this B-tree.
Definition: btr0mtib.h:916
trx_t * m_trx
Transaction id.
Definition: btr0mtib.h:978
dberr_t flush_blobs() noexcept
Flush the blob pages.
mem_heap_t * m_heap_order
Memory heap to be used for sort order checks.
Definition: btr0mtib.h:1001
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:1512
std::list< Page_extent * > m_extents_tracked
Extents that are being tracked.
Definition: btr0mtib.h:995
void track_page_flush(page_no_t page_no)
Save flushed page numbers for debugging purposes.
Definition: btr0mtib.h:732
std::ostream & print_left_pages(std::ostream &out) const
Definition: btr0mtib.cc:1884
ddl::Compare_key m_compare_key
Function object to compare two tuples.
Definition: btr0mtib.h:1004
size_t get_root_level() const
Get the level of the root page.
Definition: btr0mtib.h:757
dberr_t alloc_extent(Page_range_t &page_range, size_t level)
Allocate an extent.
Definition: btr0mtib.cc:691
bool is_extent_tracked(const Page_extent *page_extent) const
Definition: btr0mtib.h:1092
bool m_check_order
If true, check if data is inserted in sorted order.
Definition: btr0mtib.h:998
bool is_tpc_enabled() const
Check if transparent page compression (TPC) is enabled.
Definition: btr0mtib.cc:2464
std::vector< Page_load *, ut::allocator< Page_load * > > Page_loaders
Definition: btr0mtib.h:687
static bool validate_index(dict_index_t *index)
Check size and validate index of limited size.
Definition: btr0mtib.cc:1815
trx_id_t get_trx_id() const
Get the transaction id.
Definition: btr0mtib.cc:1502
void disable_check_order()
If the data is already sorted and checked for duplicates, then we can disable doing it again.
Definition: btr0mtib.h:962
bool is_interrupted() const
Check if the index build operation has been interrupted.
Definition: btr0mtib.cc:3180
uint64_t m_n_recs
Number of records inserted.
Definition: btr0mtib.h:970
Wait_callbacks::Function m_fn_wait_begin
Definition: btr0mtib.h:1017
const char * get_table_name() const
Definition: btr0mtib.h:749
void track_extent(Page_extent *page_extent)
All allocated extents registers with Btree_load.
Definition: btr0mtib.cc:1967
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:3197
fil_space_t * m_space
Definition: btr0mtib.h:975
Page_range_t m_page_range_top
Page numbers of the pages that has been allocated in the non-leaf level.
Definition: btr0mtib.h:902
Wait_callbacks::Function m_fn_wait_end
Definition: btr0mtib.h:1020
void add_to_bulk_flusher(bool finish=false)
Add fully used extents to the bulk flusher.
Definition: btr0mtib.cc:1588
unsigned m_index_online
State of the index.
Definition: btr0mtib.h:910
byte m_fseg_hdr_top[FSEG_HEADER_SIZE]
Definition: btr0mtib.h:905
dberr_t page_commit(Page_load *page_load, Page_load *next_page_load, bool insert_father) noexcept
Commit(finish) a page.
Definition: btr0mtib.cc:1447
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:3296
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:1679
std::string print_pages_in_level(const size_t level) const
Definition: btr0mtib.cc:1762
void print_tree_pages() const
Definition: btr0mtib.cc:1903
Level_ctx * get_level(size_t level) const
Get the level context object.
Definition: btr0mtib.h:1453
const page_size_t m_page_size
Definition: btr0mtib.h:1014
std::vector< Level_ctx *, ut::allocator< Level_ctx * > > Level_ctxs
Definition: btr0mtib.h:688
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:886
size_t m_stat_n_extents
Number of extents allocated for this B-tree.
Definition: btr0mtib.h:913
Definition: btr0mtib.h:385
~Bulk_extent_allocator()
Destructor to ensure thread stop.
Definition: btr0mtib.h:395
Extent_cache m_leaf_extents
Cached leaf extents.
Definition: btr0mtib.h:530
dict_table_t * m_table
Innodb dictionary table object.
Definition: btr0mtib.h:551
std::chrono::microseconds m_allocator_wait_time
Total allocator wait time in micro seconds.
Definition: btr0mtib.h:524
size_t m_allocator_wait_count
Number of times allocator had to wait.
Definition: btr0mtib.h:518
size_t m_concurrency
Number of concurrent consumers.
Definition: btr0mtib.h:557
std::condition_variable m_consumer_condition
Condition variable for extent consumer threads.
Definition: btr0mtib.h:542
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:2322
std::thread m_thread
Bulk extent allocator.
Definition: btr0mtib.h:512
size_t m_consumer_wait_count
Number of times consumer(s) had to wait.
Definition: btr0mtib.h:515
static constexpr size_t S_BULK_EXTEND_SIZE_MAX
Maximum size by which the tablespace is extended each time.
Definition: btr0mtib.h:429
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:2206
dberr_t m_error
Error code, protected by m_mutex.
Definition: btr0mtib.h:548
static constexpr size_t S_MAX_RANGES
Upper bound for max ranges.
Definition: btr0mtib.h:426
trx_t * m_trx
Innodb transaction - used for checking interrupt.
Definition: btr0mtib.h:554
Extent_cache m_non_leaf_extents
Cached non-leaf extents.
Definition: btr0mtib.h:533
void allocator_wait() const
Allocator wait function.
Definition: btr0mtib.cc:2342
dberr_t allocate_extent(bool is_leaf, mtr_t &mtr, Page_range_t &range)
Allocate one extent.
Definition: btr0mtib.cc:2200
bool is_interrupted()
Definition: btr0mtib.cc:2150
dberr_t allocate_page(bool is_leaf, Page_range_t &range)
Allocate one page.
Definition: btr0mtib.cc:2154
dberr_t run()
Exetent thread executor.
Definition: btr0mtib.cc:2410
void start()
Definition: btr0mtib.cc:2117
std::mutex m_mutex
This mutex protects the m_queue.
Definition: btr0mtib.h:536
Type m_type
Page range type.
Definition: btr0mtib.h:527
Type
Definition: btr0mtib.h:387
uint64_t init(dict_table_t *table, trx_t *trx, size_t size, size_t num_threads, bool in_pages)
Check size and set extent allocator size parameters.
Definition: btr0mtib.cc:2047
bool m_stop
Flag to indicate if the bulk allocator thread should stop.
Definition: btr0mtib.h:545
std::chrono::microseconds m_consumer_wait_time
Total consumer wait time in micro seconds.
Definition: btr0mtib.h:521
dberr_t allocate_extents(bool is_leaf, size_t num_extents)
Allocate extents and fill the cache.
Definition: btr0mtib.cc:2361
void stop()
Stop extent allocator thread, if active.
Definition: btr0mtib.cc:2125
std::condition_variable m_allocator_condition
Condition variable for allocator thread.
Definition: btr0mtib.h:539
Definition: btr0mtib.h:560
void do_work(fil_node_t *node, void *iov, size_t iov_size)
Do the actual work of flushing.
Definition: btr0mtib.cc:108
dberr_t check_and_notify() const
Check for flusher error and wake up flusher thread.
Definition: btr0mtib.cc:126
dberr_t m_error
Error code, protected by m_mutex.
Definition: btr0mtib.h:637
size_t m_pages_flushed
Number of pages flushed.
Definition: btr0mtib.h:663
space_id_t m_space_id
Bulk flusher is specific to a tablespace for now.
Definition: btr0mtib.h:666
std::atomic< bool > m_is_error
Set if error is encountered during flush.
Definition: btr0mtib.h:634
std::atomic< bool > m_stop
Flag to indicate if the bulk flusher thread should stop.
Definition: btr0mtib.h:631
dberr_t get_error() const
Definition: btr0mtib.cc:77
dberr_t run()
Thread main function.
Definition: btr0mtib.cc:178
size_t m_id
Flusher ID.
Definition: btr0mtib.h:669
bool is_error() const
Definition: btr0mtib.h:598
bool should_i_stop() const
Check if the bulk flush thread should stop working.
Definition: btr0mtib.h:611
size_t m_n_sleep
Number of times slept.
Definition: btr0mtib.h:651
std::mutex m_mutex
This mutex protects the m_queue.
Definition: btr0mtib.h:623
~Bulk_flusher()
Destructor.
Definition: btr0mtib.cc:91
void set_error(dberr_t error_code)
Set error code.
Definition: btr0mtib.cc:82
std::vector< Page_extent * > m_queue
This queue is protected by the m_mutex.
Definition: btr0mtib.h:620
std::thread m_flush_thread
Bulk flusher thread.
Definition: btr0mtib.h:648
size_t m_max_queue_size
Maximum queue size, defaults to 4.
Definition: btr0mtib.h:660
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:63
std::chrono::microseconds m_wait_time
Total sleep time in micro seconds.
Definition: btr0mtib.h:654
bool is_work_available()
Check if work is available for the bulk flusher thread.
Definition: btr0mtib.cc:162
std::vector< Page_extent * > m_priv_queue
Private queue (private to the bulk flush thread) containing the extents to flush.
Definition: btr0mtib.h:645
void wait_to_stop()
Wait till the bulk flush thread stops.
Definition: btr0mtib.cc:102
std::vector< page_no_t > m_flushed_page_nos
Vector of page numbers that are flushed by this Bulk_flusher object.
Definition: btr0mtib.h:674
size_t get_max_queue_size() const
Get the maximum allowed queue size.
Definition: btr0mtib.h:592
std::condition_variable m_condition
Condition variable to wait upon.
Definition: btr0mtib.h:626
void info()
Print useful information to the server log file while exiting.
Definition: btr0mtib.cc:2032
void wait()
When no work is available, put the thread to sleep.
Definition: btr0mtib.cc:239
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:137
static constexpr std::chrono::milliseconds s_sleep_duration
The sleep duration in milliseconds.
Definition: btr0mtib.h:657
The proper function call sequence of Page_load is as below: – Page_load::init – Page_load::insert – P...
Definition: btr0mtib.h:1107
dberr_t init_mem(const page_no_t new_page_no, Page_extent *page_extent) noexcept
Definition: btr0mtib.cc:891
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:1290
buf_block_t * get_block()
Definition: btr0mtib.h:1356
space_id_t space() const noexcept
Get the table space ID.
Definition: btr0mtib.h:1446
void rollback() noexcept
Commit mtr for a page.
Definition: btr0mtib.cc:1310
bool is_corrupted() const
Check if page is corrupted.
Definition: btr0mtib.cc:284
trx_id_t m_trx_id
The transaction id.
Definition: btr0mtib.h:1379
byte * m_heap_top
The heap top in page for next insert.
Definition: btr0mtib.h:1400
size_t get_level() const noexcept
Get page level.
Definition: btr0mtib.h:1287
rec_t * m_last_slotted_rec
Last record assigned to a slot.
Definition: btr0mtib.h:1422
dict_index_t * index()
Definition: btr0mtib.h:1354
void set_level_ctx(Level_ctx *level_ctx)
Set the level context object for this page load.
Definition: btr0mtib.h:1344
void set_trx_id(const trx_id_t trx_id)
Set the transaction id.
Definition: btr0mtib.h:1161
size_t copy_to(std::vector< Page_load * > &to_pages)
Distribute all records from this page to the given pages.
Definition: btr0mtib.cc:1348
size_t copy_records(const rec_t *first_rec) noexcept
Copy given and all following records.
Definition: btr0mtib.cc:1379
void set_flush_observer(Flush_observer *observer)
Set the flush observer.
Definition: btr0mtib.h:1165
void set_page_extent(Page_extent *page_extent)
Definition: btr0mtib.h:1358
size_t get_rec_no() const
Get record no.
Definition: btr0mtib.h:1293
void set_min_rec_flag()
Set the REC_INFO_MIN_REC_FLAG on the first user record in this page.
Definition: btr0mtib.cc:1913
page_no_t get_page_no() const noexcept
Get page no.
Definition: btr0mtib.h:1266
void set_next(page_no_t next_page_no) noexcept
Set next page.
Definition: btr0mtib.cc:1398
size_t get_page_size() const noexcept
Get the physical page size of the underlying tablespace.
Definition: btr0mtib.h:1448
dict_index_t * m_index
The index B-tree.
Definition: btr0mtib.h:1373
size_t m_slotted_rec_no
Number of records assigned to slots.
Definition: btr0mtib.h:1425
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:1193
Flush_observer * m_flush_observer
Flush observer.
Definition: btr0mtib.h:1419
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:3185
void free()
Free the memory block.
Definition: btr0mtib.cc:1961
uint64_t m_modify_clock
The modify clock value of the buffer block when the block is re-pinned.
Definition: btr0mtib.h:1416
void set_prev(page_no_t prev_page_no) noexcept
Set previous page.
Definition: btr0mtib.cc:1402
bool has_level_ctx() const
Check if this page load object contains a level context object.
Definition: btr0mtib.h:1349
Page_load(dict_index_t *index, Btree_load *btree_load)
Ctor.
Definition: btr0mtib.cc:884
size_t m_rec_no
User record no.
Definition: btr0mtib.h:1403
std::atomic_bool m_is_cached
true iff the the Page load is cached.
Definition: btr0mtib.h:1437
static void drop(Page_load *page_load)
Release the page loader.
Definition: btr0mtib.cc:665
bool is_memory() const
Check if state of this page is BUF_BLOCK_MEMORY.
Definition: btr0mtib.h:1128
bool is_leaf() const
Definition: btr0mtib.h:1169
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:1410
void reset() noexcept
Reset this object so that Page_load::init() can be called again on this object.
Definition: btr0mtib.cc:1028
size_t get_data_size() const
Definition: btr0mtib.h:1306
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:1431
size_t m_level
The page level in B-tree.
Definition: btr0mtib.h:1394
rec_t * m_cur_rec
The current rec, just before the next insert rec.
Definition: btr0mtib.h:1388
dberr_t alloc() noexcept
Allocate a page for this Page_load object.
Definition: btr0mtib.cc:981
void set_page_no(const page_no_t page_no)
Set the page number of this object.
Definition: btr0mtib.cc:875
size_t m_reserved_space
The reserved space for fill factor.
Definition: btr0mtib.h:1409
mem_heap_t * m_heap
Memory heap for internal allocation.
Definition: btr0mtib.h:1370
static Page_load * create(Btree_load *btree_load, Page_extent *page_extent)
A static member function to create this object.
Definition: btr0mtib.cc:655
page_id_t get_page_id() const noexcept
Definition: btr0mtib.h:1267
void latch() noexcept
Start mtr and latch block.
Page_extent * m_page_extent
Definition: btr0mtib.h:1434
bool is_cached() const
Definition: btr0mtib.h:1366
page_t * get_page() noexcept
Definition: btr0mtib.h:1300
bool is_index_locked() noexcept
Check if index is X locked.
Definition: btr0mtib.cc:1438
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:1146
void set_top_seg(const fseg_header_t *hdr)
Definition: btr0mtib.h:1177
dberr_t reinit() noexcept
Re-initialize this page.
Definition: btr0mtib.cc:960
~Page_load() noexcept
Destructor.
Definition: btr0mtib.cc:3169
void set_leaf_seg(const fseg_header_t *hdr)
Definition: btr0mtib.h:1174
bool is_min_rec_flag() const
Definition: btr0mtib.cc:1915
dberr_t commit() noexcept
Commit mtr for a page.
Definition: btr0mtib.cc:1280
size_t copy_all(const page_t *src_page) noexcept
Copy all records from page.
Definition: btr0mtib.cc:1339
size_t m_free_space
The free space left in the page.
Definition: btr0mtib.h:1406
void set_cached()
Mark the Page load as cached.
Definition: btr0mtib.h:1363
const bool m_is_comp
Flag: is page in compact format.
Definition: btr0mtib.h:1397
Btree_load * m_btree_load
Definition: btr0mtib.h:1430
page_no_t get_prev() noexcept
Get previous page (FIL_PAGE_PREV).
Definition: btr0mtib.cc:1406
mtr_t * m_mtr
The min-transaction.
Definition: btr0mtib.h:1376
const page_t * get_page() const noexcept
Get page.
Definition: btr0mtib.h:1296
bool m_modified
Page modified flag.
Definition: btr0mtib.h:1428
buf_block_t * m_block
The buffer block.
Definition: btr0mtib.h:1382
void print_child_page_nos() noexcept
Print the child page numbers.
Definition: btr0mtib.cc:1323
page_no_t m_page_no
The page no.
Definition: btr0mtib.h:1391
Level_ctx * m_level_ctx
Definition: btr0mtib.h:1432
dberr_t init() noexcept
Initialize members and allocate page if needed and start mtr.
Definition: btr0mtib.cc:1060
size_t m_total_data
Total data in the page.
Definition: btr0mtib.h:1412
void init_for_writing()
Definition: btr0mtib.cc:299
void finish() noexcept
Mark end of insertion to the page.
Definition: btr0mtib.cc:1225
page_t * m_page
The page.
Definition: btr0mtib.h:1385
dtuple_t * get_node_ptr() noexcept
Get node pointer.
Definition: btr0mtib.h:1442
We use Flush_observer to track flushing of non-redo logged pages in bulk create index(btr0load....
Definition: buf0flu.h:269
The proper function call sequence of Page_load is as below: – Page_load::init – Page_load::insert – P...
Definition: btr0load.cc:53
A helper RAII wrapper for otherwise difficult to use sequence of:
Definition: rem0rec.h:303
page_id_t id
Page id.
Definition: buf0buf.h:1379
Page identifier.
Definition: buf0types.h:206
Page size descriptor.
Definition: page0size.h:49
size_t physical() const
Retrieve the physical page size (on-disk).
Definition: page0size.h:120
A utility class which, if inherited from, prevents the descendant class from being copied,...
Definition: ut0class_life_cycle.h:40
const char * p
Definition: ctype-mb.cc:1234
dberr_t
Definition: db0err.h:38
@ DB_SUCCESS
Definition: db0err.h:42
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:1146
#define FSP_EXTENT_SIZE
File space extent size in pages page size | file space extent size -------—+--------------------— 4 K...
Definition: fsp0types.h:63
constexpr uint32_t FSEG_HEADER_SIZE
Length of the file system header, in bytes.
Definition: fsp0types.h:93
byte fseg_header_t
Data type for file segment header.
Definition: fsp0types.h:84
#define free(A)
Definition: lexyy.cc:915
Definition: btr0mtib.cc:55
void bulk_load_enable_slow_io_debug()
Definition: btr0mtib.cc:59
void bulk_load_disable_slow_io_debug()
Definition: btr0mtib.cc:60
std::ostream & operator<<(std::ostream &out, const Page_extent &obj)
Definition: btr0mtib.h:230
void * begin(THD *thd, const TABLE *table, size_t data_size, size_t memory, size_t num_threads) noexcept
Definition: bulk_data_service.cc:1533
static PFS_engine_table_share_proxy table
Definition: pfs.cc:60
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:191
Definition: varlen_sort.h:174
std::vector< T, ut::allocator< T > > vector
Specialization of vector which uses allocator.
Definition: ut0new.h:2873
void delete_(T *ptr) noexcept
Releases storage which has been dynamically allocated through any of the ut::new*() variants.
Definition: ut0new.h:808
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:52
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:89
constexpr uint32_t PAGE_BTR_SEG_TOP
Definition: page0types.h:97
byte page_t
Type of the index page.
Definition: page0types.h:151
byte rec_t
Definition: rem0types.h:40
bool is_blob(enum_field_types sql_type)
Definition: field.h:4755
Function object to compare two Btree_load objects.
Definition: btr0mtib.h:1521
dict_index_t * m_index
Definition: btr0mtib.h:1524
bool operator()(const Btree_load *l_btree, const Btree_load *r_btree)
Definition: btr0mtib.cc:1978
Btree_load_compare(dict_index_t *index)
Definition: btr0mtib.h:1522
bool is_empty() const
Definition: btr0mtib.h:437
size_t m_max_range
Maximum number of ranges to pre-allocate.
Definition: btr0mtib.h:465
void init(size_t max_range)
Initialize cache.
Definition: btr0mtib.cc:2039
bool check(size_t &num_alloc, size_t &num_free) const
Check for number of extents to be allocated and cached.
Definition: btr0mtib.cc:2303
std::array< Page_range_t, S_MAX_RANGES > m_ranges
Cached page ranges already allocated to the segment.
Definition: btr0mtib.h:462
std::atomic< size_t > m_num_consumed
Total number of ranges allocated.
Definition: btr0mtib.h:471
void set_range(size_t index, Page_range_t &range)
Set allocated range(extent) in cache.
Definition: btr0mtib.cc:2294
std::atomic< size_t > m_num_allocated
Total number of ranges allocated.
Definition: btr0mtib.h:468
bool is_full() const
Definition: btr0mtib.h:440
bool get_range(Page_range_t &range, bool &alloc_trigger)
Get one page range from the cache.
Definition: btr0mtib.cc:2274
Context information for each level.
Definition: btr0mtib.h:264
size_t m_stat_n_extents
Number of extents allocated at this level.
Definition: btr0mtib.h:368
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:845
dict_index_t * m_index
The index which is being built.
Definition: btr0mtib.h:353
void build_page_cache()
Build page loader cache for current exent.
Definition: btr0mtib.cc:758
bool load_extent_from_cache()
Load one extent from extent cache.
Definition: btr0mtib.cc:705
dberr_t init()
Initialize.
Definition: btr0mtib.cc:798
Btree_load * m_btree_load
A back pointer to conceptually higher level btree load object.
Definition: btr0mtib.h:362
void set_current_page_load(Page_load *sibling)
Definition: btr0mtib.h:381
page_no_t m_last_page
The page_no of the last page in this level.
Definition: btr0mtib.h:350
~Level_ctx()
Destructor.
Definition: btr0mtib.cc:3167
const size_t m_level
The B-tree level whose context information is stored in this obj.
Definition: btr0mtib.h:356
void build_extent_cache()
Build the extent cache.
Definition: btr0mtib.cc:772
void free_page_load()
Free the current page load.
Definition: btr0mtib.cc:686
Page_load * create_page_load()
Definition: btr0mtib.cc:672
std::vector< page_no_t > m_pages_allocated
Definition: btr0mtib.h:375
trx_id_t get_trx_id() const
Definition: btr0mtib.h:1482
static void destroy(Level_ctx *obj)
Static member function to destroy a Level_ctx object.
Definition: btr0mtib.cc:641
std::vector< Page_extent * > m_cached_extents
Pre allocated extents to prevent repeated allocation and free.
Definition: btr0mtib.h:344
dberr_t alloc_page_num(page_no_t &page_no)
Allocate a page number.
Definition: btr0mtib.cc:575
Level_ctx(dict_index_t *index, size_t level, Btree_load *btree_load)
Constructor.
Definition: btr0mtib.h:283
bool m_extent_full
True if the current extent is full.
Definition: btr0mtib.h:371
dberr_t alloc_extent()
Allocate one extent in the relevant file segment.
Definition: btr0mtib.cc:612
size_t m_stat_n_pages
Number of pages allocated at this level.
Definition: btr0mtib.h:365
bool is_page_tracked(const page_no_t &page_no) const
Definition: btr0mtib.cc:606
Page_load * m_page_load
The Page_load of the current page being loaded.
Definition: btr0mtib.h:359
Page_load * get_page_load_from_cache()
Get a free page loader from cache.
Definition: btr0mtib.cc:740
Page_extent * m_page_extent
The current extent that is being loaded.
Definition: btr0mtib.h:327
page_no_t m_first_page
The page_no of the first page in this level.
Definition: btr0mtib.h:347
Page_load * get_page_load() const
Definition: btr0mtib.h:379
bool is_leaf() const
Check if this is leaf level.
Definition: btr0mtib.h:298
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:633
Allocate, use, manage and flush one extent pages (FSP_EXTENT_SIZE).
Definition: btr0mtib.h:57
Page_extent(Btree_load *btree_load, const bool is_leaf)
Constructor.
Definition: btr0mtib.h:1490
static void drop(Page_extent *extent)
Release the page extent.
Definition: btr0mtib.h:1507
const bool m_is_leaf
Definition: btr0mtib.h:191
void set_cached()
Mark the extent as cached.
Definition: btr0mtib.h:171
size_t m_next_cached_page_load_index
Next cached page load index.
Definition: btr0mtib.h:199
std::atomic_bool m_is_free
true if the cached entry is free to be used.
Definition: btr0mtib.h:195
std::vector< Page_load * > m_page_loads
All the page loaders of the used pages.
Definition: btr0mtib.h:77
bool is_null() const
Definition: btr0mtib.h:103
bool is_valid() const
Check if the range is valid.
Definition: btr0mtib.h:211
dberr_t flush(fil_node_t *node, void *iov, size_t iov_size)
Flush the used pages to disk.
Definition: btr0mtib.cc:497
page_no_t alloc()
Allocate a page number.
Definition: btr0mtib.h:243
void init()
Initialize the next page number to be allocated.
Definition: btr0mtib.h:251
bool is_page_loads_full() const
Definition: btr0mtib.h:117
std::ostream & print(std::ostream &out) const
Definition: btr0mtib.h:222
dberr_t destroy()
Free all resources.
Definition: btr0mtib.cc:565
std::pair< page_no_t, page_no_t > Page_range_t
Definition: btr0mtib.h:58
std::vector< Page_load * > m_cached_page_loads
Cached page loads.
Definition: btr0mtib.h:197
size_t used_pages() const
Calculate the number of used pages.
Definition: btr0mtib.h:97
page_no_t page_count() const
Number of pages in this extent.
Definition: btr0mtib.h:259
dberr_t flush_one_by_one(fil_node_t *node)
Flush one page at a time.
Definition: btr0mtib.cc:381
dberr_t bulk_flush(fil_node_t *node, void *iov, size_t iov_size)
Flush 1 extent pages at a time.
Definition: btr0mtib.cc:482
page_no_t m_page_no
Next page number to be used.
Definition: btr0mtib.h:70
void reset_range(const Page_range_t &range)
Reset the range with the given value.
Definition: btr0mtib.h:234
Page_range_t m_range
Page numbers of the pages that has been allocated in this extent.
Definition: btr0mtib.h:74
bool is_fully_used() const
Check if no more pages are there to be used.
Definition: btr0mtib.h:116
bool is_free() const
Definition: btr0mtib.h:178
void destroy_cached()
Free any cached page load entries.
Definition: btr0mtib.cc:557
void append(Page_load *page_load)
Save a page_load.
Definition: btr0mtib.h:1467
Page_range_t pages_to_free() const
void set_state(bool free)
Set and unset free state of a cached extent.
Definition: btr0mtib.h:175
std::atomic_bool m_is_cached
true iff the the extent is cached.
Definition: btr0mtib.h:193
bool is_cached() const
Definition: btr0mtib.h:181
void reset_cached_page_loads()
Reaset page load cache to free all.
Definition: btr0mtib.h:184
space_id_t space() const
Definition: btr0mtib.h:1486
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:1496
~Page_extent()
Destructor.
Definition: btr0mtib.h:204
Btree_load * m_btree_load
Definition: btr0mtib.h:190
Information about a buffer page.
Definition: btr0mtib.h:1459
size_t m_n_recs
Number of user records in the page.
Definition: btr0mtib.h:1461
size_t m_data_size
Number of bytes of data.
Definition: btr0mtib.h:1464
Heap wrapper that destroys the heap instance when it goes out of scope.
Definition: mem0mem.h:438
Storage format for overflow data in a big record, that is, a clustered index record which needs exter...
Definition: data0data.h:837
The buffer control block structure.
Definition: buf0buf.h:1750
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:1756
bool is_memory() const noexcept
Definition: buf0buf.h:1996
Compare the keys of an index.
Definition: ddl0impl-compare.h:40
Data structure for an index.
Definition: dict0mem.h:1045
unsigned space
space where the index tree is placed
Definition: dict0mem.h:1062
dict_table_t * table
back pointer to table
Definition: dict0mem.h:1059
page_size_t get_page_size() const
Get the page size of the tablespace to which this index belongs.
Definition: dict0mem.cc:894
Data structure for a database table.
Definition: dict0mem.h:1908
table_name_t name
Table name.
Definition: dict0mem.h:1983
Structure for an SQL data tuple of fields (logical record)
Definition: data0data.h:681
File node of a tablespace or the log data space.
Definition: fil0fil.h:150
Tablespace or log data space.
Definition: fil0fil.h:233
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:301
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:176
Definition: gen_lex_token.cc:148
char * m_name
The name in internal representation.
Definition: dict0mem.h:471
Definition: trx0trx.h:683
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:137
#define IF_DEBUG(...)
Definition: univ.i:673
unsigned long int ulint
Definition: univ.i:405
Utilities related to class lifecycle.
#define UT_LOCATION_HERE
Definition: ut0core.h:72
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:104
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:92
Dynamic memory allocation routines and custom allocators specifically crafted to support memory instr...
#define UT_NEW_THIS_FILE_PSI_KEY
Definition: ut0new.h:563