~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge Monty

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 
24
24
*****************************************************************************/
25
25
 
26
 
/******************************************************
 
26
/**************************************************//**
 
27
@file btr/btr0cur.c
27
28
The index tree cursor
28
29
 
29
30
All changes that row operations make to a B-tree or the records
46
47
#include "btr0cur.ic"
47
48
#endif
48
49
 
 
50
#include "row0upd.h"
 
51
#ifndef UNIV_HOTBACKUP
 
52
#include "mtr0log.h"
49
53
#include "page0page.h"
50
54
#include "page0zip.h"
51
55
#include "rem0rec.h"
53
57
#include "buf0lru.h"
54
58
#include "btr0btr.h"
55
59
#include "btr0sea.h"
56
 
#include "row0upd.h"
57
60
#include "trx0rec.h"
58
61
#include "trx0roll.h" /* trx_is_recv() */
59
62
#include "que0que.h"
64
67
#include "zlib.h"
65
68
 
66
69
#ifdef UNIV_DEBUG
67
 
/* If the following is set to TRUE, this module prints a lot of
 
70
/** If the following is set to TRUE, this module prints a lot of
68
71
trace information of individual record operations */
69
72
UNIV_INTERN ibool       btr_cur_print_record_ops = FALSE;
70
73
#endif /* UNIV_DEBUG */
71
74
 
 
75
/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
72
76
UNIV_INTERN ulint       btr_cur_n_non_sea       = 0;
 
77
/** Number of successful adaptive hash index lookups in
 
78
btr_cur_search_to_nth_level(). */
73
79
UNIV_INTERN ulint       btr_cur_n_sea           = 0;
 
80
/** Old value of btr_cur_n_non_sea.  Copied by
 
81
srv_refresh_innodb_monitor_stats().  Referenced by
 
82
srv_printf_innodb_monitor(). */
74
83
UNIV_INTERN ulint       btr_cur_n_non_sea_old   = 0;
 
84
/** Old value of btr_cur_n_sea.  Copied by
 
85
srv_refresh_innodb_monitor_stats().  Referenced by
 
86
srv_printf_innodb_monitor(). */
75
87
UNIV_INTERN ulint       btr_cur_n_sea_old       = 0;
76
88
 
77
 
/* In the optimistic insert, if the insert does not fit, but this much space
 
89
/** In the optimistic insert, if the insert does not fit, but this much space
78
90
can be released by page reorganize, then it is reorganized */
79
 
 
80
91
#define BTR_CUR_PAGE_REORGANIZE_LIMIT   (UNIV_PAGE_SIZE / 32)
81
92
 
82
 
/* The structure of a BLOB part header */
 
93
/** The structure of a BLOB part header */
 
94
/* @{ */
83
95
/*--------------------------------------*/
84
 
#define BTR_BLOB_HDR_PART_LEN           0       /* BLOB part len on this
 
96
#define BTR_BLOB_HDR_PART_LEN           0       /*!< BLOB part len on this
85
97
                                                page */
86
 
#define BTR_BLOB_HDR_NEXT_PAGE_NO       4       /* next BLOB part page no,
 
98
#define BTR_BLOB_HDR_NEXT_PAGE_NO       4       /*!< next BLOB part page no,
87
99
                                                FIL_NULL if none */
88
100
/*--------------------------------------*/
89
 
#define BTR_BLOB_HDR_SIZE               8
 
101
#define BTR_BLOB_HDR_SIZE               8       /*!< Size of a BLOB
 
102
                                                part header, in bytes */
 
103
/* @} */
 
104
#endif /* !UNIV_HOTBACKUP */
90
105
 
91
 
/* A BLOB field reference full of zero, for use in assertions and tests.
 
106
/** A BLOB field reference full of zero, for use in assertions and tests.
92
107
Initially, BLOB field references are set to zero, in
93
108
dtuple_convert_big_rec(). */
94
 
UNIV_INTERN const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE]=
95
 
  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
109
UNIV_INTERN const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE]= {0};
96
110
 
97
 
/***********************************************************************
 
111
#ifndef UNIV_HOTBACKUP
 
112
/*******************************************************************//**
98
113
Marks all extern fields in a record as owned by the record. This function
99
114
should be called if the delete mark of a record is removed: a not delete
100
115
marked record always owns all its extern fields. */
102
117
void
103
118
btr_cur_unmark_extern_fields(
104
119
/*=========================*/
105
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
 
120
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
106
121
                                part will be updated, or NULL */
107
 
        rec_t*          rec,    /* in/out: record in a clustered index */
108
 
        dict_index_t*   index,  /* in: index of the page */
109
 
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
110
 
        mtr_t*          mtr);   /* in: mtr, or NULL if not logged */
111
 
/***********************************************************************
 
122
        rec_t*          rec,    /*!< in/out: record in a clustered index */
 
123
        dict_index_t*   index,  /*!< in: index of the page */
 
124
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
125
        mtr_t*          mtr);   /*!< in: mtr, or NULL if not logged */
 
126
/*******************************************************************//**
112
127
Adds path information to the cursor for the current page, for which
113
128
the binary search has been performed. */
114
129
static
115
130
void
116
131
btr_cur_add_path_info(
117
132
/*==================*/
118
 
        btr_cur_t*      cursor,         /* in: cursor positioned on a page */
119
 
        ulint           height,         /* in: height of the page in tree;
 
133
        btr_cur_t*      cursor,         /*!< in: cursor positioned on a page */
 
134
        ulint           height,         /*!< in: height of the page in tree;
120
135
                                        0 means leaf node */
121
 
        ulint           root_height);   /* in: root node height in tree */
122
 
/***************************************************************
 
136
        ulint           root_height);   /*!< in: root node height in tree */
 
137
/***********************************************************//**
123
138
Frees the externally stored fields for a record, if the field is mentioned
124
139
in the update vector. */
125
140
static
126
141
void
127
142
btr_rec_free_updated_extern_fields(
128
143
/*===============================*/
129
 
        dict_index_t*   index,  /* in: index of rec; the index tree MUST be
 
144
        dict_index_t*   index,  /*!< in: index of rec; the index tree MUST be
130
145
                                X-latched */
131
 
        rec_t*          rec,    /* in: record */
132
 
        page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
 
146
        rec_t*          rec,    /*!< in: record */
 
147
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
133
148
                                part will be updated, or NULL */
134
 
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
135
 
        const upd_t*    update, /* in: update vector */
136
 
        enum trx_rb_ctx rb_ctx, /* in: rollback context */
137
 
        mtr_t*          mtr);   /* in: mini-transaction handle which contains
 
149
        const ulint*    offsets,/*!< in: rec_get_offsets(rec, index) */
 
150
        const upd_t*    update, /*!< in: update vector */
 
151
        enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
 
152
        mtr_t*          mtr);   /*!< in: mini-transaction handle which contains
138
153
                                an X-latch to record page and to the tree */
139
 
/***************************************************************
 
154
/***********************************************************//**
140
155
Frees the externally stored fields for a record. */
141
156
static
142
157
void
143
158
btr_rec_free_externally_stored_fields(
144
159
/*==================================*/
145
 
        dict_index_t*   index,  /* in: index of the data, the index
 
160
        dict_index_t*   index,  /*!< in: index of the data, the index
146
161
                                tree MUST be X-latched */
147
 
        rec_t*          rec,    /* in: record */
148
 
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
149
 
        page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
 
162
        rec_t*          rec,    /*!< in: record */
 
163
        const ulint*    offsets,/*!< in: rec_get_offsets(rec, index) */
 
164
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
150
165
                                part will be updated, or NULL */
151
 
        enum trx_rb_ctx rb_ctx, /* in: rollback context */
152
 
        mtr_t*          mtr);   /* in: mini-transaction handle which contains
 
166
        enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
 
167
        mtr_t*          mtr);   /*!< in: mini-transaction handle which contains
153
168
                                an X-latch to record page and to the index
154
169
                                tree */
155
 
/***************************************************************
156
 
Gets the externally stored size of a record, in units of a database page. */
 
170
/***********************************************************//**
 
171
Gets the externally stored size of a record, in units of a database page.
 
172
@return externally stored part, in units of a database page */
157
173
static
158
174
ulint
159
175
btr_rec_get_externally_stored_len(
160
176
/*==============================*/
161
 
                                /* out: externally stored part,
162
 
                                in units of a database page */
163
 
        rec_t*          rec,    /* in: record */
164
 
        const ulint*    offsets);/* in: array returned by rec_get_offsets() */
 
177
        rec_t*          rec,    /*!< in: record */
 
178
        const ulint*    offsets);/*!< in: array returned by rec_get_offsets() */
 
179
#endif /* !UNIV_HOTBACKUP */
165
180
 
166
 
/**********************************************************
 
181
/******************************************************//**
167
182
The following function is used to set the deleted bit of a record. */
168
183
UNIV_INLINE
169
184
void
170
185
btr_rec_set_deleted_flag(
171
186
/*=====================*/
172
 
                                /* out: TRUE on success;
173
 
                                FALSE on page_zip overflow */
174
 
        rec_t*          rec,    /* in/out: physical record */
175
 
        page_zip_des_t* page_zip,/* in/out: compressed page (or NULL) */
176
 
        ulint           flag)   /* in: nonzero if delete marked */
 
187
        rec_t*          rec,    /*!< in/out: physical record */
 
188
        page_zip_des_t* page_zip,/*!< in/out: compressed page (or NULL) */
 
189
        ulint           flag)   /*!< in: nonzero if delete marked */
177
190
{
178
191
        if (page_rec_is_comp(rec)) {
179
192
                rec_set_deleted_flag_new(rec, page_zip, flag);
183
196
        }
184
197
}
185
198
 
 
199
#ifndef UNIV_HOTBACKUP
186
200
/*==================== B-TREE SEARCH =========================*/
187
201
 
188
 
/************************************************************************
 
202
/********************************************************************//**
189
203
Latches the leaf page or pages requested. */
190
204
static
191
205
void
192
206
btr_cur_latch_leaves(
193
207
/*=================*/
194
 
        page_t*         page,           /* in: leaf page where the search
 
208
        page_t*         page,           /*!< in: leaf page where the search
195
209
                                        converged */
196
 
        ulint           space,          /* in: space id */
197
 
        ulint           zip_size,       /* in: compressed page size in bytes
 
210
        ulint           space,          /*!< in: space id */
 
211
        ulint           zip_size,       /*!< in: compressed page size in bytes
198
212
                                        or 0 for uncompressed pages */
199
 
        ulint           page_no,        /* in: page number of the leaf */
200
 
        ulint           latch_mode,     /* in: BTR_SEARCH_LEAF, ... */
201
 
        btr_cur_t*      cursor,         /* in: cursor */
202
 
        mtr_t*          mtr)            /* in: mtr */
 
213
        ulint           page_no,        /*!< in: page number of the leaf */
 
214
        ulint           latch_mode,     /*!< in: BTR_SEARCH_LEAF, ... */
 
215
        btr_cur_t*      cursor,         /*!< in: cursor */
 
216
        mtr_t*          mtr)            /*!< in: mtr */
203
217
{
204
218
        ulint           mode;
205
219
        ulint           left_page_no;
289
303
        ut_error;
290
304
}
291
305
 
292
 
/************************************************************************
 
306
/********************************************************************//**
293
307
Searches an index tree and positions a tree cursor on a given level.
294
308
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
295
309
to node pointer page number fields on the upper levels of the tree!
305
319
void
306
320
btr_cur_search_to_nth_level(
307
321
/*========================*/
308
 
        dict_index_t*   index,  /* in: index */
309
 
        ulint           level,  /* in: the tree level of search */
