~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/btr/btr0btr.c

  • Committer: Eric Day
  • Date: 2009-10-31 21:53:33 UTC
  • mfrom: (1200 staging)
  • mto: This revision was merged to the branch mainline in revision 1202.
  • Revision ID: eday@oddments.org-20091031215333-j94bjoanwmi68p6f
Merged trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
*****************************************************************************/
18
18
 
19
 
/******************************************************
 
19
/**************************************************//**
 
20
@file btr/btr0btr.c
20
21
The B-tree
21
22
 
22
23
Created 6/2/1994 Heikki Tuuri
30
31
 
31
32
#include "fsp0fsp.h"
32
33
#include "page0page.h"
33
 
#include "page0zip.h"
 
34
 
 
35
#ifndef UNIV_HOTBACKUP
34
36
#include "btr0cur.h"
35
37
#include "btr0sea.h"
36
38
#include "btr0pcur.h"
96
98
*/
97
99
 
98
100
#ifdef UNIV_BTR_DEBUG
99
 
/******************************************************************
100
 
Checks a file segment header within a B-tree root page. */
 
101
/**************************************************************//**
 
102
Checks a file segment header within a B-tree root page.
 
103
@return TRUE if valid */
101
104
static
102
105
ibool
103
106
btr_root_fseg_validate(
104
107
/*===================*/
105
 
                                                /* out: TRUE if valid */
106
 
        const fseg_header_t*    seg_header,     /* in: segment header */
107
 
        ulint                   space)          /* in: tablespace identifier */
 
108
        const fseg_header_t*    seg_header,     /*!< in: segment header */
 
109
        ulint                   space)          /*!< in: tablespace identifier */
108
110
{
109
111
        ulint   offset = mach_read_from_2(seg_header + FSEG_HDR_OFFSET);
110
112
 
115
117
}
116
118
#endif /* UNIV_BTR_DEBUG */
117
119
 
118
 
/******************************************************************
119
 
Gets the root node of a tree and x-latches it. */
 
120
/**************************************************************//**
 
121
Gets the root node of a tree and x-latches it.
 
122
@return root page, x-latched */
120
123
static
121
124
buf_block_t*
122
125
btr_root_block_get(
123
126
/*===============*/
124
 
                                /* out: root page, x-latched */
125
 
        dict_index_t*   index,  /* in: index tree */
126
 
        mtr_t*          mtr)    /* in: mtr */
 
127
        dict_index_t*   index,  /*!< in: index tree */
 
128
        mtr_t*          mtr)    /*!< in: mtr */
127
129
{
128
130
        ulint           space;
129
131
        ulint           zip_size;
151
153
        return(block);
152
154
}
153
155
 
154
 
/******************************************************************
155
 
Gets the root node of a tree and x-latches it. */
 
156
/**************************************************************//**
 
157
Gets the root node of a tree and x-latches it.
 
158
@return root page, x-latched */
156
159
UNIV_INTERN
157
160
page_t*
158
161
btr_root_get(
159
162
/*=========*/
160
 
                                /* out: root page, x-latched */
161
 
        dict_index_t*   index,  /* in: index tree */
162
 
        mtr_t*          mtr)    /* in: mtr */
 
163
        dict_index_t*   index,  /*!< in: index tree */
 
164
        mtr_t*          mtr)    /*!< in: mtr */
163
165
{
164
166
        return(buf_block_get_frame(btr_root_block_get(index, mtr)));
165
167
}
166
168
 
167
 
/*****************************************************************
 
169
/*************************************************************//**
168
170
Gets pointer to the previous user record in the tree. It is assumed that
169
 
the caller has appropriate latches on the page and its neighbor. */
 
171
the caller has appropriate latches on the page and its neighbor.
 
172
@return previous user record, NULL if there is none */
170
173
UNIV_INTERN
171
174
rec_t*
172
175
btr_get_prev_user_rec(
173
176
/*==================*/
174
 
                        /* out: previous user record, NULL if there is none */
175
 
        rec_t*  rec,    /* in: record on leaf level */
176
 
        mtr_t*  mtr)    /* in: mtr holding a latch on the page, and if
 
177
        rec_t*  rec,    /*!< in: record on leaf level */
 
178
        mtr_t*  mtr)    /*!< in: mtr holding a latch on the page, and if
177
179
                        needed, also to the previous page */
178
180
{
179
181
        page_t* page;
222
224
        return(NULL);
223
225
}
224
226
 
225
 
/*****************************************************************
 
227
/*************************************************************//**
226
228
Gets pointer to the next user record in the tree. It is assumed that the
227
 
caller has appropriate latches on the page and its neighbor. */
 
229
caller has appropriate latches on the page and its neighbor.
 
230
@return next user record, NULL if there is none */
228
231
UNIV_INTERN
229
232
rec_t*
230
233
btr_get_next_user_rec(
231
234
/*==================*/
232
 
                        /* out: next user record, NULL if there is none */
233
 
        rec_t*  rec,    /* in: record on leaf level */
234
 
        mtr_t*  mtr)    /* in: mtr holding a latch on the page, and if
 
235
        rec_t*  rec,    /*!< in: record on leaf level */
 
236
        mtr_t*  mtr)    /*!< in: mtr holding a latch on the page, and if
235
237
                        needed, also to the next page */
236
238
{
237
239
        page_t* page;
278
280
        return(NULL);
279
281
}
280
282
 
281
 
/******************************************************************
 
283
/**************************************************************//**
282
284
Creates a new index page (not the root, and also not
283
285
used in page reorganization).  @see btr_page_empty(). */
284
286
static
285
287
void
286
288
btr_page_create(
287
289
/*============*/
288
 
        buf_block_t*    block,  /* in/out: page to be created */
289
 
        page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
290
 
        dict_index_t*   index,  /* in: index */
291
 
        ulint           level,  /* in: the B-tree level of the page */
292
 
        mtr_t*          mtr)    /* in: mtr */
 
290
        buf_block_t*    block,  /*!< in/out: page to be created */
 
291
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
292
        dict_index_t*   index,  /*!< in: index */
 
293
        ulint           level,  /*!< in: the B-tree level of the page */
 
294
        mtr_t*          mtr)    /*!< in: mtr */
293
295
{
294
296
        page_t*         page = buf_block_get_frame(block);
295
297
 
308
310
        btr_page_set_index_id(page, page_zip, index->id, mtr);
309
311
}
310
312
 
311
 
/******************************************************************
 
313
/**************************************************************//**
312
314
Allocates a new file page to be used in an ibuf tree. Takes the page from
313
 
the free list of the tree, which must contain pages! */
 
315
the free list of the tree, which must contain pages!
 
316
@return new allocated block, x-latched */
314
317
static
315
318
buf_block_t*
316
319
btr_page_alloc_for_ibuf(
317
320
/*====================*/
318
 
                                /* out: new allocated block, x-latched */
319
 
        dict_index_t*   index,  /* in: index tree */
320
 
        mtr_t*          mtr)    /* in: mtr */
 
321
        dict_index_t*   index,  /*!< in: index tree */
 
322
        mtr_t*          mtr)    /*!< in: mtr */
321
323
{
322
324
        fil_addr_t      node_addr;
323
325
        page_t*         root;
345
347
        return(new_block);
346
348
}
347
349
 
348
 
/******************************************************************
 
350
/**************************************************************//**
349
351
Allocates a new file page to be used in an index tree. NOTE: we assume
350
 
that the caller has made the reservation for free extents! */
 
352
that the caller has made the reservation for free extents!
 
