MySQL  8.0.23
Source Code Documentation
lob0zip.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 2016, 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 lob0zip_h
27 #define lob0zip_h
28 
29 #include "lob0ins.h"
30 
31 namespace lob {
32 
33 /** Insert or write the compressed BLOB as a single zlib stream. */
34 class zInserter : private BaseInserter {
35  public:
36  /** Constructor.
37  @param[in] ctx blob operation context. */
38  zInserter(InsertContext *ctx) : BaseInserter(ctx), m_heap(nullptr) {}
39 
40  /** Destructor. */
41  ~zInserter();
42 
43  /** Prepare to write a compressed BLOB. Setup the zlib
44  compression stream.
45  @return DB_SUCCESS on success, error code on failure. */
46  dberr_t prepare();
47 
48  /** Write all the BLOBs of the clustered index record.
49  @return DB_SUCCESS on success, error code on failure. */
50  dberr_t write();
51 
52  /** Write one blob field data.
53  @param[in] blob_j the blob field number
54  @return DB_SUCCESS on success, error code on failure. */
55  dberr_t write_one_blob(size_t blob_j);
56 
57  /** Cleanup after completing the write of compressed BLOB.
58  @param[in] validate if true, validate all the
59  lob references. if false,
60  skip this validation.
61  @return DB_SUCCESS on success, error code on failure. */
62  dberr_t finish(bool validate = true) {
63  int ret = deflateEnd(&m_stream);
64  ut_ad(ret == Z_OK);
66 
67  if (ret != Z_OK) {
68  m_err = DB_FAIL;
69  }
70  return (m_err);
71  }
72 
73  /** Write the page type of the BLOB page and also generate the
74  redo log record.
75  @param[in] blob_page the BLOB page
76  @param[in] nth_blob_page the count of BLOB page from
77  the beginning of the BLOB. */
78  void log_page_type(page_t *blob_page, ulint nth_blob_page) {
79  page_type_t page_type;
80 
81  if (is_index_sdi()) {
82  page_type = FIL_PAGE_SDI_ZBLOB;
83  } else if (nth_blob_page == 0) {
84  page_type = FIL_PAGE_TYPE_ZBLOB;
85  } else {
86  page_type = FIL_PAGE_TYPE_ZBLOB2;
87  }
88 
89  mlog_write_ulint(blob_page + FIL_PAGE_TYPE, page_type, MLOG_2BYTES,
90  &m_blob_mtr);
91  }
92 
93  /** Calculate the total number of pages needed to store
94  the given blobs */
95  ulint calc_total_pages() {
96  const page_size_t page_size = m_ctx->page_size();
97 
98  /* Space available in compressed page to carry blob data */
99  const ulint payload_size_zip = page_size.physical() - FIL_PAGE_DATA;
100 
101  const big_rec_t *vec = m_ctx->get_big_rec_vec();
102 
103  ulint total_blob_pages = 0;
104  for (ulint i = 0; i < vec->n_fields; i++) {
105  total_blob_pages +=
106  static_cast<ulint>(
107  deflateBound(&m_stream, static_cast<uLong>(vec->fields[i].len)) +
108  payload_size_zip - 1) /
109  payload_size_zip;
110  }
111 
112  return (total_blob_pages);
113  }
114 
115  /** Write contents into a single BLOB page.
116  @return code as returned by zlib. */
118 
119  /** Commit the BLOB mtr. */
121 
122  /** Write one blob page. This function will be repeatedly called
123  with an increasing nth_blob_page to completely write a BLOB.
124  @param[in] blob_j the jth blob object of the record.
125  @param[in] field the big record field.
126  @param[in] nth_blob_page count of the BLOB page (starting from 1).
127  @return code as returned by the zlib. */
128  int write_single_blob_page(size_t blob_j, big_rec_field_t &field,
129  ulint nth_blob_page);
130 
131  /** Write first blob page.
132  @param[in] blob_j the jth blob object of the record.
133  @param[in] field the big record field.
134  @return code as returned by the zlib. */
135  int write_first_page(size_t blob_j, big_rec_field_t &field);
136 
137  /** Verify that all pointers to externally stored columns in the record
138  is be valid. If validation fails, this function doesn't return.
139  @return true if valid. */
140  bool validate_blobrefs() const {
141  const ulint *offsets = m_ctx->get_offsets();
142 
143  for (ulint i = 0; i < rec_offs_n_fields(offsets); i++) {
144  if (!rec_offs_nth_extern(offsets, i)) {
145  continue;
146  }
147 
148  byte *field_ref = btr_rec_get_field_ref(m_ctx->rec(), offsets, i);
149 
150  ref_t blobref(field_ref);
151 
152  /* The pointer must not be zero if the operation
153  succeeded. */
154  ut_a(!blobref.is_null() || m_err != DB_SUCCESS);
155 
156  /* The column must not be disowned by this record. */
157  ut_a(blobref.is_owner());
158  }
159  return (true);
160  }
161 
162  /** For the given blob field, update its length in the blob reference
163  which is available in the clustered index record.
164  @param[in] field the concerned blob field. */
166 
167  /** Make the current page as next page of previous page. In other
168  words, make the page m_cur_blob_page_no as the next page
169  (FIL_PAGE_NEXT) of page m_prev_page_no.
170  @return DB_SUCCESS on success, or error code on failure. */
172 
173  /** Write one small blob field data. Refer to ref_t to determine
174  the definition of small blob.
175  @param[in] blob_j the blob field number
176  @return DB_SUCCESS on success, error code on failure. */
177  dberr_t write_one_small_blob(size_t blob_j);
178 
179  private:
180  /** Add the BLOB page information to the directory
181  @param[in] page_info BLOB page information. */
182  void add_to_blob_dir(const blob_page_info_t &page_info) {
183  m_dir.add(page_info);
184  }
185 
187  z_stream m_stream;
188 
189  /** The BLOB directory information. */
191 };
192 
193 inline zInserter::~zInserter() {
194  if (m_heap != nullptr) {
196  }
197 }
198 
199 } // namespace lob
200 
201 #endif // lob0zip_h
FIL_PAGE_DATA
constexpr ulint FIL_PAGE_DATA
start of the data on the page
Definition: fil0types.h:110
lob::BaseInserter::is_index_sdi
bool is_index_sdi()
Check if the index is SDI index.
Definition: lob0ins.h:120
lob::zInserter::finish
dberr_t finish(bool validate=true)
Cleanup after completing the write of compressed BLOB.
Definition: lob0zip.h:110
lob::zInserter::write_one_small_blob
dberr_t write_one_small_blob(size_t blob_j)
Write one small blob field data.
Definition: zlob0ins.cc:132
page_t
byte page_t
Type of the index page.
Definition: page0types.h:133
lob::zInserter::zInserter
zInserter(InsertContext *ctx)
Constructor.
Definition: lob0zip.h:86
lob::zInserter::m_dir
blob_dir_t m_dir
The BLOB directory information.
Definition: lob0zip.h:238
lob::BaseInserter::BaseInserter
BaseInserter(InsertContext *ctx)
Constructor.
Definition: lob0ins.h:86
ut_a
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:54
ut_ad
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:66
lob::zInserter::write
dberr_t write()
Write all the BLOBs of the clustered index record.
Definition: zlob0ins.cc:322
nullptr
Dialog Client Authentication nullptr
Definition: dialog.cc:353
lob::BaseInserter::m_blob_mtr
mtr_t m_blob_mtr
The mini trx used to write into blob pages.
Definition: lob0ins.h:134
FIL_PAGE_SDI_ZBLOB
constexpr page_type_t FIL_PAGE_SDI_ZBLOB
Commpressed SDI BLOB page.
Definition: fil0fil.h:1268
dberr_t
dberr_t
Definition: db0err.h:38
page_size_t::physical
size_t physical() const
Retrieve the physical page size (on-disk).
Definition: page0size.h:120
lob::zInserter::set_page_next
dberr_t set_page_next()
Make the current page as next page of previous page.
Definition: zlob0ins.cc:338
rec_offs_nth_extern
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.
lob::zInserter::m_heap
mem_heap_t * m_heap
Definition: lob0zip.h:234
rec_offs_n_fields
UNIV_INLINE ulint rec_offs_n_fields(const ulint *offsets)
The following function returns the number of fields in a record.
Definition: rec.h:442
lob::zInserter::write_first_page
int write_first_page(size_t blob_j, big_rec_field_t &field)
Write first blob page.
Definition: zlob0ins.cc:60
big_rec_t
Storage format for overflow data in a big record, that is, a clustered index record which needs exter...
Definition: data0data.h:859
mem_block_info_t
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:343
MLOG_2BYTES
@ MLOG_2BYTES
2 bytes ...
Definition: mtr0types.h:72
big_rec_field_t::len
ulint len
stored data length, in bytes
Definition: data0data.h:831
lob::ref_t
The struct 'lob::ref_t' represents an external field reference.
Definition: lob0lob.h:197
mlog_write_ulint
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:247
lob::zInserter::commit_blob_mtr
void commit_blob_mtr()
Commit the BLOB mtr.
Definition: lob0zip.h:168
page_size_t
Page size descriptor.
Definition: page0size.h:49
reference_caching::channel::validate
static mysql_service_status_t validate(reference_caching_channel channel) noexcept
Definition: component.cc:66
lob::zInserter::log_page_type
void log_page_type(page_t *blob_page, ulint nth_blob_page)
Write the page type of the BLOB page and also generate the redo log record.
Definition: lob0zip.h:126
lob::BaseInserter::m_ctx
InsertContext * m_ctx
The BLOB operation context.
Definition: lob0ins.h:128
btr_rec_get_field_ref
#define btr_rec_get_field_ref(rec, offsets, n)
Gets a pointer to the externally stored part of a field.
Definition: lob0lob.h:647
lob::zInserter::calc_total_pages
ulint calc_total_pages()
Calculate the total number of pages needed to store the given blobs.
Definition: lob0zip.h:143
big_rec_t::fields
big_rec_field_t * fields
stored fields
Definition: data0data.h:864
big_rec_t::n_fields
ulint n_fields
number of stored fields
Definition: data0data.h:863
DB_SUCCESS
@ DB_SUCCESS
Definition: db0err.h:42
mtr_commit
#define mtr_commit(m)
Commit a mini-transaction.
Definition: mtr0mtr.h:59
lob::blob_page_info_t
Information about data stored in one BLOB page.
Definition: lob0lob.h:1108
lob::BtrContext::get_offsets
ulint * get_offsets() const
Get the record offsets array.
Definition: lob0lob.h:1017
mem_heap_free
UNIV_INLINE void mem_heap_free(mem_heap_t *heap)
Frees the space occupied by a memory heap.
FIL_PAGE_TYPE
#define FIL_PAGE_TYPE
file page type: FIL_PAGE_INDEX,..., 2 bytes.
Definition: fil0types.h:75
lob::zInserter::validate_blobrefs
bool validate_blobrefs() const
Verify that all pointers to externally stored columns in the record is be valid.
Definition: lob0zip.h:188
big_rec_field_t
A slot for a field in a big rec vector.
Definition: data0data.h:816
lob::zInserter::add_to_blob_dir
void add_to_blob_dir(const blob_page_info_t &page_info)
Add the BLOB page information to the directory.
Definition: lob0zip.h:230
Z_OK
#define Z_OK
Definition: azlib.h:164
lob::zInserter::write_single_blob_page
int write_single_blob_page(size_t blob_j, big_rec_field_t &field, ulint nth_blob_page)
Write one blob page.
Definition: zlob0ins.cc:263
lob0ins.h
lob::blob_dir_t::add
dberr_t add(const blob_page_info_t &page)
Append the given blob page information.
Definition: lob0lob.h:1174
lob::zInserter::m_stream
z_stream m_stream
Definition: lob0zip.h:235
lob::BaseInserter::m_err
dberr_t m_err
Success or failure status of the operation so far.
Definition: lob0ins.h:131
page_type_t
uint16_t page_type_t
Definition: fil0fil.h:1199
FIL_PAGE_TYPE_ZBLOB
constexpr page_type_t FIL_PAGE_TYPE_ZBLOB
First compressed BLOB page.
Definition: fil0fil.h:1243
lob::zInserter::prepare
dberr_t prepare()
Prepare to write a compressed BLOB.
Definition: zlob0ins.cc:298
lob::BtrContext::page_size
const page_size_t page_size() const
Obtain the page size of the underlying table.
Definition: lob0lob.h:983
lob::zInserter::update_length_in_blobref
void update_length_in_blobref(big_rec_field_t &field)
For the given blob field, update its length in the blob reference which is available in the clustered...
Definition: zlob0ins.cc:112
lob::InsertContext::get_big_rec_vec
const big_rec_t * get_big_rec_vec()
Get the vector containing fields to be stored externally.
Definition: lob0lob.h:1094
lob::zInserter::write_one_blob
dberr_t write_one_blob(size_t blob_j)
Write one blob field data.
Definition: zlob0ins.cc:156
lob::zInserter::~zInserter
~zInserter()
Destructor.
Definition: lob0zip.h:217
lob::BtrContext::rec
rec_t * rec() const
Get the clustered index record pointer.
Definition: lob0lob.h:815
DB_FAIL
@ DB_FAIL
Definition: db0err.h:203
lob
Provides the large objects (LOB) module.
Definition: lob0del.h:31
lob::zInserter::write_into_single_page
int write_into_single_page()
Write contents into a single BLOB page.
Definition: zlob0ins.cc:187
FIL_PAGE_TYPE_ZBLOB2
constexpr page_type_t FIL_PAGE_TYPE_ZBLOB2
Subsequent compressed BLOB page.
Definition: fil0fil.h:1246
lob::blob_dir_t
The in-memory blob directory.
Definition: lob0lob.h:1160