310
 
        const dtuple_t* tuple,  /* in: data tuple; NOTE: n_fields_cmp in
 
322
        dict_index_t*   index,  /*!< in: index */
 
323
        ulint           level,  /*!< in: the tree level of search */
 
324
        const dtuple_t* tuple,  /*!< in: data tuple; NOTE: n_fields_cmp in
311
325
                                tuple must be set so that it cannot get
312
326
                                compared to the node ptr page number field! */
313
 
        ulint           mode,   /* in: PAGE_CUR_L, ...;
 
327
        ulint           mode,   /*!< in: PAGE_CUR_L, ...;
314
328
                                Inserts should always be made using
315
329
                                PAGE_CUR_LE to search the position! */
316
 
        ulint           latch_mode, /* in: BTR_SEARCH_LEAF, ..., ORed with
 
330
        ulint           latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
317
331
                                BTR_INSERT and BTR_ESTIMATE;
318
332
                                cursor->left_block is used to store a pointer
319
333
                                to the left neighbor page, in the cases
323
337
                                on the cursor page, we assume
324
338
                                the caller uses his search latch
325
339
                                to protect the record! */
326
 
        btr_cur_t*      cursor, /* in/out: tree cursor; the cursor page is
 
340
        btr_cur_t*      cursor, /*!< in/out: tree cursor; the cursor page is
327
341
                                s- or x-latched, but see also above! */
328
 
        ulint           has_search_latch,/* in: info on the latch mode the
 
342
        ulint           has_search_latch,/*!< in: info on the latch mode the
329
343
                                caller currently has on btr_search_latch:
330
344
                                RW_S_LATCH, or 0 */
331
 
        mtr_t*          mtr)    /* in: mtr */
 
345
        mtr_t*          mtr)    /*!< in: mtr */
332
346
{
333
347
        page_cur_t*     page_cursor;
334
348
        page_t*         page;
659
673
        }
660
674
}
661
675
 
662
 
/*********************************************************************
 
676
/*****************************************************************//**
663
677
Opens a cursor at either end of an index. */
664
678
UNIV_INTERN
665
679
void
666
680
btr_cur_open_at_index_side(
667
681
/*=======================*/
668
 
        ibool           from_left,      /* in: TRUE if open to the low end,
 
682
        ibool           from_left,      /*!< in: TRUE if open to the low end,
669
683
                                        FALSE if to the high end */
670
 
        dict_index_t*   index,          /* in: index */
671
 
        ulint           latch_mode,     /* in: latch mode */
672
 
        btr_cur_t*      cursor,         /* in: cursor */
673
 
        mtr_t*          mtr)            /* in: mtr */
 
684
        dict_index_t*   index,          /*!< in: index */
 
685
        ulint           latch_mode,     /*!< in: latch mode */
 
686
        btr_cur_t*      cursor,         /*!< in: cursor */
 
687
        mtr_t*          mtr)            /*!< in: mtr */
674
688
{
675
689
        page_cur_t*     page_cursor;
676
690
        ulint           page_no;
790
804
        }
791
805
}
792
806
 
793
 
/**************************************************************************
 
807
/**********************************************************************//**
794
808
Positions a cursor at a randomly chosen position within a B-tree. */
795
809
UNIV_INTERN
796
810
void
797
811
btr_cur_open_at_rnd_pos(
798
812
/*====================*/
799
 
        dict_index_t*   index,          /* in: index */
800
 
        ulint           latch_mode,     /* in: BTR_SEARCH_LEAF, ... */
801
 
        btr_cur_t*      cursor,         /* in/out: B-tree cursor */
802
 
        mtr_t*          mtr)            /* in: mtr */
 
813
        dict_index_t*   index,          /*!< in: index */
 
814
        ulint           latch_mode,     /*!< in: BTR_SEARCH_LEAF, ... */
 
815
        btr_cur_t*      cursor,         /*!< in/out: B-tree cursor */
 
816
        mtr_t*          mtr)            /*!< in: mtr */
803
817
{
804
818
        page_cur_t*     page_cursor;
805
819
        ulint           page_no;
874
888
 
875
889
/*==================== B-TREE INSERT =========================*/
876
890
 
877
 
/*****************************************************************
 
891
/*************************************************************//**
878
892
Inserts a record if there is enough space, or if enough space can
879
893
be freed by reorganizing. Differs from btr_cur_optimistic_insert because
880
894
no heuristics is applied to whether it pays to use CPU time for
881
 
reorganizing the page or not. */
 
895
reorganizing the page or not.
 
896
@return pointer to inserted record if succeed, else NULL */
882
897
static
883
898
rec_t*
884
899
btr_cur_insert_if_possible(
885
900
/*=======================*/
886
 
                                /* out: pointer to inserted record if succeed,
887
 
                                else NULL */
888
 
        btr_cur_t*      cursor, /* in: cursor on page after which to insert;
 
901
        btr_cur_t*      cursor, /*!< in: cursor on page after which to insert;
889
902
                                cursor stays valid */
890
 
        const dtuple_t* tuple,  /* in: tuple to insert; the size info need not
 
903
        const dtuple_t* tuple,  /*!< in: tuple to insert; the size info need not
891
904
                                have been stored to tuple */
892
 
        ulint           n_ext,  /* in: number of externally stored columns */
893
 
        mtr_t*          mtr)    /* in: mtr */
 
905
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
906
        mtr_t*          mtr)    /*!< in: mtr */
894
907
{
895
908
        page_cur_t*     page_cursor;
896
909
        buf_block_t*    block;
923
936
        return(rec);
924
937
}
925
938
 
926
 
/*****************************************************************
927
 
For an insert, checks the locks and does the undo logging if desired. */
 
939
/*************************************************************//**
 
940
For an insert, checks the locks and does the undo logging if desired.
 
941
@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
928
942
UNIV_INLINE
929
943
ulint
930
944
btr_cur_ins_lock_and_undo(
931
945
/*======================*/
932
 
                                /* out: DB_SUCCESS, DB_WAIT_LOCK,
933
 
                                DB_FAIL, or error number */
934
 
        ulint           flags,  /* in: undo logging and locking flags: if
 
946
        ulint           flags,  /*!< in: undo logging and locking flags: if
935
947
                                not zero, the parameters index and thr
936
948
                                should be specified */
937
 
        btr_cur_t*      cursor, /* in: cursor on page after which to insert */
938
 
        const dtuple_t* entry,  /* in: entry to insert */
939
 
        que_thr_t*      thr,    /* in: query thread or NULL */
940
 
        ibool*          inherit)/* out: TRUE if the inserted new record maybe
 
949
        btr_cur_t*      cursor, /*!< in: cursor on page after which to insert */
 
950
        const dtuple_t* entry,  /*!< in: entry to insert */
 
951
        que_thr_t*      thr,    /*!< in: query thread or NULL */
 
952
        mtr_t*          mtr,    /*!< in/out: mini-transaction */
 
953
        ibool*          inherit)/*!< out: TRUE if the inserted new record maybe
941
954
                                should inherit LOCK_GAP type locks from the
942
955
                                successor record */
943
956
{
944
957
        dict_index_t*   index;
945
958
        ulint           err;
946
959
        rec_t*          rec;
947
 
        dulint          roll_ptr;
 
960
        roll_ptr_t      roll_ptr;
948
961
 
949
962
        /* Check if we have to wait for a lock: enqueue an explicit lock
950
963
        request if yes */
954
967
 
955
968
        err = lock_rec_insert_check_and_lock(flags, rec,
956
969
                                             btr_cur_get_block(cursor),
957
 
                                             index, thr, inherit);
 
970
                                             index, thr, mtr, inherit);
958
971
 
959
972
        if (err != DB_SUCCESS) {
960
973
 
985
998
}
986
999
 
987
1000
#ifdef UNIV_DEBUG
988
 
/*****************************************************************
 
1001
/*************************************************************//**
989
1002
Report information about a transaction. */
990
1003
static
991
1004
void
992
1005
btr_cur_trx_report(
993
1006
/*===============*/
994
 
        trx_t*                  trx,    /* in: transaction */
995
 
        const dict_index_t*     index,  /* in: index */
996
 
        const char*             op)     /* in: operation */
 
1007
        trx_t*                  trx,    /*!< in: transaction */
 
1008
        const dict_index_t*     index,  /*!< in: index */
 
1009
        const char*             op)     /*!< in: operation */
997
1010
{
998
1011
        fprintf(stderr, "Trx with id " TRX_ID_FMT " going to ",
999
1012
                TRX_ID_PREP_PRINTF(trx->id));
1003
1016
}
1004
1017
#endif /* UNIV_DEBUG */
1005
1018
 
1006
 
/*****************************************************************
 
1019
/*************************************************************//**
1007
1020
Tries to perform an insert to a page in an index tree, next to cursor.
1008
1021
It is assumed that mtr holds an x-latch on the page. The operation does
1009
1022
not succeed if there is too little space on the page. If there is just
1010
1023
one record on the page, the insert will always succeed; this is to
1011
 
prevent trying to split a page with just one record. */
 
1024
prevent trying to split a page with just one record.
 
1025
@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
1012
1026
UNIV_INTERN
1013
1027
ulint
1014
1028
btr_cur_optimistic_insert(
1015
1029
/*======================*/
1016
 
                                /* out: DB_SUCCESS, DB_WAIT_LOCK,
1017
 
                                DB_FAIL, or error number */
1018
 
        ulint           flags,  /* in: undo logging and locking flags: if not
 
1030
        ulint           flags,  /*!< in: undo logging and locking flags: if not
1019
1031
                                zero, the parameters index and thr should be
1020
1032
                                specified */
1021
 
        btr_cur_t*      cursor, /* in: cursor on page after which to insert;
 
1033
        btr_cur_t*      cursor, /*!< in: cursor on page after which to insert;
1022
1034
                                cursor stays valid */
1023
 
        dtuple_t*       entry,  /* in/out: entry to insert */
1024
 
        rec_t**         rec,    /* out: pointer to inserted record if
 
1035
        dtuple_t*       entry,  /*!< in/out: entry to insert */
 
1036
        rec_t**         rec,    /*!< out: pointer to inserted record if
1025
1037
                                succeed */
1026
 
        big_rec_t**     big_rec,/* out: big rec vector whose fields have to
 
1038
        big_rec_t**     big_rec,/*!< out: big rec vector whose fields have to
1027
1039
                                be stored externally by the caller, or
1028
1040
                                NULL */
1029
 
        ulint           n_ext,  /* in: number of externally stored columns */
1030
 
        que_thr_t*      thr,    /* in: query thread or NULL */
1031
 
        mtr_t*          mtr)    /* in: mtr; if this function returns
 
1041
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
1042
        que_thr_t*      thr,    /*!< in: query thread or NULL */
 
1043
        mtr_t*          mtr)    /*!< in: mtr; if this function returns
1032
1044
                                DB_SUCCESS on a leaf page of a secondary
1033
1045
                                index in a compressed tablespace, the
1034
1046
                                mtr must be committed before latching
1168
1180
        }
1169
1181
 
1170
1182
        /* Check locks and write to the undo log, if specified */
1171
 
        err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &inherit);
 
1183
        err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
 
1184
                                        thr, mtr, &inherit);
1172
1185
 
1173
1186
        if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1174
1187
 
1248
1261
                buf_block_get_page_no(block), max_size,
1249
1262
                rec_size + PAGE_DIR_SLOT_SIZE, index->type);