353
@return new allocated block, x-latched; NULL if out of space */
351
354
UNIV_INTERN
352
355
buf_block_t*
353
356
btr_page_alloc(
354
357
/*===========*/
355
 
                                        /* out: new allocated block, x-latched;
356
 
                                        NULL if out of space */
357
 
        dict_index_t*   index,          /* in: index */
358
 
        ulint           hint_page_no,   /* in: hint of a good page */
359
 
        byte            file_direction, /* in: direction where a possible
 
358
        dict_index_t*   index,          /*!< in: index */
 
359
        ulint           hint_page_no,   /*!< in: hint of a good page */
 
360
        byte            file_direction, /*!< in: direction where a possible
360
361
                                        page split is made */
361
 
        ulint           level,          /* in: level where the page is placed
 
362
        ulint           level,          /*!< in: level where the page is placed
362
363
                                        in the tree */
363
 
        mtr_t*          mtr)            /* in: mtr */
 
364
        mtr_t*          mtr)            /*!< in: mtr */
364
365
{
365
366
        fseg_header_t*  seg_header;
366
367
        page_t*         root;
399
400
        return(new_block);
400
401
}
401
402
 
402
 
/******************************************************************
403
 
Gets the number of pages in a B-tree. */
 
403
/**************************************************************//**
 
404
Gets the number of pages in a B-tree.
 
405
@return number of pages */
404
406
UNIV_INTERN
405
407
ulint
406
408
btr_get_size(
407
409
/*=========*/
408
 
                                /* out: number of pages */
409
 
        dict_index_t*   index,  /* in: index */
410
 
        ulint           flag)   /* in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
 
410
        dict_index_t*   index,  /*!< in: index */
 
411
        ulint           flag)   /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
411
412
{
412
413
        fseg_header_t*  seg_header;
413
414
        page_t*         root;
443
444
        return(n);
444
445
}
445
446
 
446
 
/******************************************************************
 
447
/**************************************************************//**
447
448
Frees a page used in an ibuf tree. Puts the page to the free list of the
448
449
ibuf tree. */
449
450
static
450
451
void
451
452
btr_page_free_for_ibuf(
452
453
/*===================*/
453
 
        dict_index_t*   index,  /* in: index tree */
454
 
        buf_block_t*    block,  /* in: block to be freed, x-latched */
455
 
        mtr_t*          mtr)    /* in: mtr */
 
454
        dict_index_t*   index,  /*!< in: index tree */
 
455
        buf_block_t*    block,  /*!< in: block to be freed, x-latched */
 
456
        mtr_t*          mtr)    /*!< in: mtr */
456
457
{
457
458
        page_t*         root;
458
459
 
467
468
                            mtr));
468
469
}
469
470
 
470
 
/******************************************************************
 
471
/**************************************************************//**
471
472
Frees a file page used in an index tree. Can be used also to (BLOB)
472
473
external storage pages, because the page level 0 can be given as an
473
474
argument. */
475
476
void
476
477
btr_page_free_low(
477
478
/*==============*/
478
 
        dict_index_t*   index,  /* in: index tree */
479
 
        buf_block_t*    block,  /* in: block to be freed, x-latched */
480
 
        ulint           level,  /* in: page level */
481
 
        mtr_t*          mtr)    /* in: mtr */
 
479
        dict_index_t*   index,  /*!< in: index tree */
 
480
        buf_block_t*    block,  /*!< in: block to be freed, x-latched */
 
481
        ulint           level,  /*!< in: page level */
 
482
        mtr_t*          mtr)    /*!< in: mtr */
482
483
{
483
484
        fseg_header_t*  seg_header;
484
485
        page_t*         root;
509
510
                       buf_block_get_page_no(block), mtr);
510
511
}
511
512
 
512
 
/******************************************************************
 
513
/**************************************************************//**
513
514
Frees a file page used in an index tree. NOTE: cannot free field external
514
515
storage pages because the page must contain info on its level. */
515
516
UNIV_INTERN
516
517
void
517
518
btr_page_free(
518
519
/*==========*/
519
 
        dict_index_t*   index,  /* in: index tree */
520
 
        buf_block_t*    block,  /* in: block to be freed, x-latched */
521
 
        mtr_t*          mtr)    /* in: mtr */
 
520
        dict_index_t*   index,  /*!< in: index tree */
 
521
        buf_block_t*    block,  /*!< in: block to be freed, x-latched */
 
522
        mtr_t*          mtr)    /*!< in: mtr */
522
523
{
523
524
        ulint           level;
524
525
 
527
528
        btr_page_free_low(index, block, level, mtr);
528
529
}
529
530
 
530
 
/******************************************************************
 
531
/**************************************************************//**
531
532
Sets the child node file address in a node pointer. */
532
533
UNIV_INLINE
533
534
void
534
535
btr_node_ptr_set_child_page_no(
535
536
/*===========================*/
536
 
        rec_t*          rec,    /* in: node pointer record */
537
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
 
537
        rec_t*          rec,    /*!< in: node pointer record */
 
538
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
538
539
                                part will be updated, or NULL */
539
 
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
540
 
        ulint           page_no,/* in: child node address */
541
 
        mtr_t*          mtr)    /* in: mtr */
 
540
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
541
        ulint           page_no,/*!< in: child node address */
 
542
        mtr_t*          mtr)    /*!< in: mtr */
542
543
{
543
544
        byte*   field;
544
545
        ulint   len;
562
563
        }
563
564
}
564
565
 
565
 
/****************************************************************
566
 
Returns the child page of a node pointer and x-latches it. */
 
566
/************************************************************//**
 
567
Returns the child page of a node pointer and x-latches it.
 
568
@return child page, x-latched */
567
569
static
568
570
buf_block_t*
569
571
btr_node_ptr_get_child(
570
572
/*===================*/
571
 
                                /* out: child page, x-latched */
572
 
        const rec_t*    node_ptr,/* in: node pointer */
573
 
        dict_index_t*   index,  /* in: index */
574
 
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
575
 
        mtr_t*          mtr)    /* in: mtr */
 
573
        const rec_t*    node_ptr,/*!< in: node pointer */
 
574
        dict_index_t*   index,  /*!< in: index */
 
575
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
576
        mtr_t*          mtr)    /*!< in: mtr */
576
577
{
577
578
        ulint   page_no;
578
579
        ulint   space;
585
586
                             page_no, RW_X_LATCH, mtr));
586
587
}
587
588
 
588
 
/****************************************************************
 
589
/************************************************************//**
589
590
Returns the upper level node pointer to a page. It is assumed that mtr holds
590
 
an x-latch on the tree. */
 
591
an x-latch on the tree.
 
592
@return rec_get_offsets() of the node pointer record */
591
593
static
592
594
ulint*
593
595
btr_page_get_father_node_ptr(
594
596
/*=========================*/
595
 
                                /* out: rec_get_offsets() of the
596
 
                                node pointer record */
597
 
        ulint*          offsets,/* in: work area for the return value */
598
 
        mem_heap_t*     heap,   /* in: memory heap to use */
599
 
        btr_cur_t*      cursor, /* in: cursor pointing to user record,
 
597
        ulint*          offsets,/*!< in: work area for the return value */
 
598
        mem_heap_t*     heap,   /*!< in: memory heap to use */
 
599
        btr_cur_t*      cursor, /*!< in: cursor pointing to user record,
600
600
                                out: cursor on node pointer record,
601
601
                                its page x-latched */
602
 
        mtr_t*          mtr)    /* in: mtr */
 
602
        mtr_t*          mtr)    /*!< in: mtr */
603
603
{
604
604
        dtuple_t*       tuple;
605
605
        rec_t*          user_rec;
660
660
                      " to fix the\n"
661
661
                      "InnoDB: corruption. If the crash happens at "
662
662
                      "the database startup, see\n"
663
 
                      "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
664
 
                      "forcing-recovery.html about\n"
 
663
                      "InnoDB: " REFMAN "forcing-recovery.html about\n"
665
664
                      "InnoDB: forcing recovery. "
666
665
                      "Then dump + drop + reimport.\n", stderr);
667
666
 
671
670
        return(offsets);
672
671
}
673
672
 
674
 
/****************************************************************
 
673
/************************************************************//**
675
674
Returns the upper level node pointer to a page. It is assumed that mtr holds
676
 
an x-latch on the tree. */
 
675
an x-latch on the tree.
 
