MySQL 9.6.0
Source Code Documentation
btr0mtib.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2023, 2025, 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:
943 using Page_loaders = std::vector<Page_load *, ut::allocator<Page_load *>>;
944 using Level_ctxs = std::vector<Level_ctx *, ut::allocator<Level_ctx *>>;
945
946 /** Helper to set wait callbacks for the current scope. */
948 public:
949 using Function = std::function<void()>;
950 friend class Btree_load;
951
953 : m_btree_load(btree_load) {
956 }
957
959 m_btree_load->m_fn_wait_begin = nullptr;
960 m_btree_load->m_fn_wait_end = nullptr;
961 }
962
963 private:
964 /** Btree Load for the wait callbacks. */
966 };
967
968 /** Constructor
969 @param[in] index B-tree index.
970 @param[in] trx Transaction object.
971 @param[in] loader_num loader index
972 @param[in] flush_queue_size bulk flusher queue size
973 @param[in] allocator extent allocator */
974 Btree_load(dict_index_t *index, trx_t *trx, size_t loader_num,
975 size_t flush_queue_size,
976 Bulk_extent_allocator &allocator) noexcept;
977
978 /** Destructor */
980
981 /** Initialize. Allocates the m_heap_order memory heap.
982 @return DB_SUCCESS on success or an error code on failure. */
983 dberr_t init();
984
985#ifdef UNIV_DEBUG
986 /** Save flushed page numbers for debugging purposes.
987 @param[in] page_no page number of the page that is flushed. */
989 m_bulk_flusher.m_flushed_page_nos.push_back(page_no);
990 }
991#endif /* UNIV_DEBUG */
992
993 /** Check if the index build operation has been interrupted.
994 @return true if the index build operation is interrupted, false otherwise.*/
995 bool is_interrupted() const;
996
997 /** Trigger flusher thread and check for error.
998 @return Innodb error code. */
1000
1001 bool is_pk() const { return m_index->is_clustered(); }
1002
1003 /** Get the index object.
1004 @return index object. */
1005 dict_index_t *index() const { return m_index; }
1006
1007 const char *get_table_name() const { return m_index->table->name.m_name; }
1008
1009 /** Get the root page number of this tree/subtree.
1010 @return the root page number of this tree/subtree. */
1012
1013 /** Get the level of the root page.
1014 @return the level of the root page. */
1015 size_t get_root_level() const { return m_root_level; }
1016
1017 /** Get information about root page. */
1018 void get_root_page_stat(Page_stat &stat);
1019
1020 /** Get the transaction id.
1021 @return the transaction id. */
1022 trx_id_t get_trx_id() const;
1023
1024 /** Btree bulk load finish. We commit the last page in each level
1025 and copy the last page in top level to the root page of the index
1026 if no error occurs.
1027 @param[in] is_err Whether bulk load was successful until now
1028 @param[in] subtree true if a subtree is being built, false otherwise.
1029 @return error code */
1030 [[nodiscard]] dberr_t finish(bool is_err, const bool subtree) noexcept;
1031
1032 /** Insert a tuple to a page in a level
1033 @param[in] dtuple Tuple to insert
1034 @param[in] level B-tree level
1035 @return error code */
1036 [[nodiscard]] dberr_t insert(dtuple_t *dtuple, size_t level) noexcept;
1037
1038 /** Split the right most block of the tree at the given level.
1039 @param[in,out] block the right most block at the given level.
1040 @param[in] level level of the given block.
1041 @param[in] node_ptr node pointer to be inserted in the block after
1042 splitting.
1043 @param[in] mtr mini transaction context.
1044 @param[in,out] highest_level highest level among all the subtrees.*/
1045 void split_rightmost(buf_block_t *block, size_t level, dtuple_t *node_ptr,
1046 mtr_t *mtr, size_t &highest_level);
1047
1048 /** Split the left most block of the tree at the given level.
1049 @param[in,out] block the left most block at the given level. it will be
1050 updated with the new left most block.
1051 @param[in] level level of the given block.
1052 @param[in] node_ptr node pointer to be inserted in the block after
1053 splitting.
1054 @param[in] mtr mini transaction context.
1055 @param[in,out] highest_level highest level among all the subtrees.*/
1056 void split_leftmost(buf_block_t *&block, size_t level, dtuple_t *node_ptr,
1057 mtr_t *mtr, size_t &highest_level);
1058
1059 private:
1060 /** Set the root page on completion.
1061 @param[in] last_page_no Last page number (the new root).
1062 @return DB_SUCCESS or error code. */
1063 [[nodiscard]] dberr_t load_root_page(page_no_t last_page_no) noexcept;
1064
1065 public:
1066 /** Commit(finish) a page. We set next/prev page no, insert a node pointer to
1067 father page if needed, and commit mini-transaction.
1068 @param[in] page_load Page to commit
1069 @param[in] next_page_load Next page
1070 @param[in] insert_father Flag whether need to insert node ptr
1071 @return error code */
1072 [[nodiscard]] dberr_t page_commit(Page_load *page_load,
1073 Page_load *next_page_load,
1074 bool insert_father) noexcept;
1075
1076 /** Prepare space to insert a tuple.
1077 @param[in,out] page_load Page bulk that will be used to store the record.
1078 It may be replaced if there is not enough space
1079 to hold the record.
1080 @param[in] level B-tree level
1081 @param[in] rec_size Record size
1082 @return error code */
1083 [[nodiscard]] dberr_t prepare_space(Page_load *&page_load, size_t level,
1084 size_t rec_size) noexcept;
1085
1086 /** Insert a tuple to a page.
1087 @param[in] page_load Page bulk object
1088 @param[in] tuple Tuple to insert
1089 @param[in] big_rec Big record vector, maybe NULL if there is no
1090 Data to be stored externally.
1091 @param[in] rec_size Record size
1092 @return error code */
1093 [[nodiscard]] dberr_t insert(Page_load *page_load, dtuple_t *tuple,
1094 big_rec_t *big_rec, size_t rec_size) noexcept;
1095
1096 /** Btree page bulk load finish. Commits the last page in each level
1097 if no error occurs. Also releases all page bulks.
1098 @param[in] is_err Whether bulk load was successful until now
1099 @param[out] last_page_no Last page number
1100 @return error code */
1101 [[nodiscard]] dberr_t finalize_page_loads(bool is_err,
1102 page_no_t &last_page_no) noexcept;
1103
1104 public:
1105 /** Allocate an extent.
1106 @param[in,out] page_range the range of pages allocated.
1107 @param[in] level btree level for which pages are allocated.
1108 @return status code. */
1109 dberr_t alloc_extent(Page_range_t &page_range, size_t level);
1110
1111 /** Initiate a direct file write operation.
1112 @param[in] block block to be written to disk.
1113 @return error code. */
1114 [[nodiscard]] dberr_t fil_io(buf_block_t *block) noexcept;
1115
1116 /** Flush the blob pages.
1117 @return status code. */
1119
1120 /** Add the given block the internal cache of blocks.
1121 @param[in] block the block to be cached. */
1122 inline void block_put(buf_block_t *block);
1123
1124 /** Remove the given block from the internal cache of blocks.
1125 @param[in] page_no the page number of block to be removed from cache. */
1126 inline void block_remove(const page_no_t page_no);
1127
1128 /** Search for a BUF_BLOCK_MEMORY block with given page number in the local
1129 cache.
1130 @param[in] page_no the page number of block to be fetched.
1131 @return buffer block with given page number. */
1132 [[nodiscard]] inline buf_block_t *block_get(page_no_t page_no) const noexcept;
1133
1134 /** Evict all the pages in the given range from the buffer pool.
1135 @param[in] range range of page numbers.
1136 @param[in] dirty_is_ok it is OK for a page to be dirty. */
1137 void force_evict(const Page_range_t &range, const bool dirty_is_ok = true);
1138
1139 public:
1140 /** Check if a new level is needed. */
1141 bool is_new_level(size_t level) const { return level >= m_level_ctxs.size(); }
1142
1143 /** Last page numbers of each level. */
1144 std::vector<page_no_t, ut::allocator<page_no_t>> m_last_page_nos{};
1145
1146 /** First page numbers of each level. */
1147 std::vector<page_no_t, ut::allocator<page_no_t>> m_first_page_nos{};
1148
1149 /** Get the level context object.
1150 @param[in] level the level number. level 0 is leaf level.
1151 @return the level context object. */
1152 Level_ctx *get_level(size_t level) const;
1153
1154 /** Page numbers of the pages that has been allocated in the leaf level.
1155 The page range is [p1, p2), where p2 is not included. */
1157
1158 /** Page numbers of the pages that has been allocated in the non-leaf level.
1159 The page range is [p1, p2), where p2 is not included. */
1161
1164
1165 /** State of the index. Used for asserting at the end of a
1166 bulk load operation to ensure that the online status of the
1167 index does not change */
1169
1170 /** Number of extents allocated for this B-tree. */
1172
1173 /** Number of pages allocated for this B-tree. */
1175
1176 public:
1177 std::ostream &print_left_pages(std::ostream &out) const;
1178 std::ostream &print_right_pages(std::ostream &out) const;
1179
1180 dberr_t check_key_overlap(const Btree_load *r_btree) const;
1181
1182#ifdef UNIV_DEBUG
1183 void print_tree_pages() const;
1184 std::string print_pages_in_level(const size_t level) const;
1185 /** Check size and validate index of limited size.
1186 @param[in] index Index to validate
1187 @return true if successful. */
1188 static bool validate_index(dict_index_t *index);
1189#endif /* UNIV_DEBUG */
1190
1191 /** All allocated extents registers with Btree_load. */
1192 void track_extent(Page_extent *page_extent);
1193
1194 /** Add fully used extents to the bulk flusher. Call this whenever a new
1195 Page_load is allocated, with finish set to false. Only in
1196 Btree_load::finish(), the finish argument will be true.
1197 @param[in] finish if true, add all the tracked extents to the bulk flusher,
1198 irrespective of whether it is fully used or not. */
1199 void add_to_bulk_flusher(bool finish = false);
1200
1201 /** Add blob extents to the bulk flusher and wait till they are flushed. */
1203
1204 /** Add the given page extent object to the bulk flusher.
1205 @param[in] page_extent the extent to be flushed. */
1206 void add_to_bulk_flusher(Page_extent *page_extent);
1207
1208 /** Check if transparent page compression (TPC) is enabled.
1209 @return true if TPC is enabled. */
1210 bool is_tpc_enabled() const;
1211
1212 /** Check if transparent page encryption (TPE) is enabled.
1213 @return true if TPE is enabled. */
1214 bool is_tpe_enabled() const;
1215
1216 /** @return get flush queue size limit. */
1219 }
1220
1221 /** If the data is already sorted and checked for duplicates, then we can
1222 disable doing it again. */
1224
1226
1229 }
1230
1231 private:
1232 /** Page allocation type. We allocate in extents by default. */
1235
1236 /** Number of records inserted. */
1237 uint64_t m_n_recs{};
1238
1239 /** B-tree index */
1241
1243
1244 /** Transaction id */
1246
1247 /** Root page level */
1249
1250 /** Context information for each level of the B-tree. The leaf level is at
1251 m_level_ctxs[0]. */
1253
1254 /** Reference to global extent allocator. */
1256
1257 /** Extents that are being tracked. */
1258 std::list<Page_extent *> m_extents_tracked;
1259
1260 /** If true, check if data is inserted in sorted order. */
1261 bool m_check_order{true};
1262
1263 /** Memory heap to be used for sort order checks. */
1265
1266 /** Function object to compare two tuples. */
1268
1269 /** The previous tuple that has been inserted. */
1271
1272 bool is_extent_tracked(const Page_extent *page_extent) const;
1273
1274 /** Loader number. */
1276
1278
1279 /* Begin wait callback function. */
1281
1282 /* End wait callback function. */
1284
1285 /** Blob inserter to handle the externally stored fields of InnoDB. This
1286 is used when blobs are inserted using multiple calls like open_blob(),
1287 write_blob() and close_blob(). */
1289
1290 /** Need another blob inserter to store blobs with a single call using
1291 insert_blob() */
1293
1294 /* Dedicated thread to flush pages. */
1296
1298};
1299
1301 public:
1302 using Btree_loads = std::vector<Btree_load *, ut::allocator<Btree_load *>>;
1303
1304 Merger(const size_t n_threads, Btree_loads &loads, dict_index_t *index,
1305 const trx_t *trx)
1306 : m_n_threads(n_threads),
1307 m_btree_loads(loads),
1308 m_index(index),
1309 m_trx(trx),
1311
1312 dberr_t merge(bool sort);
1313
1314 private:
1315 /** Get the maximum free space available in an empty page in bytes.
1316 @return the maximum free space available in an empty page. */
1317 size_t get_max_free() const {
1319 }
1320
1321 /** Remove any empty sub-trees with no records. */
1322 void remove_empty_subtrees();
1323
1324#ifdef UNIV_DEBUG
1325 /** Validate sub-tree boundaries. */
1326 void validate_boundaries();
1327
1328#endif /* UNIV_DEBUG */
1329
1330 /** Stich sub-trees together to form a tree with one or multiple
1331 nodes at highest leve.
1332 @param[out] highest_level highest level of the merged tree.
1333 @return innodb error code. */
1334 dberr_t subtree_link_levels(size_t &highest_level);
1335
1336 /** Create root node for the stiched sub-trees by combining the nodes
1337 at highest level creating another level if required.
1338 @param[in] highest_level highest level of the merged tree.
1339 @return innodb error code. */
1340 dberr_t add_root_for_subtrees(const size_t highest_level);
1341
1342 /** Insert the given list of node pointers into pages at the given level.
1343 @param[in,out] all_node_ptrs list of node pointers
1344 @param[in,out] total_node_ptrs_size total space in bytes needed to insert
1345 all the node pointers.
1346 @param[in] level the level at which the node pointers are inserted.
1347 @return DB_SUCCESS if successful.
1348 @return error code on failure. */
1349 dberr_t insert_node_ptrs(std::vector<dtuple_t *> &all_node_ptrs,
1350 size_t &total_node_ptrs_size, size_t level);
1351
1352 /** Load the left page and update its FIL_PAGE_NEXT.
1353 @param[in] l_page_no left page number
1354 @param[in] r_page_no right page number. */
1355 void link_right_sibling(const page_no_t l_page_no, const page_no_t r_page_no);
1356
1357 private:
1358 /** Number of loader threads. */
1359 const size_t m_n_threads;
1360
1361 /** Refernce to the subtrees to be merged. */
1363
1364 /** Index which is being built. */
1366
1367 /** Transaction making the changes. */
1368 const trx_t *m_trx{};
1369
1370 /** Memory heap to store node pointers. */
1372};
1373
1375 const Page_extent *page_extent) const {
1376 for (auto e : m_extents_tracked) {
1377 if (page_extent == e) {
1378 return true;
1379 }
1380 }
1381 return false;
1382}
1383
1384/** The proper function call sequence of Page_load is as below:
1385-- Page_load::init
1386-- Page_load::insert
1387-- Page_load::finish
1388-- Page_load::commit */
1390 public:
1392
1393 /** Ctor.
1394 @param[in] index B-tree index
1395 @param[in] btree_load btree object to which this page belongs. */
1396 Page_load(dict_index_t *index, Btree_load *btree_load);
1397
1398 /** Destructor. */
1400
1401 /** Check if page is corrupted.
1402 @return true if corrupted, false otherwise. */
1403 bool is_corrupted() const;
1404
1405 /** Print the child page numbers. */
1407
1408 /** Check if state of this page is BUF_BLOCK_MEMORY.
1409 @return true if page state is BUF_BLOCK_MEMORY, false otherwise.*/
1410 bool is_memory() const { return m_block->is_memory(); }
1411
1412 /** A static member function to create this object.
1413 @param[in] btree_load the bulk load object to which this Page_load belongs.
1414 @param[in] page_extent page extent to which this page belongs. */
1415 static Page_load *create(Btree_load *btree_load, Page_extent *page_extent);
1416
1417 /** Release the page loader. Delete if not cached.
1418 @param[in] page_load page loader to delete. */
1419 static void drop(Page_load *page_load);
1420
1421 /** Constructor
1422 @param[in] index B-tree index
1423 @param[in] trx_id Transaction id
1424 @param[in] page_no Page number
1425 @param[in] level Page level
1426 @param[in] observer Flush observer
1427 @param[in] btree_load btree object to which this page belongs. */
1429 size_t level, Flush_observer *observer,
1430 Btree_load *btree_load = nullptr) noexcept
1431 : m_index(index),
1432 m_trx_id(trx_id),
1433 m_page_no(page_no),
1434 m_level(level),
1436 m_flush_observer(observer),
1437 m_btree_load(btree_load) {
1439 }
1440
1441 /** Set the transaction id.
1442 @param[in] trx_id the transaction id to used. */
1443 void set_trx_id(const trx_id_t trx_id) { m_trx_id = trx_id; }
1444
1445 /** Get the current transaction identifier.
1446 @return the current transaction identifier.*/
1447 trx_id_t get_trx_id() const { return m_trx_id; }
1448
1449 /** Set the flush observer.
1450 @param[in] observer the flush observer object to use. */
1452 m_flush_observer = observer;
1453 }
1454
1455 bool is_leaf() const { return m_level == 0; }
1456
1457 /** Set the page number of this object. */
1458 void set_page_no(const page_no_t page_no);
1459
1460 void set_leaf_seg(const fseg_header_t *hdr) {
1462 }
1463 void set_top_seg(const fseg_header_t *hdr) {
1465 }
1466
1467 /** Initialize members and allocate page if needed and start mtr.
1468 @note Must be called and only once right after constructor.
1469 @return error code */
1470 [[nodiscard]] dberr_t init() noexcept;
1471 [[nodiscard]] dberr_t init_mem(const page_no_t new_page_no,
1472 Page_extent *page_extent) noexcept;
1473
1474 /** Initialize a memory block to be used for storing blobs.
1475 @param[in] page_no the page number to be set in the memory block.
1476 @param[in] page_extent extent to which this page belongs.
1477 @return DB_SUCCESS on success, error code on failure.*/
1478 [[nodiscard]] dberr_t init_mem_blob(const page_no_t page_no,
1479 Page_extent *page_extent) noexcept;
1480
1481 /** Allocate a page for this Page_load object.
1482 @return DB_SUCCESS on success, error code on failure. */
1484
1485 /** Re-initialize this page. */
1486 [[nodiscard]] dberr_t reinit() noexcept;
1487
1488 /** Reset this object so that Page_load::init() can be called again on this
1489 object. */
1490 void reset() noexcept;
1491
1492 /** Insert a tuple in the page.
1493 @param[in] tuple Tuple to insert
1494 @param[in] big_rec External record
1495 @param[in] rec_size Record size
1496 @return error code */
1497 [[nodiscard]] dberr_t insert(const dtuple_t *tuple, const big_rec_t *big_rec,
1498 size_t rec_size) noexcept;
1499
1500 /** Mark end of insertion to the page. Scan records to set page dirs,
1501 and set page header members. The scan is incremental (slots and records
1502 which assignment could be "finalized" are not checked again. Check the
1503 m_slotted_rec_no usage, note it could be reset in some cases like
1504 during split.
1505 Note: we refer to page_copy_rec_list_end_to_created_page.*/
1506 void finish() noexcept;
1507
1508 /** Commit mtr for a page
1509 @return DB_SUCCESS on success, error code on failure. */
1511
1512 /** Commit mtr for a page */
1513 void rollback() noexcept;
1514
1515 /** Check whether the record needs to be stored externally.
1516 @return false if the entire record can be stored locally on the page */
1517 [[nodiscard]] bool need_ext(const dtuple_t *tuple,
1518 size_t rec_size) const noexcept;
1519
1520 /** Store externally the first possible field of the given tuple.
1521 @return true if a field was stored externally, false if it was not possible
1522 to store any of the fields externally. */
1523 [[nodiscard]] bool make_ext(dtuple_t *tuple);
1524
1525 /** Get node pointer
1526 @return node pointer */
1527 [[nodiscard]] dtuple_t *get_node_ptr() noexcept;
1528
1529 /** Get node pointer
1530 @param[in] heap allocate node pointer in the given heap.
1531 @return node pointer */
1532 [[nodiscard]] dtuple_t *get_node_ptr(mem_heap_t *heap) noexcept;
1533
1534 /** Copy all records from page.
1535 @param[in] src_page Page with records to copy. */
1536 size_t copy_all(const page_t *src_page) noexcept;
1537
1538 /** Distribute all records from this page to the given pages.
1539 @param[in,out] to_pages array of Page_load objects.
1540 return total number of records processed. */
1541 size_t copy_to(std::vector<Page_load *> &to_pages);
1542
1543 /** Set next page
1544 @param[in] next_page_no Next page no */
1545 void set_next(page_no_t next_page_no) noexcept;
1546
1547 /** Set previous page
1548 @param[in] prev_page_no Previous page no */
1549 void set_prev(page_no_t prev_page_no) noexcept;
1550
1551 /** Get previous page (FIL_PAGE_PREV). */
1553
1554 /** Start mtr and latch block */
1556
1557 /** Check if required space is available in the page for the rec
1558 to be inserted. We check fill factor & padding here.
1559 @param[in] rec_size Required space
1560 @return true if space is available */
1561 [[nodiscard]] inline bool is_space_available(size_t rec_size) const noexcept;
1562
1563 /** Get the page number of this page load object.
1564 @return the page number of this page load object. */
1565 [[nodiscard]] page_no_t get_page_no() const noexcept { return m_page_no; }
1566
1567 [[nodiscard]] page_id_t get_page_id() const noexcept {
1568 return m_block->page.id;
1569 }
1570
1571 /** Get the physical page size of the underlying tablespace.
1572 @return the physical page size of the tablespace. */
1573 size_t get_page_size() const noexcept;
1574
1575 /** Get the table space ID.
1576 @return the table space ID. */
1577 space_id_t space() const noexcept;
1578
1579#ifdef UNIV_DEBUG
1580 /** Obtain tablespace id from the frame and the buffer block and ensure that
1581 they are the same.
1582 @return true if space id is same in both places. */
1583 bool verify_space_id() const;
1584#endif /* UNIV_DEBUG */
1585
1586 /** Get page level */
1587 [[nodiscard]] size_t get_level() const noexcept { return m_level; }
1588
1589 /** Set the level of this page. */
1590 void set_level(size_t level) noexcept { m_level = level; }
1591
1592 /** Get record no */
1593 [[nodiscard]] size_t get_rec_no() const { return m_rec_no; }
1594
1595 /** Get page */
1596 [[nodiscard]] const page_t *get_page() const noexcept {
1598 }
1599
1600 [[nodiscard]] page_t *get_page() noexcept {
1602 }
1603
1604 public:
1605 void init_for_writing();
1606 size_t get_data_size() const { return page_get_data_size(m_page); }
1607
1608#ifdef UNIV_DEBUG
1609 /** Check if index is X locked
1610 @return true if index is locked. */
1612#endif /* UNIV_DEBUG */
1613
1614 /** Copy given and all following records.
1615 @param[in] first_rec First record to copy */
1616 size_t copy_records(const rec_t *first_rec) noexcept;
1617
1618 /** Insert a record in the page, check for duplicates too.
1619 @param[in] rec Record
1620 @param[in] offsets Record offsets
1621 @return DB_SUCCESS or error code. */
1622 dberr_t insert(const rec_t *rec, Rec_offsets offsets) noexcept;
1623
1624 public:
1625 /** Store external record
1626 Since the record is not logged yet, so we don't log update to the record.
1627 the blob data is logged first, then the record is logged in bulk mode.
1628 @param[in] big_rec External record
1629 @param[in] offsets Record offsets
1630 @return error code */
1631 [[nodiscard]] dberr_t store_ext(const big_rec_t *big_rec,
1632 Rec_offsets offsets) noexcept;
1633
1634 /** Set the REC_INFO_MIN_REC_FLAG on the first user record in this page.
1635 @param[in] mtr mini transaction context. */
1636 void set_min_rec_flag(mtr_t *mtr);
1637
1638 /** Set the REC_INFO_MIN_REC_FLAG on the first user record in this page. */
1639 void set_min_rec_flag();
1640 bool is_min_rec_flag() const;
1641
1642 /** Set the level context object for this page load
1643 @param[in] level_ctx the level context object. */
1644 void set_level_ctx(Level_ctx *level_ctx) { m_level_ctx = level_ctx; }
1645
1646 /** Check if this page load object contains a level context object.
1647 @return true if the page load contains a level context object.
1648 @return false if the page load does NOT contain a level context object.*/
1649 bool has_level_ctx() const { return m_level_ctx != nullptr; }
1650
1651 /** Free the memory block. */
1652 void free();
1653
1655
1657
1658 void set_page_extent(Page_extent *page_extent) {
1659 m_page_extent = page_extent;
1660 }
1661
1662 /** Mark the Page load as cached. Flush thread should not free this Page. */
1663 void set_cached() { m_is_cached.store(true); }
1664
1665 /** @return true iff it is a cached Page Load. */
1666 bool is_cached() const { return m_is_cached.load(); }
1667
1668 private:
1669 /** Memory heap for internal allocation */
1671
1672 /** The index B-tree */
1674
1675 /** The min-transaction */
1677
1678 /** The transaction id */
1680
1681 /** The buffer block */
1683
1684 /** The page */
1686
1687 /** The current rec, just before the next insert rec */
1689
1690 /** The page no */
1692
1693 /** The page level in B-tree */
1694 size_t m_level{};
1695
1696 /** Flag: is page in compact format */
1697 const bool m_is_comp{};
1698
1699 /** The heap top in page for next insert */
1700 byte *m_heap_top{};
1701
1702 /** User record no */
1703 size_t m_rec_no{};
1704
1705 /** The free space left in the page */
1707
1708 /** The reserved space for fill factor */
1710
1711 /** Total data in the page */
1713
1714 /** The modify clock value of the buffer block
1715 when the block is re-pinned */
1716 uint64_t m_modify_clock{};
1717
1718 /** Flush observer */
1720
1721 /** Last record assigned to a slot. */
1723
1724 /** Number of records assigned to slots. */
1726
1727 /** Page modified flag. */
1729
1731
1733
1735
1736 /** true iff the the Page load is cached. */
1737 std::atomic_bool m_is_cached{false};
1738
1739 friend class Btree_load;
1740};
1741
1743 return get_node_ptr(m_heap);
1744}
1745
1747
1748inline size_t Page_load::get_page_size() const noexcept {
1749 const page_size_t page_size = m_index->get_page_size();
1750 return page_size.physical();
1751}
1752
1753inline Level_ctx *Btree_load::get_level(size_t level) const {
1754 ut_a(m_level_ctxs.size() > level);
1755 return m_level_ctxs[level];
1756}
1757
1758/** Information about a buffer page. */
1760 /** Number of user records in the page. */
1761 size_t m_n_recs;
1762
1763 /** Number of bytes of data. */
1765};
1766
1767inline void Page_extent::append(Page_load *page_load) {
1768 ut_ad(page_load->get_block() != nullptr);
1769 ut_ad(page_load->is_memory());
1770 ut_ad(page_load->get_page_no() >= m_range.first);
1771 ut_ad(page_load->get_page_no() < m_range.second);
1772 for (auto &iter : m_page_loads) {
1773 if (iter->get_page_no() == page_load->get_page_no()) {
1774 /* Page already appended. Don't append again. */
1775 return;
1776 }
1777 }
1779 m_page_loads.push_back(page_load);
1780}
1781
1783 return m_btree_load->get_trx_id();
1784}
1785
1787 return m_btree_load->index()->space;
1788}
1789
1790inline Page_extent::Page_extent(Btree_load *btree_load, const bool is_leaf)
1791 : m_page_no(FIL_NULL),
1792 m_range(FIL_NULL, FIL_NULL),
1793 m_btree_load(btree_load),
1794 m_is_leaf(is_leaf) {
1796}
1797
1799 const bool is_leaf, bool skip_track) {
1800 Page_extent *p = ut::new_withkey<Page_extent>(UT_NEW_THIS_FILE_PSI_KEY,
1801 btree_load, is_leaf);
1802 if (!skip_track) {
1803 btree_load->track_extent(p);
1804 }
1805 p->m_is_cached.store(false);
1806 return p;
1807}
1808
1809inline void Page_extent::drop(Page_extent *extent) {
1810 if (extent == nullptr) {
1811 return;
1812 }
1813 if (extent->is_cached()) {
1814 ut_a(!extent->is_free());
1815 bool free = true;
1816 extent->set_state(free);
1817 return;
1818 }
1819 ut::delete_(extent);
1820}
1821
1822/** Function object to compare two Btree_load objects. */
1825 bool operator()(const Btree_load *l_btree, const Btree_load *r_btree);
1827};
1828
1829#ifdef UNIV_DEBUG
1832#endif /* UNIV_DEBUG */
1833
1835 for (auto page_load : m_page_loads) {
1836 page_load->free();
1837 }
1838}
1839
1840namespace bulk {
1842 return m_btree_load.get_trx_id();
1843}
1844} /* namespace bulk */
1845
1846} /* namespace Btree_multi */
1847
1848#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:1300
Merger(const size_t n_threads, Btree_loads &loads, dict_index_t *index, const trx_t *trx)
Definition: btr0mtib.h:1304
Btree_loads & m_btree_loads
Refernce to the subtrees to be merged.
Definition: btr0mtib.h:1362
std::vector< Btree_load *, ut::allocator< Btree_load * > > Btree_loads
Definition: btr0mtib.h:1302
const trx_t * m_trx
Transaction making the changes.
Definition: btr0mtib.h:1368
dict_index_t * m_index
Index which is being built.
Definition: btr0mtib.h:1365
void validate_boundaries()
Validate sub-tree boundaries.
Definition: btr0mtib.cc:2740
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:3206
size_t get_max_free() const
Get the maximum free space available in an empty page in bytes.
Definition: btr0mtib.h:1317
void remove_empty_subtrees()
Remove any empty sub-trees with no records.
Definition: btr0mtib.cc:2727
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:3048
Scoped_heap m_tuple_heap
Memory heap to store node pointers.
Definition: btr0mtib.h:1371
dberr_t merge(bool sort)
Definition: btr0mtib.cc:2666
const size_t m_n_threads
Number of loader threads.
Definition: btr0mtib.h:1359
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:3178
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:2750
Helper to set wait callbacks for the current scope.
Definition: btr0mtib.h:947
~Wait_callbacks()
Definition: btr0mtib.h:958
Wait_callbacks(Btree_load *btree_load, Function &begin, Function &end)
Definition: btr0mtib.h:952
Btree_load * m_btree_load
Btree Load for the wait callbacks.
Definition: btr0mtib.h:965
std::function< void()> Function
Definition: btr0mtib.h:949
Definition: btr0mtib.h:901
~Btree_load() noexcept
Destructor.
Definition: btr0mtib.cc:1654
bulk::Blob_inserter m_full_blob_inserter
Need another blob inserter to store blobs with a single call using insert_blob()
Definition: btr0mtib.h:1292
dict_index_t * m_index
B-tree index.
Definition: btr0mtib.h:1240
Bulk_flusher m_bulk_flusher
Definition: btr0mtib.h:1295
dberr_t finish(bool is_err, const bool subtree) noexcept
Btree bulk load finish.
Definition: btr0mtib.cc:2009
dberr_t load_root_page(page_no_t last_page_no) noexcept
Set the root page on completion.
Definition: btr0mtib.cc:1885
dberr_t trigger_flusher() const
Trigger flusher thread and check for error.
Definition: btr0mtib.h:999
bool is_tpe_enabled() const
Check if transparent page encryption (TPE) is enabled.
Definition: btr0mtib.cc:2658
Bulk_extent_allocator & m_allocator
Reference to global extent allocator.
Definition: btr0mtib.h:1255
bool is_new_level(size_t level) const
Check if a new level is needed.
Definition: btr0mtib.h:1141
bool is_pk() const
Definition: btr0mtib.h:1001
dberr_t check_key_overlap(const Btree_load *r_btree) const
Definition: btr0mtib.cc:3306
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:1634
dict_index_t * index() const
Get the index object.
Definition: btr0mtib.h:1005
size_t get_max_flush_queue_size() const
Definition: btr0mtib.h:1217
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:1781
dtuple_t * m_prev_tuple
The previous tuple that has been inserted.
Definition: btr0mtib.h:1270
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:2108
std::ostream & print_right_pages(std::ostream &out) const
Definition: btr0mtib.cc:2069
size_t m_root_level
Root page level.
Definition: btr0mtib.h:1248
std::vector< page_no_t, ut::allocator< page_no_t > > m_first_page_nos
First page numbers of each level.
Definition: btr0mtib.h:1147
byte m_fseg_hdr_leaf[FSEG_HEADER_SIZE]
Definition: btr0mtib.h:1162
void block_put(buf_block_t *block)
Add the given block the internal cache of blocks.
dberr_t init()
Initialize.
Definition: btr0mtib.cc:2201
void add_blobs_to_bulk_flusher()
Add blob extents to the bulk flusher and wait till they are flushed.
Definition: btr0mtib.cc:1741
Bulk_extent_allocator::Type m_alloc_type
Page allocation type.
Definition: btr0mtib.h:1233
Page_range_t m_page_range_leaf
Page numbers of the pages that has been allocated in the leaf level.
Definition: btr0mtib.h:1156
void get_root_page_stat(Page_stat &stat)
Get information about root page.
Definition: btr0mtib.cc:2119
size_t m_loader_num
Loader number.
Definition: btr0mtib.h:1275
Level_ctxs m_level_ctxs
Context information for each level of the B-tree.
Definition: btr0mtib.h:1252
page_no_t get_subtree_root() const
Get the root page number of this tree/subtree.
Definition: btr0mtib.h:1011
size_t m_stat_n_pages
Number of pages allocated for this B-tree.
Definition: btr0mtib.h:1174
trx_t * m_trx
Transaction id.
Definition: btr0mtib.h:1245
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:1264
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:1662
std::list< Page_extent * > m_extents_tracked
Extents that are being tracked.
Definition: btr0mtib.h:1258
void track_page_flush(page_no_t page_no)
Save flushed page numbers for debugging purposes.
Definition: btr0mtib.h:988
std::ostream & print_left_pages(std::ostream &out) const
Definition: btr0mtib.cc:2060
ddl::Compare_key m_compare_key
Function object to compare two tuples.
Definition: btr0mtib.h:1267
bulk::Blob_inserter m_blob_inserter
Blob inserter to handle the externally stored fields of InnoDB.
Definition: btr0mtib.h:1288
size_t get_root_level() const
Get the level of the root page.
Definition: btr0mtib.h:1015
dberr_t alloc_extent(Page_range_t &page_range, size_t level)
Allocate an extent.
Definition: btr0mtib.cc:742
bool is_extent_tracked(const Page_extent *page_extent) const
Definition: btr0mtib.h:1374
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:1261
bool is_tpc_enabled() const
Check if transparent page compression (TPC) is enabled.
Definition: btr0mtib.cc:2648
std::vector< Page_load *, ut::allocator< Page_load * > > Page_loaders
Definition: btr0mtib.h:943
static bool validate_index(dict_index_t *index)
Check size and validate index of limited size.
Definition: btr0mtib.cc:1989
trx_id_t get_trx_id() const
Get the transaction id.
Definition: btr0mtib.cc:1652
void disable_check_order()
If the data is already sorted and checked for duplicates, then we can disable doing it again.
Definition: btr0mtib.h:1223
bool is_interrupted() const
Check if the index build operation has been interrupted.
Definition: btr0mtib.cc:3371
uint64_t m_n_recs
Number of records inserted.
Definition: btr0mtib.h:1237
Wait_callbacks::Function m_fn_wait_begin
Definition: btr0mtib.h:1280
const char * get_table_name() const
Definition: btr0mtib.h:1007
void track_extent(Page_extent *page_extent)
All allocated extents registers with Btree_load.
Definition: btr0mtib.cc:2145
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:3388
fil_space_t * m_space
Definition: btr0mtib.h:1242
Page_range_t m_page_range_top
Page numbers of the pages that has been allocated in the non-leaf level.
Definition: btr0mtib.h:1160
Wait_callbacks::Function m_fn_wait_end
Definition: btr0mtib.h:1283
void add_to_bulk_flusher(bool finish=false)
Add fully used extents to the bulk flusher.
Definition: btr0mtib.cc:1757
unsigned m_index_online
State of the index.
Definition: btr0mtib.h:1168
byte m_fseg_hdr_top[FSEG_HEADER_SIZE]
Definition: btr0mtib.h:1163
dberr_t page_commit(Page_load *page_load, Page_load *next_page_load, bool insert_father) noexcept
Commit(finish) a page.
Definition: btr0mtib.cc:1593
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:3487
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:1853
std::string print_pages_in_level(const size_t level) const
Definition: btr0mtib.cc:1936
void print_tree_pages() const
Definition: btr0mtib.cc:2079
Level_ctx * get_level(size_t level) const
Get the level context object.
Definition: btr0mtib.h:1753
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:1277
Bulk_extent_allocator & get_extent_allocator()
Definition: btr0mtib.h:1225
std::vector< Level_ctx *, ut::allocator< Level_ctx * > > Level_ctxs
Definition: btr0mtib.h:944
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:1144
bool verify_blob_context(Blob_context ctx) const
Definition: btr0mtib.h:1227
size_t m_stat_n_extents
Number of extents allocated for this B-tree.
Definition: btr0mtib.h:1171
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:2233
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:2507
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:2391
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:2527
dberr_t allocate_extent(bool is_leaf, mtr_t &mtr, Page_range_t &range)
Allocate one extent.
Definition: btr0mtib.cc:2386
bool is_interrupted()
Definition: btr0mtib.cc:2337
dberr_t allocate_page(bool is_leaf, Page_range_t &range)
Allocate one page.
Definition: btr0mtib.cc:2341
dberr_t run()
Extent thread executor.
Definition: btr0mtib.cc:2594
void start()
Definition: btr0mtib.cc:2304
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:2546
void stop()
Stop extent allocator thread, if active.
Definition: btr0mtib.cc:2312
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:121
dberr_t check_and_notify() const
Check for flusher error and wake up flusher thread.
Definition: btr0mtib.cc:148
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:169
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:83
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:220
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:159
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:97
void set_error(dberr_t error_code)
Set error code.
Definition: btr0mtib.cc:88
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:69
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:204
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:108
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:2218
void wait()
When no work is available, put the thread to sleep.
Definition: btr0mtib.cc:281
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:174
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:1389
dberr_t init_mem(const page_no_t new_page_no, Page_extent *page_extent) noexcept
Definition: btr0mtib.cc:1004
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:1590
buf_block_t * get_block()
Definition: btr0mtib.h:1656
space_id_t space() const noexcept
Get the table space ID.
Definition: btr0mtib.h:1746
void rollback() noexcept
Commit mtr for a page.
Definition: btr0mtib.cc:1435
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:967
bool is_corrupted() const
Check if page is corrupted.
Definition: btr0mtib.cc:326
trx_id_t m_trx_id
The transaction id.
Definition: btr0mtib.h:1679
byte * m_heap_top
The heap top in page for next insert.
Definition: btr0mtib.h:1700
size_t get_level() const noexcept
Get page level.
Definition: btr0mtib.h:1587
rec_t * m_last_slotted_rec
Last record assigned to a slot.
Definition: btr0mtib.h:1722
bool make_ext(dtuple_t *tuple)
Store externally the first possible field of the given tuple.
Definition: btr0mtib.cc:1559
dict_index_t * index()
Definition: btr0mtib.h:1654
void set_level_ctx(Level_ctx *level_ctx)
Set the level context object for this page load.
Definition: btr0mtib.h:1644
void set_trx_id(const trx_id_t trx_id)
Set the transaction id.
Definition: btr0mtib.h:1443
size_t copy_to(std::vector< Page_load * > &to_pages)
Distribute all records from this page to the given pages.
Definition: btr0mtib.cc:1473
size_t copy_records(const rec_t *first_rec) noexcept
Copy given and all following records.
Definition: btr0mtib.cc:1504
void set_flush_observer(Flush_observer *observer)
Set the flush observer.
Definition: btr0mtib.h:1451
void set_page_extent(Page_extent *page_extent)
Definition: btr0mtib.h:1658
size_t get_rec_no() const
Get record no.
Definition: btr0mtib.h:1593
trx_id_t get_trx_id() const
Get the current transaction identifier.
Definition: btr0mtib.h:1447
void set_min_rec_flag()
Set the REC_INFO_MIN_REC_FLAG on the first user record in this page.
Definition: btr0mtib.cc:2089
page_no_t get_page_no() const noexcept
Get the page number of this page load object.
Definition: btr0mtib.h:1565
void set_next(page_no_t next_page_no) noexcept
Set next page.
Definition: btr0mtib.cc:1523
size_t get_page_size() const noexcept
Get the physical page size of the underlying tablespace.
Definition: btr0mtib.h:1748
dict_index_t * m_index
The index B-tree.
Definition: btr0mtib.h:1673
size_t m_slotted_rec_no
Number of records assigned to slots.
Definition: btr0mtib.h:1725
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:1309
Flush_observer * m_flush_observer
Flush observer.
Definition: btr0mtib.h:1719
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:3376
void free()
Free the memory block.
Definition: btr0mtib.cc:2137
uint64_t m_modify_clock
The modify clock value of the buffer block when the block is re-pinned.
Definition: btr0mtib.h:1716
void set_prev(page_no_t prev_page_no) noexcept
Set previous page.
Definition: btr0mtib.cc:1527
bool has_level_ctx() const
Check if this page load object contains a level context object.
Definition: btr0mtib.h:1649
Page_load(dict_index_t *index, Btree_load *btree_load)
Ctor.
Definition: btr0mtib.cc:935
size_t m_rec_no
User record no.
Definition: btr0mtib.h:1703
std::atomic_bool m_is_cached
true iff the the Page load is cached.
Definition: btr0mtib.h:1737
static void drop(Page_load *page_load)
Release the page loader.
Definition: btr0mtib.cc:716
bool is_memory() const
Check if state of this page is BUF_BLOCK_MEMORY.
Definition: btr0mtib.h:1410
bool is_leaf() const
Definition: btr0mtib.h:1455
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:1535
void reset() noexcept
Reset this object so that Page_load::init() can be called again on this object.
Definition: btr0mtib.cc:1144
size_t get_data_size() const
Definition: btr0mtib.h:1606
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:1577
size_t m_level
The page level in B-tree.
Definition: btr0mtib.h:1694
rec_t * m_cur_rec
The current rec, just before the next insert rec.
Definition: btr0mtib.h:1688
dberr_t alloc() noexcept
Allocate a page for this Page_load object.
Definition: btr0mtib.cc:1097
void set_page_no(const page_no_t page_no)
Set the page number of this object.
Definition: btr0mtib.cc:926
size_t m_reserved_space
The reserved space for fill factor.
Definition: btr0mtib.h:1709
mem_heap_t * m_heap
Memory heap for internal allocation.
Definition: btr0mtib.h:1670
static Page_load * create(Btree_load *btree_load, Page_extent *page_extent)
A static member function to create this object.
Definition: btr0mtib.cc:706
page_id_t get_page_id() const noexcept
Definition: btr0mtib.h:1567
void latch() noexcept
Start mtr and latch block.
Page_extent * m_page_extent
Definition: btr0mtib.h:1734
bool is_cached() const
Definition: btr0mtib.h:1666
page_t * get_page() noexcept
Definition: btr0mtib.h:1600
bool is_index_locked() noexcept
Check if index is X locked.
Definition: btr0mtib.cc:1584
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:1428
void set_top_seg(const fseg_header_t *hdr)
Definition: btr0mtib.h:1463
dberr_t reinit() noexcept
Re-initialize this page.
Definition: btr0mtib.cc:1076
~Page_load() noexcept
Destructor.
Definition: btr0mtib.cc:3360
void set_leaf_seg(const fseg_header_t *hdr)
Definition: btr0mtib.h:1460
bool is_min_rec_flag() const
Definition: btr0mtib.cc:2091
dberr_t commit() noexcept
Commit mtr for a page.
Definition: btr0mtib.cc:1405
size_t copy_all(const page_t *src_page) noexcept
Copy all records from page.
Definition: btr0mtib.cc:1464
size_t m_free_space
The free space left in the page.
Definition: btr0mtib.h:1706
void set_cached()
Mark the Page load as cached.
Definition: btr0mtib.h:1663
const bool m_is_comp
Flag: is page in compact format.
Definition: btr0mtib.h:1697
Btree_load * m_btree_load
Definition: btr0mtib.h:1730
page_no_t get_prev() noexcept
Get previous page (FIL_PAGE_PREV).
Definition: btr0mtib.cc:1531
mtr_t * m_mtr
The min-transaction.
Definition: btr0mtib.h:1676
const page_t * get_page() const noexcept
Get page.
Definition: btr0mtib.h:1596
bool m_modified
Page modified flag.
Definition: btr0mtib.h:1728
buf_block_t * m_block
The buffer block.
Definition: btr0mtib.h:1682
void print_child_page_nos() noexcept
Print the child page numbers.
Definition: btr0mtib.cc:1448
page_no_t m_page_no
The page no.
Definition: btr0mtib.h:1691
Level_ctx * m_level_ctx
Definition: btr0mtib.h:1732
dberr_t init() noexcept
Initialize members and allocate page if needed and start mtr.
Definition: btr0mtib.cc:1176
size_t m_total_data
Total data in the page.
Definition: btr0mtib.h:1712
void init_for_writing()
Definition: btr0mtib.cc:341
void finish() noexcept
Mark end of insertion to the page.
Definition: btr0mtib.cc:1346
page_t * m_page
The page.
Definition: btr0mtib.h:1685
dtuple_t * get_node_ptr() noexcept
Get node pointer.
Definition: btr0mtib.h:1742
Used to insert many blobs into InnoDB.
Definition: btr0mtib.h:792
Page_load * alloc_data_page()
Allocate a data page.
Definition: btr0mtib.cc:3954
Page_range_t m_page_range_first
Definition: btr0mtib.h:873
Page_load * alloc_first_page()
Allocate a LOB first page.
Definition: btr0mtib.cc:3934
Page_load * alloc_index_page()
Allocate a LOB index page.
Definition: btr0mtib.cc:3938
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:3893
Blob_inserter(Btree_load &btree_load)
Constructor.
Definition: btr0mtib.cc:3732
Page_load * alloc_page_from_extent(Page_extent *&m_page_extent)
Definition: btr0mtib.cc:3902
trx_id_t get_trx_id() const
Get the current transaction id.
Definition: btr0mtib.h:1841
~Blob_inserter()
Definition: btr0mtib.cc:3981
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:3859
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:3865
void finish()
Definition: btr0mtib.cc:3962
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:3854
dberr_t init()
Initialize by allocating necessary resources.
Definition: btr0mtib.cc:3739
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:1161
#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:60
void bulk_load_disable_slow_io_debug()
Definition: btr0mtib.cc:61
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:924
std::chrono::milliseconds milliseconds
Definition: authorize_manager.cc:67
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:1823
dict_index_t * m_index
Definition: btr0mtib.h:1826
bool operator()(const Btree_load *l_btree, const Btree_load *r_btree)
Definition: btr0mtib.cc:2156
Btree_load_compare(dict_index_t *index)
Definition: btr0mtib.h:1824
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:2225
bool check(size_t &num_alloc, size_t &num_free) const
Check for number of extents to be allocated and cached.
Definition: btr0mtib.cc:2488
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:2479
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:2459
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:896
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:809
bool load_extent_from_cache()
Load one extent from extent cache.
Definition: btr0mtib.cc:756
dberr_t init()
Initialize.
Definition: btr0mtib.cc:849
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:3358
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:823
void free_page_load()
Free the current page load.
Definition: btr0mtib.cc:737
Page_load * create_page_load()
Definition: btr0mtib.cc:723
std::vector< page_no_t > m_pages_allocated
Definition: btr0mtib.h:471
trx_id_t get_trx_id() const
Definition: btr0mtib.h:1782
static void destroy(Level_ctx *obj)
Static member function to destroy a Level_ctx object.
Definition: btr0mtib.cc:692
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:625
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:662
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:656
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:791
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:684
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:1790
static void drop(Page_extent *extent)
Release the page extent.
Definition: btr0mtib.h:1809
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:544
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:615
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:421
dberr_t bulk_flush(fil_node_t *node, void *iov, size_t iov_size)
Flush 1 extent pages at a time.
Definition: btr0mtib.cc:529
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:607
void append(Page_load *page_load)
Save a page_load.
Definition: btr0mtib.h:1767
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:1834
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:1786
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:1798
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:1759
size_t m_n_recs
Number of user records in the page.
Definition: btr0mtib.h:1761
size_t m_data_size
Number of bytes of data.
Definition: btr0mtib.h:1764
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:160
Tablespace or log data space.
Definition: fil0fil.h:240
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.