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