676
@return rec_get_offsets() of the node pointer record */
677
677
static
678
678
ulint*
679
679
btr_page_get_father_block(
680
680
/*======================*/
681
 
                                /* out: rec_get_offsets() of the
682
 
                                node pointer record */
683
 
        ulint*          offsets,/* in: work area for the return value */
684
 
        mem_heap_t*     heap,   /* in: memory heap to use */
685
 
        dict_index_t*   index,  /* in: b-tree index */
686
 
        buf_block_t*    block,  /* in: child page in the index */
687
 
        mtr_t*          mtr,    /* in: mtr */
688
 
        btr_cur_t*      cursor) /* out: cursor on node pointer record,
 
681
        ulint*          offsets,/*!< in: work area for the return value */
 
682
        mem_heap_t*     heap,   /*!< in: memory heap to use */
 
683
        dict_index_t*   index,  /*!< in: b-tree index */
 
684
        buf_block_t*    block,  /*!< in: child page in the index */
 
685
        mtr_t*          mtr,    /*!< in: mtr */
 
686
        btr_cur_t*      cursor) /*!< out: cursor on node pointer record,
689
687
                                its page x-latched */
690
688
{
691
689
        rec_t*  rec
695
693
        return(btr_page_get_father_node_ptr(offsets, heap, cursor, mtr));
696
694
}
697
695
 
698
 
/****************************************************************
 
696
/************************************************************//**
699
697
Seeks to the upper level node pointer to a page.
700
698
It is assumed that mtr holds an x-latch on the tree. */
701
699
static
702
700
void
703
701
btr_page_get_father(
704
702
/*================*/
705
 
        dict_index_t*   index,  /* in: b-tree index */
706
 
        buf_block_t*    block,  /* in: child page in the index */
707
 
        mtr_t*          mtr,    /* in: mtr */
708
 
        btr_cur_t*      cursor) /* out: cursor on node pointer record,
 
703
        dict_index_t*   index,  /*!< in: b-tree index */
 
704
        buf_block_t*    block,  /*!< in: child page in the index */
 
705
        mtr_t*          mtr,    /*!< in: mtr */
 
706
        btr_cur_t*      cursor) /*!< out: cursor on node pointer record,
709
707
                                its page x-latched */
710
708
{
711
709
        mem_heap_t*     heap;
719
717
        mem_heap_free(heap);
720
718
}
721
719
 
722
 
/****************************************************************
723
 
Creates the root node for a new index tree. */
 
720
/************************************************************//**
 
721
Creates the root node for a new index tree.
 
722
@return page number of the created root, FIL_NULL if did not succeed */
724
723
UNIV_INTERN
725
724
ulint
726
725
btr_create(
727
726
/*=======*/
728
 
                                /* out: page number of the created root,
729
 
                                FIL_NULL if did not succeed */
730
 
        ulint           type,   /* in: type of the index */
731
 
        ulint           space,  /* in: space where created */
732
 
        ulint           zip_size,/* in: compressed page size in bytes
 
727
        ulint           type,   /*!< in: type of the index */
 
728
        ulint           space,  /*!< in: space where created */
 
729
        ulint           zip_size,/*!< in: compressed page size in bytes
733
730
                                or 0 for uncompressed pages */
734
 
        dulint          index_id,/* in: index id */
735
 
        dict_index_t*   index,  /* in: index */
736
 
        mtr_t*          mtr)    /* in: mini-transaction handle */
 
731
        dulint          index_id,/*!< in: index id */
 
732
        dict_index_t*   index,  /*!< in: index */
 
733
        mtr_t*          mtr)    /*!< in: mini-transaction handle */
737
734
{
738
735
        ulint           page_no;
739
736
        buf_block_t*    block;
838
835
        return(page_no);
839
836
}
840
837
 
841
 
/****************************************************************
 
838
/************************************************************//**
842
839
Frees a B-tree except the root page, which MUST be freed after this
843
840
by calling btr_free_root. */
844
841
UNIV_INTERN
845
842
void
846
843
btr_free_but_not_root(
847
844
/*==================*/
848
 
        ulint   space,          /* in: space where created */
849
 
        ulint   zip_size,       /* in: compressed page size in bytes
 
845
        ulint   space,          /*!< in: space where created */
 
846
        ulint   zip_size,       /*!< in: compressed page size in bytes
850
847
                                or 0 for uncompressed pages */
851
 
        ulint   root_page_no)   /* in: root page number */
 
848
        ulint   root_page_no)   /*!< in: root page number */
852
849
{
853
850
        ibool   finished;
854
851
        page_t* root;
895
892
        }
896
893
}
897
894
 
898
 
/****************************************************************
 
895
/************************************************************//**
899
896
Frees the B-tree root page. Other tree MUST already have been freed. */
900
897
UNIV_INTERN
901
898
void
902
899
btr_free_root(
903
900
/*==========*/
904
 
        ulint   space,          /* in: space where created */
905
 
        ulint   zip_size,       /* in: compressed page size in bytes
 
901
        ulint   space,          /*!< in: space where created */
 
902
        ulint   zip_size,       /*!< in: compressed page size in bytes
906
903
                                or 0 for uncompressed pages */
907
 
        ulint   root_page_no,   /* in: root page number */
908
 
        mtr_t*  mtr)            /* in: a mini-transaction which has already
 
904
        ulint   root_page_no,   /*!< in: root page number */
 
905
        mtr_t*  mtr)            /*!< in: a mini-transaction which has already
909
906
                                been started */
910
907
{
911
908
        buf_block_t*    block;
922
919
 
923
920
        while (!fseg_free_step(header, mtr));
924
921
}
 
922
#endif /* !UNIV_HOTBACKUP */
925
923
 
926
 
/*****************************************************************
 
924
/*************************************************************//**
927
925
Reorganizes an index page. */
928
926
static
929
927
ibool
930
928
btr_page_reorganize_low(
931
929
/*====================*/
932
 
        ibool           recovery,/* in: TRUE if called in recovery:
 
930
        ibool           recovery,/*!< in: TRUE if called in recovery:
933
931
                                locks should not be updated, i.e.,
934
932
                                there cannot exist locks on the
935
933
                                page, and a hash index should not be
936
934
                                dropped: it cannot exist */
937
 
        buf_block_t*    block,  /* in: page to be reorganized */
938
 
        dict_index_t*   index,  /* in: record descriptor */
939
 
        mtr_t*          mtr)    /* in: mtr */
 
935
        buf_block_t*    block,  /*!< in: page to be reorganized */
 
936
        dict_index_t*   index,  /*!< in: record descriptor */
 
937
        mtr_t*          mtr)    /*!< in: mtr */
