MySQL 8.0.31
Source Code Documentation
page0page.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1994, 2022, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27#include <stddef.h>
28#include <sys/types.h>
29
30/** @file include/page0page.h
31 Index page routines
32
33 Created 2/2/1994 Heikki Tuuri
34 *******************************************************/
35
36#ifndef page0page_h
37#define page0page_h
38
39#include "univ.i"
40
41#include "buf0buf.h"
42#include "data0data.h"
43#include "dict0dict.h"
44#include "fil0fil.h"
45#include "fsp0fsp.h"
46#include "mtr0mtr.h"
47#include "page0types.h"
48#include "rem0rec.h"
49
50/* PAGE DIRECTORY
51 ==============
52*/
53
54typedef byte page_dir_slot_t;
56
57/* Offset of the directory start down from the page end. We call the
58slot with the highest file address directory start, as it points to
59the first record in the list of records. */
60constexpr uint32_t PAGE_DIR = FIL_PAGE_DATA_END;
61
62/* We define a slot in the page directory as two bytes */
63constexpr uint32_t PAGE_DIR_SLOT_SIZE = 2;
64
65/* The offset of the physically lower end of the directory, counted from
66page end, when the page is empty */
68
69/* The maximum and minimum number of records owned by a directory slot. The
70number may drop below the minimum in the first and the last slot in the
71directory. */
72constexpr uint32_t PAGE_DIR_SLOT_MAX_N_OWNED = 8;
73constexpr uint32_t PAGE_DIR_SLOT_MIN_N_OWNED = 4;
74
75/* The infimum and supremum records are omitted from the compressed page.
76On compress, we compare that the records are there, and on uncompress we
77restore the records. */
78/** Extra bytes of an infimum record */
79static const byte infimum_extra[] = {
80 0x01, /* info_bits=0, n_owned=1 */
81 0x00, 0x02 /* heap_no=0, status=2 */
82 /* ?, ? */ /* next=(first user rec, or supremum) */
83};
84/** Data bytes of an infimum record */
85static const byte infimum_data[] = {
86 0x69, 0x6e, 0x66, 0x69, 0x6d, 0x75, 0x6d, 0x00 /* "infimum\0" */
87};
88/** Extra bytes and data bytes of a supremum record */
89static const byte supremum_extra_data[] = {
90 /* 0x0?, */ /* info_bits=0, n_owned=1..8 */
91 0x00,
92 0x0b, /* heap_no=1, status=3 */
93 0x00,
94 0x00, /* next=0 */
95 0x73,
96 0x75,
97 0x70,
98 0x72,
99 0x65,
100 0x6d,
101 0x75,
102 0x6d /* "supremum" */
103};
104
105/** Gets the start of a page.
106@param[in] ptr pointer to page frame
107@return start of the page */
108static inline page_t *page_align(const void *ptr);
109
110/** Gets the offset within a page.
111@param[in] ptr pointer to page frame
112@return offset from the start of the page */
113static inline ulint page_offset(const void *ptr);
114
115/** Returns the max trx id field value. */
116static inline trx_id_t page_get_max_trx_id(const page_t *page); /*!< in: page */
117
118/** Sets the max trx id field value.
119@param[in,out] block Page
120@param[in,out] page_zip Compressed page, or NULL
121@param[in] trx_id Transaction id
122@param[in,out] mtr Mini-transaction, or NULL */
123void page_set_max_trx_id(buf_block_t *block, page_zip_des_t *page_zip,
124 trx_id_t trx_id, mtr_t *mtr);
125
126/** Sets the max trx id field value if trx_id is bigger than the previous
127value.
128@param[in,out] block Page
129@param[in,out] page_zip Compressed page whose uncompressed part will
130 be updated, or NULL
131@param[in] trx_id Transaction id
132@param[in,out] mtr Mini-transaction */
133static inline void page_update_max_trx_id(buf_block_t *block,
134 page_zip_des_t *page_zip,
135 trx_id_t trx_id, mtr_t *mtr);
136
137/** Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM).
138@param[in] page page
139@return SPLIT SEQUENCE NUMBER */
140static inline node_seq_t page_get_ssn_id(const page_t *page);
141
142/** Sets the RTREE SPLIT SEQUENCE NUMBER field value
143@param[in,out] block Page
144@param[in,out] page_zip Compressed page whose uncompressed part will
145 be updated, or NULL
146@param[in] ssn_id Split sequence id
147@param[in,out] mtr Mini-transaction */
148static inline void page_set_ssn_id(buf_block_t *block, page_zip_des_t *page_zip,
149 node_seq_t ssn_id, mtr_t *mtr);
150
151/** Reads the given header field.
152@param[in] page page
153@param[in] field PAGE_N_DIR_SLOTS, ... */
154static inline uint16_t page_header_get_field(const page_t *page, ulint field);
155
156/** Sets the given header field.
157@param[in,out] page page
158@param[in,out] page_zip compressed page whose uncompressed part will
159 be updated, or NULL
160@param[in] field PAGE_N_DIR_SLOTS, ...
161@param[in] val value */
162static inline void page_header_set_field(page_t *page, page_zip_des_t *page_zip,
163 ulint field, ulint val);
164
165/** Returns the offset stored in the given header field.
166@param[in] page Page.
167@param[in] field PAGE_FREE, ...
168@return offset from the start of the page, or 0 */
169[[nodiscard]] static inline ulint page_header_get_offs(const page_t *page,
170 ulint field);
171
172/** Returns the pointer stored in the given header field, or NULL. */
173static inline byte *page_header_get_ptr(page_t *page, uint32_t field) {
174 if (page_header_get_offs(page, field)) {
175 return page + page_header_get_offs(page, field);
176 }
177 return nullptr;
178}
179
180static inline const byte *page_header_get_ptr(const page_t *page,
181 uint32_t field) {
182 if (page_header_get_offs(page, field)) {
183 return page + page_header_get_offs(page, field);
184 }
185 return nullptr;
186}
187
188/** Sets the pointer stored in the given header field.
189@param[in,out] page page
190@param[in,out] page_zip compressed page whose uncompressed part will
191 be updated, or NULL
192@param[in,out] field PAGE_FREE, ...
193@param[in] ptr pointer or NULL */
194static inline void page_header_set_ptr(page_t *page, page_zip_des_t *page_zip,
195 ulint field, const byte *ptr);
196#ifndef UNIV_HOTBACKUP
197
198/** Resets the last insert info field in the page header. Writes to mlog about
199this operation.
200@param[in] page page
201@param[in,out] page_zip compressed page whose uncompressed part will
202 be updated, or NULL
203@param[in] mtr mtr */
205 page_zip_des_t *page_zip,
206 mtr_t *mtr);
207#endif /* !UNIV_HOTBACKUP */
208
209/** Gets the offset of the first record on the page.
210 @return offset of the first record in record list, relative from page */
212 const page_t *page); /*!< in: page which must have record(s) */
213/** Gets the offset of the last record on the page.
214 @return offset of the last record in record list, relative from page */
216 const page_t *page); /*!< in: page which must have record(s) */
217static inline byte *page_get_infimum_rec(byte *page) {
219}
220static inline const byte *page_get_infimum_rec(const byte *page) {
222}
223static inline byte *page_get_supremum_rec(byte *page) {
225}
226static inline const byte *page_get_supremum_rec(const byte *page) {
228}
229
230/** Returns the nth record of the record list.
231 This is the inverse function of page_rec_get_n_recs_before().
232 @return nth record */
233[[nodiscard]] const rec_t *page_rec_get_nth_const(
234 const page_t *page, /*!< in: page */
235 ulint nth); /*!< in: nth record */
236
237/** Returns the nth record of the record list.
238This is the inverse function of page_rec_get_n_recs_before().
239@param[in] page page
240@param[in] nth nth record
241@return nth record */
242[[nodiscard]] static inline rec_t *page_rec_get_nth(page_t *page, ulint nth);
243
244#ifndef UNIV_HOTBACKUP
245/** Returns the middle record of the records on the page. If there is an
246 even number of records in the list, returns the first record of the
247 upper half-list.
248 @return middle record */
249[[nodiscard]] static inline rec_t *page_get_middle_rec(
250 page_t *page); /*!< in: page */
251#endif /* !UNIV_HOTBACKUP */
252/** Gets the page number.
253 @return page number */
254static inline page_no_t page_get_page_no(const page_t *page); /*!< in: page */
255/** Gets the tablespace identifier.
256 @return space id */
257static inline space_id_t page_get_space_id(const page_t *page); /*!< in: page */
258
259/** Gets the space id and page number identifying the page.
260 @return page number */
261static inline page_id_t page_get_page_id(const page_t *page);
262
263/** Gets the number of user records on page (the infimum and supremum records
264 are not user records).
265 @return number of user records */
266static inline ulint page_get_n_recs(const page_t *page); /*!< in: index page */
267/** Returns the number of records before the given record in chain.
268 The number includes infimum and supremum records.
269 This is the inverse function of page_rec_get_nth().
270 @return number of records */
272 const rec_t *rec); /*!< in: the physical record */
273/** Gets the number of records in the heap.
274 @param[in] page index page
275 @return number of user records */
276static inline uint16_t page_dir_get_n_heap(const page_t *page);
277
278/** Sets the number of records in the heap.
279@param[in,out] page index page
280@param[in,out] page_zip compressed page whose uncompressed part will
281 be updated, or NULL. Note that the size of the
282 dense page directory in the compressed page
283 trailer is n_heap * PAGE_ZIP_DIR_SLOT_SIZE.
284@param[in] n_heap number of records*/
285static inline void page_dir_set_n_heap(page_t *page, page_zip_des_t *page_zip,
286 ulint n_heap);
287
288/** Gets the number of dir slots in directory.
289 @return number of slots */
291 const page_t *page); /*!< in: index page */
292
293/** Sets the number of dir slots in directory.
294@param[in,out] page page
295@param[in,out] page_zip compressed page whose uncompressed part will
296 be updated, or NULL
297@param[in] n_slots number of slots */
298static inline void page_dir_set_n_slots(page_t *page, page_zip_des_t *page_zip,
299 ulint n_slots);
300
301#ifdef UNIV_DEBUG
302/** Gets pointer to nth directory slot.
303@param[in] page index page
304@param[in] n position
305@return pointer to dir slot */
307 ulint n);
308#else /* UNIV_DEBUG */
309#define page_dir_get_nth_slot(page, n) \
310 ((page) + (UNIV_PAGE_SIZE - PAGE_DIR - (n + 1) * PAGE_DIR_SLOT_SIZE))
311#endif /* UNIV_DEBUG */
312
313/** Used to check the consistency of a record on a page.
314 @return true if succeed */
315static inline bool page_rec_check(const rec_t *rec); /*!< in: record */
316/** Gets the record pointed to by a directory slot.
317 @return pointer to record */
318static inline const rec_t *page_dir_slot_get_rec(
319 const page_dir_slot_t *slot); /*!< in: directory slot */
320
321/** This is used to set the record offset in a directory slot.
322@param[in] rec record on the page
323@param[in] slot directory slot */
324static inline void page_dir_slot_set_rec(page_dir_slot_t *slot, rec_t *rec);
325
326/** Gets the number of records owned by a directory slot.
327 @return number of records */
329 const page_dir_slot_t *slot); /*!< in: page directory slot */
330
331/** This is used to set the owned records field of a directory slot.
332@param[in,out] slot directory slot
333@param[in,out] page_zip compressed page, or NULL
334@param[in] n number of records owned by the slot */
336 page_zip_des_t *page_zip, ulint n);
337
338/** Calculates the space reserved for directory slots of a given
339 number of records. The exact value is a fraction number
340 n * PAGE_DIR_SLOT_SIZE / PAGE_DIR_SLOT_MIN_N_OWNED, and it is
341 rounded upwards to an integer. */
343 ulint n_recs); /*!< in: number of records */
344/** Looks for the directory slot which owns the given record.
345 @return the directory slot number */
347 const rec_t *rec); /*!< in: the physical record */
348/** Determine whether the page is in new-style compact format.
349 @return nonzero if the page is in compact format, zero if it is in
350 old-style format */
351static inline bool page_is_comp(const page_t *page); /*!< in: index page */
352/** true if the record is on a page in compact format.
353 @return nonzero if in compact format */
354static inline bool page_rec_is_comp(const rec_t *rec); /*!< in: record */
355/** Returns the heap number of a record.
356 @return heap number */
358 const rec_t *rec); /*!< in: the physical record */
359/** Determine whether the page is a B-tree leaf.
360 @return true if the page is a B-tree leaf (PAGE_LEVEL = 0) */
361[[nodiscard]] static inline bool page_is_leaf(
362 const page_t *page); /*!< in: page */
363/** Determine whether the page is empty.
364 @return true if the page is empty (PAGE_N_RECS = 0) */
365[[nodiscard]] static inline bool page_is_empty(
366 const page_t *page); /*!< in: page */
367/** Determine whether a page is an index root page.
368@param[in] page page frame
369@return true if the page is a root page of an index */
370[[nodiscard]] static inline bool page_is_root(const page_t *page);
371/** Determine whether the page contains garbage.
372 @return true if the page contains garbage (PAGE_GARBAGE is not 0) */
373[[nodiscard]] static inline bool page_has_garbage(
374 const page_t *page); /*!< in: page */
375
376/** Gets the pointer to the next record on the page.
377@param[in] rec pointer to record
378@param[in] comp nonzero=compact page layout
379@return pointer to next record */
380static inline const rec_t *page_rec_get_next_low(const rec_t *rec, ulint comp);
381
382/** Gets the pointer to the next record on the page.
383 @return pointer to next record */
385 rec_t *rec); /*!< in: pointer to record */
386/** Gets the pointer to the next record on the page.
387 @return pointer to next record */
388static inline const rec_t *page_rec_get_next_const(
389 const rec_t *rec); /*!< in: pointer to record */
390/** Gets the pointer to the next non delete-marked record on the page.
391 If all subsequent records are delete-marked, then this function
392 will return the supremum record.
393 @return pointer to next non delete-marked record or pointer to supremum */
395 const rec_t *rec); /*!< in: pointer to record */
396
397/** Sets the pointer to the next record on the page.
398@param[in] rec pointer to record, must not be page supremum
399@param[in] next pointer to next record, must not be page infimum */
400static inline void page_rec_set_next(rec_t *rec, const rec_t *next);
401
402/** Gets the pointer to the previous record.
403 @return pointer to previous record */
404static inline const rec_t *page_rec_get_prev_const(
405 const rec_t *rec); /*!< in: pointer to record, must not be page
406 infimum */
407/** Gets the pointer to the previous record.
408 @return pointer to previous record */
409static inline rec_t *page_rec_get_prev(rec_t *rec); /*!< in: pointer to record,
410 must not be page infimum */
411/** true if the record is a user record on the page.
412@param[in] offset record offset on page
413@return true if a user record */
414static inline bool page_rec_is_user_rec_low(ulint offset);
415
416/** true if the record is the supremum record on a page.
417@param[in] offset record offset on page
418@return true if the supremum record */
419static inline bool page_rec_is_supremum_low(ulint offset);
420
421/** true if the record is the infimum record on a page.
422@param[in] offset record offset on page
423@return true if the infimum record */
424static inline bool page_rec_is_infimum_low(ulint offset);
425
426/** true if the record is a user record on the page.
427 @return true if a user record */
428[[nodiscard]] static inline bool page_rec_is_user_rec(
429 const rec_t *rec); /*!< in: record */
430/** true if the record is the supremum record on a page.
431 @return true if the supremum record */
432[[nodiscard]] static inline bool page_rec_is_supremum(
433 const rec_t *rec); /*!< in: record */
434
435/** true if the record is the infimum record on a page.
436 @return true if the infimum record */
437[[nodiscard]] static inline bool page_rec_is_infimum(
438 const rec_t *rec); /*!< in: record */
439
440/** true if the record is the first user record on a page.
441@param[in] rec Record.
442@param[in] page Page.
443@return true if the first user record */
444[[nodiscard]] static inline bool page_rec_is_first(const rec_t *rec,
445 const page_t *page);
446
447/** true if the record is the second user record on a page.
448@param[in] rec Record.
449@param[in] page Page.
450@return true if the second user record */
451[[nodiscard]] static inline bool page_rec_is_second(const rec_t *rec,
452 const page_t *page);
453
454/** true if the record is the last user record on a page.
455@param[in] rec Record.
456@param[in] page Page.
457@return true if the last user record */
458[[nodiscard]] static inline bool page_rec_is_last(const rec_t *rec,
459 const page_t *page);
460
461/** true if distance between the records (measured in number of times we have to
462move to the next record) is at most the specified value
463@param[in] left_rec lefter record
464@param[in] right_rec righter record
465@param[in] val specified value to compare
466@return true if the distance is smaller than the value */
467[[nodiscard]] static inline bool page_rec_distance_is_at_most(
468 const rec_t *left_rec, const rec_t *right_rec, ulint val);
469
470/** true if the record is the second last user record on a page.
471@param[in] rec Record.
472@param[in] page Page.
473@return true if the second last user record */
474[[nodiscard]] static inline bool page_rec_is_second_last(const rec_t *rec,
475 const page_t *page);
476
477/** Looks for the record which owns the given record.
478 @return the owner record */
480 rec_t *rec); /*!< in: the physical record */
481
482/** Returns the maximum combined size of records which can be inserted on top
483of record heap.
484@param[in] page index page
485@param[in] n_recs number of records
486@return maximum combined size for inserted records */
487static inline ulint page_get_max_insert_size(const page_t *page, ulint n_recs);
488
489/** Returns the maximum combined size of records which can be inserted on top
490of record heap if page is first reorganized.
491@param[in] page index page
492@param[in] n_recs number of records
493@return maximum combined size for inserted records */
495 const page_t *page, ulint n_recs);
496
497/** Calculates free space if a page is emptied.
498@param[in] comp nonzero=compact page format
499@return free space */
500static inline ulint page_get_free_space_of_empty(bool comp);
501
502/** Returns the base extra size of a physical record. This is the
503 size of the fixed header, independent of the record size.
504 @return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
506 const rec_t *rec); /*!< in: physical record */
507/** Returns the sum of the sizes of the records in the record list
508 excluding the infimum and supremum records.
509 @return data in bytes */
511 const page_t *page); /*!< in: index page */
512
513/** Allocates a block of memory from the head of the free list of an index
514page.
515@param[in,out] page index page
516@param[in,out] page_zip compressed page with enough space available
517 for inserting the record, or NULL
518@param[in] next_rec pointer to the new head of the free record
519 list
520@param[in] need number of bytes allocated */
521static inline void page_mem_alloc_free(page_t *page, page_zip_des_t *page_zip,
522 rec_t *next_rec, ulint need);
523
524/** Allocates a block of memory from the heap of an index page.
525 @return pointer to start of allocated buffer, or NULL if allocation fails */
527 page_t *page, /*!< in/out: index page */
528 page_zip_des_t *page_zip, /*!< in/out: compressed page with enough
529 space available for inserting the record,
530 or NULL */
531 ulint need, /*!< in: total number of bytes needed */
532 ulint *heap_no); /*!< out: this contains the heap number
533 of the allocated record
534 if allocation succeeds */
535
536/** Puts a record to free list.
537@param[in,out] page index page
538@param[in,out] page_zip compressed page, or NULL
539@param[in] rec pointer to the (origin of) record
540@param[in] index index of rec
541@param[in] offsets array returned by rec_get_offsets() */
542static inline void page_mem_free(page_t *page, page_zip_des_t *page_zip,
543 rec_t *rec, const dict_index_t *index,
544 const ulint *offsets);
545
546/** Create an uncompressed B-tree or R-tree or SDI index page.
547@param[in] block A buffer block where the page is created
548@param[in] mtr Mini-transaction handle
549@param[in] comp nonzero=compact page format
550@param[in] page_type Page type
551@return pointer to the page */
552page_t *page_create(buf_block_t *block, mtr_t *mtr, ulint comp,
553 page_type_t page_type);
554
555/** Create a compressed B-tree index page.
556@param[in,out] block Buffer frame where the page is created
557@param[in] index Index of the page, or NULL when applying
558 TRUNCATE log record during recovery
559@param[in] level The B-tree level of the page
560@param[in] max_trx_id PAGE_MAX_TRX_ID
561@param[in] mtr Mini-transaction handle
562@param[in] page_type Page type to be created. Only FIL_PAGE_INDEX,
563 FIL_PAGE_RTREE, FIL_PAGE_SDI allowed
564@return pointer to the page */
566 trx_id_t max_trx_id, mtr_t *mtr, page_type_t page_type);
567
568/** Empty a previously created B-tree index page.
569@param[in,out] block B-tree block
570@param[in] index The index of the page
571@param[in,out] mtr Mini-transaction */
572void page_create_empty(buf_block_t *block, dict_index_t *index, mtr_t *mtr);
573
574/** Differs from page_copy_rec_list_end, because this function does not
575 touch the lock table and max trx id on page or compress the page.
576
577 IMPORTANT: The caller will have to update IBUF_BITMAP_FREE
578 if new_block is a compressed leaf page in a secondary index.
579 This has to be done either within the same mini-transaction,
580 or by invoking ibuf_reset_free_bits() before mtr_commit(). */
582 buf_block_t *new_block, /*!< in: index page to copy to */
583 buf_block_t *block, /*!< in: index page of rec */
584 rec_t *rec, /*!< in: record on page */
585 dict_index_t *index, /*!< in: record descriptor */
586 mtr_t *mtr); /*!< in: mtr */
587/** Copies records from page to new_page, from the given record onward,
588 including that record. Infimum and supremum records are not copied.
589 The records are copied to the start of the record list on new_page.
590
591 IMPORTANT: The caller will have to update IBUF_BITMAP_FREE
592 if new_block is a compressed leaf page in a secondary index.
593 This has to be done either within the same mini-transaction,
594 or by invoking ibuf_reset_free_bits() before mtr_commit().
595
596 @return pointer to the original successor of the infimum record on
597 new_page, or NULL on zip overflow (new_block will be decompressed) */
599 buf_block_t *new_block, /*!< in/out: index page to copy to */
600 buf_block_t *block, /*!< in: index page containing rec */
601 rec_t *rec, /*!< in: record on page */
602 dict_index_t *index, /*!< in: record descriptor */
603 mtr_t *mtr); /*!< in: mtr */
604/** Copies records from page to new_page, up to the given record, NOT
605 including that record. Infimum and supremum records are not copied.
606 The records are copied to the end of the record list on new_page.
607
608 IMPORTANT: The caller will have to update IBUF_BITMAP_FREE
609 if new_block is a compressed leaf page in a secondary index.
610 This has to be done either within the same mini-transaction,
611 or by invoking ibuf_reset_free_bits() before mtr_commit().
612
613 @return pointer to the original predecessor of the supremum record on
614 new_page, or NULL on zip overflow (new_block will be decompressed) */
616 buf_block_t *new_block, /*!< in/out: index page to copy to */
617 buf_block_t *block, /*!< in: index page containing rec */
618 rec_t *rec, /*!< in: record on page */
619 dict_index_t *index, /*!< in: record descriptor */
620 mtr_t *mtr); /*!< in: mtr */
621/** Deletes records from a page from a given record onward, including that
622 record. The infimum and supremum records are not deleted. */
624 rec_t *rec, /*!< in: pointer to record on page */
625 buf_block_t *block, /*!< in: buffer block of the page */
626 dict_index_t *index, /*!< in: record descriptor */
627 ulint n_recs, /*!< in: number of records to delete,
628 or ULINT_UNDEFINED if not known */
629 ulint size, /*!< in: the sum of the sizes of the
630 records in the end of the chain to
631 delete, or ULINT_UNDEFINED if not known */
632 mtr_t *mtr); /*!< in: mtr */
633/** Deletes records from page, up to the given record, NOT including
634 that record. Infimum and supremum records are not deleted. */
636 rec_t *rec, /*!< in: record on page */
637 buf_block_t *block, /*!< in: buffer block of the page */
638 dict_index_t *index, /*!< in: record descriptor */
639 mtr_t *mtr); /*!< in: mtr */
640/** Moves record list end to another page. Moved records include
641 split_rec.
642
643 IMPORTANT: The caller will have to update IBUF_BITMAP_FREE
644 if new_block is a compressed leaf page in a secondary index.
645 This has to be done either within the same mini-transaction,
646 or by invoking ibuf_reset_free_bits() before mtr_commit().
647
648 @return true on success; false on compression failure (new_block will
649 be decompressed) */
651 buf_block_t *new_block, /*!< in/out: index page where to move */
652 buf_block_t *block, /*!< in: index page from where to move */
653 rec_t *split_rec, /*!< in: first record to move */
654 dict_index_t *index, /*!< in: record descriptor */
655 mtr_t *mtr); /*!< in: mtr */
656/** Moves record list start to another page. Moved records do not include
657 split_rec.
658
659 IMPORTANT: The caller will have to update IBUF_BITMAP_FREE
660 if new_block is a compressed leaf page in a secondary index.
661 This has to be done either within the same mini-transaction,
662 or by invoking ibuf_reset_free_bits() before mtr_commit().
663
664 @return true on success; false on compression failure */
666 buf_block_t *new_block, /*!< in/out: index page where to move */
667 buf_block_t *block, /*!< in/out: page containing split_rec */
668 rec_t *split_rec, /*!< in: first record not to move */
669 dict_index_t *index, /*!< in: record descriptor */
670 mtr_t *mtr); /*!< in: mtr */
671
672/** Splits a directory slot which owns too many records.
673@param[in,out] page Index page
674@param[in,out] page_zip Compressed page whose uncompressed part will be written,
675or null
676@param[in] slot_no The directory slot */
677void page_dir_split_slot(page_t *page, page_zip_des_t *page_zip, ulint slot_no);
678
679/** Tries to balance the given directory slot with too few records with the
680 upper neighbor, so that there are at least the minimum number of records
681owned by the slot; this may result in the merging of two slots.
682@param[in,out] page Index page
683@param[in,out] page_zip Compressed page, or null
684@param[in] slot_no The directory slot */
686 ulint slot_no);
687
688/** Parses a log record of a record list end or start deletion.
689 @return end of log record or NULL */
691 mlog_id_t type, /*!< in: MLOG_LIST_END_DELETE,
692 MLOG_LIST_START_DELETE,
693 MLOG_COMP_LIST_END_DELETE or
694 MLOG_COMP_LIST_START_DELETE */
695 byte *ptr, /*!< in: buffer */
696 byte *end_ptr, /*!< in: buffer end */
697 buf_block_t *block, /*!< in/out: buffer block or NULL */
698 dict_index_t *index, /*!< in: record descriptor */
699 mtr_t *mtr); /*!< in: mtr or NULL */
700
701/** Parses a redo log record of creating a page.
702@param[in,out] block buffer block, or NULL
703@param[in] comp nonzero=compact page format
704@param[in] page_type page type (FIL_PAGE_INDEX, FIL_PAGE_RTREE
705 or FIL_PAGE_SDI) */
706void page_parse_create(buf_block_t *block, ulint comp, page_type_t page_type);
707
708#ifndef UNIV_HOTBACKUP
709/** Prints record contents including the data relevant only in
710 the index page context.
711@param[in] rec Physical record
712@param[in] offsets Record descriptor */
713void page_rec_print(const rec_t *rec, const ulint *offsets);
714#ifdef UNIV_BTR_PRINT
715/** This is used to print the contents of the directory for
716 debugging purposes. */
717void page_dir_print(page_t *page, /*!< in: index page */
718 ulint pr_n); /*!< in: print n first and n last entries */
719/** This is used to print the contents of the page record list for
720 debugging purposes. */
721void page_print_list(
722 buf_block_t *block, /*!< in: index page */
723 dict_index_t *index, /*!< in: dictionary index of the page */
724 ulint pr_n); /*!< in: print n first and n last entries */
725/** Prints the info in a page header. */
726void page_header_print(const page_t *page); /*!< in: index page */
727/** This is used to print the contents of the page for
728 debugging purposes. */
729void page_print(buf_block_t *block, /*!< in: index page */
730 dict_index_t *index, /*!< in: dictionary index of the page */
731 ulint dn, /*!< in: print dn first and last entries
732 in directory */
733 ulint rn); /*!< in: print rn first and last records
734 in directory */
735#endif /* UNIV_BTR_PRINT */
736#endif /* !UNIV_HOTBACKUP */
737/** The following is used to validate a record on a page. This function
738 differs from rec_validate as it can also check the n_owned field and
739 the heap_no field.
740 @return true if ok */
742 const rec_t *rec, /*!< in: physical record */
743 const ulint *offsets); /*!< in: array returned by rec_get_offsets() */
744#ifdef UNIV_DEBUG
745/** Checks that the first directory slot points to the infimum record and
746 the last to the supremum. This function is intended to track if the
747 bug fixed in 4.0.14 has caused corruption to users' databases. */
748void page_check_dir(const page_t *page); /*!< in: index page */
749#endif /* UNIV_DEBUG */
750/** This function checks the consistency of an index page when we do not
751 know the index. This is also resilient so that this should never crash
752 even if the page is total garbage.
753 @return true if ok */
755 const page_t *page); /*!< in: index page in ROW_FORMAT=REDUNDANT */
756/** This function checks the consistency of an index page when we do not
757 know the index. This is also resilient so that this should never crash
758 even if the page is total garbage.
759 @return true if ok */
761 const page_t *page); /*!< in: index page in ROW_FORMAT!=REDUNDANT */
762/** This function checks the consistency of an index page.
763 @return true if ok */
764bool page_validate(
765 const page_t *page, /*!< in: index page */
766 dict_index_t *index); /*!< in: data dictionary index containing
767 the page record type definition */
768/** Looks in the page record list for a record with the given heap number.
769 @return record, NULL if not found */
771 const page_t *page, /*!< in: index page */
772 ulint heap_no); /*!< in: heap number */
773/** Get the last non-delete-marked record on a page.
774@param[in] page index tree leaf page
775@return the last record, not delete-marked
776@retval infimum record if all records are delete-marked */
778
779/** Issue a warning when the checksum that is stored in the page is valid,
780but different than the global setting innodb_checksum_algorithm.
781@param[in] curr_algo current checksum algorithm
782@param[in] page_checksum page valid checksum
783@param[in] page_id page identifier */
785 srv_checksum_algorithm_t page_checksum,
786 const page_id_t &page_id);
787
788/** Check that a page_size is correct for InnoDB.
789If correct, set the associated page_size_shift which is the power of 2
790for this page size.
791@param[in] page_size Page Size to evaluate
792@return an associated page_size_shift if valid, 0 if invalid. */
793inline ulong page_size_validate(ulong page_size);
794
795/** This function checks if the page in which record is present is a
796non-leaf node of a spatial index.
797param[in] rec Btree record
798param[in] index index
799@return true if ok */
800bool page_is_spatial_non_leaf(const rec_t *rec, dict_index_t *index);
801
802#include "page0page.ic"
803
804#endif
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:50
uint32_t page_no_t
Page number.
Definition: api0api.h:48
The database buffer pool high-level routines.
srv_checksum_algorithm_t
Alternatives for srv_checksum_algorithm, which can be changed by setting innodb_checksum_algorithm.
Definition: buf0types.h:114
Page identifier.
Definition: buf0types.h:206
int page
Definition: ctype-mb.cc:1235
SQL data field and tuple.
Data dictionary system.
The low-level file system.
uint16_t page_type_t
Definition: fil0fil.h:1184
constexpr uint32_t FIL_PAGE_DATA_END
size of the page trailer
Definition: fil0types.h:118
File space management.
uint32_t node_seq_t
Definition: gis0type.h:57
Mini-transaction buffer.
mlog_id_t
Definition: mtr0types.h:62
void page_delete_rec_list_end(rec_t *rec, buf_block_t *block, dict_index_t *index, ulint n_recs, ulint size, mtr_t *mtr)
Deletes records from a page from a given record onward, including that record.
Definition: page0page.cc:873
byte page_dir_slot_t
Definition: page0page.h:54
page_t * page_create_zip(buf_block_t *block, dict_index_t *index, ulint level, trx_id_t max_trx_id, mtr_t *mtr, page_type_t page_type)
Create a compressed B-tree index page.
Definition: page0page.cc:390
void page_set_max_trx_id(buf_block_t *block, page_zip_des_t *page_zip, trx_id_t trx_id, mtr_t *mtr)
Sets the max trx id field value.
Definition: page0page.cc:196
static const byte supremum_extra_data[]
Extra bytes and data bytes of a supremum record.
Definition: page0page.h:89
static ulint page_header_get_offs(const page_t *page, ulint field)
Returns the offset stored in the given header field.
constexpr uint32_t PAGE_DIR_SLOT_MAX_N_OWNED
Definition: page0page.h:72
static bool page_rec_is_comp(const rec_t *rec)
true if the record is on a page in compact format.
static void page_header_reset_last_insert(page_t *page, page_zip_des_t *page_zip, mtr_t *mtr)
Resets the last insert info field in the page header.
static rec_t * page_rec_get_prev(rec_t *rec)
Gets the pointer to the previous record.
static const rec_t * page_rec_get_prev_const(const rec_t *rec)
Gets the pointer to the previous record.
static void page_dir_slot_set_rec(page_dir_slot_t *slot, rec_t *rec)
This is used to set the record offset in a directory slot.
static rec_t * page_rec_get_nth(page_t *page, ulint nth)
Returns the nth record of the record list.
static bool page_rec_is_supremum(const rec_t *rec)
true if the record is the supremum record on a page.
static void page_dir_set_n_heap(page_t *page, page_zip_des_t *page_zip, ulint n_heap)
Sets the number of records in the heap.
void page_create_empty(buf_block_t *block, dict_index_t *index, mtr_t *mtr)
Empty a previously created B-tree index page.
Definition: page0page.cc:429
static rec_t * page_rec_get_next(rec_t *rec)
Gets the pointer to the next record on the page.
ulint page_dir_find_owner_slot(const rec_t *rec)
Looks for the directory slot which owns the given record.
Definition: page0page.cc:93
constexpr uint32_t PAGE_DIR_SLOT_SIZE
Definition: page0page.h:63
static void page_dir_set_n_slots(page_t *page, page_zip_des_t *page_zip, ulint n_slots)
Sets the number of dir slots in directory.
static bool page_rec_is_first(const rec_t *rec, const page_t *page)
true if the record is the first user record on a page.
static bool page_is_empty(const page_t *page)
Determine whether the page is empty.
ulint page_rec_get_n_recs_before(const rec_t *rec)
Returns the number of records before the given record in chain.
Definition: page0page.cc:1455
static ulint page_get_free_space_of_empty(bool comp)
Calculates free space if a page is emptied.
void page_check_dir(const page_t *page)
Checks that the first directory slot points to the infimum record and the last to the supremum.
Definition: page0page.cc:1722
static void page_update_max_trx_id(buf_block_t *block, page_zip_des_t *page_zip, trx_id_t trx_id, mtr_t *mtr)
Sets the max trx id field value if trx_id is bigger than the previous value.
static bool page_rec_check(const rec_t *rec)
Used to check the consistency of a record on a page.
constexpr uint32_t PAGE_DIR_SLOT_MIN_N_OWNED
Definition: page0page.h:73
static uint16_t page_dir_get_n_heap(const page_t *page)
Gets the number of records in the heap.
void page_dir_balance_slot(page_t *page, page_zip_des_t *page_zip, ulint slot_no)
Tries to balance the given directory slot with too few records with the upper neighbor,...
Definition: page0page.cc:1346
page_dir_slot_t page_dir_t
Definition: page0page.h:55
static const byte infimum_extra[]
Extra bytes of an infimum record.
Definition: page0page.h:79
rec_t * page_copy_rec_list_end(buf_block_t *new_block, buf_block_t *block, rec_t *rec, dict_index_t *index, mtr_t *mtr)
Copies records from page to new_page, from the given record onward, including that record.
Definition: page0page.cc:530
bool page_move_rec_list_end(buf_block_t *new_block, buf_block_t *block, rec_t *split_rec, dict_index_t *index, mtr_t *mtr)
Moves record list end to another page.
Definition: page0page.cc:1143
bool page_is_spatial_non_leaf(const rec_t *rec, dict_index_t *index)
This function checks if the page in which record is present is a non-leaf node of a spatial index.
Definition: page0page.cc:2115
static uint16_t page_header_get_field(const page_t *page, ulint field)
Reads the given header field.
static void page_dir_slot_set_n_owned(page_dir_slot_t *slot, page_zip_des_t *page_zip, ulint n)
This is used to set the owned records field of a directory slot.
void page_parse_create(buf_block_t *block, ulint comp, page_type_t page_type)
Parses a redo log record of creating a page.
Definition: page0page.cc:362
static bool page_rec_is_supremum_low(ulint offset)
true if the record is the supremum record on a page.
static bool page_rec_is_user_rec_low(ulint offset)
true if the record is a user record on the page.
static bool page_rec_is_infimum_low(ulint offset)
true if the record is the infimum record on a page.
static ulint page_dir_calc_reserved_space(ulint n_recs)
Calculates the space reserved for directory slots of a given number of records.
bool page_rec_validate(const rec_t *rec, const ulint *offsets)
The following is used to validate a record on a page.
Definition: page0page.cc:1679
static rec_t * page_get_middle_rec(page_t *page)
Returns the middle record of the records on the page.
static void page_mem_alloc_free(page_t *page, page_zip_des_t *page_zip, rec_t *next_rec, ulint need)
Allocates a block of memory from the head of the free list of an index page.
static bool page_rec_is_second(const rec_t *rec, const page_t *page)
true if the record is the second user record on a page.
static ulint page_get_max_insert_size(const page_t *page, ulint n_recs)
Returns the maximum combined size of records which can be inserted on top of record heap.
static byte * page_header_get_ptr(page_t *page, uint32_t field)
Returns the pointer stored in the given header field, or NULL.
Definition: page0page.h:173
void page_warn_strict_checksum(srv_checksum_algorithm_t curr_algo, srv_checksum_algorithm_t page_checksum, const page_id_t &page_id)
Issue a warning when the checksum that is stored in the page is valid, but different than the global ...
Definition: page0page.cc:2571
static bool page_rec_is_infimum(const rec_t *rec)
true if the record is the infimum record on a page.
void page_copy_rec_list_end_no_locks(buf_block_t *new_block, buf_block_t *block, rec_t *rec, dict_index_t *index, mtr_t *mtr)
Differs from page_copy_rec_list_end, because this function does not touch the lock table and max trx ...
Definition: page0page.cc:466
static bool page_is_root(const page_t *page)
Determine whether a page is an index root page.
void page_dir_split_slot(page_t *page, page_zip_des_t *page_zip, ulint slot_no)
Splits a directory slot which owns too many records.
Definition: page0page.cc:1288
bool page_simple_validate_new(const page_t *page)
This function checks the consistency of an index page when we do not know the index.
Definition: page0page.cc:1932
static page_no_t page_get_page_no(const page_t *page)
Gets the page number.
static page_dir_slot_t * page_dir_get_nth_slot(const page_t *page, ulint n)
Gets pointer to nth directory slot.
static ulint page_dir_slot_get_n_owned(const page_dir_slot_t *slot)
Gets the number of records owned by a directory slot.
void page_delete_rec_list_start(rec_t *rec, buf_block_t *block, dict_index_t *index, mtr_t *mtr)
Deletes records from page, up to the given record, NOT including that record.
Definition: page0page.cc:1068
static page_id_t page_get_page_id(const page_t *page)
Gets the space id and page number identifying the page.
static const rec_t * page_dir_slot_get_rec(const page_dir_slot_t *slot)
Gets the record pointed to by a directory slot.
static void page_rec_set_next(rec_t *rec, const rec_t *next)
Sets the pointer to the next record on the page.
static bool page_rec_is_last(const rec_t *rec, const page_t *page)
true if the record is the last user record on a page.
static bool page_rec_is_second_last(const rec_t *rec, const page_t *page)
true if the record is the second last user record on a page.
static ulint page_get_max_insert_size_after_reorganize(const page_t *page, ulint n_recs)
Returns the maximum combined size of records which can be inserted on top of record heap if page is f...
static ulint page_rec_get_heap_no(const rec_t *rec)
Returns the heap number of a record.
static trx_id_t page_get_max_trx_id(const page_t *page)
Returns the max trx id field value.
static ulint page_offset(const void *ptr)
Gets the offset within a page.
static void page_mem_free(page_t *page, page_zip_des_t *page_zip, rec_t *rec, const dict_index_t *index, const ulint *offsets)
Puts a record to free list.
static ulint page_get_n_recs(const page_t *page)
Gets the number of user records on page (the infimum and supremum records are not user records).
void page_rec_print(const rec_t *rec, const ulint *offsets)
Prints record contents including the data relevant only in the index page context.
Definition: page0page.cc:1514
static void page_header_set_ptr(page_t *page, page_zip_des_t *page_zip, ulint field, const byte *ptr)
Sets the pointer stored in the given header field.
const rec_t * page_find_rec_with_heap_no(const page_t *page, ulint heap_no)
Looks in the page record list for a record with the given heap number.
Definition: page0page.cc:2458
static ulint page_get_infimum_offset(const page_t *page)
Gets the offset of the first record on the page.
static ulint page_get_data_size(const page_t *page)
Returns the sum of the sizes of the records in the record list excluding the infimum and supremum rec...
bool page_move_rec_list_start(buf_block_t *new_block, buf_block_t *block, rec_t *split_rec, dict_index_t *index, mtr_t *mtr)
Moves record list start to another page.
Definition: page0page.cc:1196
static node_seq_t page_get_ssn_id(const page_t *page)
Returns the RTREE SPLIT SEQUENCE NUMBER (FIL_RTREE_SPLIT_SEQ_NUM).
static const rec_t * page_rec_get_next_low(const rec_t *rec, ulint comp)
Gets the pointer to the next record on the page.
static void page_header_set_field(page_t *page, page_zip_des_t *page_zip, ulint field, ulint val)
Sets the given header field.
rec_t * page_copy_rec_list_start(buf_block_t *new_block, buf_block_t *block, rec_t *rec, dict_index_t *index, mtr_t *mtr)
Copies records from page to new_page, up to the given record, NOT including that record.
Definition: page0page.cc:667
static ulint page_get_supremum_offset(const page_t *page)
Gets the offset of the last record on the page.
const rec_t * page_rec_get_nth_const(const page_t *page, ulint nth)
Returns the nth record of the record list.
Definition: page0page.cc:1408
static const rec_t * page_rec_get_next_non_del_marked(const rec_t *rec)
Gets the pointer to the next non delete-marked record on the page.
static ulint page_rec_get_base_extra_size(const rec_t *rec)
Returns the base extra size of a physical record.
static bool page_is_comp(const page_t *page)
Determine whether the page is in new-style compact format.
static const byte infimum_data[]
Data bytes of an infimum record.
Definition: page0page.h:85
static bool page_has_garbage(const page_t *page)
Determine whether the page contains garbage.
static space_id_t page_get_space_id(const page_t *page)
Gets the tablespace identifier.
const rec_t * page_find_rec_last_not_deleted(const page_t *page)
Get the last non-delete-marked record on a page.
Definition: page0page.cc:2541
static ulint page_dir_get_n_slots(const page_t *page)
Gets the number of dir slots in directory.
static bool page_rec_is_user_rec(const rec_t *rec)
true if the record is a user record on the page.
static bool page_rec_distance_is_at_most(const rec_t *left_rec, const rec_t *right_rec, ulint val)
true if distance between the records (measured in number of times we have to move to the next record)...
bool page_validate(const page_t *page, dict_index_t *index)
This function checks the consistency of an index page.
Definition: page0page.cc:2121
byte * page_parse_delete_rec_list(mlog_id_t type, byte *ptr, byte *end_ptr, buf_block_t *block, dict_index_t *index, mtr_t *mtr)
Parses a log record of a record list end or start deletion.
Definition: page0page.cc:823
static byte * page_get_infimum_rec(byte *page)
Definition: page0page.h:217
constexpr uint32_t PAGE_DIR
Definition: page0page.h:60
bool page_simple_validate_old(const page_t *page)
This function checks the consistency of an index page when we do not know the index.
Definition: page0page.cc:1751
page_t * page_create(buf_block_t *block, mtr_t *mtr, ulint comp, page_type_t page_type)
Create an uncompressed B-tree or R-tree or SDI index page.
Definition: page0page.cc:374
constexpr uint32_t PAGE_EMPTY_DIR_START
Definition: page0page.h:67
static rec_t * page_rec_find_owner_rec(rec_t *rec)
Looks for the record which owns the given record.
ulong page_size_validate(ulong page_size)
Check that a page_size is correct for InnoDB.
Definition: page0page.ic:926
static page_t * page_align(const void *ptr)
Gets the start of a page.
static bool page_is_leaf(const page_t *page)
Determine whether the page is a B-tree leaf.
static void page_set_ssn_id(buf_block_t *block, page_zip_des_t *page_zip, node_seq_t ssn_id, mtr_t *mtr)
Sets the RTREE SPLIT SEQUENCE NUMBER field value.
static byte * page_get_supremum_rec(byte *page)
Definition: page0page.h:223
byte * page_mem_alloc_heap(page_t *page, page_zip_des_t *page_zip, ulint need, ulint *heap_no)
Allocates a block of memory from the heap of an index page.
Definition: page0page.cc:222
static const rec_t * page_rec_get_next_const(const rec_t *rec)
Gets the pointer to the next record on the page.
Index page routines.
Index page routines.
byte page_t
Type of the index page.
Definition: page0types.h:151
Record manager.
byte rec_t
Definition: rem0types.h:40
required string type
Definition: replication_group_member_actions.proto:33
The buffer control block structure.
Definition: buf0buf.h:1664
Data structure for an index.
Definition: dict0mem.h:1021
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:181
Compressed page descriptor.
Definition: page0types.h:199
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:137
Version control for database, common definitions, and include files.
unsigned long int ulint
Definition: univ.i:407
int n
Definition: xcom_base.cc:505