1250
1263
#endif
1251
 
        if (leaf
1252
 
            && !dict_index_is_clust(index)
1253
 
            && !dict_index_is_ibuf(index)) {
 
1264
        if (leaf && !dict_index_is_clust(index)) {
1254
1265
                /* Update the free bits of the B-tree page in the
1255
1266
                insert buffer bitmap. */
1256
1267
 
1281
1292
        return(DB_SUCCESS);
1282
1293
}
1283
1294
 
1284
 
/*****************************************************************
 
1295
/*************************************************************//**
1285
1296
Performs an insert on a page of an index tree. It is assumed that mtr
1286
1297
holds an x-latch on the tree and on the cursor page. If the insert is
1287
1298
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
1288
 
to brothers of page, if those brothers exist. */
 
1299
to brothers of page, if those brothers exist.
 
1300
@return DB_SUCCESS or error number */
1289
1301
UNIV_INTERN
1290
1302
ulint
1291
1303
btr_cur_pessimistic_insert(
1292
1304
/*=======================*/
1293
 
                                /* out: DB_SUCCESS or error number */
1294
 
        ulint           flags,  /* in: undo logging and locking flags: if not
 
1305
        ulint           flags,  /*!< in: undo logging and locking flags: if not
1295
1306
                                zero, the parameter thr should be
1296
1307
                                specified; if no undo logging is specified,
1297
1308
                                then the caller must have reserved enough
1298
1309
                                free extents in the file space so that the
1299
1310
                                insertion will certainly succeed */
1300
 
        btr_cur_t*      cursor, /* in: cursor after which to insert;
 
1311
        btr_cur_t*      cursor, /*!< in: cursor after which to insert;
1301
1312
                                cursor stays valid */
1302
 
        dtuple_t*       entry,  /* in/out: entry to insert */
1303
 
        rec_t**         rec,    /* out: pointer to inserted record if
 
1313
        dtuple_t*       entry,  /*!< in/out: entry to insert */
 
1314
        rec_t**         rec,    /*!< out: pointer to inserted record if
1304
1315
                                succeed */
1305
 
        big_rec_t**     big_rec,/* out: big rec vector whose fields have to
 
1316
        big_rec_t**     big_rec,/*!< out: big rec vector whose fields have to
1306
1317
                                be stored externally by the caller, or
1307
1318
                                NULL */
1308
 
        ulint           n_ext,  /* in: number of externally stored columns */
1309
 
        que_thr_t*      thr,    /* in: query thread or NULL */
1310
 
        mtr_t*          mtr)    /* in: mtr */
 
1319
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
1320
        que_thr_t*      thr,    /*!< in: query thread or NULL */
 
1321
        mtr_t*          mtr)    /*!< in: mtr */
1311
1322
{
1312
1323
        dict_index_t*   index           = cursor->index;
1313
1324
        ulint           zip_size        = dict_table_zip_size(index->table);
1344
1355
        /* Retry with a pessimistic insert. Check locks and write to undo log,
1345
1356
        if specified */
1346
1357
 
1347
 
        err = btr_cur_ins_lock_and_undo(flags, cursor, entry, thr, &dummy_inh);
 
1358
        err = btr_cur_ins_lock_and_undo(flags, cursor, entry,
 
1359
                                        thr, mtr, &dummy_inh);
1348
1360
 
1349
1361
        if (err != DB_SUCCESS) {
1350
1362
 
1425
1437
 
1426
1438
/*==================== B-TREE UPDATE =========================*/
1427
1439
 
1428
 
/*****************************************************************
1429
 
For an update, checks the locks and does the undo logging. */
 
1440
/*************************************************************//**
 
1441
For an update, checks the locks and does the undo logging.
 
1442
@return DB_SUCCESS, DB_WAIT_LOCK, or error number */
1430
1443
UNIV_INLINE
1431
1444
ulint
1432
1445
btr_cur_upd_lock_and_undo(
1433
1446
/*======================*/
1434
 
                                /* out: DB_SUCCESS, DB_WAIT_LOCK, or error
1435
 
                                number */
1436
 
        ulint           flags,  /* in: undo logging and locking flags */
1437
 
        btr_cur_t*      cursor, /* in: cursor on record to update */
1438
 
        const upd_t*    update, /* in: update vector */
1439
 
        ulint           cmpl_info,/* in: compiler info on secondary index
 
1447
        ulint           flags,  /*!< in: undo logging and locking flags */
 
1448
        btr_cur_t*      cursor, /*!< in: cursor on record to update */
 
1449
        const upd_t*    update, /*!< in: update vector */
 
1450
        ulint           cmpl_info,/*!< in: compiler info on secondary index
1440
1451
                                updates */
1441
 
        que_thr_t*      thr,    /* in: query thread */
1442
 
        dulint*         roll_ptr)/* out: roll pointer */
 
1452
        que_thr_t*      thr,    /*!< in: query thread */
 
1453
        mtr_t*          mtr,    /*!< in/out: mini-transaction */
 
1454
        roll_ptr_t*     roll_ptr)/*!< out: roll pointer */
1443
1455
{
1444
1456
        dict_index_t*   index;
1445
1457
        rec_t*          rec;
1455
1467
                record */
1456
1468
                return(lock_sec_rec_modify_check_and_lock(
1457
1469
                               flags, btr_cur_get_block(cursor), rec,
1458
 
                               index, thr));
 
1470
                               index, thr, mtr));
1459
1471
        }
1460
1472
 
1461
1473
        /* Check if we have to wait for a lock: enqueue an explicit lock
1489
1501
        return(err);
1490
1502
}
1491
1503
 
1492
 
/***************************************************************
 
1504
/***********************************************************//**
1493
1505
Writes a redo log record of updating a record in-place. */
1494
1506
UNIV_INLINE
1495
1507
void
1496
1508
btr_cur_update_in_place_log(
1497
1509
/*========================*/
1498
 
        ulint           flags,          /* in: flags */
1499
 
        rec_t*          rec,            /* in: record */
1500
 
        dict_index_t*   index,          /* in: index where cursor positioned */
1501
 
        const upd_t*    update,         /* in: update vector */
1502
 
        trx_t*          trx,            /* in: transaction */
1503
 
        dulint          roll_ptr,       /* in: roll ptr */
1504
 
        mtr_t*          mtr)            /* in: mtr */
 
1510
        ulint           flags,          /*!< in: flags */
 
1511
        rec_t*          rec,            /*!< in: record */
 
1512
        dict_index_t*   index,          /*!< in: index where cursor positioned */
 
1513
        const upd_t*    update,         /*!< in: update vector */
 
1514
        trx_t*          trx,            /*!< in: transaction */
 
1515
        roll_ptr_t      roll_ptr,       /*!< in: roll ptr */
 
1516
        mtr_t*          mtr)            /*!< in: mtr */
1505
1517
{
1506
1518
        byte*   log_ptr;
1507
1519
        page_t* page    = page_align(rec);
1536
1548
 
1537
1549
        row_upd_index_write_log(update, log_ptr, mtr);
1538
1550
}
 
1551
#endif /* UNIV_HOTBACKUP */
1539
1552
 
1540
 
/***************************************************************
1541
 
Parses a redo log record of updating a record in-place. */
 
1553
/***********************************************************//**
 
1554
Parses a redo log record of updating a record in-place.
 
1555
@return end of log record or NULL */
1542
1556
UNIV_INTERN
1543
1557
byte*
1544
1558
btr_cur_parse_update_in_place(
1545
1559
/*==========================*/
1546
 
                                /* out: end of log record or NULL */
1547
 
        byte*           ptr,    /* in: buffer */
1548
 
        byte*           end_ptr,/* in: buffer end */
1549
 
        page_t*         page,   /* in/out: page or NULL */
1550
 
        page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
1551
 
        dict_index_t*   index)  /* in: index corresponding to page */
 
1560
        byte*           ptr,    /*!< in: buffer */
 
1561
        byte*           end_ptr,/*!< in: buffer end */
 
1562
        page_t*         page,   /*!< in/out: page or NULL */
 
1563
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
1564
        dict_index_t*   index)  /*!< in: index corresponding to page */
1552
1565
{
1553
 
        ulint   flags;
1554
 
        rec_t*  rec;
1555
 
        upd_t*  update;
1556
 
        ulint   pos;
1557
 
        dulint  trx_id;
1558
 
        dulint  roll_ptr;
1559
 
        ulint   rec_offset;
1560
 
        mem_heap_t* heap;
1561
 
        ulint*  offsets;
 
1566
        ulint           flags;
 
1567
        rec_t*          rec;
 
1568
        upd_t*          update;
 
1569
        ulint           pos;
 
1570
        trx_id_t        trx_id;
 
1571
        roll_ptr_t      roll_ptr;
 
1572
        ulint           rec_offset;
 
1573
        mem_heap_t*     heap;
 
1574
        ulint*          offsets;
1562
1575
 
1563
1576
        if (end_ptr < ptr + 1) {
1564
1577
 
1615
1628
        return(ptr);
1616
1629
}
1617
1630
 
1618
 
/*****************************************************************
 
1631
#ifndef UNIV_HOTBACKUP
 
1632
/*************************************************************//**
1619
1633
See if there is enough place in the page modification log to log
1620
 
an update-in-place. */
 
1634
an update-in-place.
 
1635
@return TRUE if enough place */
1621
1636
static
1622
1637
ibool
1623
1638
btr_cur_update_alloc_zip(
1624
1639
/*=====================*/
1625
 
                                /* out: TRUE if enough place */
1626
 
        page_zip_des_t* page_zip,/* in/out: compressed page */
1627
 
        buf_block_t*    block,  /* in/out: buffer page */
1628
 
        dict_index_t*   index,  /* in: the index corresponding to the block */
1629
 
        ulint           length, /* in: size needed */
1630
 
        mtr_t*          mtr)    /* in: mini-transaction */
 
1640
        page_zip_des_t* page_zip,/*!< in/out: compressed page */
 
1641
        buf_block_t*    block,  /*!< in/out: buffer page */
 
1642
        dict_index_t*   index,  /*!< in: the index corresponding to the block */
 
1643
        ulint           length, /*!< in: size needed */
 
1644
        ibool           create, /*!< in: TRUE=delete-and-insert,
 
1645
                                FALSE=update-in-place */
 
1646
        mtr_t*          mtr)    /*!< in: mini-transaction */
1631
1647
{
1632
1648
        ut_a(page_zip == buf_block_get_page_zip(block));
1633
1649
        ut_ad(page_zip);
1634
1650
        ut_ad(!dict_index_is_ibuf(index));
1635
1651
 
1636
1652
        if (page_zip_available(page_zip, dict_index_is_clust(index),
1637
 
                               length, 0)) {
 
1653
                               length, create)) {
1638
1654
                return(TRUE);
1639
1655
        }
1640
1656
 
1661
1677
        the free space available on the page. */
1662
1678
 
1663
1679
        if (!page_zip_available(page_zip, dict_index_is_clust(index),
1664
 
                                length, 0)) {
 
1680
                                length, create)) {
1665
1681
                /* Out of space: reset the free bits. */
1666
1682
                if (!dict_index_is_clust(index)
1667
1683
                    && page_is_leaf(buf_block_get_frame(block))) {
1673
1689
        return(TRUE);
1674
1690
}
1675
1691
 
1676
 
/*****************************************************************
 
1692
/*************************************************************//**
1677
1693
Updates a record when the update causes no size changes in its fields.
1678
 
We assume here that the ordering fields of the record do not change. */
 
1694
We assume here that the ordering fields of the record do not change.
 
1695
@return DB_SUCCESS or error number */
1679
1696
UNIV_INTERN
1680
1697
ulint
1681
1698
btr_cur_update_in_place(
1682
1699
/*====================*/
1683
 
                                /* out: DB_SUCCESS or error number */
1684
 
        ulint           flags,  /* in: undo logging and locking flags */
1685
 
        btr_cur_t*      cursor, /* in: cursor on the record to update;
 
1700
        ulint           flags,  /*!< in: undo logging and locking flags */
 
1701
        btr_cur_t*      cursor, /*!< in: cursor on the record to update;
1686
1702
                                cursor stays valid and positioned on the
1687
1703
                                same record */
1688
 
        const upd_t*    update, /* in: update vector */
1689
 
        ulint           cmpl_info,/* in: compiler info on secondary index
 
1704
        const upd_t*    update, /*!< in: update vector */
 
1705
        ulint           cmpl_info,/*!< in: compiler info on secondary index
1690
1706
                                updates */
1691
 
        que_thr_t*      thr,    /* in: query thread */
1692
 
        mtr_t*          mtr)    /* in: mtr; must be committed before
 
1707
        que_thr_t*      thr,    /*!< in: query thread */
 
1708
        mtr_t*          mtr)    /*!< in: mtr; must be committed before
1693
1709
                                latching any further pages */