940
938
{
941
939
        page_t*         page            = buf_block_get_frame(block);
942
940
        page_zip_des_t* page_zip        = buf_block_get_page_zip(block);
957
955
        data_size1 = page_get_data_size(page);
958
956
        max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
959
957
 
 
958
#ifndef UNIV_HOTBACKUP
960
959
        /* Write the log record */
961
960
        mlog_open_and_write_index(mtr, page, index, page_is_comp(page)
962
961
                                  ? MLOG_COMP_PAGE_REORGANIZE
963
962
                                  : MLOG_PAGE_REORGANIZE, 0);
 
963
#endif /* !UNIV_HOTBACKUP */
964
964
 
965
965
        /* Turn logging off */
966
966
        log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
967
967
 
 
968
#ifndef UNIV_HOTBACKUP
968
969
        temp_block = buf_block_alloc(0);
 
970
#else /* !UNIV_HOTBACKUP */
 
971
        ut_ad(block == back_block1);
 
972
        temp_block = back_block2;
 
973
#endif /* !UNIV_HOTBACKUP */
969
974
        temp_page = temp_block->frame;
970
975
 
971
976
        /* Copy the old page to temporary space */
972
977
        buf_frame_copy(temp_page, page);
973
978
 
 
979
#ifndef UNIV_HOTBACKUP
974
980
        if (UNIV_LIKELY(!recovery)) {
975
981
                btr_search_drop_page_hash_index(block);
976
982
        }
977
983
 
 
984
        block->check_index_page_at_flush = TRUE;
 
985
#endif /* !UNIV_HOTBACKUP */
 
986
 
978
987
        /* Recreate the page: note that global data on page (possible
979
988
        segment headers, next page-field, etc.) is preserved intact */
980
989
 
981
990
        page_create(block, mtr, dict_table_is_comp(index->table));
982
 
        block->check_index_page_at_flush = TRUE;
983
991
 
984
992
        /* Copy the records from the temporary space to the recreated page;
985
993
        do not copy the lock bits yet */
987
995
        page_copy_rec_list_end_no_locks(block, temp_block,
988
996
                                        page_get_infimum_rec(temp_page),
989
997
                                        index, mtr);
990
 
        /* Copy max trx id to recreated page */
991
 
        page_set_max_trx_id(block, NULL, page_get_max_trx_id(temp_page));
 
998
 
 
999
        if (dict_index_is_sec_or_ibuf(index) && page_is_leaf(page)) {
 
1000
                /* Copy max trx id to recreated page */
 
1001
                trx_id_t        max_trx_id = page_get_max_trx_id(temp_page);
 
1002
                page_set_max_trx_id(block, NULL, max_trx_id, mtr);
 
1003
                /* In crash recovery, dict_index_is_sec_or_ibuf() always
 
1004
                returns TRUE, even for clustered indexes.  max_trx_id is
 
1005
                unused in clustered index pages. */
 
1006
                ut_ad(!ut_dulint_is_zero(max_trx_id) || recovery);
 
1007
        }
992
1008
 
993
1009
        if (UNIV_LIKELY_NULL(page_zip)
994
1010
            && UNIV_UNLIKELY
1000
1016
                goto func_exit;
1001
1017
        }
1002
1018
 
 
1019
#ifndef UNIV_HOTBACKUP
1003
1020
        if (UNIV_LIKELY(!recovery)) {
1004
1021
                /* Update the record lock bitmaps */
1005
1022
                lock_move_reorganize_page(block, temp_block);
1006
1023
        }
 
1024
#endif /* !UNIV_HOTBACKUP */
1007
1025
 
1008
1026
        data_size2 = page_get_data_size(page);
1009
1027
        max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1);
1030
1048
#ifdef UNIV_ZIP_DEBUG
1031
1049
        ut_a(!page_zip || page_zip_validate(page_zip, page));
1032
1050
#endif /* UNIV_ZIP_DEBUG */
 
1051
#ifndef UNIV_HOTBACKUP
1033
1052
        buf_block_free(temp_block);
 
1053
#endif /* !UNIV_HOTBACKUP */
1034
1054
 
1035
1055
        /* Restore logging mode */
1036
1056
        mtr_set_log_mode(mtr, log_mode);
1038
1058
        return(success);
1039
1059
}
1040
1060
 
1041
 
/*****************************************************************
 
1061
#ifndef UNIV_HOTBACKUP
 
1062
/*************************************************************//**
1042
1063
Reorganizes an index page.
1043
1064
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
1044
1065
page of a non-clustered index, the caller must update the insert
1045
1066
buffer free bits in the same mini-transaction in such a way that the
1046
 
modification will be redo-logged. */
 
1067
modification will be redo-logged.
 
1068
@return TRUE on success, FALSE on failure */
1047
1069
UNIV_INTERN
1048
1070
ibool
1049
1071
btr_page_reorganize(
1050
1072
/*================*/
1051
 
                                /* out: TRUE on success, FALSE on failure */
1052
 
        buf_block_t*    block,  /* in: page to be reorganized */
1053
 
        dict_index_t*   index,  /* in: record descriptor */
1054
 
        mtr_t*          mtr)    /* in: mtr */
 
1073
        buf_block_t*    block,  /*!< in: page to be reorganized */
 
1074
        dict_index_t*   index,  /*!< in: record descriptor */
 
1075
        mtr_t*          mtr)    /*!< in: mtr */
1055
1076
{
1056
1077
        return(btr_page_reorganize_low(FALSE, block, index, mtr));
1057
1078
}
 
1079
#endif /* !UNIV_HOTBACKUP */
1058
1080
 
1059
 
/***************************************************************
1060
 
Parses a redo log record of reorganizing a page. */
 
1081
/***********************************************************//**
 
1082
Parses a redo log record of reorganizing a page.
 
1083
@return end of log record or NULL */
1061
1084
UNIV_INTERN
1062
1085
byte*
1063
1086
btr_parse_page_reorganize(
1064
1087
/*======================*/
1065
 
                                /* out: end of log record or NULL */
1066
 
        byte*           ptr,    /* in: buffer */
 
1088
        byte*           ptr,    /*!< in: buffer */
1067
1089
        byte*           end_ptr __attribute__((unused)),
1068
 
                                /* in: buffer end */
1069
 
        dict_index_t*   index,  /* in: record descriptor */
1070
 
        buf_block_t*    block,  /* in: page to be reorganized, or NULL */
1071
 
        mtr_t*          mtr)    /* in: mtr or NULL */
 
1090
                                /*!< in: buffer end */
 
1091
        dict_index_t*   index,  /*!< in: record descriptor */
 
1092
        buf_block_t*    block,  /*!< in: page to be reorganized, or NULL */
 
1093
        mtr_t*          mtr)    /*!< in: mtr or NULL */
1072
1094
{
1073
1095
        ut_ad(ptr && end_ptr);
1074
1096
 
1081
1103
        return(ptr);
1082
1104
}
1083
1105
 
1084
 
/*****************************************************************
1085
 
Empties an index page.  @see btr_page_create().*/
 
1106
#ifndef UNIV_HOTBACKUP
 
1107
/*************************************************************//**
 
1108
Empties an index page.  @see btr_page_create(). */
1086
1109
static
1087
1110
void
1088
1111
btr_page_empty(
1089
1112
/*===========*/
1090
 
        buf_block_t*    block,  /* in: page to be emptied */
1091
 
        page_zip_des_t* page_zip,/* out: compressed page, or NULL */
1092
 
        dict_index_t*   index,  /* in: index of the page */
1093
 
        ulint           level,  /* in: the B-tree level of the page */
1094
 
        mtr_t*          mtr)    /* in: mtr */
 
1113
        buf_block_t*    block,  /*!< in: page to be emptied */
 
1114
        page_zip_des_t* page_zip,/*!< out: compressed page, or NULL */
 
1115
        dict_index_t*   index,  /*!< in: index of the page */
 
1116
        ulint           level,  /*!< in: the B-tree level of the page */
 
1117
        mtr_t*          mtr)    /*!< in: mtr */
1095
1118
{
1096
1119
        page_t* page = buf_block_get_frame(block);
1097
1120
 
1116
1139
        block->check_index_page_at_flush = TRUE;
1117
1140
}
1118
1141
 
1119
 
/*****************************************************************
 
1142
/*************************************************************//**
1120
1143
Makes tree one level higher by splitting the root, and inserts
1121
1144
the tuple. It is assumed that mtr contains an x-latch on the tree.
1122
1145
NOTE that the operation of this function must always succeed,
1123
1146
we cannot reverse it: therefore enough free disk space must be
1124
 
guaranteed to be available before this function is called. */
 
1147
guaranteed to be available before this function is called.
 
1148
@return inserted record */
1125
1149
UNIV_INTERN
1126
1150
rec_t*
1127
1151
btr_root_raise_and_insert(
1128
1152
/*======================*/
1129
 
                                /* out: inserted record */
1130
 
        btr_cur_t*      cursor, /* in: cursor at which to insert: must be
 
1153
        btr_cur_t*      cursor, /*!< in: cursor at which to insert: must be
1131
1154
                                on the root page; when the function returns,
1132
1155
                                the cursor is positioned on the predecessor
1133
1156
                                of the inserted record */
1134
 
        const dtuple_t* tuple,  /* in: tuple to insert */
1135
 
        ulint           n_ext,  /* in: number of externally stored columns */
1136
 
        mtr_t*          mtr)    /* in: mtr */
 
