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
*******************************************************/
31
#include "page0types.h"
34
#include "data0data.h"
35
#include "dict0dict.h"
40
#ifdef UNIV_MATERIALIZE
48
Index page header starts at the first offset left free by the FIL-module */
50
typedef byte page_header_t;
52
#define PAGE_HEADER FSEG_PAGE_DATA /* index page header starts at this
54
/*-----------------------------*/
55
#define PAGE_N_DIR_SLOTS 0 /* number of slots in page directory */
56
#define PAGE_HEAP_TOP 2 /* pointer to record heap top */
57
#define PAGE_N_HEAP 4 /* number of records in the heap,
58
bit 15=flag: new-style compact page format */
59
#define PAGE_FREE 6 /* pointer to start of page free record list */
60
#define PAGE_GARBAGE 8 /* number of bytes in deleted records */
61
#define PAGE_LAST_INSERT 10 /* pointer to the last inserted record, or
62
NULL if this info has been reset by a delete,
64
#define PAGE_DIRECTION 12 /* last insert direction: PAGE_LEFT, ... */
65
#define PAGE_N_DIRECTION 14 /* number of consecutive inserts to the same
67
#define PAGE_N_RECS 16 /* number of user records on the page */
68
#define PAGE_MAX_TRX_ID 18 /* highest id of a trx which may have modified
69
a record on the page; trx_id_t; defined only
70
in secondary indexes and in the insert buffer
71
tree; NOTE: this may be modified only
72
when the thread has an x-latch to the page,
73
and ALSO an x-latch to btr_search_latch
74
if there is a hash index to the page! */
75
#define PAGE_HEADER_PRIV_END 26 /* end of private data structure of the page
76
header which are set in a page create */
78
#define PAGE_LEVEL 26 /* level of the node in an index tree; the
79
leaf level is the level 0. This field should
80
not be written to after page creation. */
81
#define PAGE_INDEX_ID 28 /* index id where the page belongs.
82
This field should not be written to after
84
#define PAGE_BTR_SEG_LEAF 36 /* file segment header for the leaf pages in
85
a B-tree: defined only on the root page of a
86
B-tree, but not in the root of an ibuf tree */
87
#define PAGE_BTR_IBUF_FREE_LIST PAGE_BTR_SEG_LEAF
88
#define PAGE_BTR_IBUF_FREE_LIST_NODE PAGE_BTR_SEG_LEAF
89
/* in the place of PAGE_BTR_SEG_LEAF and _TOP
90
there is a free list base node if the page is
91
the root page of an ibuf tree, and at the same
92
place is the free list node if the page is in
94
#define PAGE_BTR_SEG_TOP (36 + FSEG_HEADER_SIZE)
95
/* file segment header for the non-leaf pages
96
in a B-tree: defined only on the root page of
97
a B-tree, but not in the root of an ibuf
100
#define PAGE_DATA (PAGE_HEADER + 36 + 2 * FSEG_HEADER_SIZE)
101
/* start of data on the page */
103
#define PAGE_OLD_INFIMUM (PAGE_DATA + 1 + REC_N_OLD_EXTRA_BYTES)
104
/* offset of the page infimum record on an
106
#define PAGE_OLD_SUPREMUM (PAGE_DATA + 2 + 2 * REC_N_OLD_EXTRA_BYTES + 8)
107
/* offset of the page supremum record on an
109
#define PAGE_OLD_SUPREMUM_END (PAGE_OLD_SUPREMUM + 9)
110
/* offset of the page supremum record end on
112
#define PAGE_NEW_INFIMUM (PAGE_DATA + REC_N_NEW_EXTRA_BYTES)
113
/* offset of the page infimum record on a
114
new-style compact page */
115
#define PAGE_NEW_SUPREMUM (PAGE_DATA + 2 * REC_N_NEW_EXTRA_BYTES + 8)
116
/* offset of the page supremum record on a
117
new-style compact page */
118
#define PAGE_NEW_SUPREMUM_END (PAGE_NEW_SUPREMUM + 8)
119
/* offset of the page supremum record end on
120
a new-style compact page */
121
/*-----------------------------*/
124
#define PAGE_HEAP_NO_INFIMUM 0 /* page infimum */
125
#define PAGE_HEAP_NO_SUPREMUM 1 /* page supremum */
126
#define PAGE_HEAP_NO_USER_LOW 2 /* first user record in
127
creation (insertion) order,
128
not necessarily collation order;
129
this record may have been deleted */
131
/* Directions of cursor movement */
134
#define PAGE_SAME_REC 3
135
#define PAGE_SAME_PAGE 4
136
#define PAGE_NO_DIRECTION 5
142
typedef byte page_dir_slot_t;
143
typedef page_dir_slot_t page_dir_t;
145
/* Offset of the directory start down from the page end. We call the
146
slot with the highest file address directory start, as it points to
147
the first record in the list of records. */
148
#define PAGE_DIR FIL_PAGE_DATA_END
150
/* We define a slot in the page directory as two bytes */
151
#define PAGE_DIR_SLOT_SIZE 2
153
/* The offset of the physically lower end of the directory, counted from
154
page end, when the page is empty */
155
#define PAGE_EMPTY_DIR_START (PAGE_DIR + 2 * PAGE_DIR_SLOT_SIZE)
157
/* The maximum and minimum number of records owned by a directory slot. The
158
number may drop below the minimum in the first and the last slot in the
160
#define PAGE_DIR_SLOT_MAX_N_OWNED 8
161
#define PAGE_DIR_SLOT_MIN_N_OWNED 4
163
/************************************************************//**
164
Gets the start of a page.
165
@return start of the page */
170
const void* ptr) /*!< in: pointer to page frame */
171
__attribute__((const));
172
/************************************************************//**
173
Gets the offset within a page.
174
@return offset from the start of the page */
179
const void* ptr) /*!< in: pointer to page frame */
180
__attribute__((const));
181
/*************************************************************//**
182
Returns the max trx id field value. */
187
const page_t* page); /*!< in: page */
188
/*************************************************************//**
189
Sets the max trx id field value. */
194
buf_block_t* block, /*!< in/out: page */
195
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
196
trx_id_t trx_id, /*!< in: transaction id */
197
mtr_t* mtr); /*!< in/out: mini-transaction, or NULL */
198
/*************************************************************//**
199
Sets the max trx id field value if trx_id is bigger than the previous
203
page_update_max_trx_id(
204
/*===================*/
205
buf_block_t* block, /*!< in/out: page */
206
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
207
uncompressed part will be updated, or NULL */
208
trx_id_t trx_id, /*!< in: transaction id */
209
mtr_t* mtr); /*!< in/out: mini-transaction */
210
/*************************************************************//**
211
Reads the given header field. */
214
page_header_get_field(
215
/*==================*/
216
const page_t* page, /*!< in: page */
217
ulint field); /*!< in: PAGE_N_DIR_SLOTS, ... */
218
/*************************************************************//**
219
Sets the given header field. */
222
page_header_set_field(
223
/*==================*/
224
page_t* page, /*!< in/out: page */
225
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
226
uncompressed part will be updated, or NULL */
227
ulint field, /*!< in: PAGE_N_DIR_SLOTS, ... */
228
ulint val); /*!< in: value */
229
/*************************************************************//**
230
Returns the offset stored in the given header field.
231
@return offset from the start of the page, or 0 */
234
page_header_get_offs(
235
/*=================*/
236
const page_t* page, /*!< in: page */
237
ulint field) /*!< in: PAGE_FREE, ... */
238
__attribute__((nonnull, pure));
240
/*************************************************************//**
241
Returns the pointer stored in the given header field, or NULL. */
242
#define page_header_get_ptr(page, field) \
243
(page_header_get_offs(page, field) \
244
? page + page_header_get_offs(page, field) : NULL)
245
/*************************************************************//**
246
Sets the pointer stored in the given header field. */
251
page_t* page, /*!< in/out: page */
252
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
253
uncompressed part will be updated, or NULL */
254
ulint field, /*!< in/out: PAGE_FREE, ... */
255
const byte* ptr); /*!< in: pointer or NULL*/
256
#ifndef UNIV_HOTBACKUP
257
/*************************************************************//**
258
Resets the last insert info field in the page header. Writes to mlog
259
about this operation. */
262
page_header_reset_last_insert(
263
/*==========================*/
264
page_t* page, /*!< in: page */
265
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
266
uncompressed part will be updated, or NULL */
267
mtr_t* mtr); /*!< in: mtr */
268
#endif /* !UNIV_HOTBACKUP */
269
/************************************************************//**
270
Gets the offset of the first record on the page.
271
@return offset of the first record in record list, relative from page */
274
page_get_infimum_offset(
275
/*====================*/
276
const page_t* page); /*!< in: page which must have record(s) */
277
/************************************************************//**
278
Gets the offset of the last record on the page.
279
@return offset of the last record in record list, relative from page */
282
page_get_supremum_offset(
283
/*=====================*/
284
const page_t* page); /*!< in: page which must have record(s) */
285
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
286
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
287
/************************************************************//**
288
Returns the middle record of record list. If there are an even number
289
of records in the list, returns the first record of upper half-list.
290
@return middle record */
295
page_t* page); /*!< in: page */
296
#ifndef UNIV_HOTBACKUP
297
/*************************************************************//**
298
Compares a data tuple to a physical record. Differs from the function
299
cmp_dtuple_rec_with_match in the way that the record must reside on an
300
index page, and also page infimum and supremum records can be given in
301
the parameter rec. These are considered as the negative infinity and
302
the positive infinity in the alphabetical order.
303
@return 1, 0, -1, if dtuple is greater, equal, less than rec,
304
respectively, when only the common first fields are compared */
307
page_cmp_dtuple_rec_with_match(
308
/*===========================*/
309
const dtuple_t* dtuple, /*!< in: data tuple */
310
const rec_t* rec, /*!< in: physical record on a page; may also
311
be page infimum or supremum, in which case
312
matched-parameter values below are not
314
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
315
ulint* matched_fields, /*!< in/out: number of already completely
316
matched fields; when function returns
317
contains the value for current comparison */
318
ulint* matched_bytes); /*!< in/out: number of already matched
319
bytes within the first field not completely
320
matched; when function returns contains the
321
value for current comparison */
322
#endif /* !UNIV_HOTBACKUP */
323
/*************************************************************//**
324
Gets the page number.
325
@return page number */
330
const page_t* page); /*!< in: page */
331
/*************************************************************//**
332
Gets the tablespace identifier.
338
const page_t* page); /*!< in: page */
339
/*************************************************************//**
340
Gets the number of user records on page (the infimum and supremum records
341
are not user records).
342
@return number of user records */
347
const page_t* page); /*!< in: index page */
348
/***************************************************************//**
349
Returns the number of records before the given record in chain.
350
The number includes infimum and supremum records.
351
@return number of records */
354
page_rec_get_n_recs_before(
355
/*=======================*/
356
const rec_t* rec); /*!< in: the physical record */
357
/*************************************************************//**
358
Gets the number of records in the heap.
359
@return number of user records */
364
const page_t* page); /*!< in: index page */
365
/*************************************************************//**
366
Sets the number of records in the heap. */
371
page_t* page, /*!< in/out: index page */
372
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
373
uncompressed part will be updated, or NULL.
374
Note that the size of the dense page directory
375
in the compressed page trailer is
376
n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
377
ulint n_heap);/*!< in: number of records */
378
/*************************************************************//**
379
Gets the number of dir slots in directory.
380
@return number of slots */
383
page_dir_get_n_slots(
384
/*=================*/
385
const page_t* page); /*!< in: index page */
386
/*************************************************************//**
387
Sets the number of dir slots in directory. */
390
page_dir_set_n_slots(
391
/*=================*/
392
page_t* page, /*!< in/out: page */
393
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
394
uncompressed part will be updated, or NULL */
395
ulint n_slots);/*!< in: number of slots */
397
/*************************************************************//**
398
Gets pointer to nth directory slot.
399
@return pointer to dir slot */
402
page_dir_get_nth_slot(
403
/*==================*/
404
const page_t* page, /*!< in: index page */
405
ulint n); /*!< in: position */
406
#else /* UNIV_DEBUG */
407
# define page_dir_get_nth_slot(page, n) \
408
((page) + UNIV_PAGE_SIZE - PAGE_DIR \
409
- (n + 1) * PAGE_DIR_SLOT_SIZE)
410
#endif /* UNIV_DEBUG */
411
/**************************************************************//**
412
Used to check the consistency of a record on a page.
413
@return TRUE if succeed */
418
const rec_t* rec); /*!< in: record */
419
/***************************************************************//**
420
Gets the record pointed to by a directory slot.
421
@return pointer to record */
424
page_dir_slot_get_rec(
425
/*==================*/
426
const page_dir_slot_t* slot); /*!< in: directory slot */
427
/***************************************************************//**
428
This is used to set the record offset in a directory slot. */
431
page_dir_slot_set_rec(
432
/*==================*/
433
page_dir_slot_t* slot, /*!< in: directory slot */
434
rec_t* rec); /*!< in: record on the page */
435
/***************************************************************//**
436
Gets the number of records owned by a directory slot.
437
@return number of records */
440
page_dir_slot_get_n_owned(
441
/*======================*/
442
const page_dir_slot_t* slot); /*!< in: page directory slot */
443
/***************************************************************//**
444
This is used to set the owned records field of a directory slot. */
447
page_dir_slot_set_n_owned(
448
/*======================*/
449
page_dir_slot_t*slot, /*!< in/out: directory slot */
450
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
451
ulint n); /*!< in: number of records owned by the slot */
452
/************************************************************//**
453
Calculates the space reserved for directory slots of a given
454
number of records. The exact value is a fraction number
455
n * PAGE_DIR_SLOT_SIZE / PAGE_DIR_SLOT_MIN_N_OWNED, and it is
456
rounded upwards to an integer. */
459
page_dir_calc_reserved_space(
460
/*=========================*/
461
ulint n_recs); /*!< in: number of records */
462
/***************************************************************//**
463
Looks for the directory slot which owns the given record.
464
@return the directory slot number */
467
page_dir_find_owner_slot(
468
/*=====================*/
469
const rec_t* rec); /*!< in: the physical record */
470
/************************************************************//**
471
Determine whether the page is in new-style compact format.
472
@return nonzero if the page is in compact format, zero if it is in
478
const page_t* page); /*!< in: index page */
479
/************************************************************//**
480
TRUE if the record is on a page in compact format.
481
@return nonzero if in compact format */
486
const rec_t* rec); /*!< in: record */
487
/***************************************************************//**
488
Returns the heap number of a record.
489
@return heap number */
492
page_rec_get_heap_no(
493
/*=================*/
494
const rec_t* rec); /*!< in: the physical record */
495
/************************************************************//**
496
Determine whether the page is a B-tree leaf.
497
@return TRUE if the page is a B-tree leaf */
502
const page_t* page) /*!< in: page */
503
__attribute__((nonnull, pure));
504
/************************************************************//**
505
Gets the pointer to the next record on the page.
506
@return pointer to next record */
509
page_rec_get_next_low(
510
/*==================*/
511
const rec_t* rec, /*!< in: pointer to record */
512
ulint comp); /*!< in: nonzero=compact page layout */
513
/************************************************************//**
514
Gets the pointer to the next record on the page.
515
@return pointer to next record */
520
rec_t* rec); /*!< in: pointer to record */
521
/************************************************************//**
522
Gets the pointer to the next record on the page.
523
@return pointer to next record */
526
page_rec_get_next_const(
527
/*====================*/
528
const rec_t* rec); /*!< in: pointer to record */
529
/************************************************************//**
530
Sets the pointer to the next record on the page. */
535
rec_t* rec, /*!< in: pointer to record,
536
must not be page supremum */
537
rec_t* next); /*!< in: pointer to next record,
538
must not be page infimum */
539
/************************************************************//**
540
Gets the pointer to the previous record.
541
@return pointer to previous record */
544
page_rec_get_prev_const(
545
/*====================*/
546
const rec_t* rec); /*!< in: pointer to record, must not be page
548
/************************************************************//**
549
Gets the pointer to the previous record.
550
@return pointer to previous record */
555
rec_t* rec); /*!< in: pointer to record,
556
must not be page infimum */
557
/************************************************************//**
558
TRUE if the record is a user record on the page.
559
@return TRUE if a user record */
562
page_rec_is_user_rec_low(
563
/*=====================*/
564
ulint offset) /*!< in: record offset on page */
565
__attribute__((const));
566
/************************************************************//**
567
TRUE if the record is the supremum record on a page.
568
@return TRUE if the supremum record */
571
page_rec_is_supremum_low(
572
/*=====================*/
573
ulint offset) /*!< in: record offset on page */
574
__attribute__((const));
575
/************************************************************//**
576
TRUE if the record is the infimum record on a page.
577
@return TRUE if the infimum record */
580
page_rec_is_infimum_low(
581
/*====================*/
582
ulint offset) /*!< in: record offset on page */
583
__attribute__((const));
585
/************************************************************//**
586
TRUE if the record is a user record on the page.
587
@return TRUE if a user record */
590
page_rec_is_user_rec(
591
/*=================*/
592
const rec_t* rec) /*!< in: record */
593
__attribute__((const));
594
/************************************************************//**
595
TRUE if the record is the supremum record on a page.
596
@return TRUE if the supremum record */
599
page_rec_is_supremum(
600
/*=================*/
601
const rec_t* rec) /*!< in: record */
602
__attribute__((const));
604
/************************************************************//**
605
TRUE if the record is the infimum record on a page.
606
@return TRUE if the infimum record */
611
const rec_t* rec) /*!< in: record */
612
__attribute__((const));
613
/***************************************************************//**
614
Looks for the record which owns the given record.
615
@return the owner record */
618
page_rec_find_owner_rec(
619
/*====================*/
620
rec_t* rec); /*!< in: the physical record */
621
/***********************************************************************//**
622
This is a low-level operation which is used in a database index creation
623
to update the page number of a created B-tree to a data dictionary
627
page_rec_write_index_page_no(
628
/*=========================*/
629
rec_t* rec, /*!< in: record to update */
630
ulint i, /*!< in: index of the field to update */
631
ulint page_no,/*!< in: value to write */
632
mtr_t* mtr); /*!< in: mtr */
633
/************************************************************//**
634
Returns the maximum combined size of records which can be inserted on top
636
@return maximum combined size for inserted records */
639
page_get_max_insert_size(
640
/*=====================*/
641
const page_t* page, /*!< in: index page */
642
ulint n_recs);/*!< in: number of records */
643
/************************************************************//**
644
Returns the maximum combined size of records which can be inserted on top
645
of record heap if page is first reorganized.
646
@return maximum combined size for inserted records */
649
page_get_max_insert_size_after_reorganize(
650
/*======================================*/
651
const page_t* page, /*!< in: index page */
652
ulint n_recs);/*!< in: number of records */
653
/*************************************************************//**
654
Calculates free space if a page is emptied.
655
@return free space */
658
page_get_free_space_of_empty(
659
/*=========================*/
660
ulint comp) /*!< in: nonzero=compact page format */
661
__attribute__((const));
662
/**********************************************************//**
663
Returns the base extra size of a physical record. This is the
664
size of the fixed header, independent of the record size.
665
@return REC_N_NEW_EXTRA_BYTES or REC_N_OLD_EXTRA_BYTES */
668
page_rec_get_base_extra_size(
669
/*=========================*/
670
const rec_t* rec); /*!< in: physical record */
671
/************************************************************//**
672
Returns the sum of the sizes of the records in the record list
673
excluding the infimum and supremum records.
674
@return data in bytes */
679
const page_t* page); /*!< in: index page */
680
/************************************************************//**
681
Allocates a block of memory from the head of the free list
687
page_t* page, /*!< in/out: index page */
688
page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
689
space available for inserting the record,
691
rec_t* next_rec,/*!< in: pointer to the new head of the
693
ulint need); /*!< in: number of bytes allocated */
694
/************************************************************//**
695
Allocates a block of memory from the heap of an index page.
696
@return pointer to start of allocated buffer, or NULL if allocation fails */
701
page_t* page, /*!< in/out: index page */
702
page_zip_des_t* page_zip,/*!< in/out: compressed page with enough
703
space available for inserting the record,
705
ulint need, /*!< in: total number of bytes needed */
706
ulint* heap_no);/*!< out: this contains the heap number
707
of the allocated record
708
if allocation succeeds */
709
/************************************************************//**
710
Puts a record to free list. */
715
page_t* page, /*!< in/out: index page */
716
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
717
rec_t* rec, /*!< in: pointer to the (origin of) record */
718
dict_index_t* index, /*!< in: index of rec */
719
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
720
/**********************************************************//**
721
Create an uncompressed B-tree index page.
722
@return pointer to the page */
727
buf_block_t* block, /*!< in: a buffer block where the
729
mtr_t* mtr, /*!< in: mini-transaction handle */
730
ulint comp); /*!< in: nonzero=compact page format */
731
/**********************************************************//**
732
Create a compressed B-tree index page.
733
@return pointer to the page */
738
buf_block_t* block, /*!< in/out: a buffer frame where the
740
dict_index_t* index, /*!< in: the index of the page */
741
ulint level, /*!< in: the B-tree level of the page */
742
mtr_t* mtr); /*!< in: mini-transaction handle */
744
/*************************************************************//**
745
Differs from page_copy_rec_list_end, because this function does not
746
touch the lock table and max trx id on page or compress the page. */
749
page_copy_rec_list_end_no_locks(
750
/*============================*/
751
buf_block_t* new_block, /*!< in: index page to copy to */
752
buf_block_t* block, /*!< in: index page of rec */
753
rec_t* rec, /*!< in: record on page */
754
dict_index_t* index, /*!< in: record descriptor */
755
mtr_t* mtr); /*!< in: mtr */
756
/*************************************************************//**
757
Copies records from page to new_page, from the given record onward,
758
including that record. Infimum and supremum records are not copied.
759
The records are copied to the start of the record list on new_page.
760
@return pointer to the original successor of the infimum record on
761
new_page, or NULL on zip overflow (new_block will be decompressed) */
764
page_copy_rec_list_end(
765
/*===================*/
766
buf_block_t* new_block, /*!< in/out: index page to copy to */
767
buf_block_t* block, /*!< in: index page containing rec */
768
rec_t* rec, /*!< in: record on page */
769
dict_index_t* index, /*!< in: record descriptor */
770
mtr_t* mtr) /*!< in: mtr */
771
__attribute__((nonnull));
772
/*************************************************************//**
773
Copies records from page to new_page, up to the given record, NOT
774
including that record. Infimum and supremum records are not copied.
775
The records are copied to the end of the record list on new_page.
776
@return pointer to the original predecessor of the supremum record on
777
new_page, or NULL on zip overflow (new_block will be decompressed) */
780
page_copy_rec_list_start(
781
/*=====================*/
782
buf_block_t* new_block, /*!< in/out: index page to copy to */
783
buf_block_t* block, /*!< in: index page containing rec */
784
rec_t* rec, /*!< in: record on page */
785
dict_index_t* index, /*!< in: record descriptor */
786
mtr_t* mtr) /*!< in: mtr */
787
__attribute__((nonnull));
788
/*************************************************************//**
789
Deletes records from a page from a given record onward, including that record.
790
The infimum and supremum records are not deleted. */
793
page_delete_rec_list_end(
794
/*=====================*/
795
rec_t* rec, /*!< in: pointer to record on page */
796
buf_block_t* block, /*!< in: buffer block of the page */
797
dict_index_t* index, /*!< in: record descriptor */
798
ulint n_recs, /*!< in: number of records to delete,
799
or ULINT_UNDEFINED if not known */
800
ulint size, /*!< in: the sum of the sizes of the
801
records in the end of the chain to
802
delete, or ULINT_UNDEFINED if not known */
803
mtr_t* mtr) /*!< in: mtr */
804
__attribute__((nonnull));
805
/*************************************************************//**
806
Deletes records from page, up to the given record, NOT including
807
that record. Infimum and supremum records are not deleted. */
810
page_delete_rec_list_start(
811
/*=======================*/
812
rec_t* rec, /*!< in: record on page */
813
buf_block_t* block, /*!< in: buffer block of the page */
814
dict_index_t* index, /*!< in: record descriptor */
815
mtr_t* mtr) /*!< in: mtr */
816
__attribute__((nonnull));
817
/*************************************************************//**
818
Moves record list end to another page. Moved records include
820
@return TRUE on success; FALSE on compression failure (new_block will
824
page_move_rec_list_end(
825
/*===================*/
826
buf_block_t* new_block, /*!< in/out: index page where to move */
827
buf_block_t* block, /*!< in: index page from where to move */
828
rec_t* split_rec, /*!< in: first record to move */
829
dict_index_t* index, /*!< in: record descriptor */
830
mtr_t* mtr) /*!< in: mtr */
831
__attribute__((nonnull(1, 2, 4, 5)));
832
/*************************************************************//**
833
Moves record list start to another page. Moved records do not include
835
@return TRUE on success; FALSE on compression failure */
838
page_move_rec_list_start(
839
/*=====================*/
840
buf_block_t* new_block, /*!< in/out: index page where to move */
841
buf_block_t* block, /*!< in/out: page containing split_rec */
842
rec_t* split_rec, /*!< in: first record not to move */
843
dict_index_t* index, /*!< in: record descriptor */
844
mtr_t* mtr) /*!< in: mtr */
845
__attribute__((nonnull(1, 2, 4, 5)));
846
/****************************************************************//**
847
Splits a directory slot which owns too many records. */
852
page_t* page, /*!< in: index page */
853
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
854
uncompressed part will be written, or NULL */
855
ulint slot_no)/*!< in: the directory slot */
856
__attribute__((nonnull(1)));
857
/*************************************************************//**
858
Tries to balance the given directory slot with too few records
859
with the upper neighbor, so that there are at least the minimum number
860
of records owned by the slot; this may result in the merging of
864
page_dir_balance_slot(
865
/*==================*/
866
page_t* page, /*!< in/out: index page */
867
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
868
ulint slot_no)/*!< in: the directory slot */
869
__attribute__((nonnull(1)));
870
/**********************************************************//**
871
Parses a log record of a record list end or start deletion.
872
@return end of log record or NULL */
875
page_parse_delete_rec_list(
876
/*=======================*/
877
byte type, /*!< in: MLOG_LIST_END_DELETE,
878
MLOG_LIST_START_DELETE,
879
MLOG_COMP_LIST_END_DELETE or
880
MLOG_COMP_LIST_START_DELETE */
881
byte* ptr, /*!< in: buffer */
882
byte* end_ptr,/*!< in: buffer end */
883
buf_block_t* block, /*!< in/out: buffer block or NULL */
884
dict_index_t* index, /*!< in: record descriptor */
885
mtr_t* mtr); /*!< in: mtr or NULL */
886
/***********************************************************//**
887
Parses a redo log record of creating a page.
888
@return end of log record or NULL */
893
byte* ptr, /*!< in: buffer */
894
byte* end_ptr,/*!< in: buffer end */
895
ulint comp, /*!< in: nonzero=compact page format */
896
buf_block_t* block, /*!< in: block or NULL */
897
mtr_t* mtr); /*!< in: mtr or NULL */
898
/************************************************************//**
899
Prints record contents including the data relevant only in
900
the index page context. */
905
const rec_t* rec, /*!< in: physical record */
906
const ulint* offsets);/*!< in: record descriptor */
907
/***************************************************************//**
908
This is used to print the contents of the directory for
909
debugging purposes. */
914
page_t* page, /*!< in: index page */
915
ulint pr_n); /*!< in: print n first and n last entries */
916
/***************************************************************//**
917
This is used to print the contents of the page record list for
918
debugging purposes. */
923
buf_block_t* block, /*!< in: index page */
924
dict_index_t* index, /*!< in: dictionary index of the page */
925
ulint pr_n); /*!< in: print n first and n last entries */
926
/***************************************************************//**
927
Prints the info in a page header. */
932
const page_t* page); /*!< in: index page */
933
/***************************************************************//**
934
This is used to print the contents of the page for
935
debugging purposes. */
940
buf_block_t* block, /*!< in: index page */
941
dict_index_t* index, /*!< in: dictionary index of the page */
942
ulint dn, /*!< in: print dn first and last entries
944
ulint rn); /*!< in: print rn first and last records
946
/***************************************************************//**
947
The following is used to validate a record on a page. This function
948
differs from rec_validate as it can also check the n_owned field and
950
@return TRUE if ok */
955
rec_t* rec, /*!< in: physical record */
956
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
957
/***************************************************************//**
958
Checks that the first directory slot points to the infimum record and
959
the last to the supremum. This function is intended to track if the
960
bug fixed in 4.0.14 has caused corruption to users' databases. */
965
const page_t* page); /*!< in: index page */
966
/***************************************************************//**
967
This function checks the consistency of an index page when we do not
968
know the index. This is also resilient so that this should never crash
969
even if the page is total garbage.
970
@return TRUE if ok */
973
page_simple_validate_old(
974
/*=====================*/
975
page_t* page); /*!< in: old-style index page */
976
/***************************************************************//**
977
This function checks the consistency of an index page when we do not
978
know the index. This is also resilient so that this should never crash
979
even if the page is total garbage.
980
@return TRUE if ok */
983
page_simple_validate_new(
984
/*=====================*/
985
page_t* block); /*!< in: new-style index page */
986
/***************************************************************//**
987
This function checks the consistency of an index page.
988
@return TRUE if ok */
993
page_t* page, /*!< in: index page */
994
dict_index_t* index); /*!< in: data dictionary index containing
995
the page record type definition */
996
/***************************************************************//**
997
Looks in the page record list for a record with the given heap number.
998
@return record, NULL if not found */
1001
page_find_rec_with_heap_no(
1002
/*=======================*/
1003
const page_t* page, /*!< in: index page */
1004
ulint heap_no);/*!< in: heap number */
1006
#ifdef UNIV_MATERIALIZE
1008
#define UNIV_INLINE UNIV_INLINE_ORIGINAL
1012
#include "page0page.ic"