MySQL 9.6.0
Source Code Documentation
lob0lob.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2015, 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#ifndef lob0lob_h
28#define lob0lob_h
29
30#include <my_dbug.h>
31#include "btr0pcur.h"
32#include "dict0mem.h"
33#include "page0page.h"
34#include "row0log.h"
35#include "univ.i"
36
37/* Uncomment the following line to generate debug data, useful to analyze
38LOB issues. */
39/* #define LOB_DEBUG */
40/* #define ZLOB_DEBUG */
41
42struct upd_t;
43typedef std::map<page_no_t, buf_block_t *> BlockCache;
44
45/**
46@file
47@brief Implements the large objects (LOB) module.
48
49InnoDB supports large objects (LOB). Previously, the LOB was called as
50externally stored fields. A large object contains a singly linked list of
51database pages, aka LOB pages. A reference to the first LOB page is stored
52along with the clustered index record. This reference is called the LOB
53reference (lob::ref_t). A single clustered index record can have many LOB
54references. Secondary indexes cannot have LOB references.
55
56There are two types of LOB - compressed and uncompressed.
57
58The main operations implemented for LOB are - INSERT, DELETE and FETCH. To
59carry out these main operations the following classes are provided.
60
61Inserter - for inserting uncompressed LOB data.
62zInserter - for inserting compressed LOB data.
63BaseInserter - a base class containing common state and functions useful for
64 both Inserter and zInserter. Inserter and zInserter derives
65 from this base class.
66Reader - for reading uncompressed LOB data.
67zReader - for reading compressed LOB data.
68Deleter - for deleting both compressed and uncompressed LOB data.
69
70For each main operation, the context information is identified separately.
71They are as follows:
72
73InsertContext - context information for doing insert of LOB. `
74DeleteContext - context information for doing delete of LOB. `
75ReadContext - context information for doing fetch of LOB. `
76
77*/
78
79/** Provides the large objects (LOB) module. Previously, the LOB was called as
80externally stored fields. */
81namespace lob {
82
83/** The maximum size possible for an LOB */
85
86/** The compressed LOB is stored as a collection of zlib streams. The
87uncompressed LOB is divided into chunks of size Z_CHUNK_SIZE and each of
88these chunks are compressed individually and stored as compressed LOB.
89data. */
90constexpr uint32_t KB128 = 128 * 1024;
91constexpr uint32_t Z_CHUNK_SIZE = KB128;
92
93/** The reference in a field for which data is stored on a different page.
94The reference is at the end of the 'locally' stored part of the field.
95'Locally' means storage in the index record.
96We store locally a long enough prefix of each column so that we can determine
97the ordering parts of each index record without looking into the externally
98stored part. */
99/*-------------------------------------- @{ */
100
101/** Space identifier where stored. */
103
104/** page number where stored */
106
107/** offset of BLOB header on that page */
109
110/** Version number of LOB (LOB in new format)*/
112
113/** 8 bytes containing the length of the externally stored part of the LOB.
114The 2 highest bits are reserved to the flags below. */
116
117/*-------------------------------------- @} */
118
119/** The most significant bit of BTR_EXTERN_LEN (i.e., the most
120significant bit of the byte at smallest address) is set to 1 if this
121field does not 'own' the externally stored field; only the owner field
122is allowed to free the field in purge! */
124
125/** If the second most significant bit of BTR_EXTERN_LEN (i.e., the
126second most significant bit of the byte at smallest address) is 1 then
127it means that the externally stored field was inherited from an
128earlier version of the row. In rollback we are not allowed to free an
129inherited external field. */
131
132/** If the 3rd most significant bit of BTR_EXTERN_LEN is 1, then it
133means that the externally stored field is currently being modified.
134This is mainly used by the READ UNCOMMITTED transaction to avoid returning
135inconsistent blob data. */
137
138/** The structure of uncompressed LOB page header */
139
140/** Offset within header of LOB length on this page. */
142
143/** Offset within header of next BLOB part page no.
144FIL_NULL if none */
146
147/** Size of an uncompressed LOB page header, in bytes */
149
150/** Start of the data on an LOB page */
152
153/** In memory representation of the LOB reference. */
154struct ref_mem_t {
155 /** Space Identifier of the clustered index. */
157
158 /** Page number of first LOB page. */
160
161 /** Offset within m_page_no where LOB begins. */
163
164 /** Length of LOB */
166
167 /** Whether the LOB is null. */
168 bool m_null;
169
170 /** Whether the clustered index record owns this LOB. */
172
173 /** Whether the clustered index record inherited this LOB from
174 another clustered index record. */
176
177 /** Whether the LOB is partially updated. */
179
180 /** Whether the blob is being modified. */
182
183 /** Check if the LOB has already been purged.
184 @return true if LOB has been purged, false otherwise. */
185 bool is_purged() const {
186 return ((m_page_no == FIL_NULL) && (m_length == 0));
187 }
188};
189
190extern const byte field_ref_almost_zero[FIELD_REF_SIZE];
191
192/** The struct 'lob::ref_t' represents an external field reference. The
193reference in a field for which data is stored on a different page. The
194reference is at the end of the 'locally' stored part of the field. 'Locally'
195means storage in the index record. We store locally a long enough prefix of
196each column so that we can determine the ordering parts of each index record
197without looking into the externally stored part. */
198struct ref_t {
199 private:
200 /** If the LOB size is equal to or above this limit (in physical page
201 size terms), then the LOB is big enough to be partially updated. Only
202 in this case LOB index needs to be built. */
204
205 public:
206 /** If the total number of bytes modified in an LOB, in an update
207 operation, is less than or equal to this threshold LOB_SMALL_CHANGE_THRESHOLD,
208 then it is considered as a small change. For small changes to LOB,
209 the changes are undo logged like any other update operation. */
211
212 /* Whether the update to the LOB can be considered as a small change.
213 Currently, the small partial update optimization is restricted to only the
214 first version of the lob, to avoid interacting with the partial update
215 feature. This restriction is because reconstructing the older versions of
216 the lob is not yet completely implemented. */
217 static bool is_small_change(size_t bytes_changed, const ref_t &blobref) {
218 return (bytes_changed <= ref_t::LOB_SMALL_CHANGE_THRESHOLD) &&
219 (blobref.version() == 1);
220 }
221
222 /** Constructor.
223 @param[in] ptr Pointer to the external field reference. */
224 explicit ref_t(byte *ptr) : m_ref(ptr) {}
225
226 /** For compressed LOB, if the length is less than or equal to Z_CHUNK_SIZE
227 then use the older single z stream format to store the LOB. */
228 bool use_single_z_stream() const { return (length() <= Z_CHUNK_SIZE); }
229
230 /** For compressed LOB, if the length is less than or equal to Z_CHUNK_SIZE
231 then use the older single z stream format to store the LOB. */
232 static bool use_single_z_stream(ulint len) { return (len <= Z_CHUNK_SIZE); }
233
234 /** Check if this LOB is big enough to do partial update.
235 @param[in] page_size the page size
236 @param[in] lob_length the size of BLOB in bytes.
237 @return true if LOB is big enough, false otherwise. */
238 static bool is_big(const page_size_t &page_size [[maybe_unused]],
239 const ulint lob_length [[maybe_unused]]) {
240 /* Disable a performance optimization */
241 return true;
242 }
243
244 /** Check if this LOB is big enough to do partial update.
245 @param[in] page_size the page size
246 @return true if LOB is big enough, false otherwise. */
247 bool is_big(const page_size_t &page_size [[maybe_unused]]) const {
248 /* Disable a performance optimization */
249 return true;
250 }
251
252 /** Parse the LOB reference object and copy data into the given
253 ref_mem_t object.
254 @param[out] obj LOB reference memory object. */
255 void parse(ref_mem_t &obj) const {
256 obj.m_space_id = space_id();
257 obj.m_page_no = page_no();
258 obj.m_offset = offset();
259 obj.m_length = length();
260 obj.m_null = is_null();
261 obj.m_owner = is_owner();
262 obj.m_inherit = is_inherited();
264 }
265
266 /** Copy the LOB reference into the given memory location.
267 @param[out] field_ref write LOB reference in this
268 location.*/
269 void copy(byte *field_ref) const { memcpy(field_ref, m_ref, SIZE); }
270
271 /** Check whether the stored external field reference is equal to the
272 given field reference.
273 @param[in] ptr supplied external field reference. */
274 bool is_equal(const byte *ptr) const { return (m_ref == ptr); }
275
276 /** Set the external field reference to the given memory location.
277 @param[in] ptr the new external field reference. */
278 void set_ref(byte *ptr) { m_ref = ptr; }
279
280 /** Check if the field reference is made of zeroes except the being_modified
281 bit.
282 @return true if field reference is made of zeroes, false otherwise. */
283 bool is_null_relaxed() const {
284 return (is_null() || memcmp(field_ref_almost_zero, m_ref, SIZE) == 0);
285 }
286
287 /** Check if the field reference is made of zeroes.
288 @return true if field reference is made of zeroes, false otherwise. */
289 bool is_null() const { return (memcmp(field_ref_zero, m_ref, SIZE) == 0); }
290
291 /** Initialize the reference object with zeroes. */
292 void init() { memset(m_ref, 0, SIZE); }
293
294#ifdef UNIV_DEBUG
295 /** Check if the LOB reference is null (all zeroes) except the "is being
296 modified" bit.
297 @param[in] ref the LOB reference.
298 @return true if the LOB reference is null (all zeros) except the "is being
299 modified" bit, false otherwise. */
300 static bool is_null_relaxed(const byte *ref) {
301 return (is_null(ref) || memcmp(field_ref_almost_zero, ref, SIZE) == 0);
302 }
303
304 /** Check if the LOB reference is null (all zeroes).
305 @param[in] ref the LOB reference.
306 @return true if the LOB reference is null (all zeros), false otherwise. */
307 static bool is_null(const byte *ref) {
308 return (memcmp(field_ref_zero, ref, SIZE) == 0);
309 }
310#endif /* UNIV_DEBUG */
311
312 /** Set the ownership flag in the blob reference.
313 @param[in] owner Whether to own or disown. If owner, unset
314 the owner flag.
315 @param[in] mtr Mini-transaction or NULL.*/
316 void set_owner(bool owner, mtr_t *mtr) {
318
319 if (owner) {
320 /* owns the blob */
321 byte_val &= ~BTR_EXTERN_OWNER_FLAG;
322 } else {
323 byte_val |= BTR_EXTERN_OWNER_FLAG;
324 }
325
327 }
328
329 /** Set the ownership flag in the blob reference.
330 @param[in] owner Whether to own or disown. If owner, unset
331 the owner flag. */
332 void set_owner(bool owner) {
334
335 if (owner) {
336 /* owns the blob */
337 byte_val &= ~BTR_EXTERN_OWNER_FLAG;
338 } else {
339 byte_val |= BTR_EXTERN_OWNER_FLAG;
340 }
341
343 }
344
345 /** Set the being_modified flag in the field reference.
346 @param[in,out] ref The LOB reference
347 @param[in] modifying true, if blob is being modified.
348 @param[in] mtr Mini-transaction context.*/
349 static void set_being_modified(byte *ref, bool modifying, mtr_t *mtr) {
351
352 if (modifying) {
354 } else {
355 byte_val &= ~BTR_EXTERN_BEING_MODIFIED_FLAG;
356 }
357
359 }
360
361 /** Set the being_modified flag in the field reference.
362 @param[in] modifying true, if blob is being modified.
363 @param[in] mtr Mini-transaction context.*/
364 void set_being_modified(bool modifying, mtr_t *mtr) {
365 set_being_modified(m_ref, modifying, mtr);
366 }
367
368 /** Check if the current blob is being modified
369 @param[in] field_ref blob field reference
370 @return true if it is being modified, false otherwise. */
371 bool static is_being_modified(const byte *field_ref) {
372 const ulint byte_val = mach_read_from_1(field_ref + BTR_EXTERN_LEN);
373 return (byte_val & BTR_EXTERN_BEING_MODIFIED_FLAG);
374 }
375
376 /** Check if the current blob is being modified
377 @return true if it is being modified, false otherwise. */
378 bool is_being_modified() const { return (is_being_modified(m_ref)); }
379
380 /** Set the inherited flag in the field reference.
381 @param[in] inherited true, if inherited.
382 @param[in] mtr Mini-transaction context.*/
383 void set_inherited(bool inherited, mtr_t *mtr) {
385
386 if (inherited) {
387 byte_val |= BTR_EXTERN_INHERITED_FLAG;
388 } else {
389 byte_val &= ~BTR_EXTERN_INHERITED_FLAG;
390 }
391
393 }
394
395 /** Check if the current row is the owner of the blob.
396 @return true if owner, false otherwise. */
397 bool is_owner() const {
399 return (!(byte_val & BTR_EXTERN_OWNER_FLAG));
400 }
401
402 /** Check if the current row inherited the blob from parent row.
403 @return true if inherited, false otherwise. */
404 bool is_inherited() const {
405 const ulint byte_val = mach_read_from_1(m_ref + BTR_EXTERN_LEN);
406 return (byte_val & BTR_EXTERN_INHERITED_FLAG);
407 }
408
409#ifdef UNIV_DEBUG
410 /** Read the space id from the given blob reference.
411 @param[in] ref the blob reference.
412 @return the space id */
413 static space_id_t space_id(const byte *ref) {
414 return (mach_read_from_4(ref));
415 }
416
417 /** Read the page no from the blob reference.
418 @return the page no */
419 static page_no_t page_no(const byte *ref) {
421 }
422#endif /* UNIV_DEBUG */
423
424 /** Read the space id from the blob reference.
425 @return the space id */
427
428 /** Read the page number from the blob reference.
429 @return the page number */
432 }
433
434 /** Read the offset of blob header from the blob reference.
435 @return the offset of the blob header */
437
438 /** Read the LOB version from the blob reference.
439 @return the LOB version number. */
440 uint32_t version() const {
442 }
443
444 /** Read the length from the blob reference.
445 @return length of the blob */
446 ulint length() const {
447 return (mach_read_from_4(m_ref + BTR_EXTERN_LEN + 4));
448 }
449
450 /** Update the information stored in the external field reference.
451 @param[in] space_id the space identifier.
452 @param[in] page_no the page number.
453 @param[in] offset the offset within the page_no
454 @param[in] mtr the mini trx or NULL. */
457 set_page_no(page_no, mtr);
458 set_offset(offset, mtr);
459 }
460
461 /** Set the space_id in the external field reference.
462 @param[in] space_id the space identifier.
463 @param[in] mtr mini-trx or NULL. */
466 }
467
468 /** Set the space_id in the external field reference.
469 @param[in] space_id the space identifier. */
472 }
473
474 /** Set the page number in the external field reference.
475 @param[in] page_no the page number.
476 @param[in] mtr mini-trx or NULL. */
477 void set_page_no(const ulint page_no, mtr_t *mtr) {
479 }
480
481 /** Set the page number in the external field reference.
482 @param[in] page_no the page number. */
485 }
486
487 /** Set the offset information in the external field reference.
488 @param[in] offset the offset.
489 @param[in] mtr mini-trx or NULL. */
490 void set_offset(const ulint offset, mtr_t *mtr) {
492 }
493
494 /** Set the version information in the external field reference.
495 @param[in] version the lob version. */
498 }
499
500 /** Set the length of blob in the external field reference.
501 @param[in] len the blob length .
502 @param[in] mtr mini-trx or NULL. */
503 void set_length(const ulint len, mtr_t *mtr) {
504 ut_ad(len <= MAX_SIZE);
506 }
507
508 /** Set the length of blob in the external field reference.
509 @param[in] len the blob length . */
510 void set_length(const ulint len) {
511 ut_ad(len <= MAX_SIZE);
513 }
514
515 /** Get the start of a page containing this blob reference.
516 @return start of the page */
517 page_t *page_align() const { return (::page_align(m_ref)); }
518
519#ifdef UNIV_DEBUG
520 /** Check if the given mtr has necessary latches to update this LOB
521 reference.
522 @param[in] mtr Mini-transaction that needs to
523 be checked.
524 @return true if valid, false otherwise. */
525 bool validate(mtr_t *mtr) {
526 ut_ad(m_ref != nullptr);
527 ut_ad(mtr != nullptr);
528
529 if (mtr->get_log_mode() == MTR_LOG_NO_REDO) {
530 return (true);
531 }
532
535 ut_ad(block != nullptr);
536 return (true);
537 }
538
539 /** Check if the space_id in the LOB reference is equal to the
540 space_id of the index to which it belongs.
541 @param[in] index the index to which LOB belongs.
542 @return true if space is valid in LOB reference, false otherwise. */
543 bool check_space_id(dict_index_t *index) const;
544#endif /* UNIV_DEBUG */
545
546 /** Check if the LOB can be partially updated. This is done by loading
547 the first page of LOB and looking at the flags.
548 @param[in] index the index to which LOB belongs.
549 @return true if LOB is partially updatable, false otherwise.*/
551
552 /** Load the first page of the LOB and mark it as not partially
553 updatable anymore.
554 @param[in] trx Current transaction
555 @param[in] mtr Mini-transaction context.
556 @param[in] index Index dictionary object.
557 @param[in] page_size Page size information. */
559 const page_size_t &page_size);
560
561 /** Load the first page of LOB and read its page type.
562 @param[in] index the index object.
563 @param[in] page_size the page size of LOB.
564 @param[out] is_partially_updatable is the LOB partially updatable.
565 @return the page type of first page of LOB.*/
567 const page_size_t &page_size,
568 bool &is_partially_updatable) const;
569
570 /** Print this LOB reference into the given output stream.
571 @param[in] out the output stream.
572 @return the output stream. */
573 std::ostream &print(std::ostream &out) const;
574
575 /** The size of an LOB reference object (in bytes) */
576 static const uint SIZE = BTR_EXTERN_FIELD_REF_SIZE;
577
578 private:
579 /** Pointing to a memory of size BTR_EXTERN_FIELD_REF_SIZE */
580 byte *m_ref;
581};
582
583/** Overload the global output stream operator to easily print the
584lob::ref_t object into the output stream.
585@param[in,out] out the output stream.
586@param[in] obj the lob::ref_t object to be printed
587@return the output stream. */
588inline std::ostream &operator<<(std::ostream &out, const ref_t &obj) {
589 return (obj.print(out));
590}
591
592/** LOB operation code for btr_store_big_rec_extern_fields(). */
593enum opcode {
594
595 /** Store off-page columns for a freshly inserted record */
597
598 /** Store off-page columns for an insert by update */
600
601 /** Store off-page columns for an update */
603
604 /** Store off-page columns for a freshly inserted record by bulk */
606
607 /** The operation code is unknown or not important. */
610
611/** Stores the fields in big_rec_vec to the tablespace and puts pointers to
612them in rec. The extern flags in rec will have to be set beforehand. The
613fields are stored on pages allocated from leaf node file segment of the index
614tree.
615
616TODO: If the allocation extends the tablespace, it will not be redo logged, in
617any mini-transaction. Tablespace extension should be redo-logged, so that
618recovery will not fail when the big_rec was written to the extended portion of
619the file, in case the file was somehow truncated in the crash.
620@param[in] trx the trx doing LOB store. If unavailable it
621 could be nullptr.
622@param[in,out] pcur a persistent cursor. if btr_mtr is restarted,
623 then this can be repositioned.
624@param[in] upd update vector
625@param[in,out] offsets rec_get_offsets() on pcur. the "external in
626 offsets will correctly correspond storage"
627 flagsin offsets will correctly correspond to
628 rec when this function returns
629@param[in] big_rec_vec vector containing fields to be stored
630 externally
631@param[in,out] btr_mtr mtr containing the latches to the clustered
632 index. can be committed and restarted.
633@param[in] op operation code
634@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
636 trx_t *trx, btr_pcur_t *pcur, const upd_t *upd, ulint *offsets,
637 const big_rec_t *big_rec_vec, mtr_t *btr_mtr, opcode op);
638
639/** Copies an externally stored field of a record to mem heap.
640@param[in] trx the current transaction.
641@param[in] index the clustered index
642@param[in] rec record in a clustered index; must be
643 protected by a lock or a page latch
644@param[in] offsets array returned by rec_get_offsets()
645@param[in] page_size BLOB page size
646@param[in] no field number
647@param[out] len length of the field
648@param[out] lob_version version of lob that has been copied
649@param[in] is_sdi true for SDI Indexes
650@param[in,out] heap mem heap
651@param[in] is_rebuilt true if rebuilt
652@return the field copied to heap, or NULL if the field is incomplete */
654 trx_t *trx, const dict_index_t *index, const rec_t *rec,
655 const ulint *offsets, const page_size_t &page_size, ulint no, ulint *len,
656 size_t *lob_version, IF_DEBUG(bool is_sdi, ) mem_heap_t *heap,
657 bool is_rebuilt);
658
660 trx_t *trx, const dict_index_t *index, const rec_t *rec,
661 const ulint *offsets, const page_size_t &page_size, ulint no, ulint *len,
662 size_t *ver, bool is_sdi [[maybe_unused]], mem_heap_t *heap) {
664 trx, index, rec, offsets, page_size, no, len, ver,
665 IF_DEBUG(is_sdi, ) heap, false);
666}
667
668/** Gets the offset of the pointer to the externally stored part of a field.
669@param[in] index Index
670@param[in] offsets array returned by rec_get_offsets()
671@param[in] n index of the external field
672@return offset of the pointer to the externally stored part */
674 const ulint *offsets, ulint n);
675
676/** Gets a pointer to the externally stored part of a field.
677@param[in] index index
678@param rec record
679@param offsets rec_get_offsets(rec)
680@param n index of the externally stored field
681@return pointer to the externally stored part */
682static inline const byte *btr_rec_get_field_ref(const dict_index_t *index,
683 const byte *rec,
684 const ulint *offsets, ulint n) {
685 return rec + lob::btr_rec_get_field_ref_offs(index, offsets, n);
686}
687
688/** Gets a pointer to the externally stored part of a field.
689@param index record descriptor
690@param rec record
691@param offsets rec_get_offsets(rec)
692@param n index of the externally stored field
693@return pointer to the externally stored part */
694static inline byte *btr_rec_get_field_ref(const dict_index_t *index, byte *rec,
695 const ulint *offsets, ulint n) {
696 return rec + lob::btr_rec_get_field_ref_offs(index, offsets, n);
697}
698
699/** Deallocate a buffer block that was reserved for a BLOB part.
700@param[in] index Index
701@param[in] block Buffer block
702@param[in] all true=remove also the compressed page
703 if there is one
704@param[in] mtr Mini-transaction to commit */
705void blob_free(dict_index_t *index, buf_block_t *block, bool all, mtr_t *mtr);
706
707/** The B-tree context under which the LOB operation is done. */
709 public:
710 /** Default Constructor */
712 : m_mtr(nullptr),
715 m_rec(nullptr),
720
721 /** Constructor **/
723 : m_mtr(mtr),
725 m_index(index),
726 m_rec(nullptr),
728 m_block(block),
731
732 /** Constructor **/
734 ulint *offsets, buf_block_t *block)
735 : m_mtr(mtr),
736 m_pcur(pcur),
737 m_index(index),
738 m_rec(rec),
739 m_offsets(offsets),
740 m_block(block),
743 ut_ad(m_pcur == nullptr || rec_offs_validate());
744 ut_ad(m_block == nullptr || m_rec == nullptr ||
746 ut_ad(m_pcur == nullptr || m_rec == m_pcur->get_rec());
747 }
748
749 /** Constructor **/
751 ulint *offsets, buf_block_t *block, opcode op)
752 : m_mtr(mtr),
753 m_pcur(pcur),
754 m_index(index),
755 m_rec(rec),
756 m_offsets(offsets),
757 m_block(block),
758 m_op(op),
760 ut_ad(m_pcur == nullptr || rec_offs_validate());
762 ut_ad(m_pcur == nullptr || m_rec == m_pcur->get_rec());
763 }
764
765 /** Copy Constructor **/
766 BtrContext(const BtrContext &other)
767 : m_mtr(other.m_mtr),
768 m_pcur(other.m_pcur),
769 m_index(other.m_index),
770 m_rec(other.m_rec),
771 m_offsets(other.m_offsets),
772 m_block(other.m_block),
773 m_op(other.m_op),
775
776 /** Marks non-updated off-page fields as disowned by this record.
777 The ownership must be transferred to the updated record which is
778 inserted elsewhere in the index tree. In purge only the owner of
779 externally stored field is allowed to free the field.
780 @param[in] update update vector. */
782
783 /** Sets the ownership bit of an externally stored field in a record.
784 @param[in] i field number
785 @param[in] val value to set */
787 byte *data;
788 ulint local_len;
789
790 data = rec_get_nth_field(m_index, m_rec, m_offsets, i, &local_len);
792 ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
793
794 local_len -= BTR_EXTERN_FIELD_REF_SIZE;
795
796 ref_t ref(data + local_len);
797
798 ut_a(val || ref.is_owner());
799
800 page_zip_des_t *page_zip = get_page_zip();
801
802 if (page_zip) {
803 ref.set_owner(val, nullptr);
805 } else {
806 ref.set_owner(val, m_mtr);
807 }
808 }
809
810 /** Marks all extern fields in a record as owned by the record.
811 This function should be called if the delete mark of a record is
812 removed: a not delete marked record always owns all its extern
813 fields.*/
816
818
820 return;
821 }
822
823 for (ulint i = 0; i < n; i++) {
826 }
827 }
828 }
829
830 /** Frees the externally stored fields for a record.
831 @param[in] trx_id transaction identifier whose LOB is
832 being freed.
833 @param[in] undo_no undo number within a transaction whose
834 LOB is being freed.
835 @param[in] rollback performing rollback?
836 @param[in] rec_type undo record type.
837 @param[in] node purge node or nullptr */
839 bool rollback, ulint rec_type,
840 purge_node_t *node);
841
842 /** Frees the externally stored fields for a record, if the field
843 is mentioned in the update vector.
844 @param[in] trx_id the transaction identifier.
845 @param[in] undo_no undo number within a transaction whose
846 LOB is being freed.
847 @param[in] update update vector
848 @param[in] rollback performing rollback?
849 @param[in] big_rec_vec big record vector */
850 void free_updated_extern_fields(trx_id_t trx_id, undo_no_t undo_no,
851 const upd_t *update, bool rollback,
852 big_rec_t *big_rec_vec);
853
854 /** Gets the compressed page descriptor
855 @return the compressed page descriptor. */
858 }
859
860 /** Get the page number of clustered index block.
861 @return the page number. */
864 }
865
866 /** Get the record offset within page of the clustered index record.
867 @return the record offset. */
868 ulint get_rec_offset() const { return (page_offset(m_rec)); }
869
870 /** Check if there is a need to recalculate the context information.
871 @return true if there is a need to recalculate, false otherwise. */
872 bool need_recalc() const {
873 return ((m_pcur != nullptr) && (m_rec != m_pcur->get_rec()));
874 }
875
876 /** Get the clustered index record pointer.
877 @return clustered index record pointer. */
878 rec_t *rec() const {
879 ut_ad(m_pcur == nullptr || m_rec == m_pcur->get_rec());
880 return (m_rec);
881 }
882
883 /** Get the LOB reference for the given field number.
884 @param[in] field_no field number.
885 @return LOB reference (aka external field reference).*/
886 byte *get_field_ref(ulint field_no) const {
887 return (btr_rec_get_field_ref(m_index, m_rec, get_offsets(), field_no));
888 }
889
890#ifdef UNIV_DEBUG
891 /** Validate the current BLOB context object. The BLOB context object
892 is valid if the necessary latches are being held by the
893 mini-transaction of the B-tree (btr mtr). Does not return if the
894 validation fails.
895 @return true if valid */
896 bool validate() const {
898
901 table()->is_intrinsic());
902
905 table()->is_intrinsic());
906
907 return (true);
908 }
909
910 /** Check to see if all pointers to externally stored columns in
911 the record must be valid.
912 @return true if all blob references are valid.
913 @return will not return if any blob reference is invalid. */
915 for (ulint i = 0; i < rec_offs_n_fields(m_offsets); i++) {
917 continue;
918 }
919
920 byte *field_ref = btr_rec_get_field_ref(m_index, rec(), m_offsets, i);
921
922 ref_t blobref(field_ref);
923
924 /* The pointer must not be zero if the operation
925 succeeded. */
926 ut_a(!blobref.is_null());
927
928 /* The column must not be disowned by this record. */
929 ut_a(blobref.is_owner());
930 }
931
932 return (true);
933 }
934#endif /* UNIV_DEBUG */
935
936 /** Determine whether current operation is a bulk insert operation.
937 @return true, if bulk insert operation, false otherwise. */
938 bool is_bulk() const { return (m_op == OPCODE_INSERT_BULK); }
939
940 /** Get the beginning of the B-tree clustered index page frame
941 that contains the current clustered index record (m_rec).
942 @return the page frame containing the clust rec. */
943 const page_t *rec_frame() const {
945 return (m_block->frame);
946 }
947
948 /** Commit the mini-transaction that is holding the latches
949 of the clustered index record block. */
951
952 /** Start the mini-transaction that will be holding the latches
953 of the clustered index record block. */
955 mtr_log_t log_mode = m_mtr->get_log_mode();
956 m_mtr->start();
957 m_mtr->set_log_mode(log_mode);
958 }
959
960 /** Get the page number of clustered index record.
961 @return page number of clustered index record. */
964 }
965
966#ifndef UNIV_HOTBACKUP
967
968 /** Increment the buffer fix count of the clustered index record block.
969 This is to be called before commit_btr_mtr() which decrements the count when
970 you want to prevent the block from being freed:
971 rec_block_fix(); // buf_fix_count++
972 commit_btr_mtr(); // releasing mtr internally does buf_fix_count--
973 start_btr_mtr();
974 rec_block_unfix(); // calls btr_block_get() which does buf_fix_count++ and
975 // then does buf_fix_count--
976 */
981 }
982
983 /** Decrement the buffer fix count of the clustered index record block,
984 X-latching it before, so that the overall buffer_fix_count doesn't change.
985 This is done to restore X-latch on the page after mtr restart:
986 rec_block_fix(); // buf_fix_count++
987 commit_btr_mtr(); // releasing mtr internally does buf_fix_count--
988 start_btr_mtr();
989 rec_block_unfix(); // calls btr_block_get() which does buf_fix_count++ and
990 // then does buf_fix_count--
991 */
993 space_id_t space_id = space();
994 page_id_t page_id(space_id, m_btr_page_no);
996 page_cur_t *page_cur = &m_pcur->m_btr_cur.page_cur;
997
999
1000 page_cur->block = btr_block_get(page_id, page_size, RW_X_LATCH,
1002
1003 page_cur->rec = buf_block_get_frame(page_cur->block) + m_rec_offset;
1004
1005 buf_block_buf_fix_dec(page_cur->block);
1006 /* This decrement above is paired with increment in rec_block_fix(), and
1007 there is another increment done within btr_block_get(), so overall the block
1008 should be buffer-fixed and thus safe to be used. */
1009 ut_ad(page_cur->block->page.buf_fix_count > 0);
1010 recalc();
1011 }
1012#endif /* !UNIV_HOTBACKUP */
1013
1014 /** Restore the position of the persistent cursor. */
1017 bool ret =
1019
1020 ut_a(ret);
1021
1022 recalc();
1023 }
1024
1025 /** Get the index object.
1026 @return index object */
1027 dict_index_t *index() const { return (m_index); }
1028
1029 /** Get the table object.
1030 @return table object or NULL. */
1032 dict_table_t *result = nullptr;
1033
1034 if (m_pcur != nullptr && m_pcur->index() != nullptr) {
1035 result = m_pcur->index()->table;
1036 }
1037
1038 return (result);
1039 }
1040
1041 /** Get the space id.
1042 @return space id. */
1043 space_id_t space() const { return (index()->space); }
1044
1045 /** Obtain the page size of the underlying table.
1046 @return page size of the underlying table. */
1047 const page_size_t page_size() const {
1048 return (dict_table_page_size(table()));
1049 }
1050
1051 /** Determine the extent size (in pages) for the underlying table
1052 @return extent size in pages */
1054 return (dict_table_extent_size(table()));
1055 }
1056
1057 /** Check if there is enough space in the redo log file. The btr
1058 mini-transaction will be restarted. */
1061 }
1062
1063 /** Mark the nth field as externally stored.
1064 @param[in] field_no the field number. */
1065 void make_nth_extern(ulint field_no) {
1067 }
1068
1069 /** Get the log mode of the btr mtr.
1070 @return the log mode. */
1072
1073 /** Get flush observer
1074 @return flush observer */
1076 return (m_mtr->get_flush_observer());
1077 }
1078
1079 /** Get the record offsets array.
1080 @return the record offsets array. */
1081 ulint *get_offsets() const { return (m_offsets); }
1082
1083 /** Validate the record offsets array.
1084 @return true if validation succeeds, false otherwise. */
1085 bool rec_offs_validate() const {
1086 if (m_rec != nullptr) {
1088 }
1089 return (true);
1090 }
1091
1092 /** Get the associated mini-transaction.
1093 @return the mini-transaction. */
1094 mtr_t *get_mtr() { return (m_mtr); }
1095
1096 /** Get the pointer to the clustered record block.
1097 @return pointer to the clustered rec block. */
1098 buf_block_t *block() const { return (m_block); }
1099
1100 /** Save the position of the persistent cursor. */
1102
1103 /** Check if there is enough space in log file. Commit and re-start the
1104 mini-transaction. */
1105 void check_redolog_normal();
1106
1107 /** When bulk load is being done, check if there is enough space in redo
1108 log file. */
1109 void check_redolog_bulk();
1110
1111 /** Recalculate some of the members after restoring the persistent
1112 cursor. */
1113 void recalc() {
1115 m_rec = m_pcur->get_rec();
1118
1120 }
1121
1122 /** Write a blob reference of a field into a clustered index record
1123 in a compressed leaf page. The information must already have been
1124 updated on the uncompressed page.
1125 @param[in] field_no BLOB field number
1126 @param[in] mtr Mini-transaction to update blob page. */
1127 void zblob_write_blobref(ulint field_no, mtr_t *mtr) {
1129 mtr);
1130 }
1131
1132 /** The btr mtr that is holding the latch on the B-tree index page
1133 containing the clustered index record.*/
1135
1136 /** Persistent cursor positioned on the clustered index record.*/
1143
1144 /** Record offset within the page. */
1146
1147 /** Page number where the clust rec is present. */
1149};
1150
1151/** The context for a LOB operation. It contains the necessary information
1152to carry out a LOB operation. */
1153struct InsertContext : public BtrContext {
1154 /** Constructor
1155 @param[in] btr_ctx b-tree context for lob operation.
1156 @param[in] big_rec_vec array of blobs */
1157 InsertContext(const BtrContext &btr_ctx, const big_rec_t *big_rec_vec)
1158 : BtrContext(btr_ctx), m_big_rec_vec(big_rec_vec) {}
1159
1160 /** Get the vector containing fields to be stored externally.
1161 @return the big record vector */
1163
1164 /** Get the size of vector containing fields to be stored externally.
1165 @return the big record vector size */
1167
1168 /** The B-tree Context */
1169 // const BtrContext m_btr_ctx;
1170
1171 /** vector containing fields to be stored externally */
1173};
1174
1175/** Information about data stored in one BLOB page. */
1177 /** Constructor.
1178 @param[in] page_no the BLOB page number.
1179 @param[in] bytes amount of uncompressed BLOB data
1180 in BLOB page in bytes.
1181 @param[in] zbytes amount of compressed BLOB data
1182 in BLOB page in bytes. */
1183 blob_page_info_t(page_no_t page_no, uint bytes, uint zbytes)
1184 : m_page_no(page_no), m_bytes(bytes), m_zbytes(zbytes) {}
1185
1186 /** Re-initialize the current object. */
1187 void reset() {
1188 m_page_no = 0;
1189 m_bytes = 0;
1190 m_zbytes = 0;
1191 }
1192
1193 /** Print this blob_page_into_t object into the given output stream.
1194 @param[in] out the output stream.
1195 @return the output stream. */
1196 std::ostream &print(std::ostream &out) const;
1197
1198 /** Set the compressed data size in bytes.
1199 @param[in] bytes the new compressed data size. */
1200 void set_compressed_size(uint bytes) { m_zbytes = bytes; }
1201
1202 /** Set the uncompressed data size in bytes.
1203 @param[in] bytes the new uncompressed data size. */
1204 void set_uncompressed_size(uint bytes) { m_bytes = bytes; }
1205
1206 /** Set the page number.
1207 @param[in] page_no the page number */
1208 void set_page_no(page_no_t page_no) { m_page_no = page_no; }
1209
1210 private:
1211 /** The BLOB page number */
1213
1214 /** Amount of uncompressed data (in bytes) in the BLOB page. */
1216
1217 /** Amount of compressed data (in bytes) in the BLOB page. */
1219};
1220
1221inline std::ostream &operator<<(std::ostream &out,
1222 const blob_page_info_t &obj) {
1223 return (obj.print(out));
1224}
1225
1226/** The in-memory blob directory. Each blob contains a sequence of pages.
1227This directory contains a list of those pages along with their metadata. */
1229 typedef std::vector<blob_page_info_t>::const_iterator const_iterator;
1230
1231 /** Print this blob directory into the given output stream.
1232 @param[in] out the output stream.
1233 @return the output stream. */
1234 std::ostream &print(std::ostream &out) const;
1235
1236 /** Clear the contents of this blob directory. */
1237 void clear() { m_pages.clear(); }
1238
1239 /** Append the given blob page information.
1240 @param[in] page the blob page information to be added.
1241 @return DB_SUCCESS on success, error code on failure. */
1243 m_pages.push_back(page);
1244 return (DB_SUCCESS);
1245 }
1246
1247 /** A vector of blob pages along with its metadata. */
1248 std::vector<blob_page_info_t> m_pages;
1249};
1250
1251/** Overloading the global output operator to print the blob_dir_t
1252object into an output stream.
1253@param[in,out] out the output stream.
1254@param[in] obj the object to be printed.
1255@return the output stream. */
1256inline std::ostream &operator<<(std::ostream &out, const blob_dir_t &obj) {
1257 return (obj.print(out));
1258}
1259
1260/** The context information for reading a single BLOB */
1262 /** Constructor
1263 @param[in] page_size page size information.
1264 @param[in] data 'internally' stored part of the field
1265 containing also the reference to the
1266 external part; must be protected by
1267 a lock or a page latch.
1268 @param[in] prefix_len length of BLOB data stored inline in
1269 the clustered index record, including
1270 the blob reference.
1271 @param[out] buf the output buffer.
1272 @param[in] len the output buffer length.
1273 @param[in] is_sdi true for SDI Indexes. */
1274 ReadContext(const page_size_t &page_size, const byte *data, ulint prefix_len,
1275 byte *buf, ulint len IF_DEBUG(, bool is_sdi))
1276 : m_page_size(page_size),
1277 m_data(data),
1278 m_local_len(prefix_len),
1279 m_blobref(const_cast<byte *>(data) + prefix_len -
1281 m_buf(buf),
1282 m_len(len),
1284 read_blobref();
1285 }
1286
1287 /** Read the space_id, page_no and offset information from the BLOB
1288 reference object and update the member variables. */
1293 }
1294
1295 /** Check if the BLOB reference is valid. For this particular check,
1296 if the length of the BLOB is greater than 0, it is considered
1297 valid.
1298 @return true if valid. */
1299 bool is_valid_blob() const { return (m_blobref.length() > 0); }
1300
1301 dict_index_t *index() { return (m_index); }
1302
1303 /** The page size information. */
1305
1306 /** The 'internally' stored part of the field containing also the
1307 reference to the external part; must be protected by a lock or a page
1308 latch */
1309 const byte *m_data;
1310
1311 /** Length (in bytes) of BLOB prefix stored inline in clustered
1312 index record. */
1314
1315 /** The blob reference of the blob that is being read. */
1317
1318 /** Buffer into which data is read. */
1319 byte *m_buf;
1320
1321 /** Length of the buffer m_buf. */
1323
1324 /** The identifier of the space in which blob is available. */
1326
1327 /** The page number obtained from the blob reference. */
1329
1330 /** The offset information obtained from the blob reference. */
1332
1334
1336
1337#ifdef UNIV_DEBUG
1338 /** Is it a space dictionary index (SDI)?
1339 @return true if SDI, false otherwise. */
1340 bool is_sdi() const { return (m_is_sdi); }
1341
1342 /** Is it a tablespace dictionary index (SDI)? */
1343 const bool m_is_sdi;
1344
1345 /** Assert that current trx is using isolation level read uncommitted.
1346 @return true if transaction is using read uncommitted, false otherwise. */
1347 bool assert_read_uncommitted() const;
1348#endif /* UNIV_DEBUG */
1349
1350 /** The transaction that is reading. */
1351 trx_t *m_trx = nullptr;
1352};
1353
1354/** Fetch compressed BLOB */
1355struct zReader {
1356 /** Constructor. */
1357 explicit zReader(const ReadContext &ctx) : m_rctx(ctx) {}
1358
1359 /** Fetch the BLOB.
1360 @return DB_SUCCESS on success. */
1361 dberr_t fetch();
1362
1363 /** Fetch one BLOB page.
1364 @return DB_SUCCESS on success. */
1366
1367 /** Get the length of data that has been read.
1368 @return the length of data that has been read. */
1369 ulint length() const { return (m_stream.total_out); }
1370
1371 private:
1372 /** Do setup of the zlib stream.
1373 @return code returned by zlib. */
1374 int setup_zstream();
1375
1376#ifdef UNIV_DEBUG
1377 /** Assert that the local prefix is empty. For compressed row format,
1378 there is no local prefix stored. This function doesn't return if the
1379 local prefix is non-empty.
1380 @return true if local prefix is empty*/
1382#endif /* UNIV_DEBUG */
1383
1385
1386 /** Bytes yet to be read. */
1388
1389 /** The zlib stream used to uncompress while fetching blob. */
1390 z_stream m_stream;
1391
1392 /** The memory heap that will be used by zlib allocator. */
1394
1395 /* There is no latch on m_bpage directly. Instead,
1396 m_bpage is protected by the B-tree page latch that
1397 is being held on the clustered index record, or,
1398 in row_merge_copy_blobs(), by an exclusive table lock. */
1400
1401#ifdef UNIV_DEBUG
1402 /** The expected page type. */
1404#endif /* UNIV_DEBUG */
1405};
1406
1407/** Fetch uncompressed BLOB */
1408struct Reader {
1409 /** Constructor. */
1411 : m_rctx(ctx), m_cur_block(nullptr), m_copied_len(0) {}
1412
1413 /** Fetch the complete or prefix of the uncompressed LOB data.
1414 @return bytes of LOB data fetched. */
1415 ulint fetch();
1416
1417 /** Fetch one BLOB page. */
1418 void fetch_page();
1419
1421
1422 /** Buffer block of the current BLOB page */
1424
1425 /** Total bytes of LOB data that has been copied from multiple
1426 LOB pages. This is a cumulative value. When this value reaches
1427 m_rctx.m_len, then the read operation is completed. */
1429};
1430
1431/** The context information when the delete operation on LOB is
1432taking place. */
1433struct DeleteContext : public BtrContext {
1434 /** Constructor.
1435 @param[in] btr the B-tree context of the blob operation.
1436 @param[in] field_ref reference to a blob
1437 @param[in] field_no field containing the blob.
1438 @param[in] rollback true if it is rollback, false if it is purge. */
1439 DeleteContext(const BtrContext &btr, byte *field_ref, ulint field_no,
1440 bool rollback);
1441
1442 /** Constructor.
1443 @param[in] btr the B-tree context of the blob operation.
1444 @param[in] rollback true if it is rollback, false if it is purge. */
1445 DeleteContext(const BtrContext &btr, bool rollback);
1446
1447 /** Update the delete context to point to a different blob.
1448 @param[in] field_ref blob reference
1449 @param[in] field_no the field that contains the blob. */
1450 void set_blob(byte *field_ref, ulint field_no);
1451
1452 /** Check if the blob reference is valid.
1453 @return true if valid, false otherwise. */
1454 bool is_ref_valid() const {
1456 }
1457
1458 /** Determine if it is compressed page format.
1459 @return true if compressed. */
1460 bool is_compressed() const { return (m_page_size.is_compressed()); }
1461
1462 /** Check if tablespace supports atomic blobs.
1463 @return true if tablespace has atomic blobs. */
1464 bool has_atomic_blobs() const {
1465 space_id_t space_id = m_blobref.space_id();
1466 uint32_t flags = fil_space_get_flags(space_id);
1468 }
1469
1470 bool is_delete_marked() const {
1471 rec_t *clust_rec = rec();
1472 if (clust_rec == nullptr) {
1473 return (true);
1474 }
1475 return (rec_get_deleted_flag(clust_rec, page_rec_is_comp(clust_rec)));
1476 }
1477
1478#ifdef UNIV_DEBUG
1479 /** Validate the LOB reference object.
1480 @return true if valid, false otherwise. */
1481 bool validate_blobref() const {
1482 rec_t *clust_rec = rec();
1483 if (clust_rec != nullptr) {
1484 const byte *v2 =
1486
1488 }
1489 return (true);
1490 }
1491#endif /* UNIV_DEBUG */
1492
1493 /** Acquire an x-latch on the index page containing the clustered
1494 index record, in the given mini-transaction context.
1495 @param[in] mtr Mini-transaction context. */
1496 void x_latch_rec_page(mtr_t *mtr);
1497
1498 /** the BLOB reference or external field reference. */
1500
1501 /** field number of externally stored column; ignored if rec == NULL */
1503
1504 /** Is this operation part of rollback? */
1506
1507 /** The page size of the tablespace.*/
1509
1510 /** Add a buffer block that is to be freed.
1511 @param[in] block buffer block to be freed.*/
1513
1514 /** Free all the stored lob blocks. */
1515 void free_lob_blocks();
1516
1517 /** Destructor. Just add some asserts to ensure that resources are freed. */
1519
1520 private:
1521 /** Memory copy of the original LOB reference. */
1523
1524 using Block_vector = std::vector<buf_block_t *, ut::allocator<buf_block_t *>>;
1525
1526 /** The buffer blocks of lob to be freed. */
1528
1529 /** Obtain the page size from the tablespace flags.
1530 @return the page size. */
1531 page_size_t get_page_size() const;
1532};
1533
1535 : DeleteContext(btr, nullptr, 0, rollback) {}
1536
1537inline DeleteContext::DeleteContext(const BtrContext &btr, byte *field_ref,
1538 ulint field_no, bool rollback)
1539 : BtrContext(btr),
1540 m_blobref(field_ref),
1541 m_field_no(field_no),
1542 m_rollback(rollback),
1543 m_page_size(table() == nullptr ? get_page_size()
1545 if (field_ref != nullptr) {
1547 }
1548}
1549
1550inline void DeleteContext::set_blob(byte *field_ref, ulint field_no) {
1551 m_blobref.set_ref(field_ref);
1552 m_field_no = field_no;
1553 if (field_ref != nullptr) {
1555 }
1556}
1557
1559 bool found;
1560 space_id_t space_id = m_blobref.space_id();
1561 const page_size_t &tmp = fil_space_get_page_size(space_id, &found);
1562 ut_ad(found);
1563 return tmp;
1564}
1565
1567
1570 m_lob_blocks.push_back(block);
1571}
1572
1574 for (auto block_ptr : m_lob_blocks) {
1577 }
1578 m_lob_blocks.clear();
1579}
1580
1581/** Determine if an operation on off-page columns is an update.
1582@param[in] op type of BLOB operation.
1583@return true if op != OPCODE_INSERT */
1585 switch (op) {
1586 case OPCODE_INSERT:
1587 case OPCODE_INSERT_BULK:
1588 return (false);
1590 case OPCODE_UPDATE:
1591 return (true);
1592 case OPCODE_UNKNOWN:
1593 break;
1594 }
1595
1596 ut_d(ut_error);
1597 ut_o(return false);
1598}
1599
1600/** Copies the prefix of an externally stored field of a record.
1601The clustered index record must be protected by a lock or a page latch.
1602@param[in] trx the current transaction object if available
1603or nullptr.
1604@param[in] index the clust index in which lob is read.
1605@param[out] buf the field, or a prefix of it
1606@param[in] len length of buf, in bytes
1607@param[in] page_size BLOB page size
1608@param[in] data 'internally' stored part of the field
1609 containing also the reference to the external
1610 part; must be protected by a lock or a page
1611 latch.
1612@param[in] is_sdi true for SDI indexes
1613@param[in] local_len length of data, in bytes
1614@return the length of the copied field, or 0 if the column was being
1615or has been deleted */
1617 trx_t *trx, const dict_index_t *index, byte *buf, ulint len,
1618 const page_size_t &page_size, const byte *data,
1619 IF_DEBUG(bool is_sdi, ) ulint local_len);
1620
1621/** Copies an externally stored field of a record to mem heap.
1622The clustered index record must be protected by a lock or a page latch.
1623@param[in] trx the current trx object or nullptr
1624@param[in] index the clust index in which lob is read.
1625@param[out] len length of the whole field
1626@param[out] lob_version LOB version number.
1627@param[in] data 'internally' stored part of the field
1628 containing also the reference to the external
1629 part; must be protected by a lock or a page
1630 latch.
1631@param[in] page_size BLOB page size
1632@param[in] local_len length of data
1633@param[in] is_sdi true for SDI Indexes
1634@param[in,out] heap mem heap
1635@return the whole field copied to heap */
1637 trx_t *trx, const dict_index_t *index, ulint *len, size_t *lob_version,
1638 const byte *data, const page_size_t &page_size, ulint local_len,
1639 IF_DEBUG(bool is_sdi, ) mem_heap_t *heap);
1640
1642 trx_t *trx, const dict_index_t *index, byte *buf, ulint len,
1643 const page_size_t &page_size, const byte *data, bool is_sdi,
1644 ulint local_len) {
1646 trx, index, buf, len, page_size, data, IF_DEBUG(is_sdi, ) local_len);
1647}
1649 trx_t *trx, const dict_index_t *index, ulint *len, size_t *ver,
1650 const byte *data, const page_size_t &page_size, ulint local_len,
1651 bool is_sdi, mem_heap_t *heap) {
1652 return btr_copy_externally_stored_field_func(trx, index, len, ver, data,
1653 page_size, local_len,
1654 IF_DEBUG(is_sdi, ) heap);
1655}
1656
1657/** Gets the externally stored size of a record, in units of a database page.
1658@param[in] index index
1659@param[in] rec record
1660@param[in] offsets array returned by rec_get_offsets()
1661@return externally stored part, in units of a database page */
1663 const rec_t *rec, const ulint *offsets);
1664
1665/** Purge an LOB (either of compressed or uncompressed).
1666@param[in] ctx the delete operation context information.
1667@param[in] index clustered index in which LOB is present
1668@param[in] trxid the transaction that is being purged.
1669@param[in] undo_no during rollback to savepoint, purge only up to
1670 this undo number.
1671@param[in] rec_type undo record type.
1672@param[in] uf the update vector for the field.
1673@param[in] node the purge node or nullptr. */
1675 undo_no_t undo_no, ulint rec_type, const upd_field_t *uf,
1676 purge_node_t *node);
1677
1678/** Update a portion of the given LOB.
1679@param[in] ctx update operation context information.
1680@param[in] trx the transaction that is doing the
1681modification.
1682@param[in] index the clustered index containing the LOB.
1683@param[in] upd update vector
1684@param[in] field_no the LOB field number
1685@param[in] blobref LOB reference stored in clust record.
1686@return DB_SUCCESS on success, error code on failure. */
1687dberr_t update(InsertContext &ctx, trx_t *trx, dict_index_t *index,
1688 const upd_t *upd, ulint field_no, ref_t blobref);
1689
1690/** Update a portion of the given LOB.
1691@param[in] ctx update operation context information.
1692@param[in] trx the transaction that is doing the
1693modification.
1694@param[in] index the clustered index containing the LOB.
1695@param[in] upd update vector
1696@param[in] field_no the LOB field number
1697@param[in] blobref LOB reference stored in clust record.
1698@return DB_SUCCESS on success, error code on failure. */
1699dberr_t z_update(InsertContext &ctx, trx_t *trx, dict_index_t *index,
1700 const upd_t *upd, ulint field_no, ref_t blobref);
1701
1702/** Print information about the given LOB.
1703@param[in] trx the current transaction.
1704@param[in] index the clust index that contains the LOB.
1705@param[in] out the output stream into which LOB info is printed.
1706@param[in] ref the LOB reference
1707@param[in] fatal if true assert at end of function. */
1708void print(trx_t *trx, dict_index_t *index, std::ostream &out, ref_t ref,
1709 bool fatal);
1710
1711/** Import the given LOB. Update the creator trx id and the modifier trx
1712id to the given import trx id.
1713@param[in] index clustered index containing the lob.
1714@param[in] field_ref the lob reference.
1715@param[in] trx_id the import trx id. */
1716void z_import(const dict_index_t *index, byte *field_ref, trx_id_t trx_id);
1717
1718/** Import the given LOB. Update the creator trx id and the modifier trx
1719id to the given import trx id.
1720@param[in] index clustered index containing the lob.
1721@param[in] field_ref the lob reference.
1722@param[in] trx_id the import trx id. */
1723void import(const dict_index_t *index, byte *field_ref, trx_id_t trx_id);
1724
1725#ifdef UNIV_DEBUG
1726/** Check if all the LOB references in the given clustered index record has
1727valid space_id in it.
1728@param[in] index the index to which the LOB belongs.
1729@param[in] rec the clust_rec in which the LOB references are checked.
1730@param[in] offsets the field offsets of the given rec.
1731@return true if LOB references have valid space_id, false otherwise. */
1733 const ulint *offsets);
1734#endif /* UNIV_DEBUG */
1735
1736/** Mark an LOB that it is not partially updatable anymore.
1737@param[in] trx Current transaction.
1738@param[in] index Clustered index to which the LOB belongs.
1739@param[in] update Update vector.
1740@param[in] btr_mtr Mini-transaction context holding latches on the B-tree.
1741This function does not generate redo log using this btr_mtr. It only obtains
1742the log mode.
1743@return DB_SUCCESS on success, error code on failure. */
1745 const upd_t *update, const mtr_t *btr_mtr);
1746
1747} // namespace lob
1748
1749#endif /* lob0lob_h */
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
void btr_page_free_low(dict_index_t *index, buf_block_t *block, ulint level, mtr_t *mtr)
Frees a file page used in an index tree.
Definition: btr0btr.cc:554
static buf_block_t * btr_block_get(const page_id_t &page_id, const page_size_t &page_size, ulint mode, ut::Location location, const dict_index_t *index, mtr_t *mtr)
Gets a buffer page and declares its latching order level.
Definition: btr0btr.h:202
The index tree persistent cursor.
@ BTR_PCUR_ON
Definition: btr0pcur.h:53
constexpr uint32_t BTR_EXTERN_FIELD_REF_SIZE
The size of a reference to data stored on a different page.
Definition: btr0types.h:66
static buf_frame_t * buf_block_get_frame(const buf_block_t *block)
Gets a pointer to the memory frame of a block.
page_zip_des_t * buf_block_get_page_zip(buf_block_t *block) noexcept
Gets the compressed page descriptor corresponding to an uncompressed page if applicable.
Definition: buf0buf.h:2772
void buf_block_buf_fix_inc(buf_block_t *b, ut::Location l)
Increments the bufferfix count.
Definition: buf0buf.h:614
static void buf_block_buf_fix_dec(buf_block_t *block)
Decrements the bufferfix count.
Definition: buf0buf.ic:805
We use Flush_observer to track flushing of non-redo logged pages in bulk create index(btr0load....
Definition: buf0flu.h:258
Definition: buf0buf.h:1164
buf_fix_count_atomic_t buf_fix_count
Count of how many fold this block is currently bufferfixed.
Definition: buf0buf.h:1393
The B-tree context under which the LOB operation is done.
Definition: lob0lob.h:708
void set_ownership_of_extern_field(ulint i, bool val)
Sets the ownership bit of an externally stored field in a record.
Definition: lob0lob.h:786
void start_btr_mtr()
Start the mini-transaction that will be holding the latches of the clustered index record block.
Definition: lob0lob.h:954
void unmark_extern_fields()
Marks all extern fields in a record as owned by the record.
Definition: lob0lob.h:814
mtr_t * get_mtr()
Get the associated mini-transaction.
Definition: lob0lob.h:1094
buf_block_t * block() const
Get the pointer to the clustered record block.
Definition: lob0lob.h:1098
void check_redolog_normal()
Check if there is enough space in log file.
Definition: lob0lob.cc:114
void make_nth_extern(ulint field_no)
Mark the nth field as externally stored.
Definition: lob0lob.h:1065
const page_t * rec_frame() const
Get the beginning of the B-tree clustered index page frame that contains the current clustered index ...
Definition: lob0lob.h:943
BtrContext(const BtrContext &other)
Copy Constructor.
Definition: lob0lob.h:766
void zblob_write_blobref(ulint field_no, mtr_t *mtr)
Write a blob reference of a field into a clustered index record in a compressed leaf page.
Definition: lob0lob.h:1127
void recalc()
Recalculate some of the members after restoring the persistent cursor.
Definition: lob0lob.h:1113
void store_position()
Save the position of the persistent cursor.
Definition: lob0lob.h:1101
mtr_t * m_mtr
The btr mtr that is holding the latch on the B-tree index page containing the clustered index record.
Definition: lob0lob.h:1134
bool are_all_blobrefs_valid() const
Check to see if all pointers to externally stored columns in the record must be valid.
Definition: lob0lob.h:914
void restore_position()
Restore the position of the persistent cursor.
Definition: lob0lob.h:1015
BtrContext(mtr_t *mtr, btr_pcur_t *pcur, dict_index_t *index, rec_t *rec, ulint *offsets, buf_block_t *block, opcode op)
Constructor.
Definition: lob0lob.h:750
mtr_log_t get_log_mode()
Get the log mode of the btr mtr.
Definition: lob0lob.h:1071
dict_table_t * table() const
Get the table object.
Definition: lob0lob.h:1031
ulint get_rec_offset() const
Get the record offset within page of the clustered index record.
Definition: lob0lob.h:868
opcode m_op
Definition: lob0lob.h:1142
space_id_t space() const
Get the space id.
Definition: lob0lob.h:1043
page_no_t get_btr_page_no() const
Get the page number of clustered index record.
Definition: lob0lob.h:962
Flush_observer * get_flush_observer() const
Get flush observer.
Definition: lob0lob.h:1075
page_no_t get_page_no() const
Get the page number of clustered index block.
Definition: lob0lob.h:862
buf_block_t * m_block
Definition: lob0lob.h:1141
rec_t * rec() const
Get the clustered index record pointer.
Definition: lob0lob.h:878
void free_updated_extern_fields(trx_id_t trx_id, undo_no_t undo_no, const upd_t *update, bool rollback, big_rec_t *big_rec_vec)
Frees the externally stored fields for a record, if the field is mentioned in the update vector.
Definition: lob0lob.cc:958
void check_redolog()
Check if there is enough space in the redo log file.
Definition: lob0lob.h:1059
page_no_t pages_in_extent() const
Determine the extent size (in pages) for the underlying table.
Definition: lob0lob.h:1053
void disown_inherited_fields(const upd_t *update)
Marks non-updated off-page fields as disowned by this record.
Definition: lob0lob.cc:76
void commit_btr_mtr()
Commit the mini-transaction that is holding the latches of the clustered index record block.
Definition: lob0lob.h:950
ulint m_rec_offset
Record offset within the page.
Definition: lob0lob.h:1145
void check_redolog_bulk()
When bulk load is being done, check if there is enough space in redo log file.
Definition: lob0lob.cc:92
ulint * m_offsets
Definition: lob0lob.h:1140
dict_index_t * m_index
Definition: lob0lob.h:1138
rec_t * m_rec
Definition: lob0lob.h:1139
BtrContext(mtr_t *mtr, dict_index_t *index, buf_block_t *block)
Constructor.
Definition: lob0lob.h:722
page_no_t m_btr_page_no
Page number where the clust rec is present.
Definition: lob0lob.h:1148
void free_externally_stored_fields(trx_id_t trx_id, undo_no_t undo_no, bool rollback, ulint rec_type, purge_node_t *node)
Frees the externally stored fields for a record.
Definition: lob0lob.cc:1099
ulint * get_offsets() const
Get the record offsets array.
Definition: lob0lob.h:1081
BtrContext()
Default Constructor.
Definition: lob0lob.h:711
void rec_block_fix()
Increment the buffer fix count of the clustered index record block.
Definition: lob0lob.h:977
byte * get_field_ref(ulint field_no) const
Get the LOB reference for the given field number.
Definition: lob0lob.h:886
BtrContext(mtr_t *mtr, btr_pcur_t *pcur, dict_index_t *index, rec_t *rec, ulint *offsets, buf_block_t *block)
Constructor.
Definition: lob0lob.h:733
bool need_recalc() const
Check if there is a need to recalculate the context information.
Definition: lob0lob.h:872
btr_pcur_t * m_pcur
Persistent cursor positioned on the clustered index record.
Definition: lob0lob.h:1137
bool validate() const
Validate the current BLOB context object.
Definition: lob0lob.h:896
void rec_block_unfix()
Decrement the buffer fix count of the clustered index record block, X-latching it before,...
Definition: lob0lob.h:992
bool is_bulk() const
Determine whether current operation is a bulk insert operation.
Definition: lob0lob.h:938
dict_index_t * index() const
Get the index object.
Definition: lob0lob.h:1027
bool rec_offs_validate() const
Validate the record offsets array.
Definition: lob0lob.h:1085
const page_size_t page_size() const
Obtain the page size of the underlying table.
Definition: lob0lob.h:1047
page_zip_des_t * get_page_zip() const
Gets the compressed page descriptor.
Definition: lob0lob.h:856
Page identifier.
Definition: buf0types.h:207
Page size descriptor.
Definition: page0size.h:50
bool is_compressed() const
Check whether the page is compressed on disk.
Definition: page0size.h:158
int page
Definition: ctype-mb.cc:1226
dberr_t
Definition: db0err.h:39
@ DB_SUCCESS
Definition: db0err.h:43
page_no_t dict_table_extent_size(const dict_table_t *table)
Determine the extent size (in pages) for the given table.
Definition: dict0dict.cc:5017
static const page_size_t dict_table_page_size(const dict_table_t *table)
Get the table page size.
static rw_lock_t * dict_index_get_lock(dict_index_t *index)
Gets the read-write lock of the index tree.
Data dictionary memory object creation.
uint32_t DICT_TF_HAS_ATOMIC_BLOBS(uint32_t flags)
Return the value of the ATOMIC_BLOBS field.
Definition: dict0mem.h:239
uint32_t fil_space_get_flags(space_id_t space_id)
Returns the flags of the space.
Definition: fil0fil.cc:3492
const page_size_t fil_space_get_page_size(space_id_t space_id, bool *found)
Returns the page size of the space and whether it is compressed or not.
Definition: fil0fil.cc:3559
constexpr page_no_t FIL_NULL
'null' (undefined) page offset in the context of file spaces
Definition: fil0fil.h:1161
constexpr uint32_t FIL_PAGE_DATA
start of the data on the page
Definition: fil0types.h:111
static int flags[50]
Definition: hp_test1.cc:40
#define UINT32_MAX
Definition: lexyy.cc:86
unsigned char byte
Blob class.
Definition: common.h:151
std::map< page_no_t, buf_block_t * > BlockCache
Definition: lob0lob.h:42
static uint32_t mach_read_from_4(const byte *b)
The following function is used to fetch data from 4 consecutive bytes.
static uint8_t mach_read_from_1(const byte *b)
The following function is used to fetch data from one byte.
static void mach_write_ulint(byte *ptr, ulint val, mlog_id_t type)
Writes 1, 2 or 4 bytes to a file page.
Definition: mach0data.h:292
void mlog_write_ulint(byte *ptr, ulint val, mlog_id_t type, mtr_t *mtr)
Writes 1, 2 or 4 bytes to a file page.
Definition: mtr0log.cc:258
#define mtr_memo_contains_flagged(m, p, l)
Definition: mtr0mtr.h:137
#define mtr_x_lock(l, m, loc)
Lock an rw-lock in x-mode.
Definition: mtr0mtr.h:129
@ MLOG_4BYTES
4 bytes ...
Definition: mtr0types.h:76
@ MLOG_1BYTE
one byte is written
Definition: mtr0types.h:70
mtr_log_t
Logging modes for a mini-transaction.
Definition: mtr0types.h:42
@ MTR_LOG_NO_REDO
Don't generate REDO log but add dirty pages to flush list.
Definition: mtr0types.h:50
@ MTR_MEMO_X_LOCK
Definition: mtr0types.h:304
@ MTR_MEMO_PAGE_X_FIX
Definition: mtr0types.h:292
@ MTR_MEMO_SX_LOCK
Definition: mtr0types.h:306
@ MTR_MEMO_PAGE_SX_FIX
Definition: mtr0types.h:294
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
Definition: buf0block_hint.cc:30
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
Provides the large objects (LOB) module.
Definition: lob0bulk.h:44
const ulint BTR_EXTERN_OWNER_FLAG
The most significant bit of BTR_EXTERN_LEN (i.e., the most significant bit of the byte at smallest ad...
Definition: lob0lob.h:123
const ulint BTR_EXTERN_SPACE_ID
The reference in a field for which data is stored on a different page.
Definition: lob0lob.h:102
const ulint BTR_EXTERN_PAGE_NO
page number where stored
Definition: lob0lob.h:105
const ulint BTR_EXTERN_BEING_MODIFIED_FLAG
If the 3rd most significant bit of BTR_EXTERN_LEN is 1, then it means that the externally stored fiel...
Definition: lob0lob.h:136
static void rollback(DeleteContext *ctx, dict_index_t *index, trx_id_t trxid, undo_no_t undo_no, ulint rec_type, const upd_field_t *uf)
Rollback modification of a uncompressed LOB.
Definition: lob0purge.cc:65
byte * btr_copy_externally_stored_field_func(trx_t *trx, const dict_index_t *index, ulint *len, size_t *lob_version, const byte *data, const page_size_t &page_size, ulint local_len, bool is_sdi, mem_heap_t *heap)
Copies an externally stored field of a record to mem heap.
Definition: lob0lob.cc:878
const ulint LOB_HDR_SIZE
Size of an uncompressed LOB page header, in bytes.
Definition: lob0lob.h:148
const ulint BTR_EXTERN_LEN
8 bytes containing the length of the externally stored part of the LOB.
Definition: lob0lob.h:115
bool rec_check_lobref_space_id(dict_index_t *index, const rec_t *rec, const ulint *offsets)
Check if all the LOB references in the given clustered index record has valid space_id in it.
Definition: lob0lob.cc:1273
dberr_t z_update(trx_t *trx, dict_index_t *index, const upd_t *upd, ulint field_no)
Update a portion of the given LOB.
static byte * btr_copy_externally_stored_field(trx_t *trx, const dict_index_t *index, ulint *len, size_t *ver, const byte *data, const page_size_t &page_size, ulint local_len, bool is_sdi, mem_heap_t *heap)
Definition: lob0lob.h:1648
dberr_t mark_not_partially_updatable(trx_t *trx, dict_index_t *index, const upd_t *update, const mtr_t *btr_mtr)
Mark an LOB that it is not partially updatable anymore.
Definition: lob0lob.cc:1312
const ulint BTR_EXTERN_VERSION
Version number of LOB (LOB in new format)
Definition: lob0lob.h:111
const ulint MAX_SIZE
The maximum size possible for an LOB.
Definition: lob0lob.h:84
opcode
LOB operation code for btr_store_big_rec_extern_fields().
Definition: lob0lob.h:593
@ OPCODE_UPDATE
Store off-page columns for an update.
Definition: lob0lob.h:602
@ OPCODE_INSERT
Store off-page columns for a freshly inserted record.
Definition: lob0lob.h:596
@ OPCODE_INSERT_UPDATE
Store off-page columns for an insert by update.
Definition: lob0lob.h:599
@ OPCODE_UNKNOWN
The operation code is unknown or not important.
Definition: lob0lob.h:608
@ OPCODE_INSERT_BULK
Store off-page columns for a freshly inserted record by bulk.
Definition: lob0lob.h:605
void z_import(const dict_index_t *index, byte *field_ref, trx_id_t trx_id)
Import the given LOB.
void print(trx_t *trx, dict_index_t *index, std::ostream &out, ref_t ref, bool fatal)
Print information about the given LOB.
Definition: lob0impl.cc:1333
const ulint LOB_HDR_NEXT_PAGE_NO
Offset within header of next BLOB part page no.
Definition: lob0lob.h:145
void purge(lob::DeleteContext *ctx, dict_index_t *index, trx_id_t trxid, undo_no_t undo_no, ulint rec_type, const upd_field_t *uf, purge_node_t *node)
Purge an LOB (either of compressed or uncompressed).
Definition: lob0purge.cc:414
static byte * btr_rec_copy_externally_stored_field(trx_t *trx, const dict_index_t *index, const rec_t *rec, const ulint *offsets, const page_size_t &page_size, ulint no, ulint *len, size_t *ver, bool is_sdi, mem_heap_t *heap)
Definition: lob0lob.h:659
dberr_t update(trx_t *trx, dict_index_t *index, const upd_t *upd, ulint field_no)
Update a portion of the given LOB.
const ulint BTR_EXTERN_INHERITED_FLAG
If the second most significant bit of BTR_EXTERN_LEN (i.e., the second most significant bit of the by...
Definition: lob0lob.h:130
static const byte * btr_rec_get_field_ref(const dict_index_t *index, const byte *rec, const ulint *offsets, ulint n)
Gets a pointer to the externally stored part of a field.
Definition: lob0lob.h:682
ulint btr_rec_get_externally_stored_len(const dict_index_t *index, const rec_t *rec, const ulint *offsets)
Gets the externally stored size of a record, in units of a database page.
Definition: lob0lob.cc:1064
byte * btr_rec_copy_externally_stored_field_func(trx_t *trx, const dict_index_t *index, const rec_t *rec, const ulint *offsets, const page_size_t &page_size, ulint no, ulint *len, size_t *lob_version, bool is_sdi, mem_heap_t *heap, bool is_rebuilt)
Copies an externally stored field of a record to mem heap.
Definition: lob0lob.cc:638
constexpr uint32_t Z_CHUNK_SIZE
Definition: lob0lob.h:91
const byte field_ref_almost_zero[FIELD_REF_SIZE]
A BLOB field reference has all the bits set to zero, except the "being modified" bit.
Definition: lob0lob.cc:47
const uint ZLOB_PAGE_DATA
Start of the data on an LOB page.
Definition: lob0lob.h:151
void blob_free(dict_index_t *index, buf_block_t *block, bool all, mtr_t *mtr)
Deallocate a buffer block that was reserved for a BLOB part.
Definition: lob0lob.cc:1024
bool btr_lob_op_is_update(opcode op)
Determine if an operation on off-page columns is an update.
Definition: lob0lob.h:1584
const ulint BTR_EXTERN_OFFSET
offset of BLOB header on that page
Definition: lob0lob.h:108
const ulint LOB_HDR_PART_LEN
The structure of uncompressed LOB page header.
Definition: lob0lob.h:141
ulint btr_copy_externally_stored_field_prefix_func(trx_t *trx, const dict_index_t *index, byte *buf, ulint len, const page_size_t &page_size, const byte *data, bool is_sdi, ulint local_len)
Copies the prefix of an externally stored field of a record.
Definition: lob0lob.cc:814
dberr_t btr_store_big_rec_extern_fields(trx_t *trx, btr_pcur_t *pcur, const upd_t *upd, ulint *offsets, const big_rec_t *big_rec_vec, mtr_t *btr_mtr, opcode op)
Stores the fields in big_rec_vec to the tablespace and puts pointers to them in rec.
Definition: lob0lob.cc:411
std::ostream & operator<<(std::ostream &out, const plist_node_t &obj)
Definition: lob0impl.h:239
static ulint btr_copy_externally_stored_field_prefix(trx_t *trx, const dict_index_t *index, byte *buf, ulint len, const page_size_t &page_size, const byte *data, bool is_sdi, ulint local_len)
Definition: lob0lob.h:1641
constexpr uint32_t KB128
The compressed LOB is stored as a collection of zlib streams.
Definition: lob0lob.h:90
ulint btr_rec_get_field_ref_offs(const dict_index_t *index, const ulint *offsets, ulint n)
Gets the offset of the pointer to the externally stored part of a field.
Definition: lob0lob.cc:58
Index page routines.
static bool page_rec_is_comp(const rec_t *rec)
true if the record is on a page in compact format.
static page_no_t page_get_page_no(const page_t *page)
Gets the page number.
static ulint page_offset(const void *ptr)
Gets the offset within a page.
static page_t * page_align(const void *ptr)
Gets the start of a page.
constexpr size_t FIELD_REF_SIZE
Definition: page0size.h:39
const byte field_ref_zero[FIELD_REF_SIZE]
A BLOB field reference full of zero, for use in assertions and tests.Initially, BLOB field references...
Definition: page0zip.cc:42
byte page_t
Type of the index page.
Definition: page0types.h:152
void page_zip_write_blob_ptr(page_zip_des_t *page_zip, const byte *rec, const dict_index_t *index, const ulint *offsets, ulint n, mtr_t *mtr)
Write a BLOB pointer of a record on the leaf page of a clustered index.
Definition: page0zip.cc:1884
static void rec_offs_make_valid(const rec_t *rec, const dict_index_t *index, ulint *offsets)
Updates debug data in offsets, in order to avoid bogus rec_offs_validate() failures.
Definition: rec.h:628
static ulint rec_offs_n_fields(const ulint *offsets)
The following function returns the number of fields in a record.
Definition: rec.h:506
static bool rec_get_node_ptr_flag(const rec_t *rec)
The following function tells if a new-style record is a node pointer.
static bool rec_get_deleted_flag(const rec_t *rec, bool comp)
The following function tells if record is delete marked.
static bool rec_offs_any_extern(const ulint *offsets)
Determine if the offsets are for a record containing externally stored columns.
static bool rec_offs_comp(const ulint *offsets)
Determine if the offsets are for a record in the new compact format.
byte rec_t
Definition: rem0types.h:41
void rec_offs_make_nth_extern(dict_index_t *index, ulint *offsets, ulint n)
Mark the nth field as externally stored.
Definition: rem0wrec.cc:118
const byte * rec_get_nth_field(const dict_index_t *index, const rec_t *rec, const ulint *offsets, ulint n, ulint *len)
Gets the value of the specified field in the record.
Definition: rem0wrec.h:108
ulint rec_offs_nth_extern(const dict_index_t *index, const ulint *offsets, ulint n)
Returns nonzero if the extern bit is set in nth field of rec.
Definition: rem0wrec.h:150
Modification log for online index creation and online table rebuild.
Storage format for overflow data in a big record, that is, a clustered index record which needs exter...
Definition: data0data.h:859
ulint n_fields
number of stored fields
Definition: data0data.h:863
page_cur_t page_cur
Page cursor.
Definition: btr0cur.h:677
Definition: btr0pcur.h:99
bool restore_position(ulint latch_mode, mtr_t *mtr, ut::Location location)
Restores the stored position of a persistent cursor bufferfixing the page and obtaining the specified...
Definition: btr0pcur.cc:147
btr_pcur_pos_t m_rel_pos
BTR_PCUR_ON, BTR_PCUR_BEFORE, or BTR_PCUR_AFTER, depending on whether cursor was on,...
Definition: btr0pcur.h:470
dict_index_t * index()
Definition: btr0pcur.h:106
buf_block_t * get_block()
Returns the current buffer block (non const version).
Definition: btr0pcur.h:656
ulint m_latch_mode
see TODO note below! BTR_SEARCH_LEAF, BTR_MODIFY_LEAF, BTR_MODIFY_TREE or BTR_NO_LATCHES,...
Definition: btr0pcur.h:456
btr_cur_t m_btr_cur
a B-tree cursor
Definition: btr0pcur.h:447
void store_position(mtr_t *mtr)
The position of the cursor is stored by taking an initial segment of the record the cursor is positio...
Definition: btr0pcur.cc:42
rec_t * get_rec()
Returns the current record (non const version).
Definition: btr0pcur.h:668
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
byte * frame
pointer to buffer frame which is of size UNIV_PAGE_SIZE, and aligned to an address divisible by UNIV_...
Definition: buf0buf.h:1786
Data structure for an index.
Definition: dict0mem.h:1067
dict_table_t * table
back pointer to table
Definition: dict0mem.h:1081
Data structure for a database table.
Definition: dict0mem.h:1925
The context information when the delete operation on LOB is taking place.
Definition: lob0lob.h:1433
bool is_ref_valid() const
Check if the blob reference is valid.
Definition: lob0lob.h:1454
bool is_compressed() const
Determine if it is compressed page format.
Definition: lob0lob.h:1460
page_size_t m_page_size
The page size of the tablespace.
Definition: lob0lob.h:1508
page_size_t get_page_size() const
Obtain the page size from the tablespace flags.
Definition: lob0lob.h:1558
~DeleteContext()
Destructor.
Definition: lob0lob.h:1566
bool m_rollback
Is this operation part of rollback?
Definition: lob0lob.h:1505
DeleteContext(const BtrContext &btr, byte *field_ref, ulint field_no, bool rollback)
Constructor.
Definition: lob0lob.h:1537
Block_vector m_lob_blocks
The buffer blocks of lob to be freed.
Definition: lob0lob.h:1527
bool is_delete_marked() const
Definition: lob0lob.h:1470
ref_mem_t m_blobref_mem
Memory copy of the original LOB reference.
Definition: lob0lob.h:1522
bool validate_blobref() const
Validate the LOB reference object.
Definition: lob0lob.h:1481
std::vector< buf_block_t *, ut::allocator< buf_block_t * > > Block_vector
Definition: lob0lob.h:1524
void x_latch_rec_page(mtr_t *mtr)
Acquire an x-latch on the index page containing the clustered index record, in the given mini-transac...
Definition: lob0lob.cc:1253
void set_blob(byte *field_ref, ulint field_no)
Update the delete context to point to a different blob.
Definition: lob0lob.h:1550
void add_lob_block(buf_block_t *block)
Add a buffer block that is to be freed.
Definition: lob0lob.h:1568
bool has_atomic_blobs() const
Check if tablespace supports atomic blobs.
Definition: lob0lob.h:1464
ref_t m_blobref
the BLOB reference or external field reference.
Definition: lob0lob.h:1499
void free_lob_blocks()
Free all the stored lob blocks.
Definition: lob0lob.h:1573
ulint m_field_no
field number of externally stored column; ignored if rec == NULL
Definition: lob0lob.h:1502
The context for a LOB operation.
Definition: lob0lob.h:1153
ulint get_big_rec_vec_size()
Get the size of vector containing fields to be stored externally.
Definition: lob0lob.h:1166
const big_rec_t * get_big_rec_vec()
Get the vector containing fields to be stored externally.
Definition: lob0lob.h:1162
const big_rec_t * m_big_rec_vec
The B-tree Context.
Definition: lob0lob.h:1172
InsertContext(const BtrContext &btr_ctx, const big_rec_t *big_rec_vec)
Constructor.
Definition: lob0lob.h:1157
The context information for reading a single BLOB.
Definition: lob0lob.h:1261
bool is_valid_blob() const
Check if the BLOB reference is valid.
Definition: lob0lob.h:1299
const byte * m_data
The 'internally' stored part of the field containing also the reference to the external part; must be...
Definition: lob0lob.h:1309
bool assert_read_uncommitted() const
Assert that current trx is using isolation level read uncommitted.
Definition: lob0lob.cc:52
dict_index_t * index()
Definition: lob0lob.h:1301
const ref_t m_blobref
The blob reference of the blob that is being read.
Definition: lob0lob.h:1316
ulint m_lob_version
Definition: lob0lob.h:1335
const bool m_is_sdi
Is it a tablespace dictionary index (SDI)?
Definition: lob0lob.h:1343
ulint m_local_len
Length (in bytes) of BLOB prefix stored inline in clustered index record.
Definition: lob0lob.h:1313
ulint m_offset
The offset information obtained from the blob reference.
Definition: lob0lob.h:1331
const page_size_t & m_page_size
The page size information.
Definition: lob0lob.h:1304
byte * m_buf
Buffer into which data is read.
Definition: lob0lob.h:1319
page_no_t m_page_no
The page number obtained from the blob reference.
Definition: lob0lob.h:1328
dict_index_t * m_index
Definition: lob0lob.h:1333
ulint m_len
Length of the buffer m_buf.
Definition: lob0lob.h:1322
space_id_t m_space_id
The identifier of the space in which blob is available.
Definition: lob0lob.h:1325
bool is_sdi() const
Is it a space dictionary index (SDI)?
Definition: lob0lob.h:1340
trx_t * m_trx
The transaction that is reading.
Definition: lob0lob.h:1351
void read_blobref()
Read the space_id, page_no and offset information from the BLOB reference object and update the membe...
Definition: lob0lob.h:1289
ReadContext(const page_size_t &page_size, const byte *data, ulint prefix_len, byte *buf, ulint len, bool is_sdi)
Constructor.
Definition: lob0lob.h:1274
Fetch uncompressed BLOB.
Definition: lob0lob.h:1408
ulint m_copied_len
Total bytes of LOB data that has been copied from multiple LOB pages.
Definition: lob0lob.h:1428
void fetch_page()
Fetch one BLOB page.
Definition: lob0lob.cc:740
ReadContext m_rctx
Definition: lob0lob.h:1420
buf_block_t * m_cur_block
Buffer block of the current BLOB page.
Definition: lob0lob.h:1423
ulint fetch()
Fetch the complete or prefix of the uncompressed LOB data.
Definition: lob0lob.cc:776
Reader(const ReadContext &ctx)
Constructor.
Definition: lob0lob.h:1410
The in-memory blob directory.
Definition: lob0lob.h:1228
std::vector< blob_page_info_t >::const_iterator const_iterator
Definition: lob0lob.h:1229
std::vector< blob_page_info_t > m_pages
A vector of blob pages along with its metadata.
Definition: lob0lob.h:1248
std::ostream & print(std::ostream &out) const
Print this blob directory into the given output stream.
Definition: lob0lob.cc:140
dberr_t add(const blob_page_info_t &page)
Append the given blob page information.
Definition: lob0lob.h:1242
void clear()
Clear the contents of this blob directory.
Definition: lob0lob.h:1237
Information about data stored in one BLOB page.
Definition: lob0lob.h:1176
page_no_t m_page_no
The BLOB page number.
Definition: lob0lob.h:1212
blob_page_info_t(page_no_t page_no, uint bytes, uint zbytes)
Constructor.
Definition: lob0lob.h:1183
uint m_zbytes
Amount of compressed data (in bytes) in the BLOB page.
Definition: lob0lob.h:1218
std::ostream & print(std::ostream &out) const
Print this blob_page_into_t object into the given output stream.
Definition: lob0lob.cc:152
void set_uncompressed_size(uint bytes)
Set the uncompressed data size in bytes.
Definition: lob0lob.h:1204
void set_page_no(page_no_t page_no)
Set the page number.
Definition: lob0lob.h:1208
uint m_bytes
Amount of uncompressed data (in bytes) in the BLOB page.
Definition: lob0lob.h:1215
void set_compressed_size(uint bytes)
Set the compressed data size in bytes.
Definition: lob0lob.h:1200
void reset()
Re-initialize the current object.
Definition: lob0lob.h:1187
In memory representation of the LOB reference.
Definition: lob0lob.h:154
bool m_partial
Whether the LOB is partially updated.
Definition: lob0lob.h:178
page_no_t m_page_no
Page number of first LOB page.
Definition: lob0lob.h:159
ulint m_offset
Offset within m_page_no where LOB begins.
Definition: lob0lob.h:162
bool m_inherit
Whether the clustered index record inherited this LOB from another clustered index record.
Definition: lob0lob.h:175
bool m_owner
Whether the clustered index record owns this LOB.
Definition: lob0lob.h:171
ulint m_length
Length of LOB.
Definition: lob0lob.h:165
bool m_null
Whether the LOB is null.
Definition: lob0lob.h:168
bool m_being_modified
Whether the blob is being modified.
Definition: lob0lob.h:181
space_id_t m_space_id
Space Identifier of the clustered index.
Definition: lob0lob.h:156
bool is_purged() const
Check if the LOB has already been purged.
Definition: lob0lob.h:185
The struct 'lob::ref_t' represents an external field reference.
Definition: lob0lob.h:198
static bool use_single_z_stream(ulint len)
For compressed LOB, if the length is less than or equal to Z_CHUNK_SIZE then use the older single z s...
Definition: lob0lob.h:232
void set_page_no(const ulint page_no, mtr_t *mtr)
Set the page number in the external field reference.
Definition: lob0lob.h:477
void set_space_id(const space_id_t space_id, mtr_t *mtr)
Set the space_id in the external field reference.
Definition: lob0lob.h:464
void update(space_id_t space_id, ulint page_no, ulint offset, mtr_t *mtr)
Update the information stored in the external field reference.
Definition: lob0lob.h:455
void set_owner(bool owner)
Set the ownership flag in the blob reference.
Definition: lob0lob.h:332
void set_inherited(bool inherited, mtr_t *mtr)
Set the inherited flag in the field reference.
Definition: lob0lob.h:383
void set_version(const ulint version)
Set the version information in the external field reference.
Definition: lob0lob.h:496
void parse(ref_mem_t &obj) const
Parse the LOB reference object and copy data into the given ref_mem_t object.
Definition: lob0lob.h:255
void set_length(const ulint len)
Set the length of blob in the external field reference.
Definition: lob0lob.h:510
static bool is_null(const byte *ref)
Check if the LOB reference is null (all zeroes).
Definition: lob0lob.h:307
static const ulint LOB_BIG_THRESHOLD_SIZE
If the LOB size is equal to or above this limit (in physical page size terms), then the LOB is big en...
Definition: lob0lob.h:203
static const ulint LOB_SMALL_CHANGE_THRESHOLD
If the total number of bytes modified in an LOB, in an update operation, is less than or equal to thi...
Definition: lob0lob.h:210
static bool is_being_modified(const byte *field_ref)
Check if the current blob is being modified.
Definition: lob0lob.h:371
static const uint SIZE
The size of an LOB reference object (in bytes)
Definition: lob0lob.h:576
bool check_space_id(dict_index_t *index) const
Check if the space_id in the LOB reference is equal to the space_id of the index to which it belongs.
Definition: lob0lob.cc:1241
void set_length(const ulint len, mtr_t *mtr)
Set the length of blob in the external field reference.
Definition: lob0lob.h:503
void set_owner(bool owner, mtr_t *mtr)
Set the ownership flag in the blob reference.
Definition: lob0lob.h:316
bool is_null() const
Check if the field reference is made of zeroes.
Definition: lob0lob.h:289
static bool is_small_change(size_t bytes_changed, const ref_t &blobref)
Definition: lob0lob.h:217
void set_space_id(const space_id_t space_id)
Set the space_id in the external field reference.
Definition: lob0lob.h:470
ulint length() const
Read the length from the blob reference.
Definition: lob0lob.h:446
ref_t(byte *ptr)
Constructor.
Definition: lob0lob.h:224
bool is_being_modified() const
Check if the current blob is being modified.
Definition: lob0lob.h:378
bool use_single_z_stream() const
For compressed LOB, if the length is less than or equal to Z_CHUNK_SIZE then use the older single z s...
Definition: lob0lob.h:228
bool is_lob_partially_updatable(const dict_index_t *index) const
Check if the LOB can be partially updated.
Definition: lob0lob.cc:1212
static space_id_t space_id(const byte *ref)
Read the space id from the given blob reference.
Definition: lob0lob.h:413
std::ostream & print(std::ostream &out) const
Print this LOB reference into the given output stream.
Definition: lob0lob.cc:1232
static void set_being_modified(byte *ref, bool modifying, mtr_t *mtr)
Set the being_modified flag in the field reference.
Definition: lob0lob.h:349
static bool is_big(const page_size_t &page_size, const ulint lob_length)
Check if this LOB is big enough to do partial update.
Definition: lob0lob.h:238
ulint offset() const
Read the offset of blob header from the blob reference.
Definition: lob0lob.h:436
bool is_inherited() const
Check if the current row inherited the blob from parent row.
Definition: lob0lob.h:404
void copy(byte *field_ref) const
Copy the LOB reference into the given memory location.
Definition: lob0lob.h:269
byte * m_ref
Pointing to a memory of size BTR_EXTERN_FIELD_REF_SIZE.
Definition: lob0lob.h:580
ulint get_lob_page_info(const dict_index_t *index, const page_size_t &page_size, bool &is_partially_updatable) const
Load the first page of LOB and read its page type.
Definition: lob0lob.cc:1131
page_no_t page_no() const
Read the page number from the blob reference.
Definition: lob0lob.h:430
void init()
Initialize the reference object with zeroes.
Definition: lob0lob.h:292
bool is_big(const page_size_t &page_size) const
Check if this LOB is big enough to do partial update.
Definition: lob0lob.h:247
void set_being_modified(bool modifying, mtr_t *mtr)
Set the being_modified flag in the field reference.
Definition: lob0lob.h:364
page_t * page_align() const
Get the start of a page containing this blob reference.
Definition: lob0lob.h:517
static bool is_null_relaxed(const byte *ref)
Check if the LOB reference is null (all zeroes) except the "is being modified" bit.
Definition: lob0lob.h:300
space_id_t space_id() const
Read the space id from the blob reference.
Definition: lob0lob.h:426
void set_page_no(const ulint page_no)
Set the page number in the external field reference.
Definition: lob0lob.h:483
bool is_null_relaxed() const
Check if the field reference is made of zeroes except the being_modified bit.
Definition: lob0lob.h:283
bool validate(mtr_t *mtr)
Check if the given mtr has necessary latches to update this LOB reference.
Definition: lob0lob.h:525
bool is_equal(const byte *ptr) const
Check whether the stored external field reference is equal to the given field reference.
Definition: lob0lob.h:274
void mark_not_partially_updatable(trx_t *trx, mtr_t *mtr, dict_index_t *index, const page_size_t &page_size)
Load the first page of the LOB and mark it as not partially updatable anymore.
Definition: lob0lob.cc:1173
bool is_owner() const
Check if the current row is the owner of the blob.
Definition: lob0lob.h:397
void set_ref(byte *ptr)
Set the external field reference to the given memory location.
Definition: lob0lob.h:278
void set_offset(const ulint offset, mtr_t *mtr)
Set the offset information in the external field reference.
Definition: lob0lob.h:490
uint32_t version() const
Read the LOB version from the blob reference.
Definition: lob0lob.h:440
static page_no_t page_no(const byte *ref)
Read the page no from the blob reference.
Definition: lob0lob.h:419
Fetch compressed BLOB.
Definition: lob0lob.h:1355
ulint length() const
Get the length of data that has been read.
Definition: lob0lob.h:1369
int setup_zstream()
Do setup of the zlib stream.
Definition: lob0lob.cc:160
dberr_t fetch()
Fetch the BLOB.
Definition: lob0lob.cc:179
zReader(const ReadContext &ctx)
Constructor.
Definition: lob0lob.h:1357
ulint m_page_type_ex
The expected page type.
Definition: lob0lob.h:1403
buf_page_t * m_bpage
Definition: lob0lob.h:1399
dberr_t fetch_page()
Fetch one BLOB page.
Definition: lob0lob.cc:256
mem_heap_t * m_heap
The memory heap that will be used by zlib allocator.
Definition: lob0lob.h:1393
z_stream m_stream
The zlib stream used to uncompress while fetching blob.
Definition: lob0lob.h:1390
ReadContext m_rctx
Definition: lob0lob.h:1384
bool assert_empty_local_prefix()
Assert that the local prefix is empty.
Definition: lob0lob.cc:250
ulint m_remaining
Bytes yet to be read.
Definition: lob0lob.h:1387
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:302
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:177
Flush_observer * get_flush_observer() const
Get flush observer.
Definition: mtr0mtr.h:516
mtr_log_t set_log_mode(mtr_log_t mode)
Change the logging mode.
Definition: mtr0mtr.cc:468
void commit()
Commit the mini-transaction.
Definition: mtr0mtr.cc:662
mtr_log_t get_log_mode() const
Get the logging mode.
Definition: mtr0mtr.ic:153
void start(bool sync=true)
Start a mini-transaction.
Definition: mtr0mtr.cc:565
buf_block_t * memo_contains_page_flagged(const byte *ptr, ulint flags) const
Check if memo contains the given page.
Definition: mtr0mtr.cc:1075
Index page cursor.
Definition: page0cur.h:311
buf_block_t * block
Pointer to the current block containing rec.
Definition: page0cur.h:322
rec_t * rec
pointer to a record on page
Definition: page0cur.h:316
Compressed page descriptor.
Definition: page0types.h:201
Definition: row0purge.h:93
Definition: result.h:30
Definition: trx0trx.h:675
Definition: row0upd.h:476
Definition: row0upd.h:571
@ RW_X_LATCH
Definition: sync0rw.h:98
ib_id_t undo_no_t
Undo number.
Definition: trx0types.h:142
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:138
Version control for database, common definitions, and include files.
#define IF_DEBUG(...)
Definition: univ.i:674
unsigned long int ulint
Definition: univ.i:406
constexpr ulint ULINT_UNDEFINED
The 'undefined' value for a ulint.
Definition: univ.i:420
#define UT_LOCATION_HERE
Definition: ut0core.h:73
#define ut_error
Abort execution.
Definition: ut0dbg.h:101
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105
#define ut_o(EXPR)
Opposite of ut_d().
Definition: ut0dbg.h:109
#define ut_d(EXPR)
Debug statement.
Definition: ut0dbg.h:107
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:93
int n
Definition: xcom_base.cc:509