1
/*****************************************************************************
3
Copyright (C) 1994, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/page0page.h
23
Created 2/2/1994 Heikki Tuuri
24
*******************************************************/
32
#include "page0types.h"
35
#include "data0data.h"
36
#include "dict0dict.h"
41
#ifdef UNIV_MATERIALIZE
49
Index page header starts at the first offset left free by the FIL-module */
51
typedef byte page_header_t;
53
#define PAGE_HEADER FSEG_PAGE_DATA /* index page header starts at this
55
/*-----------------------------*/
56
#define PAGE_N_DIR_SLOTS 0 /* number of slots in page directory */
57
#define PAGE_HEAP_TOP 2 /* pointer to record heap top */
58
#define PAGE_N_HEAP 4 /* number of records in the heap,
59
bit 15=flag: new-style compact page format */
60
#define PAGE_FREE 6 /* pointer to start of page free record list */
61
#define PAGE_GARBAGE 8 /* number of bytes in deleted records */
62
#define PAGE_LAST_INSERT 10 /* pointer to the last inserted record, or
63
NULL if this info has been reset by a delete,
65
#define PAGE_DIRECTION 12 /* last insert direction: PAGE_LEFT, ... */
66
#define PAGE_N_DIRECTION 14 /* number of consecutive inserts to the same
68
#define PAGE_N_RECS 16 /* number of user records on the page */
69
#define PAGE_MAX_TRX_ID 18 /* highest id of a trx which may have modified
70
a record on the page; trx_id_t; defined only
71
in secondary indexes and in the insert buffer
72
tree; NOTE: this may be modified only
73
when the thread has an x-latch to the page,
74
and ALSO an x-latch to btr_search_latch
75
if there is a hash index to the page! */
76
#define PAGE_HEADER_PRIV_END 26 /* end of private data structure of the page
77
header which are set in a page create */
79
#define PAGE_LEVEL 26 /* level of the node in an index tree; the
80
leaf level is the level 0. This field should
81
not be written to after page creation. */
82
#define PAGE_INDEX_ID 28 /* index id where the page belongs.
83
This field should not be written to after
85
#define PAGE_BTR_SEG_LEAF 36 /* file segment header for the leaf pages in
86
a B-tree: defined only on the root page of a
87
B-tree, but not in the root of an ibuf tree */
88
#define PAGE_BTR_IBUF_FREE_LIST PAGE_BTR_SEG_LEAF
89
#define PAGE_BTR_IBUF_FREE_LIST_NODE PAGE_BTR_SEG_LEAF
90
/* in the place of PAGE_BTR_SEG_LEAF and _TOP
91
there is a free list base node if the page is
92
the root page of an ibuf tree, and at the same
93
place is the free list node if the page is in
95
#define PAGE_BTR_SEG_TOP (36 + FSEG_HEADER_SIZE)
96
/* file segment header for the non-leaf pages
97
in a B-tree: defined only on the root page of
98
a B-tree, but not in the root of an ibuf
101
#define PAGE_DATA (PAGE_HEADER + 36 + 2 * FSEG_HEADER_SIZE)
102
/* start of data on the page */
104
#define PAGE_OLD_INFIMUM (PAGE_DATA + 1 + REC_N_OLD_EXTRA_BYTES)
105
/* offset of the page infimum record on an
107
#define PAGE_OLD_SUPREMUM (PAGE_DATA + 2 + 2 * REC_N_OLD_EXTRA_BYTES + 8)
108
/* offset of the page supremum record on an
110
#define PAGE_OLD_SUPREMUM_END (PAGE_OLD_SUPREMUM + 9)
111
/* offset of the page supremum record end on
113
#define PAGE_NEW_INFIMUM (PAGE_DATA + REC_N_NEW_EXTRA_BYTES)
114
/* offset of the page infimum record on a
115
new-style compact page */
116
#define PAGE_NEW_SUPREMUM (PAGE_DATA + 2 * REC_N_NEW_EXTRA_BYTES + 8)
117
/* offset of the page supremum record on a
118
new-style compact page */
119
#define PAGE_NEW_SUPREMUM_END (PAGE_NEW_SUPREMUM + 8)
120
/* offset of the page supremum record end on
121
a new-style compact page */
122
/*-----------------------------*/
125
#define PAGE_HEAP_NO_INFIMUM 0 /* page infimum */
126
#define PAGE_HEAP_NO_SUPREMUM 1 /* page supremum */
127
#define PAGE_HEAP_NO_USER_LOW 2 /* first user record in
128
creation (insertion) order,
129
not necessarily collation order;
130
this record may have been deleted */
132
/* Directions of cursor movement */
135
#define PAGE_SAME_REC 3
136
#define PAGE_SAME_PAGE 4
137
#define PAGE_NO_DIRECTION 5
143
typedef byte page_dir_slot_t;
144
typedef page_dir_slot_t page_dir_t;
146
/* Offset of the directory start down from the page end. We call the
147
slot with the highest file address directory start, as it points to
148
the first record in the list of records. */
149
#define PAGE_DIR FIL_PAGE_DATA_END
151
/* We define a slot in the page directory as two bytes */
152
#define PAGE_DIR_SLOT_SIZE 2
154
/* The offset of the physically lower end of the directory, counted from
155
page end, when the page is empty */
156
#define PAGE_EMPTY_DIR_START (PAGE_DIR + 2 * PAGE_DIR_SLOT_SIZE)
158
/* The maximum and minimum number of records owned by a directory slot. The
159
number may drop below the minimum in the first and the last slot in the
161
#define PAGE_DIR_SLOT_MAX_N_OWNED 8
162
#define PAGE_DIR_SLOT_MIN_N_OWNED 4
164
/************************************************************//**
165
Gets the start of a page.
166
@return start of the page */
171
const void* ptr) /*!< in: pointer to page frame */
172
__attribute__((const));
173
/************************************************************//**
174
Gets the offset within a page.
175
@return offset from the start of the page */
180
const void* ptr) /*!< in: pointer to page frame */
181
__attribute__((const));
182
/*************************************************************//**
183
Returns the max trx id field value. */
188
const page_t* page); /*!< in: page */
189
/*************************************************************//**
190
Sets the max trx id field value. */
195
buf_block_t* block, /*!< in/out: page */
196
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
197
trx_id_t trx_id, /*!< in: transaction id */
198
mtr_t* mtr); /*!< in/out: mini-transaction, or NULL */
199
/*************************************************************//**
200
Sets the max trx id field value if trx_id is bigger than the previous
204
page_update_max_trx_id(
205
/*===================*/
206
buf_block_t* block, /*!< in/out: page */
207
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
208
uncompressed part will be updated, or NULL */
209
trx_id_t trx_id, /*!< in: transaction id */
210
mtr_t* mtr); /*!< in/out: mini-transaction */
211
/*************************************************************//**
212
Reads the given header field. */
215
page_header_get_field(
216
/*==================*/
217
const page_t* page, /*!< in: page */
218
ulint field); /*!< in: PAGE_N_DIR_SLOTS, ... */
219
/*************************************************************//**
220
Sets the given header field. */
223
page_header_set_field(
224
/*==================*/
225
page_t* page, /*!< in/out: page */
226
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
227
uncompressed part will be updated, or NULL */
228
ulint field, /*!< in: PAGE_N_DIR_SLOTS, ... */
229
ulint val); /*!< in: value */
230
/*************************************************************//**
231
Returns the offset stored in the given header field.
232
@return offset from the start of the page, or 0 */
235
page_header_get_offs(
236
/*=================*/
237
const page_t* page, /*!< in: page */
238
ulint field) /*!< in: PAGE_FREE, ... */
239
__attribute__((nonnull, pure));
241
/*************************************************************//**
242
Returns the pointer stored in the given header field, or NULL. */
243
#define page_header_get_ptr(page, field) \
244
(page_header_get_offs(page, field) \
245
? page + page_header_get_offs(page, field) : NULL)
246
/*************************************************************//**
247
Sets the pointer stored in the given header field. */
252
page_t* page, /*!< in/out: page */
253
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
254
uncompressed part will be updated, or NULL */
255
ulint field, /*!< in/out: PAGE_FREE, ... */
256
const byte* ptr); /*!< in: pointer or NULL*/
257
#ifndef UNIV_HOTBACKUP
258
/*************************************************************//**
259
Resets the last insert info field in the page header. Writes to mlog
260
about this operation. */
263
page_header_reset_last_insert(
264
/*==========================*/
265
page_t* page, /*!< in: page */
266
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
267
uncompressed part will be updated, or NULL */
268
mtr_t* mtr); /*!< in: mtr */
269
#endif /* !UNIV_HOTBACKUP */
270
/************************************************************//**
271
Gets the offset of the first record on the page.
272
@return offset of the first record in record list, relative from page */
275
page_get_infimum_offset(
276
/*====================*/
277
const page_t* page); /*!< in: page which must have record(s) */
278
/************************************************************//**
279
Gets the offset of the last record on the page.
280
@return offset of the last record in record list, relative from page */
283
page_get_supremum_offset(
284
/*=====================*/
285
const page_t* page); /*!< in: page which must have record(s) */
286
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
287
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
288
/************************************************************//**
289
Returns the middle record of record list. If there are an even number
290
of records in the list, returns the first record of upper half-list.
291
@return middle record */
296
page_t* page); /*!< in: page */
297
#ifndef UNIV_HOTBACKUP
298
/*************************************************************//**
299
Compares a data tuple to a physical record. Differs from the function
300
cmp_dtuple_rec_with_match in the way that the record must reside on an
301
index page, and also page infimum and supremum records can be given in
302
the parameter rec. These are considered as the negative infinity and
303
the positive infinity in the alphabetical order.
304
@return 1, 0, -1, if dtuple is greater, equal, less than rec,
305
respectively, when only the common first fields are compared */
308
page_cmp_dtuple_rec_with_match(
309
/*===========================*/
310
const dtuple_t* dtuple, /*!< in: data tuple */
311
const rec_t* rec, /*!< in: physical record on a page; may also
312
be page infimum or supremum, in which case
313
matched-parameter values below are not
315
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
316
ulint* matched_fields, /*!< in/out: number of already completely
317
matched fields; when function returns
318
contains the value for current comparison */
319
ulint* matched_bytes); /*!< in/out: number of already matched
320
bytes within the first field not completely
321
matched; when function returns contains the
322
value for current comparison */
323
#endif /* !UNIV_HOTBACKUP */
324
/*************************************************************//**
325
Gets the page number.
326
@return page number */
331
const page_t* page); /*!< in: page */
332
/*************************************************************//**
333
Gets the tablespace identifier.
339
const page_t* page); /*!< in: page */
340
/*************************************************************//**
341
Gets the number of user records on page (the infimum and supremum records
342
are not user records).
343
@return number of user records */
348
const page_t* page); /*!< in: index page */
349
/***************************************************************//**
350
Returns the number of records before the given record in chain.
351
The number includes infimum and supremum records.
352
@return number of records */
355
page_rec_get_n_recs_before(
356
/*=======================*/
357
const rec_t* rec); /*!< in: the physical record */
358
/*************************************************************//**
359
Gets the number of records in the heap.
360
@return number of user records */
365
const page_t* page); /*!< in: index page */
366
/*************************************************************//**
367
Sets the number of records in the heap. */
372
page_t* page, /*!< in/out: index page */
373
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
374
uncompressed part will be updated, or NULL.
375
Note that the size of the dense page directory
376
in the compressed page trailer is
377
n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
378
ulint n_heap);/*!< in: number of records */
379
/*************************************************************//**
380
Gets the number of dir slots in directory.
381
@return number of slots */
384
page_dir_get_n_slots(
385
/*=================*/
386
const page_t* page); /*!< in: index page */
387
/*************************************************************//**
388
Sets the number of dir slots in directory. */
391
page_dir_set_n_slots(
392
/*=================*/
393
page_t* page, /*!< in/out: page */
394
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
395
uncompressed part will be updated, or NULL */
396
ulint n_slots);/*!< in: number of slots */
398
/*************************************************************//**
399
Gets pointer to nth directory slot.
400
@return pointer to dir slot */
403
page_dir_get_nth_slot(
404
/*==================*/
405
const page_t* page, /*!< in: index page */
406
ulint n); /*!< in: position */
407
#else /* UNIV_DEBUG */
408
# define page_dir_get_nth_slot(page, n) \
409
((page) + UNIV_PAGE_SIZE - PAGE_DIR \
410
- (n + 1) * PAGE_DIR_SLOT_SIZE)
411
#endif /* UNIV_DEBUG */
412
/**************************************************************//**
413
Used to check the consistency of a record on a page.
414
@return TRUE if succeed */
419
const rec_t* rec); /*!< in: record */
420
/***************************************************************//**
421
Gets the record pointed to by a directory slot.
422
@return pointer to record */
425
page_dir_slot_get_rec(
426
/*==================*/
427
const page_dir_slot_t* slot); /*!< in: directory slot */
428
/***************************************************************//**
429
This is used to set the record offset in a directory slot. */
432
page_dir_slot_set_rec(
433
/*==================*/
434
page_dir_slot_t* slot, /*!< in: directory slot */
435
rec_t* rec); /*!< in: record on the page */
436
/***************************************************************//**
437
Gets the number of records owned by a directory slot.
438
@return number of records */
441
page_dir_slot_get_n_owned(
442
/*======================*/
443
const page_dir_slot_t* slot); /*!< in: page directory slot */
444
/***************************************************************//**
445
This is used to set the owned records field of a directory slot. */
448
page_dir_slot_set_n_owned(
449
/*======================*/
450
page_dir_slot_t*slot, /*!< in/out: directory slot */
451
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
452
ulint n); /*!< in: number of records owned by the slot */
453
/************************************************************//**
454
Calculates the space reserved for directory slots of a given
455
number of records. The exact value is a fraction number
456
n * PAGE_DIR_SLOT_SIZE / PAGE_DIR_SLOT_MIN_N_OWNED, and it is
457
rounded upwards to an integer. */
460
page_dir_calc_reserved_space(
461
/*=========================*/
462
ulint n_recs); /*!< in: number of records */
463
/***************************************************************//**
464
Looks for the directory slot which owns the given record.
465
@return the directory slot number */
468
page_dir_find_owner_slot(
469
/*=====================*/
470
const rec_t* rec); /*!< in: the physical record */
471
/************************************************************//**
472
Determine whether the page is in new-style compact format.
473
@return nonzero if the page is in compact format, zero if it is in
479
const page_t* page); /*!< in: index page */
480
/************************************************************//**
481
TRUE if the record is on a page in compact format.
482
@return nonzero if in compact format */
487
const rec_t* rec); /*!< in: record */
488
/***************************************************************//**
489
Returns the heap number of a record.
490
@return heap number */
493
page_rec_get_heap_no(
494
/*=================*/
495
const rec_t* rec); /*!< in: the physical record */
496
/************************************************************//**
497
Determine whether the page is a B-tree leaf.
498
@return TRUE if the page is a B-tree leaf */
503
const page_t* page) /*!< in: page */
504
__attribute__((nonnull, pure));
505
/************************************************************//**
506
Gets the pointer to the next record on the page.
507
@return pointer to next record */
510
page_rec_get_next_low(
511
/*==================*/
512
const rec_t* rec, /*!< in: pointer to record */
513
ulint comp); /*!< in: nonzero=compact page layout */
514
/************************************************************//**
515
Gets the pointer to the next record on the page.
516
@return pointer to next record */
521
rec_t* rec); /*!< in: pointer to record */
522
/************************************************************//**
523
Gets the pointer to the next record on the page.
524
@return pointer to next record */
527
page_rec_get_next_const(
528
/*====================*/
529
const rec_t* rec); /*!< in: pointer to record */
530
/************************************************************//**
531
Sets the pointer to the next record on the page. */
536
rec_t* rec, /*!< in: pointer to record,
537
must not be page supremum */
538
rec_t* next); /*!< in: pointer to next record,
539
must not be page infimum */
540
/************************************************************//**
541
Gets the pointer to the previous record.
542
@return pointer to previous record */
545
page_rec_get_prev_const(
546
/*====================*/
547
const rec_t* rec); /*!< in: pointer to record, must not be page
549
/************************************************************//**
550
Gets the pointer to the previous record.
551
@return pointer to previous record */
556
rec_t* rec); /*!< in: pointer to record,
557
must not be page infimum */
558
/************************************************************//**
559
TRUE if the record is a user record on the page.
560
@return TRUE if a user record */
563
page_rec_is_user_rec_low(
564
/*=====================*/
565
ulint offset) /*!< in: record offset on page */
566
__attribute__((const));
567
/************************************************************//**
568
TRUE if the record is the supremum record on a page.
569
@return TRUE if the supremum record */
572
page_rec_is_supremum_low(
573
/*=====================*/
574
ulint offset) /*!< in: record offset on page */
575
__attribute__((const));
576
/************************************************************//**
577
TRUE if the record is the infimum record on a page.
578
@return TRUE if the infimum record */
581
page_rec_is_infimum_low(
582
/*====================*/
583
ulint offset) /*!< in: record offset on page */
584
__attribute__((const));
586
/************************************************************//**
587
TRUE if the record is a user record on the page.
588
@return TRUE if a user record */
591
page_rec_is_user_rec(
592
/*=================*/
593
const rec_t* rec) /*!< in: record */
594
__attribute__((const));
595
/************************************************************//**
596
TRUE if the record is the supremum record on a page.
597
@return TRUE if the supremum record */
600
page_rec_is_supremum(
601
/*=================*/
602
const rec_t* rec) /*!< in: record */
603
__attribute__((const));
605
/************************************************************//**
606
TRUE if the record is the infimum record on a page.
607
@return TRUE if the infimum record */
612
const rec_t* rec) /*!< in: record */
613
__attribute__((const));
614
/***************************************************************//**
615
Looks for the record which owns the given record.
616
@return the owner record */
619
page_rec_find_owner_rec(
620
/*====================*/
621
rec_t* rec); /*!< in: the physical record */
622
/***********************************************************************//**
623
This is a low-level operation which is used in a database index creation
624
to update the page number of a created B-tree to a data dictionary
628
page_rec_write_index_page_no(
629
/*=========================*/
630
rec_t* rec, /*!< in: record to update */
631
ulint i, /*!< in: index of the field to update */
632
ulint page_no,/*!< in: value to write */
633
mtr_t* mtr); /*!< in: mtr */
634
/************************************************************//**
635
Returns the maximum combined size of records which can be inserted on top
637
@return maximum combined size for inserted records */
640
page_get_max_insert_size(
641
/*=====================*/
642
const page_t* page, /*!< in: index page */
643
ulint n_recs);/*!< in: number of records */
644
/************************************************************//**
645
Returns the maximum combined size of records which can be inserted on top
646
of record heap if page is first reorganized.
647
@return maximum combined size for inserted records */
650
page_get_max_insert_size_after_reorganize(
651
/*======================================*/
652
const page_t* page, /*!< in: index page */
653
ulint n_recs);/*!< in: number of records */
654
/*************************************************************//**
655
Calculates free space if a page is emptied.
656
@return free space */
659
page_get_free_space_of_empty(
660
/*=========================*/
661
ulint comp) /*!< in: nonzero=compact page format */
662
__attribute__((const));
663
/**********************************************************//**
664
Returns the base extra size of a physical record. This is the
665
size of the fixed header, independent of the record size.
666
@return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
669
page_rec_get_base_extra_size(
670
/*=========================*/
671
const rec_t* rec); /*!< in: physical record */
672
/************************************************************//**
673
Returns the sum of the sizes of the records in the record list
674
excluding the infimum and supremum records.
675
@return data in bytes */
680
const page_t* page); /*!< in: index page */
681
/************************************************************//**
682
Allocates a block of memory from the head of the free list
688
page_t* page, /*!< in/out: index page */
689
page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
690
space available for inserting the record,
692
rec_t* next_rec,/*!< in: pointer to the new head of the
694
ulint need); /*!< in: number of bytes allocated */
695
/************************************************************//**
696
Allocates a block of memory from the heap of an index page.
697
@return pointer to start of allocated buffer, or NULL if allocation fails */
702
page_t* page, /*!< in/out: index page */
703
page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
704
space available for inserting the record,
706
ulint need, /*!< in: total number of bytes needed */
707
ulint* heap_no);/*!< out: this contains the heap number
708
of the allocated record
709
if allocation succeeds */
710
/************************************************************//**
711
Puts a record to free list. */
716
page_t* page, /*!< in/out: index page */
717
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
718
rec_t* rec, /*!< in: pointer to the (origin of) record */
719
dict_index_t* index, /*!< in: index of rec */
720
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
721
/**********************************************************//**
722
Create an uncompressed B-tree index page.
723
@return pointer to the page */
728
buf_block_t* block, /*!< in: a buffer block where the
730
mtr_t* mtr, /*!< in: mini-transaction handle */
731
ulint comp); /*!< in: nonzero=compact page format */
732
/**********************************************************//**
733
Create a compressed B-tree index page.
734
@return pointer to the page */
739
buf_block_t* block, /*!< in/out: a buffer frame where the
741
dict_index_t* index, /*!< in: the index of the page */
742
ulint level, /*!< in: the B-tree level of the page */
743
mtr_t* mtr); /*!< in: mini-transaction handle */
745
/*************************************************************//**
746
Differs from page_copy_rec_list_end, because this function does not
747
touch the lock table and max trx id on page or compress the page. */
750
page_copy_rec_list_end_no_locks(
751
/*============================*/
752
buf_block_t* new_block, /*!< in: index page to copy to */
753
buf_block_t* block, /*!< in: index page of rec */
754
rec_t* rec, /*!< in: record on page */
755
dict_index_t* index, /*!< in: record descriptor */
756
mtr_t* mtr); /*!< in: mtr */
757
/*************************************************************//**
758
Copies records from page to new_page, from the given record onward,
759
including that record. Infimum and supremum records are not copied.
760
The records are copied to the start of the record list on new_page.
761
@return pointer to the original successor of the infimum record on
762
new_page, or NULL on zip overflow (new_block will be decompressed) */
765
page_copy_rec_list_end(
766
/*===================*/
767
buf_block_t* new_block, /*!< in/out: index page to copy to */
768
buf_block_t* block, /*!< in: index page containing rec */
769
rec_t* rec, /*!< in: record on page */
770
dict_index_t* index, /*!< in: record descriptor */
771
mtr_t* mtr) /*!< in: mtr */
772
__attribute__((nonnull));
773
/*************************************************************//**
774
Copies records from page to new_page, up to the given record, NOT
775
including that record. Infimum and supremum records are not copied.
776
The records are copied to the end of the record list on new_page.
777
@return pointer to the original predecessor of the supremum record on
778
new_page, or NULL on zip overflow (new_block will be decompressed) */
781
page_copy_rec_list_start(
782
/*=====================*/
783
buf_block_t* new_block, /*!< in/out: index page to copy to */
784
buf_block_t* block, /*!< in: index page containing rec */
785
rec_t* rec, /*!< in: record on page */
786
dict_index_t* index, /*!< in: record descriptor */
787
mtr_t* mtr) /*!< in: mtr */
788
__attribute__((nonnull));
789
/*************************************************************//**
790
Deletes records from a page from a given record onward, including that record.
791
The infimum and supremum records are not deleted. */
794
page_delete_rec_list_end(
795
/*=====================*/
796
rec_t* rec, /*!< in: pointer to record on page */
797
buf_block_t* block, /*!< in: buffer block of the page */
798
dict_index_t* index, /*!< in: record descriptor */
799
ulint n_recs, /*!< in: number of records to delete,
800
or ULINT_UNDEFINED if not known */
801
ulint size, /*!< in: the sum of the sizes of the
802
records in the end of the chain to
803
delete, or ULINT_UNDEFINED if not known */
804
mtr_t* mtr) /*!< in: mtr */
805
__attribute__((nonnull));
806
/*************************************************************//**
807
Deletes records from page, up to the given record, NOT including
808
that record. Infimum and supremum records are not deleted. */
811
page_delete_rec_list_start(
812
/*=======================*/
813
rec_t* rec, /*!< in: record on page */
814
buf_block_t* block, /*!< in: buffer block of the page */
815
dict_index_t* index, /*!< in: record descriptor */
816
mtr_t* mtr) /*!< in: mtr */
817
__attribute__((nonnull));
818
/*************************************************************//**
819
Moves record list end to another page. Moved records include
821
@return TRUE on success; FALSE on compression failure (new_block will
825
page_move_rec_list_end(
826
/*===================*/
827
buf_block_t* new_block, /*!< in/out: index page where to move */
828
buf_block_t* block, /*!< in: index page from where to move */
829
rec_t* split_rec, /*!< in: first record to move */
830
dict_index_t* index, /*!< in: record descriptor */
831
mtr_t* mtr) /*!< in: mtr */
832
__attribute__((nonnull(1, 2, 4, 5)));
833
/*************************************************************//**
834
Moves record list start to another page. Moved records do not include
836
@return TRUE on success; FALSE on compression failure */
839
page_move_rec_list_start(
840
/*=====================*/
841
buf_block_t* new_block, /*!< in/out: index page where to move */
842
buf_block_t* block, /*!< in/out: page containing split_rec */
843
rec_t* split_rec, /*!< in: first record not to move */
844
dict_index_t* index, /*!< in: record descriptor */
845
mtr_t* mtr) /*!< in: mtr */
846
__attribute__((nonnull(1, 2, 4, 5)));
847
/****************************************************************//**
848
Splits a directory slot which owns too many records. */
853
page_t* page, /*!< in: index page */
854
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
855
uncompressed part will be written, or NULL */
856
ulint slot_no)/*!< in: the directory slot */
857
__attribute__((nonnull(1)));
858
/*************************************************************//**
859
Tries to balance the given directory slot with too few records
860
with the upper neighbor, so that there are at least the minimum number
861
of records owned by the slot; this may result in the merging of
865
page_dir_balance_slot(
866
/*==================*/
867
page_t* page, /*!< in/out: index page */
868
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
869
ulint slot_no)/*!< in: the directory slot */
870
__attribute__((nonnull(1)));
871
/**********************************************************//**
872
Parses a log record of a record list end or start deletion.
873
@return end of log record or NULL */
876
page_parse_delete_rec_list(
877
/*=======================*/
878
byte type, /*!< in: MLOG_LIST_END_DELETE,
879
MLOG_LIST_START_DELETE,
880
MLOG_COMP_LIST_END_DELETE or
881
MLOG_COMP_LIST_START_DELETE */
882
byte* ptr, /*!< in: buffer */
883
byte* end_ptr,/*!< in: buffer end */
884
buf_block_t* block, /*!< in/out: buffer block or NULL */
885
dict_index_t* index, /*!< in: record descriptor */
886
mtr_t* mtr); /*!< in: mtr or NULL */
887
/***********************************************************//**
888
Parses a redo log record of creating a page.
889
@return end of log record or NULL */
894
byte* ptr, /*!< in: buffer */
895
byte* end_ptr,/*!< in: buffer end */
896
ulint comp, /*!< in: nonzero=compact page format */
897
buf_block_t* block, /*!< in: block or NULL */
898
mtr_t* mtr); /*!< in: mtr or NULL */
899
/************************************************************//**
900
Prints record contents including the data relevant only in
901
the index page context. */
906
const rec_t* rec, /*!< in: physical record */
907
const ulint* offsets);/*!< in: record descriptor */
908
/***************************************************************//**
909
This is used to print the contents of the directory for
910
debugging purposes. */
915
page_t* page, /*!< in: index page */
916
ulint pr_n); /*!< in: print n first and n last entries */
917
/***************************************************************//**
918
This is used to print the contents of the page record list for
919
debugging purposes. */
924
buf_block_t* block, /*!< in: index page */
925
dict_index_t* index, /*!< in: dictionary index of the page */
926
ulint pr_n); /*!< in: print n first and n last entries */
927
/***************************************************************//**
928
Prints the info in a page header. */
933
const page_t* page); /*!< in: index page */
934
/***************************************************************//**
935
This is used to print the contents of the page for
936
debugging purposes. */
941
buf_block_t* block, /*!< in: index page */
942
dict_index_t* index, /*!< in: dictionary index of the page */
943
ulint dn, /*!< in: print dn first and last entries
945
ulint rn); /*!< in: print rn first and last records
947
/***************************************************************//**
948
The following is used to validate a record on a page. This function
949
differs from rec_validate as it can also check the n_owned field and
951
@return TRUE if ok */
956
rec_t* rec, /*!< in: physical record */
957
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
958
/***************************************************************//**
959
Checks that the first directory slot points to the infimum record and
960
the last to the supremum. This function is intended to track if the
961
bug fixed in 4.0.14 has caused corruption to users' databases. */
966
const page_t* page); /*!< in: index page */
967
/***************************************************************//**
968
This function checks the consistency of an index page when we do not
969
know the index. This is also resilient so that this should never crash
970
even if the page is total garbage.
971
@return TRUE if ok */
974
page_simple_validate_old(
975
/*=====================*/
976
page_t* page); /*!< in: old-style index page */
977
/***************************************************************//**
978
This function checks the consistency of an index page when we do not
979
know the index. This is also resilient so that this should never crash
980
even if the page is total garbage.
981
@return TRUE if ok */
984
page_simple_validate_new(
985
/*=====================*/
986
page_t* block); /*!< in: new-style index page */
987
/***************************************************************//**
988
This function checks the consistency of an index page.
989
@return TRUE if ok */
994
page_t* page, /*!< in: index page */
995
dict_index_t* index); /*!< in: data dictionary index containing
996
the page record type definition */
997
/***************************************************************//**
998
Looks in the page record list for a record with the given heap number.
999
@return record, NULL if not found */
1002
page_find_rec_with_heap_no(
1003
/*=======================*/
1004
const page_t* page, /*!< in: index page */
1005
ulint heap_no);/*!< in: heap number */
1007
#ifdef UNIV_MATERIALIZE
1009
#define UNIV_INLINE UNIV_INLINE_ORIGINAL
1013
#include "page0page.ic"