59
58
page_update_max_trx_id(
60
59
/*===================*/
61
buf_block_t* block, /* in/out: page */
62
page_zip_des_t* page_zip,/* in/out: compressed page whose
63
uncompressed part will be updated, or NULL */
64
dulint trx_id) /* in: transaction id */
60
page_t* page, /* in: page */
61
dulint trx_id) /* in: transaction id */
68
if (ut_dulint_cmp(page_get_max_trx_id(buf_block_get_frame(block)),
71
page_set_max_trx_id(block, page_zip, trx_id);
65
if (ut_dulint_cmp(page_get_max_trx_id(page), trx_id) < 0) {
67
page_set_max_trx_id(page, trx_id);
79
75
page_header_get_field(
80
76
/*==================*/
81
const page_t* page, /* in: page */
82
ulint field) /* in: PAGE_LEVEL, ... */
77
page_t* page, /* in: page */
78
ulint field) /* in: PAGE_LEVEL, ... */
85
81
ut_ad(field <= PAGE_INDEX_ID);
94
90
page_header_set_field(
95
91
/*==================*/
96
page_t* page, /* in/out: page */
97
page_zip_des_t* page_zip,/* in/out: compressed page whose
98
uncompressed part will be updated, or NULL */
99
ulint field, /* in: PAGE_N_DIR_SLOTS, ... */
100
ulint val) /* in: value */
92
page_t* page, /* in: page */
93
ulint field, /* in: PAGE_LEVEL, ... */
94
ulint val) /* in: value */
103
97
ut_ad(field <= PAGE_N_RECS);
105
99
ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < UNIV_PAGE_SIZE);
107
101
mach_write_to_2(page + PAGE_HEADER + field, val);
108
if (UNIV_LIKELY_NULL(page_zip)) {
109
page_zip_write_header(page_zip,
110
page + PAGE_HEADER + field, 2, NULL);
114
104
/*****************************************************************
115
Returns the offset stored in the given header field. */
105
Returns the pointer stored in the given header field. */
118
page_header_get_offs(
119
/*=================*/
120
/* out: offset from the start of the page,
122
const page_t* page, /* in: page */
123
ulint field) /* in: PAGE_FREE, ... */
110
/* out: pointer or NULL */
111
page_t* page, /* in: page */
112
ulint field) /* in: PAGE_FREE, ... */
143
137
page_header_set_ptr(
144
138
/*================*/
145
page_t* page, /* in: page */
146
page_zip_des_t* page_zip,/* in/out: compressed page whose
147
uncompressed part will be updated, or NULL */
148
ulint field, /* in: PAGE_FREE, ... */
149
const byte* ptr) /* in: pointer or NULL*/
139
page_t* page, /* in: page */
140
ulint field, /* in: PAGE_FREE, ... */
141
byte* ptr) /* in: pointer or NULL*/
164
156
ut_ad((field != PAGE_HEAP_TOP) || offs);
166
page_header_set_field(page, page_zip, field, offs);
158
page_header_set_field(page, field, offs);
169
161
/*****************************************************************
174
166
page_header_reset_last_insert(
175
167
/*==========================*/
176
page_t* page, /* in/out: page */
177
page_zip_des_t* page_zip,/* in/out: compressed page whose
178
uncompressed part will be updated, or NULL */
179
mtr_t* mtr) /* in: mtr */
168
page_t* page, /* in: page */
169
mtr_t* mtr) /* in: mtr */
181
171
ut_ad(page && mtr);
183
if (UNIV_LIKELY_NULL(page_zip)) {
184
mach_write_to_2(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0);
185
page_zip_write_header(page_zip,
186
page + (PAGE_HEADER + PAGE_LAST_INSERT),
189
mlog_write_ulint(page + (PAGE_HEADER + PAGE_LAST_INSERT), 0,
173
mlog_write_ulint(page + PAGE_HEADER + PAGE_LAST_INSERT, 0,
194
177
/****************************************************************
200
/* out: nonzero if the page is in compact
201
format, zero if it is in old-style format */
202
const page_t* page) /* in: index page */
183
/* out: nonzero if the page is in compact
184
format, zero if it is in old-style format */
185
page_t* page) /* in: index page */
204
187
return(UNIV_EXPECT(page_header_get_field(page, PAGE_N_HEAP) & 0x8000,
217
200
return(page_is_comp(page_align(rec)));
220
/*******************************************************************
221
Returns the heap number of a record. */
224
page_rec_get_heap_no(
225
/*=================*/
226
/* out: heap number */
227
const rec_t* rec) /* in: the physical record */
229
if (page_rec_is_comp(rec)) {
230
return(rec_get_heap_no_new(rec));
232
return(rec_get_heap_no_old(rec));
236
/****************************************************************
237
Determine whether the page is a B-tree leaf. */
242
/* out: TRUE if the page is a B-tree leaf */
243
const page_t* page) /* in: page */
245
return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
248
203
/****************************************************************
249
204
Gets the first record on the page. */
398
353
/* out: 1, 0, -1, if dtuple is greater, equal,
399
354
less than rec, respectively, when only the
400
355
common first fields are compared */
401
const dtuple_t* dtuple, /* in: data tuple */
402
const rec_t* rec, /* in: physical record on a page; may also
356
dtuple_t* dtuple, /* in: data tuple */
357
rec_t* rec, /* in: physical record on a page; may also
403
358
be page infimum or supremum, in which case
404
359
matched-parameter values below are not
437
392
/*****************************************************************
438
Gets the page number. */
443
/* out: page number */
444
const page_t* page) /* in: page */
446
ut_ad(page == page_align((page_t*) page));
447
return(mach_read_from_4(page + FIL_PAGE_OFFSET));
450
/*****************************************************************
451
Gets the tablespace identifier. */
457
const page_t* page) /* in: page */
459
ut_ad(page == page_align((page_t*) page));
460
return(mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID));
463
/*****************************************************************
464
393
Gets the number of user records on page (infimum and supremum records
465
394
are not user records). */
470
/* out: number of user records */
471
const page_t* page) /* in: index page */
399
/* out: number of user records */
400
page_t* page) /* in: index page */
473
402
return(page_header_get_field(page, PAGE_N_RECS));
491
420
page_dir_set_n_slots(
492
421
/*=================*/
493
page_t* page, /* in/out: page */
494
page_zip_des_t* page_zip,/* in/out: compressed page whose
495
uncompressed part will be updated, or NULL */
496
ulint n_slots)/* in: number of slots */
422
/* out: number of slots */
423
page_t* page, /* in: index page */
424
ulint n_slots)/* in: number of slots */
498
page_header_set_field(page, page_zip, PAGE_N_DIR_SLOTS, n_slots);
426
page_header_set_field(page, PAGE_N_DIR_SLOTS, n_slots);
501
429
/*****************************************************************
517
445
page_dir_set_n_heap(
518
446
/*================*/
519
page_t* page, /* in/out: index page */
520
page_zip_des_t* page_zip,/* in/out: compressed page whose
521
uncompressed part will be updated, or NULL.
522
Note that the size of the dense page directory
523
in the compressed page trailer is
524
n_heap * PAGE_ZIP_DIR_SLOT_SIZE. */
525
ulint n_heap) /* in: number of records */
447
page_t* page, /* in: index page */
448
ulint n_heap) /* in: number of records */
527
450
ut_ad(n_heap < 0x8000);
528
ut_ad(!page_zip || n_heap
529
== (page_header_get_field(page, PAGE_N_HEAP) & 0x7fff) + 1);
531
page_header_set_field(page, page_zip, PAGE_N_HEAP, n_heap
452
page_header_set_field(page, PAGE_N_HEAP, n_heap
533
454
& page_header_get_field(page, PAGE_N_HEAP)));
537
457
/*****************************************************************
538
458
Gets pointer to nth directory slot. */
541
461
page_dir_get_nth_slot(
542
462
/*==================*/
543
/* out: pointer to dir slot */
544
const page_t* page, /* in: index page */
545
ulint n) /* in: position */
463
/* out: pointer to dir slot */
464
page_t* page, /* in: index page */
465
ulint n) /* in: position */
547
467
ut_ad(page_dir_get_n_slots(page) > n);
549
return((page_dir_slot_t*)
550
page + UNIV_PAGE_SIZE - PAGE_DIR
469
return(page + UNIV_PAGE_SIZE - PAGE_DIR
551
470
- (n + 1) * PAGE_DIR_SLOT_SIZE);
553
#endif /* UNIV_DEBUG */
555
473
/******************************************************************
556
474
Used to check the consistency of a record on a page. */
561
/* out: TRUE if succeed */
562
const rec_t* rec) /* in: record */
479
/* out: TRUE if succeed */
480
rec_t* rec) /* in: record */
564
const page_t* page = page_align(rec);
568
ut_a(page_offset(rec) <= page_header_get_field(page, PAGE_HEAP_TOP));
569
ut_a(page_offset(rec) >= PAGE_DATA);
486
page = buf_frame_align(rec);
488
ut_a(rec <= page_header_get_ptr(page, PAGE_HEAP_TOP));
489
ut_a(rec >= page + PAGE_DATA);
574
494
/*******************************************************************
575
495
Gets the record pointed to by a directory slot. */
578
498
page_dir_slot_get_rec(
579
499
/*==================*/
580
500
/* out: pointer to record */
581
const page_dir_slot_t* slot) /* in: directory slot */
501
page_dir_slot_t* slot) /* in: directory slot */
583
return(page_align(slot) + mach_read_from_2(slot));
503
return(buf_frame_align(slot) + mach_read_from_2(slot));
586
506
/*******************************************************************
604
524
page_dir_slot_get_n_owned(
605
525
/*======================*/
606
526
/* out: number of records */
607
const page_dir_slot_t* slot) /* in: page directory slot */
527
page_dir_slot_t* slot) /* in: page directory slot */
609
const rec_t* rec = page_dir_slot_get_rec(slot);
610
if (page_rec_is_comp(slot)) {
611
return(rec_get_n_owned_new(rec));
613
return(rec_get_n_owned_old(rec));
529
rec_t* rec = page_dir_slot_get_rec(slot);
530
return(rec_get_n_owned(rec, page_rec_is_comp(rec)));
617
533
/*******************************************************************
621
537
page_dir_slot_set_n_owned(
622
538
/*======================*/
623
page_dir_slot_t*slot, /* in/out: directory slot */
624
page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
625
ulint n) /* in: number of records owned by the slot */
539
page_dir_slot_t* slot, /* in: directory slot */
540
ulint n) /* in: number of records owned
627
rec_t* rec = (rec_t*) page_dir_slot_get_rec(slot);
628
if (page_rec_is_comp(slot)) {
629
rec_set_n_owned_new(rec, page_zip, n);
632
rec_set_n_owned_old(rec, n);
543
rec_t* rec = page_dir_slot_get_rec(slot);
544
rec_set_n_owned(rec, page_rec_is_comp(rec), n);
636
547
/****************************************************************
650
561
/****************************************************************
651
562
Gets the pointer to the next record on the page. */
654
page_rec_get_next_low(
655
/*==================*/
656
/* out: pointer to next record */
657
const rec_t* rec, /* in: pointer to record */
658
ulint comp) /* in: nonzero=compact page layout */
567
/* out: pointer to next record */
568
rec_t* rec) /* in: pointer to record */
663
573
ut_ad(page_rec_check(rec));
665
575
page = page_align(rec);
667
offs = rec_get_next_offs(rec, comp);
577
offs = rec_get_next_offs(rec, page_is_comp(page));
669
579
if (UNIV_UNLIKELY(offs >= UNIV_PAGE_SIZE)) {
671
581
"InnoDB: Next record offset is nonsensical %lu"
672
582
" in record at offset %lu\n"
673
"InnoDB: rec address %p, space id %lu, page %lu\n",
674
(ulong)offs, (ulong) page_offset(rec),
676
(ulong) page_get_space_id(page),
677
(ulong) page_get_page_no(page));
678
buf_page_print(page, 0);
583
"InnoDB: rec address %p, first buffer frame %p\n"
584
"InnoDB: buffer pool high end %p, buf fix count %lu\n",
585
(ulong)offs, (ulong)(rec - page),
586
(void*) rec, (void*) buf_pool->frame_zero,
587
(void*) buf_pool->high_end,
588
(ulong) buf_block_align(rec)->buf_fix_count);
589
buf_page_print(page);
691
602
/****************************************************************
692
Gets the pointer to the next record on the page. */
697
/* out: pointer to next record */
698
rec_t* rec) /* in: pointer to record */
700
return((rec_t*) page_rec_get_next_low(rec, page_rec_is_comp(rec)));
703
/****************************************************************
704
Gets the pointer to the next record on the page. */
707
page_rec_get_next_const(
708
/*====================*/
709
/* out: pointer to next record */
710
const rec_t* rec) /* in: pointer to record */
712
return(page_rec_get_next_low(rec, page_rec_is_comp(rec)));
715
/****************************************************************
716
603
Sets the pointer to the next record on the page. */
719
606
page_rec_set_next(
720
607
/*==============*/
721
rec_t* rec, /* in: pointer to record,
722
must not be page supremum */
723
rec_t* next) /* in: pointer to next record,
724
must not be page infimum */
608
rec_t* rec, /* in: pointer to record, must not be page supremum */
609
rec_t* next) /* in: pointer to next record, must not be page
728
615
ut_ad(page_rec_check(rec));
729
616
ut_ad(!page_rec_is_supremum(rec));
732
ut_ad(!next || !page_rec_is_infimum(next));
733
ut_ad(!next || page_align(rec) == page_align(next));
735
if (UNIV_LIKELY(next != NULL)) {
736
offs = page_offset(next);
617
page = page_align(rec);
620
ut_ad(!page_rec_is_infimum(next));
621
ut_ad(page == page_align(next));
622
offs = (ulint) (next - page);
741
if (page_rec_is_comp(rec)) {
742
rec_set_next_offs_new(rec, offs);
744
rec_set_next_offs_old(rec, offs);
627
rec_set_next_offs(rec, page_is_comp(page), offs);
748
630
/****************************************************************
749
631
Gets the pointer to the previous record. */
752
page_rec_get_prev_const(
753
/*====================*/
754
/* out: pointer to previous record */
755
const rec_t* rec) /* in: pointer to record, must not be page
636
/* out: pointer to previous record */
637
rec_t* rec) /* in: pointer to record, must not be page
758
const page_dir_slot_t* slot;
640
page_dir_slot_t* slot;
761
const rec_t* prev_rec = NULL;
643
rec_t* prev_rec = NULL;
764
646
ut_ad(page_rec_check(rec));
792
667
return(prev_rec);
795
/****************************************************************
796
Gets the pointer to the previous record. */
801
/* out: pointer to previous record */
802
rec_t* rec) /* in: pointer to record, must not be page
805
return((rec_t*) page_rec_get_prev_const(rec));
808
670
/*******************************************************************
809
671
Looks for the record which owns the given record. */
817
679
ut_ad(page_rec_check(rec));
819
681
if (page_rec_is_comp(rec)) {
820
while (rec_get_n_owned_new(rec) == 0) {
682
while (rec_get_n_owned(rec, TRUE) == 0) {
821
683
rec = page_rec_get_next(rec);
824
while (rec_get_n_owned_old(rec) == 0) {
686
while (rec_get_n_owned(rec, FALSE) == 0) {
825
687
rec = page_rec_get_next(rec);
832
/**************************************************************
833
Returns the base extra size of a physical record. This is the
834
size of the fixed header, independent of the record size. */
837
page_rec_get_base_extra_size(
838
/*=========================*/
839
/* out: REC_N_NEW_EXTRA_BYTES
840
or REC_N_OLD_EXTRA_BYTES */
841
const rec_t* rec) /* in: physical record */
843
#if REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES
844
# error "REC_N_NEW_EXTRA_BYTES + 1 != REC_N_OLD_EXTRA_BYTES"
846
return(REC_N_NEW_EXTRA_BYTES + (ulint) !page_rec_is_comp(rec));
849
694
/****************************************************************
850
695
Returns the sum of the sizes of the records in the record list, excluding
851
696
the infimum and supremum records. */
873
/****************************************************************
874
Allocates a block of memory from the free list of an index page. */
879
page_t* page, /* in/out: index page */
880
page_zip_des_t* page_zip,/* in/out: compressed page with enough
881
space available for inserting the record,
883
rec_t* next_rec,/* in: pointer to the new head of the
885
ulint need) /* in: number of bytes allocated */
890
const rec_t* old_rec = page_header_get_ptr(page, PAGE_FREE);
894
next_offs = rec_get_next_offs(old_rec, page_is_comp(page));
895
ut_ad(next_rec == (next_offs ? page + next_offs : NULL));
898
page_header_set_ptr(page, page_zip, PAGE_FREE, next_rec);
900
garbage = page_header_get_field(page, PAGE_GARBAGE);
901
ut_ad(garbage >= need);
903
page_header_set_field(page, page_zip, PAGE_GARBAGE, garbage - need);
906
717
/*****************************************************************
907
718
Calculates free space if a page is emptied. */
937
748
page_get_max_insert_size(
938
749
/*=====================*/
939
/* out: maximum combined size for
941
const page_t* page, /* in: index page */
942
ulint n_recs) /* in: number of records */
750
/* out: maximum combined size for inserted records */
751
page_t* page, /* in: index page */
752
ulint n_recs) /* in: number of records */
945
755
ulint free_space;
980
790
page_get_max_insert_size_after_reorganize(
981
791
/*======================================*/
982
/* out: maximum combined size for
984
const page_t* page, /* in: index page */
985
ulint n_recs) /* in: number of records */
792
/* out: maximum combined size for inserted records */
793
page_t* page, /* in: index page */
794
ulint n_recs) /* in: number of records */
988
797
ulint free_space;
1009
page_t* page, /* in/out: index page */
1010
page_zip_des_t* page_zip,/* in/out: compressed page with at least
1011
6 bytes available, or NULL */
818
page_t* page, /* in: index page */
1012
819
rec_t* rec, /* in: pointer to the (origin of) record */
1013
dict_index_t* index, /* in: index of rec */
1014
820
const ulint* offsets)/* in: array returned by rec_get_offsets() */
1019
ut_ad(rec_offs_validate(rec, index, offsets));
825
ut_ad(rec_offs_validate(rec, NULL, offsets));
826
ut_ad(!rec_offs_comp(offsets) == !page_rec_is_comp(rec));
1020
827
free = page_header_get_ptr(page, PAGE_FREE);
1022
829
page_rec_set_next(rec, free);
1023
page_header_set_ptr(page, page_zip, PAGE_FREE, rec);
830
page_header_set_ptr(page, PAGE_FREE, rec);
832
#if 0 /* It's better not to destroy the user's data. */
834
/* Clear the data bytes of the deleted record in order to improve
835
the compression ratio of the page and to make it easier to read
836
page dumps in corruption reports. The extra bytes of the record
837
cannot be cleared, because page_mem_alloc() needs them in order
838
to determine the size of the deleted record. */
839
memset(rec, 0, rec_offs_data_size(offsets));
1025
842
garbage = page_header_get_field(page, PAGE_GARBAGE);
1027
page_header_set_field(page, page_zip, PAGE_GARBAGE,
844
page_header_set_field(page, PAGE_GARBAGE,
1028
845
garbage + rec_offs_size(offsets));
1030
if (UNIV_LIKELY_NULL(page_zip)) {
1031
page_zip_dir_delete(page_zip, rec, index, offsets, free);
1033
page_header_set_field(page, page_zip, PAGE_N_RECS,
1034
page_get_n_recs(page) - 1);
1038
848
#ifdef UNIV_MATERIALIZE