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