1694
1710
{
1695
1711
        dict_index_t*   index;
1697
1713
        page_zip_des_t* page_zip;
1698
1714
        ulint           err;
1699
1715
        rec_t*          rec;
1700
 
        dulint          roll_ptr        = ut_dulint_zero;
 
1716
        roll_ptr_t      roll_ptr        = ut_dulint_zero;
1701
1717
        trx_t*          trx;
1702
1718
        ulint           was_delete_marked;
1703
1719
        mem_heap_t*     heap            = NULL;
1726
1742
        /* Check that enough space is available on the compressed page. */
1727
1743
        if (UNIV_LIKELY_NULL(page_zip)
1728
1744
            && !btr_cur_update_alloc_zip(page_zip, block, index,
1729
 
                                         rec_offs_size(offsets), mtr)) {
 
1745
                                         rec_offs_size(offsets), FALSE, mtr)) {
1730
1746
                return(DB_ZIP_OVERFLOW);
1731
1747
        }
1732
1748
 
1733
1749
        /* Do lock checking and undo logging */
1734
1750
        err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
1735
 
                                        thr, &roll_ptr);
 
1751
                                        thr, mtr, &roll_ptr);
1736
1752
        if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1737
1753
 
1738
1754
                if (UNIV_LIKELY_NULL(heap)) {
1795
1811
        return(DB_SUCCESS);
1796
1812
}
1797
1813
 
1798
 
/*****************************************************************
 
1814
/*************************************************************//**
1799
1815
Tries to update a record on a page in an index tree. It is assumed that mtr
1800
1816
holds an x-latch on the page. The operation does not succeed if there is too
1801
1817
little space on the page or if the update would result in too empty a page,
1802
1818
so that tree compression is recommended. We assume here that the ordering
1803
 
fields of the record do not change. */
 
1819
fields of the record do not change.
 
1820
@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
 
1821
DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
 
1822
there is not enough space left on the compressed page */
1804
1823
UNIV_INTERN
1805
1824
ulint
1806
1825
btr_cur_optimistic_update(
1807
1826
/*======================*/
1808
 
                                /* out: DB_SUCCESS, or DB_OVERFLOW if the
1809
 
                                updated record does not fit, DB_UNDERFLOW
1810
 
                                if the page would become too empty, or
1811
 
                                DB_ZIP_OVERFLOW if there is not enough
1812
 
                                space left on the compressed page */
1813
 
        ulint           flags,  /* in: undo logging and locking flags */
1814
 
        btr_cur_t*      cursor, /* in: cursor on the record to update;
 
1827
        ulint           flags,  /*!< in: undo logging and locking flags */
 
1828
        btr_cur_t*      cursor, /*!< in: cursor on the record to update;
1815
1829
                                cursor stays valid and positioned on the
1816
1830
                                same record */
1817
 
        const upd_t*    update, /* in: update vector; this must also
 
1831
        const upd_t*    update, /*!< in: update vector; this must also
1818
1832
                                contain trx id and roll ptr fields */
1819
 
        ulint           cmpl_info,/* in: compiler info on secondary index
 
1833
        ulint           cmpl_info,/*!< in: compiler info on secondary index
1820
1834
                                updates */
1821
 
        que_thr_t*      thr,    /* in: query thread */
1822
 
        mtr_t*          mtr)    /* in: mtr; must be committed before
 
1835
        que_thr_t*      thr,    /*!< in: query thread */
 
1836
        mtr_t*          mtr)    /*!< in: mtr; must be committed before
1823
1837
                                latching any further pages */
1824
1838
{
1825
1839
        dict_index_t*   index;
1834
1848
        ulint           new_rec_size;
1835
1849
        ulint           old_rec_size;
1836
1850
        dtuple_t*       new_entry;
1837
 
        dulint          roll_ptr;
 
1851
        roll_ptr_t      roll_ptr;
1838
1852
        trx_t*          trx;
1839
1853
        mem_heap_t*     heap;
1840
1854
        ulint           i;
1910
1924
 
1911
1925
        if (UNIV_LIKELY_NULL(page_zip)
1912
1926
            && !btr_cur_update_alloc_zip(page_zip, block, index,
1913
 
                                         new_rec_size, mtr)) {
 
1927
                                         new_rec_size, TRUE, mtr)) {
1914
1928
                err = DB_ZIP_OVERFLOW;
1915
1929
                goto err_exit;
1916
1930
        }
1949
1963
        }
1950
1964
 
1951
1965
        /* Do lock checking and undo logging */
1952
 
        err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info, thr,
1953
 
                                        &roll_ptr);
 
1966
        err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
 
1967
                                        thr, mtr, &roll_ptr);
1954
1968
        if (err != DB_SUCCESS) {
1955
1969
err_exit:
1956
1970
                mem_heap_free(heap);
2005
2019
        return(DB_SUCCESS);
2006
2020
}
2007
2021
 
2008
 
/*****************************************************************
 
2022
/*************************************************************//**
2009
2023
If, in a split, a new supremum record was created as the predecessor of the
2010
2024
updated record, the supremum record must inherit exactly the locks on the
2011
2025
updated record. In the split it may have inherited locks from the successor
2015
2029
void
2016
2030
btr_cur_pess_upd_restore_supremum(
2017
2031
/*==============================*/
2018
 
        buf_block_t*    block,  /* in: buffer block of rec */
2019
 
        const rec_t*    rec,    /* in: updated record */
2020
 
        mtr_t*          mtr)    /* in: mtr */
 
2032
        buf_block_t*    block,  /*!< in: buffer block of rec */
 
2033
        const rec_t*    rec,    /*!< in: updated record */
 
2034
        mtr_t*          mtr)    /*!< in: mtr */
2021
2035
{
2022
2036
        page_t*         page;
2023
2037
        buf_block_t*    prev_block;
2053
2067
                                             page_rec_get_heap_no(rec));
2054
2068
}
2055
2069
 
2056
 
/*****************************************************************
 
2070
/*************************************************************//**
2057
2071
Performs an update of a record on a page of a tree. It is assumed
2058
2072
that mtr holds an x-latch on the tree and on the cursor page. If the
2059
2073
update is made on the leaf level, to avoid deadlocks, mtr must also
2060
2074
own x-latches to brothers of page, if those brothers exist. We assume
2061
 
here that the ordering fields of the record do not change. */
 
2075
here that the ordering fields of the record do not change.
 
2076
@return DB_SUCCESS or error code */
2062
2077
UNIV_INTERN
2063
2078
ulint
2064
2079
btr_cur_pessimistic_update(
2065
2080
/*=======================*/
2066
 
                                /* out: DB_SUCCESS or error code */
2067
 
        ulint           flags,  /* in: undo logging, locking, and rollback
 
2081
        ulint           flags,  /*!< in: undo logging, locking, and rollback
2068
2082
                                flags */
2069
 
        btr_cur_t*      cursor, /* in: cursor on the record to update */
2070
 
        mem_heap_t**    heap,   /* in/out: pointer to memory heap, or NULL */
2071
 
        big_rec_t**     big_rec,/* out: big rec vector whose fields have to
 
2083
        btr_cur_t*      cursor, /*!< in: cursor on the record to update */
 
2084
        mem_heap_t**    heap,   /*!< in/out: pointer to memory heap, or NULL */
 
2085
        big_rec_t**     big_rec,/*!< out: big rec vector whose fields have to
2072
2086
                                be stored externally by the caller, or NULL */
2073
 
        const upd_t*    update, /* in: update vector; this is allowed also
 
2087
        const upd_t*    update, /*!< in: update vector; this is allowed also
2074
2088
                                contain trx id and roll ptr fields, but
2075
2089
                                the values in update vector have no effect */
2076
 
        ulint           cmpl_info,/* in: compiler info on secondary index
 
2090
        ulint           cmpl_info,/*!< in: compiler info on secondary index
2077
2091
                                updates */
2078
 
        que_thr_t*      thr,    /* in: query thread */
2079
 
        mtr_t*          mtr)    /* in: mtr; must be committed before
 
2092
        que_thr_t*      thr,    /*!< in: query thread */
 
2093
        mtr_t*          mtr)    /*!< in: mtr; must be committed before
2080
2094
                                latching any further pages */
2081
2095
{
2082
2096
        big_rec_t*      big_rec_vec     = NULL;
2090
2104
        dtuple_t*       new_entry;
2091
2105
        ulint           err;
2092
2106
        ulint           optim_err;
2093
 
        dulint          roll_ptr;
 
2107
        roll_ptr_t      roll_ptr;
2094
2108
        trx_t*          trx;
2095
2109
        ibool           was_first;
2096
2110
        ulint           n_extents       = 0;
2129
2143
 
2130
2144
        /* Do lock checking and undo logging */
2131
2145
        err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
2132
 
                                        thr, &roll_ptr);
 
2146
                                        thr, mtr, &roll_ptr);
2133
2147
        if (err != DB_SUCCESS) {
2134
2148
 
2135
2149
                return(err);
2304
2318
        ut_a(err == DB_SUCCESS);
2305
2319
        ut_a(dummy_big_rec == NULL);
2306
2320
 
 
2321
        if (dict_index_is_sec_or_ibuf(index)) {
 
2322
                /* Update PAGE_MAX_TRX_ID in the index page header.
 
2323
                It was not updated by btr_cur_pessimistic_insert()
 
2324
                because of BTR_NO_LOCKING_FLAG. */
 
2325
                buf_block_t*    rec_block;
 
2326
 
 
2327
                rec_block = btr_cur_get_block(cursor);
 
2328
 
 
2329
                page_update_max_trx_id(rec_block,
 
2330
                                       buf_block_get_page_zip(rec_block),
 
2331
                                       trx->id, mtr);
 
2332
        }
 
2333
 
2307
2334
        if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
2308
2335
                /* The new inserted record owns its possible externally
2309
2336
                stored fields */
2350
2377
 
2351
2378
/*==================== B-TREE DELETE MARK AND UNMARK ===============*/
2352
2379
 
2353
 
/********************************************************************
 
2380
/****************************************************************//**
2354
2381
Writes the redo log record for delete marking or unmarking of an index
2355
2382
record. */
2356
2383
UNIV_INLINE
2357
2384
void
2358
2385
btr_cur_del_mark_set_clust_rec_log(
2359
2386
/*===============================*/
2360
 
        ulint           flags,  /* in: flags */
2361
 
        rec_t*          rec,    /* in: record */
2362
 
        dict_index_t*   index,  /* in: index of the record */
2363
 
        ibool           val,    /* in: value to set */
2364
 
        trx_t*          trx,    /* in: deleting transaction */
2365
 
        dulint          roll_ptr,/* in: roll ptr to the undo log record */
2366
 
        mtr_t*          mtr)    /* in: mtr */
 
2387
        ulint           flags,  /*!< in: flags */
 
2388
        rec_t*          rec,    /*!< in: record */
 
2389
        dict_index_t*   index,  /*!< in: index of the record */
 
2390
        ibool           val,    /*!< in: value to set */
 
2391
        trx_t*          trx,    /*!< in: deleting transaction */
 
2392
        roll_ptr_t      roll_ptr,/*!< in: roll ptr to the undo log record */
 
2393
        mtr_t*          mtr)    /*!< in: mtr */
