35
34
#include "page0types.h"
36
35
#include "buf0types.h"
37
36
#include "dict0types.h"
38
#include "trx0types.h"
39
37
#include "mem0mem.h"
41
/**********************************************************************//**
42
Determine the size of a compressed page in bytes.
43
@return size in bytes */
39
/**************************************************************************
40
Determine the size of a compressed page in bytes. */
48
const page_zip_des_t* page_zip) /*!< in: compressed page */
45
/* out: size in bytes */
46
const page_zip_des_t* page_zip) /* in: compressed page */
49
47
__attribute__((nonnull, pure));
50
/**********************************************************************//**
48
/**************************************************************************
51
49
Set the size of a compressed page in bytes. */
56
page_zip_des_t* page_zip, /*!< in/out: compressed page */
57
ulint size); /*!< in: size in bytes */
54
page_zip_des_t* page_zip, /* in/out: compressed page */
55
ulint size); /* in: size in bytes */
59
#ifndef UNIV_HOTBACKUP
60
/**********************************************************************//**
61
Determine if a record is so big that it needs to be stored externally.
62
@return FALSE if the entire record can be stored locally on the page */
57
/**************************************************************************
58
Determine if a record is so big that it needs to be stored externally. */
65
61
page_zip_rec_needs_ext(
66
62
/*===================*/
67
ulint rec_size, /*!< in: length of the record in bytes */
68
ulint comp, /*!< in: nonzero=compact format */
69
ulint n_fields, /*!< in: number of fields in the record;
63
/* out: FALSE if the entire record
64
can be stored locally on the page */
65
ulint rec_size, /* in: length of the record in bytes */
66
ulint comp, /* in: nonzero=compact format */
67
ulint n_fields, /* in: number of fields in the record;
70
68
ignored if zip_size == 0 */
71
ulint zip_size) /*!< in: compressed page size in bytes, or 0 */
72
__attribute__((const));
69
ulint zip_size) /* in: compressed page size in bytes, or 0 */
70
__attribute__((__const__));
74
/**********************************************************************//**
75
Determine the guaranteed free space on an empty page.
76
@return minimum payload size on the page */
72
/**************************************************************************
73
Determine the guaranteed free space on an empty page. */
79
76
page_zip_empty_size(
80
77
/*================*/
81
ulint n_fields, /*!< in: number of columns in the index */
82
ulint zip_size) /*!< in: compressed page size in bytes */
78
/* out: minimum payload size on the page */
79
ulint n_fields, /* in: number of columns in the index */
80
ulint zip_size) /* in: compressed page size in bytes */
83
81
__attribute__((const));
84
#endif /* !UNIV_HOTBACKUP */
86
/**********************************************************************//**
83
/**************************************************************************
87
84
Initialize a compressed page descriptor. */
92
page_zip_des_t* page_zip); /*!< in/out: compressed page
89
page_zip_des_t* page_zip); /* in/out: compressed page
95
/**********************************************************************//**
92
/**************************************************************************
96
93
Configure the zlib allocator to use the given memory heap. */
99
96
page_zip_set_alloc(
100
97
/*===============*/
101
void* stream, /*!< in/out: zlib stream */
102
mem_heap_t* heap); /*!< in: memory heap to use */
98
void* stream, /* in/out: zlib stream */
99
mem_heap_t* heap); /* in: memory heap to use */
104
/**********************************************************************//**
106
@return TRUE on success, FALSE on failure; page_zip will be left
107
intact on failure. */
101
/**************************************************************************
110
105
page_zip_compress(
111
106
/*==============*/
112
page_zip_des_t* page_zip,/*!< in: size; out: data, n_blobs,
107
/* out: TRUE on success, FALSE on failure;
108
page_zip will be left intact on failure. */
109
page_zip_des_t* page_zip,/* in: size; out: data, n_blobs,
113
110
m_start, m_end, m_nonempty */
114
const page_t* page, /*!< in: uncompressed page */
115
dict_index_t* index, /*!< in: index of the B-tree node */
116
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
111
const page_t* page, /* in: uncompressed page */
112
dict_index_t* index, /* in: index of the B-tree node */
113
mtr_t* mtr) /* in: mini-transaction, or NULL */
117
114
__attribute__((nonnull(1,2,3)));
119
/**********************************************************************//**
116
/**************************************************************************
120
117
Decompress a page. This function should tolerate errors on the compressed
121
118
page. Instead of letting assertions fail, it will return FALSE if an
122
inconsistency is detected.
123
@return TRUE on success, FALSE on failure */
119
inconsistency is detected. */
126
122
page_zip_decompress(
127
123
/*================*/
128
page_zip_des_t* page_zip,/*!< in: data, ssize;
124
/* out: TRUE on success, FALSE on failure */
125
page_zip_des_t* page_zip,/* in: data, ssize;
129
126
out: m_start, m_end, m_nonempty, n_blobs */
130
page_t* page, /*!< out: uncompressed page, may be trashed */
131
ibool all) /*!< in: TRUE=decompress the whole page;
132
FALSE=verify but do not copy some
133
page header fields that should not change
134
after page creation */
135
__attribute__((nonnull(1,2)));
127
page_t* page) /* out: uncompressed page, may be trashed */
128
__attribute__((nonnull));
137
130
#ifdef UNIV_DEBUG
138
/**********************************************************************//**
139
Validate a compressed page descriptor.
140
@return TRUE if ok */
131
/**************************************************************************
132
Validate a compressed page descriptor. */
143
135
page_zip_simple_validate(
144
136
/*=====================*/
145
const page_zip_des_t* page_zip); /*!< in: compressed page
137
/* out: TRUE if ok */
138
const page_zip_des_t* page_zip); /* in: compressed page
147
140
#endif /* UNIV_DEBUG */
149
142
#ifdef UNIV_ZIP_DEBUG
150
/**********************************************************************//**
151
Check that the compressed and decompressed pages match.
152
@return TRUE if valid, FALSE if not */
143
/**************************************************************************
144
Check that the compressed and decompressed pages match. */
155
147
page_zip_validate_low(
156
148
/*==================*/
157
const page_zip_des_t* page_zip,/*!< in: compressed page */
158
const page_t* page, /*!< in: uncompressed page */
159
ibool sloppy) /*!< in: FALSE=strict,
149
/* out: TRUE if valid, FALSE if not */
150
const page_zip_des_t* page_zip,/* in: compressed page */
151
const page_t* page, /* in: uncompressed page */
152
ibool sloppy) /* in: FALSE=strict,
160
153
TRUE=ignore the MIN_REC_FLAG */
161
154
__attribute__((nonnull));
162
/**********************************************************************//**
155
/**************************************************************************
163
156
Check that the compressed and decompressed pages match. */
166
159
page_zip_validate(
167
160
/*==============*/
168
const page_zip_des_t* page_zip,/*!< in: compressed page */
169
const page_t* page) /*!< in: uncompressed page */
161
const page_zip_des_t* page_zip,/* in: compressed page */
162
const page_t* page) /* in: uncompressed page */
170
163
__attribute__((nonnull));
171
164
#endif /* UNIV_ZIP_DEBUG */
173
/**********************************************************************//**
174
Determine how big record can be inserted without recompressing the page.
175
@return a positive number indicating the maximum size of a record
176
whose insertion is guaranteed to succeed, or zero or negative */
166
/**************************************************************************
167
Determine how big record can be inserted without recompressing the page. */
179
170
page_zip_max_ins_size(
180
171
/*==================*/
181
const page_zip_des_t* page_zip,/*!< in: compressed page */
182
ibool is_clust)/*!< in: TRUE if clustered index */
172
/* out: a positive number
173
indicating the maximum size of
174
a record whose insertion is
175
guaranteed to succeed, or
177
const page_zip_des_t* page_zip,/* in: compressed page */
178
ibool is_clust)/* in: TRUE if clustered index */
183
179
__attribute__((nonnull, pure));
185
/**********************************************************************//**
186
Determine if enough space is available in the modification log.
187
@return TRUE if page_zip_write_rec() will succeed */
181
/**************************************************************************
182
Determine if enough space is available in the modification log. */
190
185
page_zip_available(
191
186
/*===============*/
192
const page_zip_des_t* page_zip,/*!< in: compressed page */
193
ibool is_clust,/*!< in: TRUE if clustered index */
194
ulint length, /*!< in: combined size of the record */
195
ulint create) /*!< in: nonzero=add the record to
187
/* out: TRUE if page_zip_write_rec()
189
const page_zip_des_t* page_zip,/* in: compressed page */
190
ibool is_clust,/* in: TRUE if clustered index */
191
ulint length, /* in: combined size of the record */
192
ulint create) /* in: nonzero=add the record to
197
194
__attribute__((nonnull, pure));
199
/**********************************************************************//**
200
Write data to the uncompressed header portion of a page. The data must
201
already have been written to the uncompressed page. */
204
page_zip_write_header(
205
/*==================*/
206
page_zip_des_t* page_zip,/*!< in/out: compressed page */
207
const byte* str, /*!< in: address on the uncompressed page */
208
ulint length, /*!< in: length of the data */
209
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
210
__attribute__((nonnull(1,2)));
212
/**********************************************************************//**
196
/**************************************************************************
213
197
Write an entire record on the compressed page. The data must already
214
198
have been written to the uncompressed page. */
217
201
page_zip_write_rec(
218
202
/*===============*/
219
page_zip_des_t* page_zip,/*!< in/out: compressed page */
220
const byte* rec, /*!< in: record being written */
221
dict_index_t* index, /*!< in: the index the record belongs to */
222
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
223
ulint create) /*!< in: nonzero=insert, zero=update */
203
page_zip_des_t* page_zip,/* in/out: compressed page */
204
const byte* rec, /* in: record being written */
205
dict_index_t* index, /* in: the index the record belongs to */
206
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
207
ulint create) /* in: nonzero=insert, zero=update */
224
208
__attribute__((nonnull));
226
/***********************************************************//**
227
Parses a log record of writing a BLOB pointer of a record.
228
@return end of log record or NULL */
210
/***************************************************************
211
Parses a log record of writing a BLOB pointer of a record. */
231
214
page_zip_parse_write_blob_ptr(
232
215
/*==========================*/
233
byte* ptr, /*!< in: redo log buffer */
234
byte* end_ptr,/*!< in: redo log buffer end */
235
page_t* page, /*!< in/out: uncompressed page */
236
page_zip_des_t* page_zip);/*!< in/out: compressed page */
216
/* out: end of log record or NULL */
217
byte* ptr, /* in: redo log buffer */
218
byte* end_ptr,/* in: redo log buffer end */
219
page_t* page, /* in/out: uncompressed page */
220
page_zip_des_t* page_zip);/* in/out: compressed page */
238
/**********************************************************************//**
222
/**************************************************************************
239
223
Write a BLOB pointer of a record on the leaf page of a clustered index.
240
224
The information must already have been updated on the uncompressed page. */
243
227
page_zip_write_blob_ptr(
244
228
/*====================*/
245
page_zip_des_t* page_zip,/*!< in/out: compressed page */
246
const byte* rec, /*!< in/out: record whose data is being
229
page_zip_des_t* page_zip,/* in/out: compressed page */
230
const byte* rec, /* in/out: record whose data is being
248
dict_index_t* index, /*!< in: index of the page */
249
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
250
ulint n, /*!< in: column index */
251
mtr_t* mtr) /*!< in: mini-transaction handle,
232
dict_index_t* index, /* in: index of the page */
233
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
234
ulint n, /* in: column index */
235
mtr_t* mtr) /* in: mini-transaction handle,
252
236
or NULL if no logging is needed */
253
237
__attribute__((nonnull(1,2,3,4)));
255
/***********************************************************//**
256
Parses a log record of writing the node pointer of a record.
257
@return end of log record or NULL */
239
/***************************************************************
240
Parses a log record of writing the node pointer of a record. */
260
243
page_zip_parse_write_node_ptr(
261
244
/*==========================*/
262
byte* ptr, /*!< in: redo log buffer */
263
byte* end_ptr,/*!< in: redo log buffer end */
264
page_t* page, /*!< in/out: uncompressed page */
265
page_zip_des_t* page_zip);/*!< in/out: compressed page */
245
/* out: end of log record or NULL */
246
byte* ptr, /* in: redo log buffer */
247
byte* end_ptr,/* in: redo log buffer end */
248
page_t* page, /* in/out: uncompressed page */
249
page_zip_des_t* page_zip);/* in/out: compressed page */
267
/**********************************************************************//**
251
/**************************************************************************
268
252
Write the node pointer of a record on a non-leaf compressed page. */
271
255
page_zip_write_node_ptr(
272
256
/*====================*/
273
page_zip_des_t* page_zip,/*!< in/out: compressed page */
274
byte* rec, /*!< in/out: record */
275
ulint size, /*!< in: data size of rec */
276
ulint ptr, /*!< in: node pointer */
277
mtr_t* mtr) /*!< in: mini-transaction, or NULL */
257
page_zip_des_t* page_zip,/* in/out: compressed page */
258
byte* rec, /* in/out: record */
259
ulint size, /* in: data size of rec */
260
ulint ptr, /* in: node pointer */
261
mtr_t* mtr) /* in: mini-transaction, or NULL */
278
262
__attribute__((nonnull(1,2)));
280
/**********************************************************************//**
264
/**************************************************************************
281
265
Write the trx_id and roll_ptr of a record on a B-tree leaf node page. */
284
268
page_zip_write_trx_id_and_roll_ptr(
285
269
/*===============================*/
286
page_zip_des_t* page_zip,/*!< in/out: compressed page */
287
byte* rec, /*!< in/out: record */
288
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
289
ulint trx_id_col,/*!< in: column number of TRX_ID in rec */
290
trx_id_t trx_id, /*!< in: transaction identifier */
291
roll_ptr_t roll_ptr)/*!< in: roll_ptr */
270
page_zip_des_t* page_zip,/* in/out: compressed page */
271
byte* rec, /* in/out: record */
272
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
273
ulint trx_id_col,/* in: column number of TRX_ID in rec */
274
dulint trx_id, /* in: transaction identifier */
275
dulint roll_ptr)/* in: roll_ptr */
292
276
__attribute__((nonnull));
295
/**********************************************************************//**
278
/**************************************************************************
296
279
Insert a record to the dense page directory. */
299
282
page_zip_dir_insert(
300
283
/*================*/
301
page_zip_des_t* page_zip,/*!< in/out: compressed page */
302
const byte* prev_rec,/*!< in: record after which to insert */
303
const byte* free_rec,/*!< in: record from which rec was
284
page_zip_des_t* page_zip,/* in/out: compressed page */
285
const byte* prev_rec,/* in: record after which to insert */
286
const byte* free_rec,/* in: record from which rec was
304
287
allocated, or NULL */
305
byte* rec); /*!< in: record to insert */
288
byte* rec); /* in: record to insert */
290
/***************************************************************
291
Parses a log record of writing to the header of a page. */
309
294
page_zip_parse_write_header(
310
295
/*========================*/
311
byte* ptr, /*!< in: redo log buffer */
312
byte* end_ptr,/*!< in: redo log buffer end */
313
page_t* page, /*!< in/out: uncompressed page */
314
page_zip_des_t* page_zip);/*!< in/out: compressed page */
317
/**********************************************************************//**
296
/* out: end of log record or NULL */
297
byte* ptr, /* in: redo log buffer */
298
byte* end_ptr,/* in: redo log buffer end */
299
page_t* page, /* in/out: uncompressed page */
300
page_zip_des_t* page_zip);/* in/out: compressed page */
302
/**************************************************************************
303
Write data to the uncompressed header portion of a page. The data must
304
already have been written to the uncompressed page.
305
However, the data portion of the uncompressed page may differ from
306
the compressed page when a record is being inserted in
307
page_cur_insert_rec_low(). */
310
page_zip_write_header(
311
/*==================*/
312
page_zip_des_t* page_zip,/* in/out: compressed page */
313
const byte* str, /* in: address on the uncompressed page */
314
ulint length, /* in: length of the data */
315
mtr_t* mtr) /* in: mini-transaction, or NULL */
316
__attribute__((nonnull(1,2)));
318
/**************************************************************************
318
319
Reorganize and compress a page. This is a low-level operation for
319
320
compressed pages, to be used when page_zip_compress() fails.
320
321
On success, a redo log entry MLOG_ZIP_PAGE_COMPRESS will be written.