1157
        const dtuple_t* tuple,  /*!< in: tuple to insert */
 
1158
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
1159
        mtr_t*          mtr)    /*!< in: mtr */
1137
1160
{
1138
1161
        dict_index_t*   index;
1139
1162
        page_t*         root;
1288
1311
        return(btr_page_split_and_insert(cursor, tuple, n_ext, mtr));
1289
1312
}
1290
1313
 
1291
 
/*****************************************************************
 
1314
/*************************************************************//**
1292
1315
Decides if the page should be split at the convergence point of inserts
1293
 
converging to the left. */
 
1316
converging to the left.
 
1317
@return TRUE if split recommended */
1294
1318
UNIV_INTERN
1295
1319
ibool
1296
1320
btr_page_get_split_rec_to_left(
1297
1321
/*===========================*/
1298
 
                                /* out: TRUE if split recommended */
1299
 
        btr_cur_t*      cursor, /* in: cursor at which to insert */
1300
 
        rec_t**         split_rec) /* out: if split recommended,
 
1322
        btr_cur_t*      cursor, /*!< in: cursor at which to insert */
 
1323
        rec_t**         split_rec) /*!< out: if split recommended,
1301
1324
                                the first record on upper half page,
1302
1325
                                or NULL if tuple to be inserted should
1303
1326
                                be first */
1333
1356
        return(FALSE);
1334
1357
}
1335
1358
 
1336
 
/*****************************************************************
 
1359
/*************************************************************//**
1337
1360
Decides if the page should be split at the convergence point of inserts
1338
 
converging to the right. */
 
1361
converging to the right.
 
1362
@return TRUE if split recommended */
1339
1363
UNIV_INTERN
1340
1364
ibool
1341
1365
btr_page_get_split_rec_to_right(
1342
1366
/*============================*/
1343
 
                                /* out: TRUE if split recommended */
1344
 
        btr_cur_t*      cursor, /* in: cursor at which to insert */
1345
 
        rec_t**         split_rec) /* out: if split recommended,
 
1367
        btr_cur_t*      cursor, /*!< in: cursor at which to insert */
 
1368
        rec_t**         split_rec) /*!< out: if split recommended,
1346
1369
                                the first record on upper half page,
1347
1370
                                or NULL if tuple to be inserted should
1348
1371
                                be first */
1391
1414
        return(FALSE);
1392
1415
}
1393
1416
 
1394
 
/*****************************************************************
 
1417
/*************************************************************//**
1395
1418
Calculates a split record such that the tuple will certainly fit on
1396
1419
its half-page when the split is performed. We assume in this function
1397
 
only that the cursor page has at least one user record. */
 
1420
only that the cursor page has at least one user record.
 
1421
@return split record, or NULL if tuple will be the first record on
 
1422
upper half-page */
1398
1423
static
1399
1424
rec_t*
1400
1425
btr_page_get_sure_split_rec(
1401
1426
/*========================*/
1402
 
                                /* out: split record, or NULL if tuple
1403
 
                                will be the first record on upper half-page */
1404
 
        btr_cur_t*      cursor, /* in: cursor at which insert should be made */
1405
 
        const dtuple_t* tuple,  /* in: tuple to insert */
1406
 
        ulint           n_ext)  /* in: number of externally stored columns */
 
1427
        btr_cur_t*      cursor, /*!< in: cursor at which insert should be made */
 
1428
        const dtuple_t* tuple,  /*!< in: tuple to insert */
 
1429
        ulint           n_ext)  /*!< in: number of externally stored columns */
1407
1430
{
1408
1431
        page_t*         page;
1409
1432
        page_zip_des_t* page_zip;
1511
1534
        return(rec);
1512
1535
}
1513
1536
 
1514
 
/*****************************************************************
 
1537
/*************************************************************//**
1515
1538
Returns TRUE if the insert fits on the appropriate half-page with the
1516
 
chosen split_rec. */
 
1539
chosen split_rec.
 
1540
@return TRUE if fits */
1517
1541
static
1518
1542
ibool
1519
1543
btr_page_insert_fits(
1520
1544
/*=================*/
1521
 
                                /* out: TRUE if fits */
1522
 
        btr_cur_t*      cursor, /* in: cursor at which insert
 
1545
        btr_cur_t*      cursor, /*!< in: cursor at which insert
1523
1546
                                should be made */
1524
 
        const rec_t*    split_rec,/* in: suggestion for first record
 
1547
        const rec_t*    split_rec,/*!< in: suggestion for first record
1525
1548
                                on upper half-page, or NULL if
1526
1549
                                tuple to be inserted should be first */
1527
 
        const ulint*    offsets,/* in: rec_get_offsets(
 
1550
        const ulint*    offsets,/*!< in: rec_get_offsets(
1528
1551
                                split_rec, cursor->index) */
1529
 
        const dtuple_t* tuple,  /* in: tuple to insert */
1530
 
        ulint           n_ext,  /* in: number of externally stored columns */
1531
 
        mem_heap_t*     heap)   /* in: temporary memory heap */
 
1552
        const dtuple_t* tuple,  /*!< in: tuple to insert */
 
1553
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
1554
        mem_heap_t*     heap)   /*!< in: temporary memory heap */
1532
1555
{
1533
1556
        page_t*         page;
1534
1557
        ulint           insert_size;
1608
1631
        return(FALSE);
1609
1632
}
1610
1633
 
1611
 
/***********************************************************
 
1634
/*******************************************************//**
1612
1635
Inserts a data tuple to a tree on a non-leaf level. It is assumed
1613
1636
that mtr holds an x-latch on the tree. */
1614
1637
UNIV_INTERN
1615
1638
void
1616
1639
btr_insert_on_non_leaf_level(
1617
1640
/*=========================*/
1618
 
        dict_index_t*   index,  /* in: index */
1619
 
        ulint           level,  /* in: level, must be > 0 */
1620
 
        dtuple_t*       tuple,  /* in: the record to be inserted */
1621
 
        mtr_t*          mtr)    /* in: mtr */
 
1641
        dict_index_t*   index,  /*!< in: index */
 
1642
        ulint           level,  /*!< in: level, must be > 0 */
 
1643
        dtuple_t*       tuple,  /*!< in: the record to be inserted */
 
1644
        mtr_t*          mtr)    /*!< in: mtr */
1622
1645
{
1623
1646
        big_rec_t*      dummy_big_rec;
1624
1647
        btr_cur_t       cursor;
1639
1662
        ut_a(err == DB_SUCCESS);
1640
1663
}
1641
1664
 
1642
 
/******************************************************************
 
1665
/**************************************************************//**
1643
1666
Attaches the halves of an index page on the appropriate level in an
1644
1667
index tree. */
1645
1668
static
1646
1669
void
1647
1670
btr_attach_half_pages(
1648
1671
/*==================*/
1649
 
        dict_index_t*   index,          /* in: the index tree */
1650
 
        buf_block_t*    block,          /* in/out: page to be split */
1651
 
        rec_t*          split_rec,      /* in: first record on upper
 
1672
        dict_index_t*   index,          /*!< in: the index tree */
 
1673
        buf_block_t*    block,          /*!< in/out: page to be split */
 
1674
        rec_t*          split_rec,      /*!< in: first record on upper
1652
1675
                                        half page */
1653
 
        buf_block_t*    new_block,      /* in/out: the new half page */
1654
 
        ulint           direction,      /* in: FSP_UP or FSP_DOWN */
1655
 
        mtr_t*          mtr)            /* in: mtr */
 
1676
        buf_block_t*    new_block,      /*!< in/out: the new half page */
 
1677
        ulint           direction,      /*!< in: FSP_UP or FSP_DOWN */
 
1678
        mtr_t*          mtr)            /*!< in: mtr */
1656
1679
{
1657
1680
        ulint           space;
1658
1681
        ulint           zip_size;
1774
1797
        btr_page_set_next(upper_page, upper_page_zip, next_page_no, mtr);
1775
1798
}
1776
1799
 