2367
2394
{
2368
2395
        byte*   log_ptr;
2369
2396
        ut_ad(flags < 256);
2395
2422
 
2396
2423
        mlog_close(mtr, log_ptr);
2397
2424
}
 
2425
#endif /* !UNIV_HOTBACKUP */
2398
2426
 
2399
 
/********************************************************************
 
2427
/****************************************************************//**
2400
2428
Parses the redo log record for delete marking or unmarking of a clustered
2401
 
index record. */
 
2429
index record.
 
2430
@return end of log record or NULL */
2402
2431
UNIV_INTERN
2403
2432
byte*
2404
2433
btr_cur_parse_del_mark_set_clust_rec(
2405
2434
/*=================================*/
2406
 
                                /* out: end of log record or NULL */
2407
 
        byte*           ptr,    /* in: buffer */
2408
 
        byte*           end_ptr,/* in: buffer end */
2409
 
        page_t*         page,   /* in/out: page or NULL */
2410
 
        page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
2411
 
        dict_index_t*   index)  /* in: index corresponding to page */
 
2435
        byte*           ptr,    /*!< in: buffer */
 
2436
        byte*           end_ptr,/*!< in: buffer end */
 
2437
        page_t*         page,   /*!< in/out: page or NULL */
 
2438
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
2439
        dict_index_t*   index)  /*!< in: index corresponding to page */
2412
2440
{
2413
 
        ulint   flags;
2414
 
        ulint   val;
2415
 
        ulint   pos;
2416
 
        dulint  trx_id;
2417
 
        dulint  roll_ptr;
2418
 
        ulint   offset;
2419
 
        rec_t*  rec;
 
2441
        ulint           flags;
 
2442
        ulint           val;
 
2443
        ulint           pos;
 
2444
        trx_id_t        trx_id;
 
2445
        roll_ptr_t      roll_ptr;
 
2446
        ulint           offset;
 
2447
        rec_t*          rec;
2420
2448
 
2421
2449
        ut_ad(!page
2422
2450
              || !!page_is_comp(page) == dict_table_is_comp(index->table));
2476
2504
        return(ptr);
2477
2505
}
2478
2506
 
2479
 
/***************************************************************
 
2507
#ifndef UNIV_HOTBACKUP
 
2508
/***********************************************************//**
2480
2509
Marks a clustered index record deleted. Writes an undo log record to
2481
2510
undo log on this delete marking. Writes in the trx id field the id
2482
2511
of the deleting transaction, and in the roll ptr field pointer to the
2483
 
undo log record created. */
 
2512
undo log record created.
 
2513
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
2484
2514
UNIV_INTERN
2485
2515
ulint
2486
2516
btr_cur_del_mark_set_clust_rec(
2487
2517
/*===========================*/
2488
 
                                /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
2489
 
                                number */
2490
 
        ulint           flags,  /* in: undo logging and locking flags */
2491
 
        btr_cur_t*      cursor, /* in: cursor */
2492
 
        ibool           val,    /* in: value to set */
2493
 
        que_thr_t*      thr,    /* in: query thread */
2494
 
        mtr_t*          mtr)    /* in: mtr */
 
2518
        ulint           flags,  /*!< in: undo logging and locking flags */
 
2519
        btr_cur_t*      cursor, /*!< in: cursor */
 
2520
        ibool           val,    /*!< in: value to set */
 
2521
        que_thr_t*      thr,    /*!< in: query thread */
 
2522
        mtr_t*          mtr)    /*!< in: mtr */
2495
2523
{
2496
2524
        dict_index_t*   index;
2497
2525
        buf_block_t*    block;
2498
 
        dulint          roll_ptr;
 
2526
        roll_ptr_t      roll_ptr;
2499
2527
        ulint           err;
2500
2528
        rec_t*          rec;
2501
2529
        page_zip_des_t* page_zip;
2568
2596
        return(err);
2569
2597
}
2570
2598
 
2571
 
/********************************************************************
 
2599
/****************************************************************//**
2572
2600
Writes the redo log record for a delete mark setting of a secondary
2573
2601
index record. */
2574
2602
UNIV_INLINE
2575
2603
void
2576
2604
btr_cur_del_mark_set_sec_rec_log(
2577
2605
/*=============================*/
2578
 
        rec_t*          rec,    /* in: record */
2579
 
        ibool           val,    /* in: value to set */
2580
 
        mtr_t*          mtr)    /* in: mtr */
 
2606
        rec_t*          rec,    /*!< in: record */
 
2607
        ibool           val,    /*!< in: value to set */
 
2608
        mtr_t*          mtr)    /*!< in: mtr */
2581
2609
{
2582
2610
        byte*   log_ptr;
2583
2611
        ut_ad(val <= 1);
2600
2628
 
2601
2629
        mlog_close(mtr, log_ptr);
2602
2630
}
 
2631
#endif /* !UNIV_HOTBACKUP */
2603
2632
 
2604
 
/********************************************************************
 
2633
/****************************************************************//**
2605
2634
Parses the redo log record for delete marking or unmarking of a secondary
2606
 
index record. */
 
2635
index record.
 
2636
@return end of log record or NULL */
2607
2637
UNIV_INTERN
2608
2638
byte*
2609
2639
btr_cur_parse_del_mark_set_sec_rec(
2610
2640
/*===============================*/
2611
 
                                /* out: end of log record or NULL */
2612
 
        byte*           ptr,    /* in: buffer */
2613
 
        byte*           end_ptr,/* in: buffer end */
2614
 
        page_t*         page,   /* in/out: page or NULL */
2615
 
        page_zip_des_t* page_zip)/* in/out: compressed page, or NULL */
 
2641
        byte*           ptr,    /*!< in: buffer */
 
2642
        byte*           end_ptr,/*!< in: buffer end */
 
2643
        page_t*         page,   /*!< in/out: page or NULL */
 
2644
        page_zip_des_t* page_zip)/*!< in/out: compressed page, or NULL */
2616
2645
{
2617
2646
        ulint   val;
2618
2647
        ulint   offset;
2644
2673
        return(ptr);
2645
2674
}
2646
2675
 
2647
 
/***************************************************************
2648
 
Sets a secondary index record delete mark to TRUE or FALSE. */
 
2676
#ifndef UNIV_HOTBACKUP
 
2677
/***********************************************************//**
 
2678
Sets a secondary index record delete mark to TRUE or FALSE.
 
2679
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
2649
2680
UNIV_INTERN
2650
2681
ulint
2651
2682
btr_cur_del_mark_set_sec_rec(
2652
2683
/*=========================*/
2653
 
                                /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
2654
 
                                number */
2655
 
        ulint           flags,  /* in: locking flag */
2656
 
        btr_cur_t*      cursor, /* in: cursor */
2657
 
        ibool           val,    /* in: value to set */
2658
 
        que_thr_t*      thr,    /* in: query thread */
2659
 
        mtr_t*          mtr)    /* in: mtr */
 
2684
        ulint           flags,  /*!< in: locking flag */
 
2685
        btr_cur_t*      cursor, /*!< in: cursor */
 
2686
        ibool           val,    /*!< in: value to set */
 
2687
        que_thr_t*      thr,    /*!< in: query thread */
 
2688
        mtr_t*          mtr)    /*!< in: mtr */
2660
2689
{
2661
2690
        buf_block_t*    block;
2662
2691
        rec_t*          rec;
2675
2704
 
2676
2705
        err = lock_sec_rec_modify_check_and_lock(flags,
2677
2706
                                                 btr_cur_get_block(cursor),
2678
 
                                                 rec, cursor->index, thr);
 
2707
                                                 rec, cursor->index, thr, mtr);
2679
2708
        if (err != DB_SUCCESS) {
2680
2709
 
2681
2710
                return(err);
2699
2728
        return(DB_SUCCESS);
2700
2729
}
2701
2730
 
2702
 
/***************************************************************
 
2731
/***********************************************************//**
2703
2732
Clear a secondary index record's delete mark.  This function is only
2704
2733
used by the insert buffer insert merge mechanism. */
2705
2734
UNIV_INTERN
2706
2735
void
2707
2736
btr_cur_del_unmark_for_ibuf(
2708
2737
/*========================*/
2709
 
        rec_t*          rec,            /* in/out: record to delete unmark */
2710
 
        page_zip_des_t* page_zip,       /* in/out: compressed page
 
2738
        rec_t*          rec,            /*!< in/out: record to delete unmark */
 
2739
        page_zip_des_t* page_zip,       /*!< in/out: compressed page
2711
2740
                                        corresponding to rec, or NULL
2712
2741
                                        when the tablespace is
2713
2742
                                        uncompressed */
2714
 
        mtr_t*          mtr)            /* in: mtr */
 
2743
        mtr_t*          mtr)            /*!< in: mtr */
2715
2744
{
2716
2745
        /* We do not need to reserve btr_search_latch, as the page has just
2717
2746
        been read to the buffer pool and there cannot be a hash index to it. */
2723
2752
 
2724
2753
/*==================== B-TREE RECORD REMOVE =========================*/
2725
2754
 
2726
 
/*****************************************************************
 
2755
/*************************************************************//**
2727
2756
Tries to compress a page of the tree if it seems useful. It is assumed
2728
2757
that mtr holds an x-latch on the tree and on the cursor page. To avoid
2729
2758
deadlocks, mtr must also own x-latches to brothers of page, if those
2730
2759
brothers exist. NOTE: it is assumed that the caller has reserved enough
2731
 
free extents so that the compression will always succeed if done! */
 
2760
free extents so that the compression will always succeed if done!
 
2761
@return TRUE if compression occurred */
2732
2762
UNIV_INTERN
2733
2763
ibool
2734
2764
btr_cur_compress_if_useful(
2735
2765
/*=======================*/
2736
 
                                /* out: TRUE if compression occurred */
2737
 
        btr_cur_t*      cursor, /* in: cursor on the page to compress;
 
2766
        btr_cur_t*      cursor, /*!< in: cursor on the page to compress;
2738
2767
                                cursor does not stay valid if compression
2739
2768
                                occurs */
2740
 
        mtr_t*          mtr)    /* in: mtr */
 
2769
        mtr_t*          mtr)    /*!< in: mtr */
2741
2770
{
2742
2771
        ut_ad(mtr_memo_contains(mtr,
2743
2772
                                dict_index_get_lock(btr_cur_get_index(cursor)),
2749
2778
               && btr_compress(cursor, mtr));
2750
2779
}
2751
2780
 
2752
 
/***********************************************************
 
2781
/*******************************************************//**
2753
2782
Removes the record on which the tree cursor is positioned on a leaf page.
2754
2783
It is assumed that the mtr has an x-latch on the page where the cursor is
2755
 
positioned, but no latch on the whole tree. */
 
2784
positioned, but no latch on the whole tree.
 
2785
@return TRUE if success, i.e., the page did not become too empty */
2756
2786
UNIV_INTERN
2757
2787
ibool
2758
2788
btr_cur_optimistic_delete(
2759
2789
/*======================*/
2760
 
                                /* out: TRUE if success, i.e., the page
2761
 
                                did not become too empty */
2762
 
        btr_cur_t*      cursor, /* in: cursor on leaf page, on the record to
 
2790
        btr_cur_t*      cursor, /*!< in: cursor on leaf page, on the record to
2763
2791
                                delete; cursor stays valid: if deletion
2764
2792
                                succeeds, on function exit it points to the
2765
2793
                                successor of the deleted record */
2766
 
        mtr_t*          mtr)    /* in: mtr; if this function returns
 
2794
        mtr_t*          mtr)    /*!< in: mtr; if this function returns
2767
2795
                                TRUE on a leaf page of a secondary
2768
2796
                                index, the mtr must be committed
2769
2797
                                before latching any further pages */
2836
2864
        return(no_compress_needed);
2837
2865
}
2838
2866
 
