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