1777
 
/*****************************************************************
 
1800
/*************************************************************//**
1778
1801
Splits an index page to halves and inserts the tuple. It is assumed
1779
 
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch
1780
 
is released within this function! NOTE that the operation of this
1781
 
function must always succeed, we cannot reverse it: therefore
1782
 
enough free disk space must be guaranteed to be available before
1783
 
this function is called. */
 
1802
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
 
1803
released within this function! NOTE that the operation of this
 
1804
function must always succeed, we cannot reverse it: therefore enough
 
1805
free disk space (2 pages) must be guaranteed to be available before
 
1806
this function is called.
 
1807
 
 
1808
@return inserted record */
1784
1809
UNIV_INTERN
1785
1810
rec_t*
1786
1811
btr_page_split_and_insert(
1787
1812
/*======================*/
1788
 
                                /* out: inserted record; NOTE: the tree
1789
 
                                x-latch is released! NOTE: 2 free disk
1790
 
                                pages must be available! */
1791
 
        btr_cur_t*      cursor, /* in: cursor at which to insert; when the
 
1813
        btr_cur_t*      cursor, /*!< in: cursor at which to insert; when the
1792
1814
                                function returns, the cursor is positioned
1793
1815
                                on the predecessor of the inserted record */
1794
 
        const dtuple_t* tuple,  /* in: tuple to insert */
1795
 
        ulint           n_ext,  /* in: number of externally stored columns */
1796
 
        mtr_t*          mtr)    /* in: mtr */
 
1816
        const dtuple_t* tuple,  /*!< in: tuple to insert */
 
1817
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
1818
        mtr_t*          mtr)    /*!< in: mtr */
1797
1819
{
1798
1820
        buf_block_t*    block;
1799
1821
        page_t*         page;
2145
2167
        return(rec);
2146
2168
}
2147
2169
 
2148
 
/*****************************************************************
 
2170
/*************************************************************//**
2149
2171
Removes a page from the level list of pages. */
2150
2172
static
2151
2173
void
2152
2174
btr_level_list_remove(
2153
2175
/*==================*/
2154
 
        ulint           space,  /* in: space where removed */
2155
 
        ulint           zip_size,/* in: compressed page size in bytes
 
2176
        ulint           space,  /*!< in: space where removed */
 
2177
        ulint           zip_size,/*!< in: compressed page size in bytes
2156
2178
                                or 0 for uncompressed pages */
2157
 
        page_t*         page,   /* in: page to remove */
2158
 
        mtr_t*          mtr)    /* in: mtr */
 
2179
        page_t*         page,   /*!< in: page to remove */
 
2180
        mtr_t*          mtr)    /*!< in: mtr */
2159
2181
{
2160
2182
        ulint   prev_page_no;
2161
2183
        ulint   next_page_no;
2205
2227
        }
2206
2228
}
2207
2229
 
2208
 
/********************************************************************
 
2230
/****************************************************************//**
2209
2231
Writes the redo log record for setting an index record as the predefined
2210
2232
minimum record. */
2211
2233
UNIV_INLINE
2212
2234
void
2213
2235
btr_set_min_rec_mark_log(
2214
2236
/*=====================*/
2215
 
        rec_t*  rec,    /* in: record */
2216
 
        byte    type,   /* in: MLOG_COMP_REC_MIN_MARK or MLOG_REC_MIN_MARK */
2217
 
        mtr_t*  mtr)    /* in: mtr */
 
2237
        rec_t*  rec,    /*!< in: record */
 
2238
        byte    type,   /*!< in: MLOG_COMP_REC_MIN_MARK or MLOG_REC_MIN_MARK */
 
2239
        mtr_t*  mtr)    /*!< in: mtr */
2218
2240
{
2219
2241
        mlog_write_initial_log_record(rec, type, mtr);
2220
2242
 
2221
2243
        /* Write rec offset as a 2-byte ulint */
2222
2244
        mlog_catenate_ulint(mtr, page_offset(rec), MLOG_2BYTES);
2223
2245
}
 
2246
#else /* !UNIV_HOTBACKUP */
 
2247
# define btr_set_min_rec_mark_log(rec,comp,mtr) ((void) 0)
 
2248
#endif /* !UNIV_HOTBACKUP */
2224
2249
 
2225
 
/********************************************************************
 
2250
/****************************************************************//**
2226
2251
Parses the redo log record for setting an index record as the predefined
2227
 
minimum record. */
 
2252
minimum record.
 
2253
@return end of log record or NULL */
2228
2254
UNIV_INTERN
2229
2255
byte*
2230
2256
btr_parse_set_min_rec_mark(
2231
2257
/*=======================*/
2232
 
                        /* out: end of log record or NULL */
2233
 
        byte*   ptr,    /* in: buffer */
2234
 
        byte*   end_ptr,/* in: buffer end */
2235
 
        ulint   comp,   /* in: nonzero=compact page format */
2236
 
        page_t* page,   /* in: page or NULL */
2237
 
        mtr_t*  mtr)    /* in: mtr or NULL */
 
2258
        byte*   ptr,    /*!< in: buffer */
 
2259
        byte*   end_ptr,/*!< in: buffer end */
 
2260
        ulint   comp,   /*!< in: nonzero=compact page format */
 
2261
        page_t* page,   /*!< in: page or NULL */
 
2262
        mtr_t*  mtr)    /*!< in: mtr or NULL */
2238
2263
{
2239
2264
        rec_t*  rec;
2240
2265
 
2254
2279
        return(ptr + 2);
2255
2280
}
2256
2281
 
2257
 
/********************************************************************
 
2282
/****************************************************************//**
2258
2283
Sets a record as the predefined minimum record. */
2259
2284
UNIV_INTERN
2260
2285
void
2261
2286
btr_set_min_rec_mark(
2262
2287
/*=================*/
2263
 
        rec_t*  rec,    /* in: record */
2264
 
        mtr_t*  mtr)    /* in: mtr */
 
2288
        rec_t*  rec,    /*!< in: record */
 
2289
        mtr_t*  mtr)    /*!< in: mtr */
2265
2290
{
2266
2291
        ulint   info_bits;
2267
2292
 
2280
2305
        }
2281
2306
}
2282
2307
 
2283
 
/*****************************************************************
 
2308
#ifndef UNIV_HOTBACKUP
 
2309
/*************************************************************//**
2284
2310
Deletes on the upper level the node pointer to a page. */
2285
2311
UNIV_INTERN
2286
2312
void
2287
2313
btr_node_ptr_delete(
2288
2314
/*================*/
2289
 
        dict_index_t*   index,  /* in: index tree */
2290
 
        buf_block_t*    block,  /* in: page whose node pointer is deleted */
2291
 
        mtr_t*          mtr)    /* in: mtr */
 
2315
        dict_index_t*   index,  /*!< in: index tree */
 
2316
        buf_block_t*    block,  /*!< in: page whose node pointer is deleted */
 
2317
        mtr_t*          mtr)    /*!< in: mtr */
2292
2318
{
2293
2319
        btr_cur_t       cursor;
2294
2320
        ibool           compressed;
2308
2334
        }
2309
2335
}
2310
2336
 
2311
 
/*****************************************************************
 
2337
/*************************************************************//**
2312
2338
If page is the only on its level, this function moves its records to the
2313
2339
father page, thus reducing the tree height. */
2314
2340
static
2315
2341
void
2316
2342
btr_lift_page_up(
2317
2343
/*=============*/
2318
 
        dict_index_t*   index,  /* in: index tree */
2319
 
        buf_block_t*    block,  /* in: page which is the only on its level;
 
2344
        dict_index_t*   index,  /*!< in: index tree */
 
2345
        buf_block_t*    block,  /*!< in: page which is the only on its level;
2320
2346
                                must not be empty: use
2321
2347
                                btr_discard_only_page_on_level if the last
2322
2348
                                record from the page should be removed */
2323
 
        mtr_t*          mtr)    /* in: mtr */
 