2839
 
/*****************************************************************
 
2867
/*************************************************************//**
2840
2868
Removes the record on which the tree cursor is positioned. Tries
2841
2869
to compress the page if its fillfactor drops below a threshold
2842
2870
or if it is the only page on the level. It is assumed that mtr holds
2843
2871
an x-latch on the tree and on the cursor page. To avoid deadlocks,
2844
2872
mtr must also own x-latches to brothers of page, if those brothers
2845
 
exist. */
 
2873
exist.
 
2874
@return TRUE if compression occurred */
2846
2875
UNIV_INTERN
2847
2876
ibool
2848
2877
btr_cur_pessimistic_delete(
2849
2878
/*=======================*/
2850
 
                                /* out: TRUE if compression occurred */
2851
 
        ulint*          err,    /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
 
2879
        ulint*          err,    /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
2852
2880
                                the latter may occur because we may have
2853
2881
                                to update node pointers on upper levels,
2854
2882
                                and in the case of variable length keys
2855
2883
                                these may actually grow in size */
2856
 
        ibool           has_reserved_extents, /* in: TRUE if the
 
2884
        ibool           has_reserved_extents, /*!< in: TRUE if the
2857
2885
                                caller has already reserved enough free
2858
2886
                                extents so that he knows that the operation
2859
2887
                                will succeed */
2860
 
        btr_cur_t*      cursor, /* in: cursor on the record to delete;
 
2888
        btr_cur_t*      cursor, /*!< in: cursor on the record to delete;
2861
2889
                                if compression does not occur, the cursor
2862
2890
                                stays valid: it points to successor of
2863
2891
                                deleted record on function exit */
2864
 
        enum trx_rb_ctx rb_ctx, /* in: rollback context */
2865
 
        mtr_t*          mtr)    /* in: mtr */
 
2892
        enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
 
2893
        mtr_t*          mtr)    /*!< in: mtr */
2866
2894
{
2867
2895
        buf_block_t*    block;
2868
2896
        page_t*         page;
2999
3027
        return(ret);
3000
3028
}
3001
3029
 
3002
 
/***********************************************************************
 
3030
/*******************************************************************//**
3003
3031
Adds path information to the cursor for the current page, for which
3004
3032
the binary search has been performed. */
3005
3033
static
3006
3034
void
3007
3035
btr_cur_add_path_info(
3008
3036
/*==================*/
3009
 
        btr_cur_t*      cursor,         /* in: cursor positioned on a page */
3010
 
        ulint           height,         /* in: height of the page in tree;
 
3037
        btr_cur_t*      cursor,         /*!< in: cursor positioned on a page */
 
3038
        ulint           height,         /*!< in: height of the page in tree;
3011
3039
                                        0 means leaf node */
3012
 
        ulint           root_height)    /* in: root node height in tree */
 
3040
        ulint           root_height)    /*!< in: root node height in tree */
3013
3041
{
3014
3042
        btr_path_t*     slot;
3015
3043
        rec_t*          rec;
3039
3067
        slot->n_recs = page_get_n_recs(page_align(rec));
3040
3068
}
3041
3069
 
3042
 
/***********************************************************************
3043
 
Estimates the number of rows in a given index range. */
 
3070
/*******************************************************************//**
 
3071
Estimates the number of rows in a given index range.
 
3072
@return estimated number of rows */
3044
3073
UNIV_INTERN
3045
3074
ib_int64_t
3046
3075
btr_estimate_n_rows_in_range(
3047
3076
/*=========================*/
3048
 
                                /* out: estimated number of rows */
3049
 
        dict_index_t*   index,  /* in: index */
3050
 
        const dtuple_t* tuple1, /* in: range start, may also be empty tuple */
3051
 
        ulint           mode1,  /* in: search mode for range start */
3052
 
        const dtuple_t* tuple2, /* in: range end, may also be empty tuple */
3053
 
        ulint           mode2)  /* in: search mode for range end */
 
3077
        dict_index_t*   index,  /*!< in: index */
 
3078
        const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
 
3079
        ulint           mode1,  /*!< in: search mode for range start */
 
3080
        const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
 
3081
        ulint           mode2)  /*!< in: search mode for range end */
3054
3082
{
3055
3083
        btr_path_t      path1[BTR_PATH_ARRAY_N_SLOTS];
3056
3084
        btr_path_t      path2[BTR_PATH_ARRAY_N_SLOTS];
3187
3215
        }
3188
3216
}
3189
3217
 
3190
 
/***********************************************************************
 
3218
/*******************************************************************//**
3191
3219
Estimates the number of different key values in a given index, for
3192
3220
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
3193
3221
The estimates are stored in the array index->stat_n_diff_key_vals. */
3195
3223
void
3196
3224
btr_estimate_number_of_different_key_vals(
3197
3225
/*======================================*/
3198
 
        dict_index_t*   index)  /* in: index */
 
3226
        dict_index_t*   index)  /*!< in: index */
3199
3227
{
3200
3228
        btr_cur_t       cursor;
3201
3229
        page_t*         page;
3370
3398
 
3371
3399
/*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/
3372
3400
 
3373
 
/***************************************************************
3374
 
Gets the externally stored size of a record, in units of a database page. */
 
3401
/***********************************************************//**
 
3402
Gets the externally stored size of a record, in units of a database page.
 
3403
@return externally stored part, in units of a database page */
3375
3404
static
3376
3405
ulint
3377
3406
btr_rec_get_externally_stored_len(
3378
3407
/*==============================*/
3379
 
                                /* out: externally stored part,
3380
 
                                in units of a database page */
3381
 
        rec_t*          rec,    /* in: record */
3382
 
        const ulint*    offsets)/* in: array returned by rec_get_offsets() */
 
3408
        rec_t*          rec,    /*!< in: record */
 
3409
        const ulint*    offsets)/*!< in: array returned by rec_get_offsets() */
3383
3410
{
3384
3411
        ulint   n_fields;
3385
3412
        byte*   data;
3409
3436
        return(total_extern_len / UNIV_PAGE_SIZE);
3410
3437
}
3411
3438
 
3412
 
/***********************************************************************
 
3439
/*******************************************************************//**
3413
3440
Sets the ownership bit of an externally stored field in a record. */
3414
3441
static
3415
3442
void
3416
3443
btr_cur_set_ownership_of_extern_field(
3417
3444
/*==================================*/
3418
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
 
3445
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
3419
3446
                                part will be updated, or NULL */
3420
 
        rec_t*          rec,    /* in/out: clustered index record */
3421
 
        dict_index_t*   index,  /* in: index of the page */
3422
 
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
3423
 
        ulint           i,      /* in: field number */
3424
 
        ibool           val,    /* in: value to set */
3425
 
        mtr_t*          mtr)    /* in: mtr, or NULL if not logged */
 
3447
        rec_t*          rec,    /*!< in/out: clustered index record */
 
3448
        dict_index_t*   index,  /*!< in: index of the page */
 
3449
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
3450
        ulint           i,      /*!< in: field number */
 
3451
        ibool           val,    /*!< in: value to set */
 
3452
        mtr_t*          mtr)    /*!< in: mtr, or NULL if not logged */
3426
3453
{
3427
3454
        byte*   data;
3428
3455
        ulint   local_len;
3454
3481
        }
3455
3482
}
3456
3483
 
3457
 
/***********************************************************************
 
3484
/*******************************************************************//**
3458
3485
Marks not updated extern fields as not-owned by this record. The ownership
3459
3486
is transferred to the updated record which is inserted elsewhere in the
3460
3487
index tree. In purge only the owner of externally stored field is allowed
3463
3490
void
3464
3491
btr_cur_mark_extern_inherited_fields(
3465
3492
/*=================================*/
3466
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
 
3493
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
3467
3494
                                part will be updated, or NULL */
3468
 
        rec_t*          rec,    /* in/out: record in a clustered index */
3469
 
        dict_index_t*   index,  /* in: index of the page */
3470
 
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
3471
 
        const upd_t*    update, /* in: update vector */
3472
 
        mtr_t*          mtr)    /* in: mtr, or NULL if not logged */
 
3495
        rec_t*          rec,    /*!< in/out: record in a clustered index */
 
3496
        dict_index_t*   index,  /*!< in: index of the page */
 
3497
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
3498
        const upd_t*    update, /*!< in: update vector */
 
3499
        mtr_t*          mtr)    /*!< in: mtr, or NULL if not logged */
3473
3500
{
3474
3501
        ulint   n;
3475
3502
        ulint   j;
3509
3536
        }
3510
3537
}
3511
3538
 
3512
 
/***********************************************************************
 
3539
/*******************************************************************//**
3513
3540
The complement of the previous function: in an update entry may inherit
3514
3541
some externally stored fields from a record. We must mark them as inherited
3515
3542
in entry, so that they are not freed in a rollback. */
3517
3544
void
3518
3545
btr_cur_mark_dtuple_inherited_extern(
3519
3546
/*=================================*/
3520
 
        dtuple_t*       entry,          /* in/out: updated entry to be
 
3547
        dtuple_t*       entry,          /*!< in/out: updated entry to be
3521
3548
                                        inserted to clustered index */
3522
 
        const upd_t*    update)         /* in: update vector */
 
3549
        const upd_t*    update)         /*!< in: update vector */
3523
3550
{
3524
3551
        ulint           i;
3525
3552
 
3553
3580
        }
3554
3581
}
3555
3582
 
3556
 
/***********************************************************************
 
3583
/*******************************************************************//**
3557
3584
Marks all extern fields in a record as owned by the record. This function
3558
3585
should be called if the delete mark of a record is removed: a not delete
3559
3586
marked record always owns all its extern fields. */
3561
3588
void
3562
3589
btr_cur_unmark_extern_fields(
3563
3590
/*=========================*/
3564
 
        page_zip_des_t* page_zip,/* in/out: compressed page whose uncompressed
 
3591
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
3565
3592
                                part will be updated, or NULL */
3566
 
        rec_t*          rec,    /* in/out: record in a clustered index */
3567
 
        dict_index_t*   index,  /* in: index of the page */
3568
 
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
3569
 
        mtr_t*          mtr)    /* in: mtr, or NULL if not logged */
 
3593
        rec_t*          rec,    /*!< in/out: record in a clustered index */
 
3594
        dict_index_t*   index,  /*!< in: index of the page */
 
3595
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
3596
        mtr_t*          mtr)    /*!< in: mtr, or NULL if not logged */
3570
3597
{
3571
3598
        ulint   n;
3572
3599
        ulint   i;
3588
3615
        }
3589
3616
}
3590
3617
 
3591
 
/***********************************************************************
 
3618
/*******************************************************************//**
3592
3619
Marks all extern fields in a dtuple as owned by the record. */
3593
3620
UNIV_INTERN
3594
3621
void
3595
3622
btr_cur_unmark_dtuple_extern_fields(
3596
3623
/*================================*/
3597
 
        dtuple_t*       entry)          /* in/out: clustered index entry */
 
3624
        dtuple_t*       entry)          /*!< in/out: clustered index entry */
