~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2009-08-12 06:25:19 UTC
  • mto: (1114.1.1 innodb-plugin-merge)
  • mto: This revision was merged to the branch mainline in revision 1183.
  • Revision ID: mordred@inaugust.com-20090812062519-cij02mrrunvnxblt
Tags: innodb-plugin-1.0.4
InnoDB Plugin 1.0.4

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