2349
        mtr_t*          mtr)    /*!< in: mtr */
2324
2350
{
2325
2351
        buf_block_t*    father_block;
2326
2352
        page_t*         father_page;
2329
2355
        page_t*         page            = buf_block_get_frame(block);
2330
2356
        ulint           root_page_no;
2331
2357
        buf_block_t*    blocks[BTR_MAX_LEVELS];
2332
 
        ulint           n_blocks;       /* last used index in blocks[] */
 
2358
        ulint           n_blocks;       /*!< last used index in blocks[] */
2333
2359
        ulint           i;
2334
2360
 
2335
2361
        ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
2430
2456
        ut_ad(btr_check_node_ptr(index, father_block, mtr));
2431
2457
}
2432
2458
 
2433
 
/*****************************************************************
 
2459
/*************************************************************//**
2434
2460
Tries to merge the page first to the left immediate brother if such a
2435
2461
brother exists, and the node pointers to the current page and to the brother
2436
2462
reside on the same page. If the left brother does not satisfy these
2438
2464
level lifts the records of the page to the father page, thus reducing the
2439
2465
tree height. It is assumed that mtr holds an x-latch on the tree and on the
2440
2466
page. If cursor is on the leaf level, mtr must also hold x-latches to the
2441
 
brothers, if they exist. */
 
2467
brothers, if they exist.
 
2468
@return TRUE on success */
2442
2469
UNIV_INTERN
2443
2470
ibool
2444
2471
btr_compress(
2445
2472
/*=========*/
2446
 
                                /* out: TRUE on success */
2447
 
        btr_cur_t*      cursor, /* in: cursor on the page to merge or lift;
 
2473
        btr_cur_t*      cursor, /*!< in: cursor on the page to merge or lift;
2448
2474
                                the page must not be empty: in record delete
2449
2475
                                use btr_discard_page if the page would become
2450
2476
                                empty */
2451
 
        mtr_t*          mtr)    /* in: mtr */
 
2477
        mtr_t*          mtr)    /*!< in: mtr */
2452
2478
{
2453
2479
        dict_index_t*   index;
2454
2480
        ulint           space;
2722
2748
        return(TRUE);
2723
2749
}
2724
2750
 
2725
 
/*****************************************************************
 
2751
/*************************************************************//**
2726
2752
Discards a page that is the only page on its level.  This will empty
2727
2753
the whole B-tree, leaving just an empty root page.  This function
2728
2754
should never be reached, because btr_compress(), which is invoked in
2731
2757
void
2732
2758
btr_discard_only_page_on_level(
2733
2759
/*===========================*/
2734
 
        dict_index_t*   index,  /* in: index tree */
2735
 
        buf_block_t*    block,  /* in: page which is the only on its level */
2736
 
        mtr_t*          mtr)    /* in: mtr */
 
2760
        dict_index_t*   index,  /*!< in: index tree */
 
2761
        buf_block_t*    block,  /*!< in: page which is the only on its level */
 
2762
        mtr_t*          mtr)    /*!< in: mtr */
2737
2763
{
2738
 
        ulint   page_level = 0;
 
2764
        ulint           page_level = 0;
 
2765
        trx_id_t        max_trx_id;
 
2766
 
 
2767
        /* Save the PAGE_MAX_TRX_ID from the leaf page. */
 
2768
        max_trx_id = page_get_max_trx_id(buf_block_get_frame(block));
2739
2769
 
2740
2770
        while (buf_block_get_page_no(block) != dict_index_get_page(index)) {
2741
2771
                btr_cur_t       cursor;
2778
2808
 
2779
2809
        btr_page_empty(block, buf_block_get_page_zip(block), index, 0, mtr);
2780
2810
 
2781
 
        /* We play it safe and reset the free bits for the root */
2782
2811
        if (!dict_index_is_clust(index)) {
 
2812
                /* We play it safe and reset the free bits for the root */
2783
2813
                ibuf_reset_free_bits(block);
 
2814
 
 
2815
                if (page_is_leaf(buf_block_get_frame(block))) {
 
2816
                        ut_a(!ut_dulint_is_zero(max_trx_id));
 
2817
                        page_set_max_trx_id(block,
 
2818
                                            buf_block_get_page_zip(block),
 
2819
                                            max_trx_id, mtr);
 
2820
                }
2784
2821
        }
2785
2822
}
2786
2823
 
2787
 
/*****************************************************************
 
2824
/*************************************************************//**
2788
2825
Discards a page from a B-tree. This is used to remove the last record from
2789
2826
a B-tree page: the whole page must be removed at the same time. This cannot
2790
2827
be used for the root page, which is allowed to be empty. */
2792
2829
void
2793
2830
btr_discard_page(
2794
2831
/*=============*/
2795
 
        btr_cur_t*      cursor, /* in: cursor on the page to discard: not on
 
2832
        btr_cur_t*      cursor, /*!< in: cursor on the page to discard: not on
2796
2833
                                the root page */
2797
 
        mtr_t*          mtr)    /* in: mtr */
 
2834
        mtr_t*          mtr)    /*!< in: mtr */
2798
2835
{
2799
2836
        dict_index_t*   index;
2800
2837
        ulint           space;
2893
2930
}
2894
2931
 
2895
2932
#ifdef UNIV_BTR_PRINT
2896
 
/*****************************************************************
 
2933
/*************************************************************//**
2897
2934
Prints size info of a B-tree. */
2898
2935
UNIV_INTERN
2899
2936
void
2900
2937
btr_print_size(
2901
2938
/*===========*/
2902
 
        dict_index_t*   index)  /* in: index tree */
 
2939
        dict_index_t*   index)  /*!< in: index tree */
2903
2940
{
2904
2941
        page_t*         root;
2905
2942
        fseg_header_t*  seg;
2932
2969
        mtr_commit(&mtr);
2933
2970
}
2934
2971
 
2935
 
/****************************************************************
 
2972
/************************************************************//**
2936
2973
Prints recursively index tree pages. */
2937
2974
static
2938
2975
void
2939
2976
btr_print_recursive(
2940
2977
/*================*/
2941
 
        dict_index_t*   index,  /* in: index tree */
2942
 
        buf_block_t*    block,  /* in: index page */
2943
 
        ulint           width,  /* in: print this many entries from start
 
2978
        dict_index_t*   index,  /*!< in: index tree */
 
2979
        buf_block_t*    block,  /*!< in: index page */
 
2980
        ulint           width,  /*!< in: print this many entries from start
2944
2981
                                and end */
2945
 
        mem_heap_t**    heap,   /* in/out: heap for rec_get_offsets() */
2946
 
        ulint**         offsets,/* in/out: buffer for rec_get_offsets() */
2947
 
        mtr_t*          mtr)    /* in: mtr */
 
2982
        mem_heap_t**    heap,   /*!< in/out: heap for rec_get_offsets() */
 
2983
        ulint**         offsets,/*!< in/out: buffer for rec_get_offsets() */
 
2984
        mtr_t*          mtr)    /*!< in: mtr */
2948
2985
{
2949
2986
        const page_t*   page    = buf_block_get_frame(block);
2950
2987
        page_cur_t      cursor;
2994
3031
        }
2995
3032
}
2996
3033
 
2997
 
/******************************************************************
 
3034
/**************************************************************//**
2998
3035
Prints directories and other info of all nodes in the tree. */
2999
3036
UNIV_INTERN
3000
3037
void
3001
3038
btr_print_index(
3002
3039
/*============*/
3003
 
        dict_index_t*   index,  /* in: index */
3004
 
        ulint           width)  /* in: print this many entries from start
 
3040
        dict_index_t*   index,  /*!< in: index */
 
3041
        ulint           width)  /*!< in: print this many entries from start
3005
3042
                                and end */