3598
3625
{
3599
3626
        ulint   i;
3600
3627
 
3611
3638
        }
3612
3639
}
3613
3640
 
3614
 
/***********************************************************************
 
3641
/*******************************************************************//**
3615
3642
Flags the data tuple fields that are marked as extern storage in the
3616
3643
update vector.  We use this function to remember which fields we must
3617
 
mark as extern storage in a record inserted for an update. */
 
3644
mark as extern storage in a record inserted for an update.
 
3645
@return number of flagged external columns */
3618
3646
UNIV_INTERN
3619
3647
ulint
3620
3648
btr_push_update_extern_fields(
3621
3649
/*==========================*/
3622
 
                                /* out: number of flagged external columns */
3623
 
        dtuple_t*       tuple,  /* in/out: data tuple */
3624
 
        const upd_t*    update, /* in: update vector */
3625
 
        mem_heap_t*     heap)   /* in: memory heap */
 
3650
        dtuple_t*       tuple,  /*!< in/out: data tuple */
 
3651
        const upd_t*    update, /*!< in: update vector */
 
3652
        mem_heap_t*     heap)   /*!< in: memory heap */
3626
3653
{
3627
3654
        ulint                   n_pushed        = 0;
3628
3655
        ulint                   n;
3691
3718
        return(n_pushed);
3692
3719
}
3693
3720
 
3694
 
/***********************************************************************
3695
 
Returns the length of a BLOB part stored on the header page. */
 
3721
/*******************************************************************//**
 
3722
Returns the length of a BLOB part stored on the header page.
 
3723
@return part length */
3696
3724
static
3697
3725
ulint
3698
3726
btr_blob_get_part_len(
3699
3727
/*==================*/
3700
 
                                        /* out: part length */
3701
 
        const byte*     blob_header)    /* in: blob header */
 
3728
        const byte*     blob_header)    /*!< in: blob header */
3702
3729
{
3703
3730
        return(mach_read_from_4(blob_header + BTR_BLOB_HDR_PART_LEN));
3704
3731
}
3705
3732
 
3706
 
/***********************************************************************
3707
 
Returns the page number where the next BLOB part is stored. */
 
3733
/*******************************************************************//**
 
3734
Returns the page number where the next BLOB part is stored.
 
3735
@return page number or FIL_NULL if no more pages */
3708
3736
static
3709
3737
ulint
3710
3738
btr_blob_get_next_page_no(
3711
3739
/*======================*/
3712
 
                                        /* out: page number or FIL_NULL if
3713
 
                                        no more pages */
3714
 
        const byte*     blob_header)    /* in: blob header */
 
3740
        const byte*     blob_header)    /*!< in: blob header */
3715
3741
{
3716
3742
        return(mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO));
3717
3743
}
3718
3744
 
3719
 
/***********************************************************************
 
3745
/*******************************************************************//**
3720
3746
Deallocate a buffer block that was reserved for a BLOB part. */
3721
3747
static
3722
3748
void
3723
3749
btr_blob_free(
3724
3750
/*==========*/
3725
 
        buf_block_t*    block,  /* in: buffer block */
3726
 
        ibool           all,    /* in: TRUE=remove also the compressed page
 
3751
        buf_block_t*    block,  /*!< in: buffer block */
 
3752
        ibool           all,    /*!< in: TRUE=remove also the compressed page
3727
3753
                                if there is one */
3728
 
        mtr_t*          mtr)    /* in: mini-transaction to commit */
 
3754
        mtr_t*          mtr)    /*!< in: mini-transaction to commit */
3729
3755
{
3730
3756
        ulint   space   = buf_block_get_space(block);
3731
3757
        ulint   page_no = buf_block_get_page_no(block);
3759
3785
        mutex_exit(&block->mutex);
3760
3786
}
3761
3787
 
3762
 
/***********************************************************************
 
3788
/*******************************************************************//**
3763
3789
Stores the fields in big_rec_vec to the tablespace and puts pointers to
3764
3790
them in rec.  The extern flags in rec will have to be set beforehand.
3765
3791
The fields are stored on pages allocated from leaf node
3766
 
file segment of the index tree. */
 
3792
file segment of the index tree.
 
3793
@return DB_SUCCESS or error */
3767
3794
UNIV_INTERN
3768
3795
ulint
3769
3796
btr_store_big_rec_extern_fields(
3770
3797
/*============================*/
3771
 
                                        /* out: DB_SUCCESS or error */
3772
 
        dict_index_t*   index,          /* in: index of rec; the index tree
 
3798
        dict_index_t*   index,          /*!< in: index of rec; the index tree
3773
3799
                                        MUST be X-latched */
3774
 
        buf_block_t*    rec_block,      /* in/out: block containing rec */
3775
 
        rec_t*          rec,            /* in/out: record */
3776
 
        const ulint*    offsets,        /* in: rec_get_offsets(rec, index);
 
3800
        buf_block_t*    rec_block,      /*!< in/out: block containing rec */
 
3801
        rec_t*          rec,            /*!< in/out: record */
 
3802
        const ulint*    offsets,        /*!< in: rec_get_offsets(rec, index);
3777
3803
                                        the "external storage" flags in offsets
3778
3804
                                        will not correspond to rec when
3779
3805
                                        this function returns */
3780
 
        big_rec_t*      big_rec_vec,    /* in: vector containing fields
 
3806
        big_rec_t*      big_rec_vec,    /*!< in: vector containing fields
3781
3807
                                        to be stored externally */
3782
 
        mtr_t*          local_mtr __attribute__((unused))) /* in: mtr
 
3808
        mtr_t*          local_mtr __attribute__((unused))) /*!< in: mtr
3783
3809
                                        containing the latch to rec and to the
3784
3810
                                        tree */
3785
3811
{
3920
3946
                                int             err;
3921
3947
                                page_zip_des_t* blob_page_zip;
3922
3948
 
3923
 
                                mach_write_to_2(page + FIL_PAGE_TYPE,
3924
 
                                                prev_page_no == FIL_NULL
3925
 
                                                ? FIL_PAGE_TYPE_ZBLOB
3926
 
                                                : FIL_PAGE_TYPE_ZBLOB2);
 
3949
                                /* Write FIL_PAGE_TYPE to the redo log
 
3950
                                separately, before logging any other
 
3951
                                changes to the page, so that the debug
 
3952
                                assertions in
 
3953
                                recv_parse_or_apply_log_rec_body() can
 
3954
                                be made simpler.  Before InnoDB Plugin
 
3955
                                1.0.4, the initialization of
 
3956
                                FIL_PAGE_TYPE was logged as part of
 
3957
                                the mlog_log_string() below. */
 
3958
 
 
3959
                                mlog_write_ulint(page + FIL_PAGE_TYPE,
 
3960
                                                 prev_page_no == FIL_NULL
 
3961
                                                 ? FIL_PAGE_TYPE_ZBLOB
 
3962
                                                 : FIL_PAGE_TYPE_ZBLOB2,
 
3963
                                                 MLOG_2BYTES, &mtr);
3927
3964
 
3928
3965
                                c_stream.next_out = page
3929
3966
                                        + FIL_PAGE_DATA;
3969
4006
                                memset(page + page_zip_get_size(page_zip)
3970
4007
                                       - c_stream.avail_out,
3971
4008
                                       0, c_stream.avail_out);
3972
 
                                mlog_log_string(page + FIL_PAGE_TYPE,
 
4009
                                mlog_log_string(page + FIL_PAGE_FILE_FLUSH_LSN,
3973
4010
                                                page_zip_get_size(page_zip)
3974
 
                                                - FIL_PAGE_TYPE,
 
4011
                                                - FIL_PAGE_FILE_FLUSH_LSN,
3975
4012
                                                &mtr);
3976
4013
                                /* Copy the page to compressed storage,
3977
4014
                                because it will be flushed to disk
4116
4153
        return(DB_SUCCESS);
4117
4154
}
4118
4155
 
4119
 
/***********************************************************************
 
4156
/*******************************************************************//**
4120
4157
Check the FIL_PAGE_TYPE on an uncompressed BLOB page. */
4121
4158
static
4122
4159
void
4123
4160
btr_check_blob_fil_page_type(
4124
4161
/*=========================*/
4125
 
        ulint           space_id,       /* in: space id */
4126
 
        ulint           page_no,        /* in: page number */
4127
 
        const page_t*   page,           /* in: page */
4128
 
        ibool           read)           /* in: TRUE=read, FALSE=purge */
 
4162
        ulint           space_id,       /*!< in: space id */
 
4163
        ulint           page_no,        /*!< in: page number */
 
4164
        const page_t*   page,           /*!< in: page */
 
4165
        ibool           read)           /*!< in: TRUE=read, FALSE=purge */
4129
4166
{
4130
4167
        ulint   type = fil_page_get_type(page);
4131
4168
 
4154
4191
        }
4155
4192
}
4156
4193
 
4157
 
/***********************************************************************
 
4194
/*******************************************************************//**
4158
4195
Frees the space in an externally stored field to the file space
4159
4196
management if the field in data is owned by the externally stored field,
4160
4197
in a rollback we may have the additional condition that the field must
4163
4200
void
4164
4201
btr_free_externally_stored_field(
4165
4202
/*=============================*/
4166
 
        dict_index_t*   index,          /* in: index of the data, the index
 
4203
        dict_index_t*   index,          /*!< in: index of the data, the index
4167
4204
                                        tree MUST be X-latched; if the tree
4168
4205
                                        height is 1, then also the root page
4169
4206
                                        must be X-latched! (this is relevant
4171
4208
                                        from purge where 'data' is located on
4172
4209
                                        an undo log page, not an index
4173
4210
                                        page) */
4174
 
        byte*           field_ref,      /* in/out: field reference */
4175
 
        const rec_t*    rec,            /* in: record containing field_ref, for
 
4211
        byte*           field_ref,      /*!< in/out: field reference */
 
4212
        const rec_t*    rec,            /*!< in: record containing field_ref, for
4176
4213
                                        page_zip_write_blob_ptr(), or NULL */
4177
 
        const ulint*    offsets,        /* in: rec_get_offsets(rec, index),
 
4214
        const ulint*    offsets,        /*!< in: rec_get_offsets(rec, index),
4178
4215
                                        or NULL */
4179
 
        page_zip_des_t* page_zip,       /* in: compressed page corresponding
 
4216
        page_zip_des_t* page_zip,       /*!< in: compressed page corresponding
4180
4217
                                        to rec, or NULL if rec == NULL */
4181
 
        ulint           i,              /* in: field number of field_ref;
 
4218
        ulint           i,              /*!< in: field number of field_ref;
4182
4219
                                        ignored if rec == NULL */
4183
 
        enum trx_rb_ctx rb_ctx,         /* in: rollback context */
4184
 
        mtr_t*          local_mtr __attribute__((unused))) /* in: mtr
 
4220
        enum trx_rb_ctx rb_ctx,         /*!< in: rollback context */
 
4221
        mtr_t*          local_mtr __attribute__((unused))) /*!< in: mtr
4185
4222
                                        containing the latch to data an an
4186
4223
                                        X-latch to the index tree */
4187
4224
{
4339
4376
        }
4340
4377
}
4341
4378
 
4342
 
