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