3006
3043
{
3007
3044
        mtr_t           mtr;
3030
3067
#endif /* UNIV_BTR_PRINT */
3031
3068
 
3032
3069
#ifdef UNIV_DEBUG
3033
 
/****************************************************************
3034
 
Checks that the node pointer to a page is appropriate. */
 
3070
/************************************************************//**
 
3071
Checks that the node pointer to a page is appropriate.
 
3072
@return TRUE */
3035
3073
UNIV_INTERN
3036
3074
ibool
3037
3075
btr_check_node_ptr(
3038
3076
/*===============*/
3039
 
                                /* out: TRUE */
3040
 
        dict_index_t*   index,  /* in: index tree */
3041
 
        buf_block_t*    block,  /* in: index page */
3042
 
        mtr_t*          mtr)    /* in: mtr */
 
3077
        dict_index_t*   index,  /*!< in: index tree */
 
3078
        buf_block_t*    block,  /*!< in: index page */
 
3079
        mtr_t*          mtr)    /*!< in: mtr */
3043
3080
{
3044
3081
        mem_heap_t*     heap;
3045
3082
        dtuple_t*       tuple;
3074
3111
}
3075
3112
#endif /* UNIV_DEBUG */
3076
3113
 
3077
 
/****************************************************************
 
3114
/************************************************************//**
3078
3115
Display identification information for a record. */
3079
3116
static
3080
3117
void
3081
3118
btr_index_rec_validate_report(
3082
3119
/*==========================*/
3083
 
        const page_t*           page,   /* in: index page */
3084
 
        const rec_t*            rec,    /* in: index record */
3085
 
        const dict_index_t*     index)  /* in: index */
 
3120
        const page_t*           page,   /*!< in: index page */
 
3121
        const rec_t*            rec,    /*!< in: index record */
 
3122
        const dict_index_t*     index)  /*!< in: index */
3086
3123
{
3087
3124
        fputs("InnoDB: Record in ", stderr);
3088
3125
        dict_index_name_print(stderr, NULL, index);
3090
3127
                page_get_page_no(page), (ulint) page_offset(rec));
3091
3128
}
3092
3129
 
3093
 
/****************************************************************
 
3130
/************************************************************//**
3094
3131
Checks the size and number of fields in a record based on the definition of
3095
 
the index. */
 
3132
the index.
 
3133
@return TRUE if ok */
3096
3134
UNIV_INTERN
3097
3135
ibool
3098
3136
btr_index_rec_validate(
3099
3137
/*===================*/
3100
 
                                                /* out: TRUE if ok */
3101
 
        const rec_t*            rec,            /* in: index record */
3102
 
        const dict_index_t*     index,          /* in: index */
3103
 
        ibool                   dump_on_error)  /* in: TRUE if the function
 
3138
        const rec_t*            rec,            /*!< in: index record */
 
3139
        const dict_index_t*     index,          /*!< in: index */
 
3140
        ibool                   dump_on_error)  /*!< in: TRUE if the function
3104
3141
                                                should print hex dump of record
3105
3142
                                                and page on error */
3106
3143
{
3155
3192
 
3156
3193
        for (i = 0; i < n; i++) {
3157
3194
                ulint   fixed_size = dict_col_get_fixed_size(
3158
 
                        dict_index_get_nth_col(index, i));
 
3195
                        dict_index_get_nth_col(index, i), page_is_comp(page));
3159
3196
 
3160
3197
                rec_get_nth_field_offs(offsets, i, &len);
3161
3198
 
3199
3236
        return(TRUE);
3200
3237
}
3201
3238
 
3202
 
/****************************************************************
 
3239
/************************************************************//**
3203
3240
Checks the size and number of fields in records based on the definition of
3204
 
the index. */
 
3241
the index.
 
3242
@return TRUE if ok */
3205
3243
static
3206
3244
ibool
3207
3245
btr_index_page_validate(
3208
3246
/*====================*/
3209
 
                                /* out: TRUE if ok */
3210
 
        buf_block_t*    block,  /* in: index page */
3211
 
        dict_index_t*   index)  /* in: index */
 
3247
        buf_block_t*    block,  /*!< in: index page */
 
3248
        dict_index_t*   index)  /*!< in: index */
3212
3249
{
3213
3250
        page_cur_t      cur;
3214
3251
        ibool           ret     = TRUE;
3233
3270
        return(ret);
3234
3271
}
3235
3272
 
3236
 
/****************************************************************
 
3273
/************************************************************//**
3237
3274
Report an error on one page of an index tree. */
3238
3275
static
3239
3276
void
3240
3277
btr_validate_report1(
3241
3278
/*=================*/
3242
 
                                        /* out: TRUE if ok */
3243
 
        dict_index_t*           index,  /* in: index */
3244
 
        ulint                   level,  /* in: B-tree level */
3245
 
        const buf_block_t*      block)  /* in: index page */
 
3279
        dict_index_t*           index,  /*!< in: index */
 
3280
        ulint                   level,  /*!< in: B-tree level */
 
3281
        const buf_block_t*      block)  /*!< in: index page */
3246
3282
{
3247
3283
        fprintf(stderr, "InnoDB: Error in page %lu of ",
3248
3284
                buf_block_get_page_no(block));
3253
3289
        putc('\n', stderr);
3254
3290
}
3255
3291
 
3256
 
/****************************************************************
 
3292
/************************************************************//**
3257
3293
Report an error on two pages of an index tree. */
3258
3294
static
3259
3295
void
3260
3296
btr_validate_report2(
3261
3297
/*=================*/
3262
 
                                        /* out: TRUE if ok */
3263
 
        const dict_index_t*     index,  /* in: index */
3264
 
        ulint                   level,  /* in: B-tree level */
3265
 
        const buf_block_t*      block1, /* in: first index page */
3266
 
        const buf_block_t*      block2) /* in: second index page */
 
3298
        const dict_index_t*     index,  /*!< in: index */
 
3299
        ulint                   level,  /*!< in: B-tree level */
 
3300
        const buf_block_t*      block1, /*!< in: first index page */
 
3301
        const buf_block_t*      block2) /*!< in: second index page */
3267
3302
{
3268
3303
        fprintf(stderr, "InnoDB: Error in pages %lu and %lu of ",
3269
3304
                buf_block_get_page_no(block1),
3275
3310
        putc('\n', stderr);
3276
3311
}
3277
3312
 
3278
 
/****************************************************************
3279
 
Validates index tree level. */
 
3313
/************************************************************//**
 
3314
Validates index tree level.
 
3315
@return TRUE if ok */
3280
3316
static
3281
3317
ibool
3282
3318
btr_validate_level(
3283
3319
/*===============*/
3284
 
                                /* out: TRUE if ok */
3285
 
        dict_index_t*   index,  /* in: index tree */
3286
 
        trx_t*          trx,    /* in: transaction or NULL */
3287
 
        ulint           level)  /* in: level number */
 
3320
        dict_index_t*   index,  /*!< in: index tree */
 
3321
        trx_t*          trx,    /*!< in: transaction or NULL */
 
3322
        ulint           level)  /*!< in: level number */
3288
3323
{
3289
3324
        ulint           space;
3290
3325
        ulint           zip_size;
3621
3656
        return(ret);
3622
3657
}
3623
3658
 
3624
 
/******************************************************************
3625
 
Checks the consistency of an index tree. */
 
3659
/**************************************************************//**
 
3660
Checks the consistency of an index tree.
 
3661
@return TRUE if ok */
3626
3662
UNIV_INTERN
3627
3663
ibool
3628
3664
btr_validate_index(
3629
3665
/*===============*/
3630
 
                                /* out: TRUE if ok */
3631
 
        dict_index_t*   index,  /* in: index */
3632
 
        trx_t*          trx)    /* in: transaction or NULL */
 
3666
        dict_index_t*   index,  /*!< in: index */
 
3667
        trx_t*          trx)    /*!< in: transaction or NULL */
3633
3668
{
3634
3669
        mtr_t   mtr;
3635
3670
        page_t* root;
3655
3690
 
3656
3691
        return(TRUE);
3657
3692
}
 
3693
#endif /* !UNIV_HOTBACKUP */