/***************************************************************
 
4379
/***********************************************************//**
4343
4380
Frees the externally stored fields for a record. */
4344
4381
static
4345
4382
void
4346
4383
btr_rec_free_externally_stored_fields(
4347
4384
/*==================================*/
4348
 
        dict_index_t*   index,  /* in: index of the data, the index
 
4385
        dict_index_t*   index,  /*!< in: index of the data, the index
4349
4386
                                tree MUST be X-latched */
4350
 
        rec_t*          rec,    /* in/out: record */
4351
 
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
4352
 
        page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
 
4387
        rec_t*          rec,    /*!< in/out: record */
 
4388
        const ulint*    offsets,/*!< in: rec_get_offsets(rec, index) */
 
4389
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
4353
4390
                                part will be updated, or NULL */
4354
 
        enum trx_rb_ctx rb_ctx, /* in: rollback context */
4355
 
        mtr_t*          mtr)    /* in: mini-transaction handle which contains
 
4391
        enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
 
4392
        mtr_t*          mtr)    /*!< in: mini-transaction handle which contains
4356
4393
                                an X-latch to record page and to the index
4357
4394
                                tree */
4358
4395
{
4380
4417
        }
4381
4418
}
4382
4419
 
4383
 
/***************************************************************
 
4420
/***********************************************************//**
4384
4421
Frees the externally stored fields for a record, if the field is mentioned
4385
4422
in the update vector. */
4386
4423
static
4387
4424
void
4388
4425
btr_rec_free_updated_extern_fields(
4389
4426
/*===============================*/
4390
 
        dict_index_t*   index,  /* in: index of rec; the index tree MUST be
 
4427
        dict_index_t*   index,  /*!< in: index of rec; the index tree MUST be
4391
4428
                                X-latched */
4392
 
        rec_t*          rec,    /* in/out: record */
4393
 
        page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
 
4429
        rec_t*          rec,    /*!< in/out: record */
 
4430
        page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed
4394
4431
                                part will be updated, or NULL */
4395
 
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
4396
 
        const upd_t*    update, /* in: update vector */
4397
 
        enum trx_rb_ctx rb_ctx, /* in: rollback context */
4398
 
        mtr_t*          mtr)    /* in: mini-transaction handle which contains
 
4432
        const ulint*    offsets,/*!< in: rec_get_offsets(rec, index) */
 
4433
        const upd_t*    update, /*!< in: update vector */
 
4434
        enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
 
4435
        mtr_t*          mtr)    /*!< in: mini-transaction handle which contains
4399
4436
                                an X-latch to record page and to the tree */
4400
4437
{
4401
4438
        ulint   n_fields;
4425
4462
        }
4426
4463
}
4427
4464
 
4428
 
/***********************************************************************
 
4465
/*******************************************************************//**
4429
4466
Copies the prefix of an uncompressed BLOB.  The clustered index record
4430
 
that points to this BLOB must be protected by a lock or a page latch. */
 
4467
that points to this BLOB must be protected by a lock or a page latch.
 
4468
@return number of bytes written to buf */
4431
4469
static
4432
4470
ulint
4433
4471
btr_copy_blob_prefix(
4434
4472
/*=================*/
4435
 
                                /* out: number of bytes written to buf */
4436
 
        byte*           buf,    /* out: the externally stored part of
 
4473
        byte*           buf,    /*!< out: the externally stored part of
4437
4474
                                the field, or a prefix of it */
4438
 
        ulint           len,    /* in: length of buf, in bytes */
4439
 
        ulint           space_id,/* in: space id of the BLOB pages */
4440
 
        ulint           page_no,/* in: page number of the first BLOB page */
4441
 
        ulint           offset) /* in: offset on the first BLOB page */
 
4475
        ulint           len,    /*!< in: length of buf, in bytes */
 
4476
        ulint           space_id,/*!< in: space id of the BLOB pages */
 
4477
        ulint           page_no,/*!< in: page number of the first BLOB page */
 
4478
        ulint           offset) /*!< in: offset on the first BLOB page */
4442
4479
{
4443
4480
        ulint   copied_len      = 0;
4444
4481
 
4483
4520
        }
4484
4521
}
4485
4522
 
4486
 
/***********************************************************************
 
4523
/*******************************************************************//**
4487
4524
Copies the prefix of a compressed BLOB.  The clustered index record
4488
4525
that points to this BLOB must be protected by a lock or a page latch. */
4489
4526
static
4490
4527
void
4491
4528
btr_copy_zblob_prefix(
4492
4529
/*==================*/
4493
 
        z_stream*       d_stream,/* in/out: the decompressing stream */
4494
 
        ulint           zip_size,/* in: compressed BLOB page size */
4495
 
        ulint           space_id,/* in: space id of the BLOB pages */
4496
 
        ulint           page_no,/* in: page number of the first BLOB page */
4497
 
        ulint           offset) /* in: offset on the first BLOB page */
 
4530
        z_stream*       d_stream,/*!< in/out: the decompressing stream */
 
4531
        ulint           zip_size,/*!< in: compressed BLOB page size */
 
4532
        ulint           space_id,/*!< in: space id of the BLOB pages */
 
4533
        ulint           page_no,/*!< in: page number of the first BLOB page */
 
4534
        ulint           offset) /*!< in: offset on the first BLOB page */
4498
4535
{
4499
4536
        ulint   page_type = FIL_PAGE_TYPE_ZBLOB;
4500
4537
 
4611
4648
        }
4612
4649
}
4613
4650
 
4614
 
/***********************************************************************
 
4651
/*******************************************************************//**
4615
4652
Copies the prefix of an externally stored field of a record.  The
4616
4653
clustered index record that points to this BLOB must be protected by a
4617
 
lock or a page latch. */
 
4654
lock or a page latch.
 
4655
@return number of bytes written to buf */
4618
4656
static
4619
4657
ulint
4620
4658
btr_copy_externally_stored_field_prefix_low(
4621
4659
/*========================================*/
4622
 
                                /* out: number of bytes written to buf */
4623
 
        byte*           buf,    /* out: the externally stored part of
 
4660
        byte*           buf,    /*!< out: the externally stored part of
4624
4661
                                the field, or a prefix of it */
4625
 
        ulint           len,    /* in: length of buf, in bytes */
4626
 
        ulint           zip_size,/* in: nonzero=compressed BLOB page size,
 
4662
        ulint           len,    /*!< in: length of buf, in bytes */
 
4663
        ulint           zip_size,/*!< in: nonzero=compressed BLOB page size,
4627
4664
                                zero for uncompressed BLOBs */
4628
 
        ulint           space_id,/* in: space id of the first BLOB page */
4629
 
        ulint           page_no,/* in: page number of the first BLOB page */
4630
 
        ulint           offset) /* in: offset on the first BLOB page */
 
4665
        ulint           space_id,/*!< in: space id of the first BLOB page */
 
4666
        ulint           page_no,/*!< in: page number of the first BLOB page */
 
4667
        ulint           offset) /*!< in: offset on the first BLOB page */
4631
4668
{
4632
4669
        if (UNIV_UNLIKELY(len == 0)) {
4633
4670
                return(0);
4661
4698
        }
4662
4699
}
4663
4700
 
4664
 
/***********************************************************************
 
4701
/*******************************************************************//**
4665
4702
Copies the prefix of an externally stored field of a record.  The
4666
 
clustered index record must be protected by a lock or a page latch. */
 
4703
clustered index record must be protected by a lock or a page latch.
 
4704
@return the length of the copied field, or 0 if the column was being
 
4705
or has been deleted */
4667
4706
UNIV_INTERN
4668
4707
ulint
4669
4708
btr_copy_externally_stored_field_prefix(
4670
4709
/*====================================*/
4671
 
                                /* out: the length of the copied field,
4672
 
                                or 0 if the column was being or has been
4673
 
                                deleted */
4674
 
        byte*           buf,    /* out: the field, or a prefix of it */
4675
 
        ulint           len,    /* in: length of buf, in bytes */
4676
 
        ulint           zip_size,/* in: nonzero=compressed BLOB page size,
 
4710
        byte*           buf,    /*!< out: the field, or a prefix of it */
 
4711
        ulint           len,    /*!< in: length of buf, in bytes */
 
4712
        ulint           zip_size,/*!< in: nonzero=compressed BLOB page size,
4677
4713
                                zero for uncompressed BLOBs */
4678
 
        const byte*     data,   /* in: 'internally' stored part of the
 
4714
        const byte*     data,   /*!< in: 'internally' stored part of the
4679
4715
                                field containing also the reference to
4680
4716
                                the external part; must be protected by
4681
4717
                                a lock or a page latch */
4682
 
        ulint           local_len)/* in: length of data, in bytes */
 
4718
        ulint           local_len)/*!< in: length of data, in bytes */
4683
4719
{
4684
4720
        ulint   space_id;
4685
4721
        ulint   page_no;
4721
4757
                                                             offset));
4722
4758
}
4723
4759
 
4724
 
/***********************************************************************
 
4760
/*******************************************************************//**
4725
4761
Copies an externally stored field of a record to mem heap.  The
4726
 
clustered index record must be protected by a lock or a page latch. */
 
4762
clustered index record must be protected by a lock or a page latch.
 
4763
@return the whole field copied to heap */
4727
4764
static
4728
4765
byte*
4729
4766
btr_copy_externally_stored_field(
4730
4767
/*=============================*/
4731
 
                                /* out: the whole field copied to heap */
4732
 
        ulint*          len,    /* out: length of the whole field */
4733
 
        const byte*     data,   /* in: 'internally' stored part of the
 
4768
        ulint*          len,    /*!< out: length of the whole field */
 
4769
        const byte*     data,   /*!< in: 'internally' stored part of the
4734
4770
                                field containing also the reference to
4735
4771
                                the external part; must be protected by
4736
4772
                                a lock or a page latch */
4737
 
        ulint           zip_size,/* in: nonzero=compressed BLOB page size,
 
4773
        ulint           zip_size,/*!< in: nonzero=compressed BLOB page size,
4738
4774
                                zero for uncompressed BLOBs */
4739
 
        ulint           local_len,/* in: length of data */
4740
 
        mem_heap_t*     heap)   /* in: mem heap */
 
4775
        ulint           local_len,/*!< in: length of data */
 
4776
        mem_heap_t*     heap)   /*!< in: mem heap */
4741
4777
{
4742
4778
        ulint   space_id;
4743
4779
        ulint   page_no;
4773
4809
        return(buf);
4774
4810
}
4775
4811
 
4776
 
/***********************************************************************
4777
 
Copies an externally stored field of a record to mem heap. */
 
4812
/*******************************************************************//**
 
4813
Copies an externally stored field of a record to mem heap.
 
4814
@return the field copied to heap */
4778
4815
UNIV_INTERN
4779
4816
byte*
4780
4817
btr_rec_copy_externally_stored_field(
4781
4818
/*=================================*/
4782
 
                                /* out: the field copied to heap */
4783
 
        const rec_t*    rec,    /* in: record in a clustered index;
 
4819
        const rec_t*    rec,    /*!< in: record in a clustered index;
4784
4820
                                must be protected by a lock or a page latch */
4785
 
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
4786
 
        ulint           zip_size,/* in: nonzero=compressed BLOB page size,
 
4821
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
4822
        ulint           zip_size,/*!< in: nonzero=compressed BLOB page size,
4787
4823
                                zero for uncompressed BLOBs */
4788
 
        ulint           no,     /* in: field number */
4789
 
        ulint*          len,    /* out: length of the field */
4790
 
        mem_heap_t*     heap)   /* in: mem heap */
 
4824
        ulint           no,     /*!< in: field number */
 
4825
        ulint*          len,    /*!< out: length of the field */
 
4826
        mem_heap_t*     heap)   /*!< in: mem heap */
4791
4827
{
4792
4828
        ulint           local_len;
4793
4829
        const byte*     data;
4808
4844
        return(btr_copy_externally_stored_field(len, data,
4809
4845
                                                zip_size, local_len, heap));
4810
4846
}
 
4847
#endif /* !UNIV_HOTBACKUP */