~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/btr0cur.h

  • Committer: Monty Taylor
  • Date: 2010-12-24 02:13:05 UTC
  • mto: This revision was merged to the branch mainline in revision 2038.
  • Revision ID: mordred@inaugust.com-20101224021305-e3slv1cyjczqorij
Changed the bzrignore file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (C) 1994, 2010, Innobase Oy. All Rights Reserved.
 
4
 
 
5
This program is free software; you can redistribute it and/or modify it under
 
6
the terms of the GNU General Public License as published by the Free Software
 
7
Foundation; version 2 of the License.
 
8
 
 
9
This program is distributed in the hope that it will be useful, but WITHOUT
 
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
12
 
 
13
You should have received a copy of the GNU General Public License along with
 
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 
15
St, Fifth Floor, Boston, MA 02110-1301 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/**************************************************//**
 
20
@file include/btr0cur.h
 
21
The index tree cursor
 
22
 
 
23
Created 10/16/1994 Heikki Tuuri
 
24
*******************************************************/
 
25
 
 
26
#ifndef btr0cur_h
 
27
#define btr0cur_h
 
28
 
 
29
#include "univ.i"
 
30
#include "dict0dict.h"
 
31
#include "page0cur.h"
 
32
#include "btr0types.h"
 
33
 
 
34
/* Mode flags for btr_cur operations; these can be ORed */
 
35
#define BTR_NO_UNDO_LOG_FLAG    1       /* do no undo logging */
 
36
#define BTR_NO_LOCKING_FLAG     2       /* do no record lock checking */
 
37
#define BTR_KEEP_SYS_FLAG       4       /* sys fields will be found from the
 
38
                                        update vector or inserted entry */
 
39
 
 
40
#ifndef UNIV_HOTBACKUP
 
41
#include "que0types.h"
 
42
#include "row0types.h"
 
43
#include "ha0ha.h"
 
44
 
 
45
#define BTR_CUR_ADAPT
 
46
#define BTR_CUR_HASH_ADAPT
 
47
 
 
48
#ifdef UNIV_DEBUG
 
49
/*********************************************************//**
 
50
Returns the page cursor component of a tree cursor.
 
51
@return pointer to page cursor component */
 
52
UNIV_INLINE
 
53
page_cur_t*
 
54
btr_cur_get_page_cur(
 
55
/*=================*/
 
56
        const btr_cur_t*        cursor);/*!< in: tree cursor */
 
57
#else /* UNIV_DEBUG */
 
58
# define btr_cur_get_page_cur(cursor) (&(cursor)->page_cur)
 
59
#endif /* UNIV_DEBUG */
 
60
/*********************************************************//**
 
61
Returns the buffer block on which the tree cursor is positioned.
 
62
@return pointer to buffer block */
 
63
UNIV_INLINE
 
64
buf_block_t*
 
65
btr_cur_get_block(
 
66
/*==============*/
 
67
        btr_cur_t*      cursor);/*!< in: tree cursor */
 
68
/*********************************************************//**
 
69
Returns the record pointer of a tree cursor.
 
70
@return pointer to record */
 
71
UNIV_INLINE
 
72
rec_t*
 
73
btr_cur_get_rec(
 
74
/*============*/
 
75
        btr_cur_t*      cursor);/*!< in: tree cursor */
 
76
/*********************************************************//**
 
77
Returns the compressed page on which the tree cursor is positioned.
 
78
@return pointer to compressed page, or NULL if the page is not compressed */
 
79
UNIV_INLINE
 
80
page_zip_des_t*
 
81
btr_cur_get_page_zip(
 
82
/*=================*/
 
83
        btr_cur_t*      cursor);/*!< in: tree cursor */
 
84
/*********************************************************//**
 
85
Invalidates a tree cursor by setting record pointer to NULL. */
 
86
UNIV_INLINE
 
87
void
 
88
btr_cur_invalidate(
 
89
/*===============*/
 
90
        btr_cur_t*      cursor);/*!< in: tree cursor */
 
91
/*********************************************************//**
 
92
Returns the page of a tree cursor.
 
93
@return pointer to page */
 
94
UNIV_INLINE
 
95
page_t*
 
96
btr_cur_get_page(
 
97
/*=============*/
 
98
        btr_cur_t*      cursor);/*!< in: tree cursor */
 
99
/*********************************************************//**
 
100
Returns the index of a cursor.
 
101
@return index */
 
102
UNIV_INLINE
 
103
dict_index_t*
 
104
btr_cur_get_index(
 
105
/*==============*/
 
106
        btr_cur_t*      cursor);/*!< in: B-tree cursor */
 
107
/*********************************************************//**
 
108
Positions a tree cursor at a given record. */
 
109
UNIV_INLINE
 
110
void
 
111
btr_cur_position(
 
112
/*=============*/
 
113
        dict_index_t*   index,  /*!< in: index */
 
114
        rec_t*          rec,    /*!< in: record in tree */
 
115
        buf_block_t*    block,  /*!< in: buffer block of rec */
 
116
        btr_cur_t*      cursor);/*!< in: cursor */
 
117
/********************************************************************//**
 
118
Searches an index tree and positions a tree cursor on a given level.
 
119
NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
 
120
to node pointer page number fields on the upper levels of the tree!
 
121
Note that if mode is PAGE_CUR_LE, which is used in inserts, then
 
122
cursor->up_match and cursor->low_match both will have sensible values.
 
123
If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
 
124
UNIV_INTERN
 
125
void
 
126
btr_cur_search_to_nth_level(
 
127
/*========================*/
 
128
        dict_index_t*   index,  /*!< in: index */
 
129
        ulint           level,  /*!< in: the tree level of search */
 
130
        const dtuple_t* tuple,  /*!< in: data tuple; NOTE: n_fields_cmp in
 
131
                                tuple must be set so that it cannot get
 
132
                                compared to the node ptr page number field! */
 
133
        ulint           mode,   /*!< in: PAGE_CUR_L, ...;
 
134
                                NOTE that if the search is made using a unique
 
135
                                prefix of a record, mode should be PAGE_CUR_LE,
 
136
                                not PAGE_CUR_GE, as the latter may end up on
 
137
                                the previous page of the record! Inserts
 
138
                                should always be made using PAGE_CUR_LE to
 
139
                                search the position! */
 
140
        ulint           latch_mode, /*!< in: BTR_SEARCH_LEAF, ..., ORed with
 
141
                                at most one of BTR_INSERT, BTR_DELETE_MARK,
 
142
                                BTR_DELETE, or BTR_ESTIMATE;
 
143
                                cursor->left_block is used to store a pointer
 
144
                                to the left neighbor page, in the cases
 
145
                                BTR_SEARCH_PREV and BTR_MODIFY_PREV;
 
146
                                NOTE that if has_search_latch
 
147
                                is != 0, we maybe do not have a latch set
 
148
                                on the cursor page, we assume
 
149
                                the caller uses his search latch
 
150
                                to protect the record! */
 
151
        btr_cur_t*      cursor, /*!< in/out: tree cursor; the cursor page is
 
152
                                s- or x-latched, but see also above! */
 
153
        ulint           has_search_latch,/*!< in: latch mode the caller
 
154
                                currently has on btr_search_latch:
 
155
                                RW_S_LATCH, or 0 */
 
156
        const char*     file,   /*!< in: file name */
 
157
        ulint           line,   /*!< in: line where called */
 
158
        mtr_t*          mtr);   /*!< in: mtr */
 
159
/*****************************************************************//**
 
160
Opens a cursor at either end of an index. */
 
161
UNIV_INTERN
 
162
void
 
163
btr_cur_open_at_index_side_func(
 
164
/*============================*/
 
165
        ibool           from_left,      /*!< in: TRUE if open to the low end,
 
166
                                        FALSE if to the high end */
 
167
        dict_index_t*   index,          /*!< in: index */
 
168
        ulint           latch_mode,     /*!< in: latch mode */
 
169
        btr_cur_t*      cursor,         /*!< in: cursor */
 
170
        const char*     file,           /*!< in: file name */
 
171
        ulint           line,           /*!< in: line where called */
 
172
        mtr_t*          mtr);           /*!< in: mtr */
 
173
#define btr_cur_open_at_index_side(f,i,l,c,m)                           \
 
174
        btr_cur_open_at_index_side_func(f,i,l,c,__FILE__,__LINE__,m)
 
175
/**********************************************************************//**
 
176
Positions a cursor at a randomly chosen position within a B-tree. */
 
177
UNIV_INTERN
 
178
void
 
179
btr_cur_open_at_rnd_pos_func(
 
180
/*=========================*/
 
181
        dict_index_t*   index,          /*!< in: index */
 
182
        ulint           latch_mode,     /*!< in: BTR_SEARCH_LEAF, ... */
 
183
        btr_cur_t*      cursor,         /*!< in/out: B-tree cursor */
 
184
        const char*     file,           /*!< in: file name */
 
185
        ulint           line,           /*!< in: line where called */
 
186
        mtr_t*          mtr);           /*!< in: mtr */
 
187
#define btr_cur_open_at_rnd_pos(i,l,c,m)                                \
 
188
        btr_cur_open_at_rnd_pos_func(i,l,c,__FILE__,__LINE__,m)
 
189
/*************************************************************//**
 
190
Tries to perform an insert to a page in an index tree, next to cursor.
 
191
It is assumed that mtr holds an x-latch on the page. The operation does
 
192
not succeed if there is too little space on the page. If there is just
 
193
one record on the page, the insert will always succeed; this is to
 
194
prevent trying to split a page with just one record.
 
195
@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
 
196
UNIV_INTERN
 
197
ulint
 
198
btr_cur_optimistic_insert(
 
199
/*======================*/
 
200
        ulint           flags,  /*!< in: undo logging and locking flags: if not
 
201
                                zero, the parameters index and thr should be
 
202
                                specified */
 
203
        btr_cur_t*      cursor, /*!< in: cursor on page after which to insert;
 
204
                                cursor stays valid */
 
205
        dtuple_t*       entry,  /*!< in/out: entry to insert */
 
206
        rec_t**         rec,    /*!< out: pointer to inserted record if
 
207
                                succeed */
 
208
        big_rec_t**     big_rec,/*!< out: big rec vector whose fields have to
 
209
                                be stored externally by the caller, or
 
210
                                NULL */
 
211
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
212
        que_thr_t*      thr,    /*!< in: query thread or NULL */
 
213
        mtr_t*          mtr);   /*!< in: mtr; if this function returns
 
214
                                DB_SUCCESS on a leaf page of a secondary
 
215
                                index in a compressed tablespace, the
 
216
                                mtr must be committed before latching
 
217
                                any further pages */
 
218
/*************************************************************//**
 
219
Performs an insert on a page of an index tree. It is assumed that mtr
 
220
holds an x-latch on the tree and on the cursor page. If the insert is
 
221
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
 
222
to brothers of page, if those brothers exist.
 
223
@return DB_SUCCESS or error number */
 
224
UNIV_INTERN
 
225
ulint
 
226
btr_cur_pessimistic_insert(
 
227
/*=======================*/
 
228
        ulint           flags,  /*!< in: undo logging and locking flags: if not
 
229
                                zero, the parameter thr should be
 
230
                                specified; if no undo logging is specified,
 
231
                                then the caller must have reserved enough
 
232
                                free extents in the file space so that the
 
233
                                insertion will certainly succeed */
 
234
        btr_cur_t*      cursor, /*!< in: cursor after which to insert;
 
235
                                cursor stays valid */
 
236
        dtuple_t*       entry,  /*!< in/out: entry to insert */
 
237
        rec_t**         rec,    /*!< out: pointer to inserted record if
 
238
                                succeed */
 
239
        big_rec_t**     big_rec,/*!< out: big rec vector whose fields have to
 
240
                                be stored externally by the caller, or
 
241
                                NULL */
 
242
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
243
        que_thr_t*      thr,    /*!< in: query thread or NULL */
 
244
        mtr_t*          mtr);   /*!< in: mtr */
 
245
/*************************************************************//**
 
246
See if there is enough place in the page modification log to log
 
247
an update-in-place.
 
248
@return TRUE if enough place */
 
249
UNIV_INTERN
 
250
ibool
 
251
btr_cur_update_alloc_zip(
 
252
/*=====================*/
 
253
        page_zip_des_t* page_zip,/*!< in/out: compressed page */
 
254
        buf_block_t*    block,  /*!< in/out: buffer page */
 
255
        dict_index_t*   index,  /*!< in: the index corresponding to the block */
 
256
        ulint           length, /*!< in: size needed */
 
257
        ibool           create, /*!< in: TRUE=delete-and-insert,
 
258
                                FALSE=update-in-place */
 
259
        mtr_t*          mtr)    /*!< in: mini-transaction */
 
260
        UNIV_WARN_UNUSED_RESULT_NONNULL;
 
261
/*************************************************************//**
 
262
Updates a record when the update causes no size changes in its fields.
 
263
@return DB_SUCCESS or error number */
 
264
UNIV_INTERN
 
265
ulint
 
266
btr_cur_update_in_place(
 
267
/*====================*/
 
268
        ulint           flags,  /*!< in: undo logging and locking flags */
 
269
        btr_cur_t*      cursor, /*!< in: cursor on the record to update;
 
270
                                cursor stays valid and positioned on the
 
271
                                same record */
 
272
        const upd_t*    update, /*!< in: update vector */
 
273
        ulint           cmpl_info,/*!< in: compiler info on secondary index
 
274
                                updates */
 
275
        que_thr_t*      thr,    /*!< in: query thread */
 
276
        mtr_t*          mtr);   /*!< in: mtr; must be committed before
 
277
                                latching any further pages */
 
278
/*************************************************************//**
 
279
Tries to update a record on a page in an index tree. It is assumed that mtr
 
280
holds an x-latch on the page. The operation does not succeed if there is too
 
281
little space on the page or if the update would result in too empty a page,
 
282
so that tree compression is recommended.
 
283
@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
 
284
DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
 
285
there is not enough space left on the compressed page */
 
286
UNIV_INTERN
 
287
ulint
 
288
btr_cur_optimistic_update(
 
289
/*======================*/
 
290
        ulint           flags,  /*!< in: undo logging and locking flags */
 
291
        btr_cur_t*      cursor, /*!< in: cursor on the record to update;
 
292
                                cursor stays valid and positioned on the
 
293
                                same record */
 
294
        const upd_t*    update, /*!< in: update vector; this must also
 
295
                                contain trx id and roll ptr fields */
 
296
        ulint           cmpl_info,/*!< in: compiler info on secondary index
 
297
                                updates */
 
298
        que_thr_t*      thr,    /*!< in: query thread */
 
299
        mtr_t*          mtr);   /*!< in: mtr; must be committed before
 
300
                                latching any further pages */
 
301
/*************************************************************//**
 
302
Performs an update of a record on a page of a tree. It is assumed
 
303
that mtr holds an x-latch on the tree and on the cursor page. If the
 
304
update is made on the leaf level, to avoid deadlocks, mtr must also
 
305
own x-latches to brothers of page, if those brothers exist.
 
306
@return DB_SUCCESS or error code */
 
307
UNIV_INTERN
 
308
ulint
 
309
btr_cur_pessimistic_update(
 
310
/*=======================*/
 
311
        ulint           flags,  /*!< in: undo logging, locking, and rollback
 
312
                                flags */
 
313
        btr_cur_t*      cursor, /*!< in: cursor on the record to update */
 
314
        mem_heap_t**    heap,   /*!< in/out: pointer to memory heap, or NULL */
 
315
        big_rec_t**     big_rec,/*!< out: big rec vector whose fields have to
 
316
                                be stored externally by the caller, or NULL */
 
317
        const upd_t*    update, /*!< in: update vector; this is allowed also
 
318
                                contain trx id and roll ptr fields, but
 
319
                                the values in update vector have no effect */
 
320
        ulint           cmpl_info,/*!< in: compiler info on secondary index
 
321
                                updates */
 
322
        que_thr_t*      thr,    /*!< in: query thread */
 
323
        mtr_t*          mtr);   /*!< in: mtr; must be committed before
 
324
                                latching any further pages */
 
325
/***********************************************************//**
 
326
Marks a clustered index record deleted. Writes an undo log record to
 
327
undo log on this delete marking. Writes in the trx id field the id
 
328
of the deleting transaction, and in the roll ptr field pointer to the
 
329
undo log record created.
 
330
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
 
331
UNIV_INTERN
 
332
ulint
 
333
btr_cur_del_mark_set_clust_rec(
 
334
/*===========================*/
 
335
        ulint           flags,  /*!< in: undo logging and locking flags */
 
336
        btr_cur_t*      cursor, /*!< in: cursor */
 
337
        ibool           val,    /*!< in: value to set */
 
338
        que_thr_t*      thr,    /*!< in: query thread */
 
339
        mtr_t*          mtr);   /*!< in: mtr */
 
340
/***********************************************************//**
 
341
Sets a secondary index record delete mark to TRUE or FALSE.
 
342
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
 
343
UNIV_INTERN
 
344
ulint
 
345
btr_cur_del_mark_set_sec_rec(
 
346
/*=========================*/
 
347
        ulint           flags,  /*!< in: locking flag */
 
348
        btr_cur_t*      cursor, /*!< in: cursor */
 
349
        ibool           val,    /*!< in: value to set */
 
350
        que_thr_t*      thr,    /*!< in: query thread */
 
351
        mtr_t*          mtr);   /*!< in: mtr */
 
352
/*************************************************************//**
 
353
Tries to compress a page of the tree if it seems useful. It is assumed
 
354
that mtr holds an x-latch on the tree and on the cursor page. To avoid
 
355
deadlocks, mtr must also own x-latches to brothers of page, if those
 
356
brothers exist. NOTE: it is assumed that the caller has reserved enough
 
357
free extents so that the compression will always succeed if done!
 
358
@return TRUE if compression occurred */
 
359
UNIV_INTERN
 
360
ibool
 
361
btr_cur_compress_if_useful(
 
362
/*=======================*/
 
363
        btr_cur_t*      cursor, /*!< in: cursor on the page to compress;
 
364
                                cursor does not stay valid if compression
 
365
                                occurs */
 
366
        mtr_t*          mtr);   /*!< in: mtr */
 
367
/*******************************************************//**
 
368
Removes the record on which the tree cursor is positioned. It is assumed
 
369
that the mtr has an x-latch on the page where the cursor is positioned,
 
370
but no latch on the whole tree.
 
371
@return TRUE if success, i.e., the page did not become too empty */
 
372
UNIV_INTERN
 
373
ibool
 
374
btr_cur_optimistic_delete(
 
375
/*======================*/
 
376
        btr_cur_t*      cursor, /*!< in: cursor on the record to delete;
 
377
                                cursor stays valid: if deletion succeeds,
 
378
                                on function exit it points to the successor
 
379
                                of the deleted record */
 
380
        mtr_t*          mtr);   /*!< in: mtr; if this function returns
 
381
                                TRUE on a leaf page of a secondary
 
382
                                index, the mtr must be committed
 
383
                                before latching any further pages */
 
384
/*************************************************************//**
 
385
Removes the record on which the tree cursor is positioned. Tries
 
386
to compress the page if its fillfactor drops below a threshold
 
387
or if it is the only page on the level. It is assumed that mtr holds
 
388
an x-latch on the tree and on the cursor page. To avoid deadlocks,
 
389
mtr must also own x-latches to brothers of page, if those brothers
 
390
exist.
 
391
@return TRUE if compression occurred */
 
392
UNIV_INTERN
 
393
ibool
 
394
btr_cur_pessimistic_delete(
 
395
/*=======================*/
 
396
        ulint*          err,    /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
 
397
                                the latter may occur because we may have
 
398
                                to update node pointers on upper levels,
 
399
                                and in the case of variable length keys
 
400
                                these may actually grow in size */
 
401
        ibool           has_reserved_extents, /*!< in: TRUE if the
 
402
                                caller has already reserved enough free
 
403
                                extents so that he knows that the operation
 
404
                                will succeed */
 
405
        btr_cur_t*      cursor, /*!< in: cursor on the record to delete;
 
406
                                if compression does not occur, the cursor
 
407
                                stays valid: it points to successor of
 
408
                                deleted record on function exit */
 
409
        enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
 
410
        mtr_t*          mtr);   /*!< in: mtr */
 
411
#endif /* !UNIV_HOTBACKUP */
 
412
/***********************************************************//**
 
413
Parses a redo log record of updating a record in-place.
 
414
@return end of log record or NULL */
 
415
UNIV_INTERN
 
416
byte*
 
417
btr_cur_parse_update_in_place(
 
418
/*==========================*/
 
419
        byte*           ptr,    /*!< in: buffer */
 
420
        byte*           end_ptr,/*!< in: buffer end */
 
421
        page_t*         page,   /*!< in/out: page or NULL */
 
422
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
423
        dict_index_t*   index); /*!< in: index corresponding to page */
 
424
/****************************************************************//**
 
425
Parses the redo log record for delete marking or unmarking of a clustered
 
426
index record.
 
427
@return end of log record or NULL */
 
428
UNIV_INTERN
 
429
byte*
 
430
btr_cur_parse_del_mark_set_clust_rec(
 
431
/*=================================*/
 
432
        byte*           ptr,    /*!< in: buffer */
 
433
        byte*           end_ptr,/*!< in: buffer end */
 
434
        page_t*         page,   /*!< in/out: page or NULL */
 
435
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
436
        dict_index_t*   index); /*!< in: index corresponding to page */
 
437
/****************************************************************//**
 
438
Parses the redo log record for delete marking or unmarking of a secondary
 
439
index record.
 
440
@return end of log record or NULL */
 
441
UNIV_INTERN
 
442
byte*
 
443
btr_cur_parse_del_mark_set_sec_rec(
 
444
/*===============================*/
 
445
        byte*           ptr,    /*!< in: buffer */
 
446
        byte*           end_ptr,/*!< in: buffer end */
 
447
        page_t*         page,   /*!< in/out: page or NULL */
 
448
        page_zip_des_t* page_zip);/*!< in/out: compressed page, or NULL */
 
449
#ifndef UNIV_HOTBACKUP
 
450
/*******************************************************************//**
 
451
Estimates the number of rows in a given index range.
 
452
@return estimated number of rows */
 
453
UNIV_INTERN
 
454
ib_int64_t
 
455
btr_estimate_n_rows_in_range(
 
456
/*=========================*/
 
457
        dict_index_t*   index,  /*!< in: index */
 
458
        const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
 
459
        ulint           mode1,  /*!< in: search mode for range start */
 
460
        const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
 
461
        ulint           mode2); /*!< in: search mode for range end */
 
462
/*******************************************************************//**
 
463
Estimates the number of different key values in a given index, for
 
464
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
 
465
The estimates are stored in the array index->stat_n_diff_key_vals. */
 
466
UNIV_INTERN
 
467
void
 
468
btr_estimate_number_of_different_key_vals(
 
469
/*======================================*/
 
470
        dict_index_t*   index); /*!< in: index */
 
471
/*******************************************************************//**
 
472
Marks not updated extern fields as not-owned by this record. The ownership
 
473
is transferred to the updated record which is inserted elsewhere in the
 
474
index tree. In purge only the owner of externally stored field is allowed
 
475
to free the field.
 
476
@return TRUE if BLOB ownership was transferred */
 
477
UNIV_INTERN
 
478
ibool
 
479
btr_cur_mark_extern_inherited_fields(
 
480
/*=================================*/
 
481
        page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
 
482
                                part will be updated, or NULL */
 
483
        rec_t*          rec,    /*!< in/out: record in a clustered index */
 
484
        dict_index_t*   index,  /*!< in: index of the page */
 
485
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
486
        const upd_t*    update, /*!< in: update vector */
 
487
        mtr_t*          mtr);   /*!< in: mtr, or NULL if not logged */
 
488
/*******************************************************************//**
 
489
The complement of the previous function: in an update entry may inherit
 
490
some externally stored fields from a record. We must mark them as inherited
 
491
in entry, so that they are not freed in a rollback. */
 
492
UNIV_INTERN
 
493
void
 
494
btr_cur_mark_dtuple_inherited_extern(
 
495
/*=================================*/
 
496
        dtuple_t*       entry,          /*!< in/out: updated entry to be
 
497
                                        inserted to clustered index */
 
498
        const upd_t*    update);        /*!< in: update vector */
 
499
/*******************************************************************//**
 
500
Marks all extern fields in a dtuple as owned by the record. */
 
501
UNIV_INTERN
 
502
void
 
503
btr_cur_unmark_dtuple_extern_fields(
 
504
/*================================*/
 
505
        dtuple_t*       entry);         /*!< in/out: clustered index entry */
 
506
/*******************************************************************//**
 
507
Stores the fields in big_rec_vec to the tablespace and puts pointers to
 
508
them in rec.  The extern flags in rec will have to be set beforehand.
 
509
The fields are stored on pages allocated from leaf node
 
510
file segment of the index tree.
 
511
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
 
512
UNIV_INTERN
 
513
ulint
 
514
btr_store_big_rec_extern_fields(
 
515
/*============================*/
 
516
        dict_index_t*   index,          /*!< in: index of rec; the index tree
 
517
                                        MUST be X-latched */
 
518
        buf_block_t*    rec_block,      /*!< in/out: block containing rec */
 
519
        rec_t*          rec,            /*!< in: record */
 
520
        const ulint*    offsets,        /*!< in: rec_get_offsets(rec, index);
 
521
                                        the "external storage" flags in offsets
 
522
                                        will not correspond to rec when
 
523
                                        this function returns */
 
524
        big_rec_t*      big_rec_vec,    /*!< in: vector containing fields
 
525
                                        to be stored externally */
 
526
        mtr_t*          local_mtr);     /*!< in: mtr containing the latch to
 
527
                                        rec and to the tree */
 
528
/*******************************************************************//**
 
529
Frees the space in an externally stored field to the file space
 
530
management if the field in data is owned the externally stored field,
 
531
in a rollback we may have the additional condition that the field must
 
532
not be inherited. */
 
533
UNIV_INTERN
 
534
void
 
535
btr_free_externally_stored_field(
 
536
/*=============================*/
 
537
        dict_index_t*   index,          /*!< in: index of the data, the index
 
538
                                        tree MUST be X-latched; if the tree
 
539
                                        height is 1, then also the root page
 
540
                                        must be X-latched! (this is relevant
 
541
                                        in the case this function is called
 
542
                                        from purge where 'data' is located on
 
543
                                        an undo log page, not an index
 
544
                                        page) */
 
545
        byte*           field_ref,      /*!< in/out: field reference */
 
546
        const rec_t*    rec,            /*!< in: record containing field_ref, for
 
547
                                        page_zip_write_blob_ptr(), or NULL */
 
548
        const ulint*    offsets,        /*!< in: rec_get_offsets(rec, index),
 
549
                                        or NULL */
 
550
        page_zip_des_t* page_zip,       /*!< in: compressed page corresponding
 
551
                                        to rec, or NULL if rec == NULL */
 
552
        ulint           i,              /*!< in: field number of field_ref;
 
553
                                        ignored if rec == NULL */
 
554
        enum trx_rb_ctx rb_ctx,         /*!< in: rollback context */
 
555
        mtr_t*          local_mtr);     /*!< in: mtr containing the latch to
 
556
                                        data an an X-latch to the index
 
557
                                        tree */
 
558
/*******************************************************************//**
 
559
Copies the prefix of an externally stored field of a record.  The
 
560
clustered index record must be protected by a lock or a page latch.
 
561
@return the length of the copied field, or 0 if the column was being
 
562
or has been deleted */
 
563
UNIV_INTERN
 
564
ulint
 
565
btr_copy_externally_stored_field_prefix(
 
566
/*====================================*/
 
567
        byte*           buf,    /*!< out: the field, or a prefix of it */
 
568
        ulint           len,    /*!< in: length of buf, in bytes */
 
569
        ulint           zip_size,/*!< in: nonzero=compressed BLOB page size,
 
570
                                zero for uncompressed BLOBs */
 
571
        const byte*     data,   /*!< in: 'internally' stored part of the
 
572
                                field containing also the reference to
 
573
                                the external part; must be protected by
 
574
                                a lock or a page latch */
 
575
        ulint           local_len);/*!< in: length of data, in bytes */
 
576
/*******************************************************************//**
 
577
Copies an externally stored field of a record to mem heap.
 
578
@return the field copied to heap, or NULL if the field is incomplete */
 
579
UNIV_INTERN
 
580
byte*
 
581
btr_rec_copy_externally_stored_field(
 
582
/*=================================*/
 
583
        const rec_t*    rec,    /*!< in: record in a clustered index;
 
584
                                must be protected by a lock or a page latch */
 
585
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
586
        ulint           zip_size,/*!< in: nonzero=compressed BLOB page size,
 
587
                                zero for uncompressed BLOBs */
 
588
        ulint           no,     /*!< in: field number */
 
589
        ulint*          len,    /*!< out: length of the field */
 
590
        mem_heap_t*     heap);  /*!< in: mem heap */
 
591
/*******************************************************************//**
 
592
Flags the data tuple fields that are marked as extern storage in the
 
593
update vector.  We use this function to remember which fields we must
 
594
mark as extern storage in a record inserted for an update.
 
595
@return number of flagged external columns */
 
596
UNIV_INTERN
 
597
ulint
 
598
btr_push_update_extern_fields(
 
599
/*==========================*/
 
600
        dtuple_t*       tuple,  /*!< in/out: data tuple */
 
601
        const upd_t*    update, /*!< in: update vector */
 
602
        mem_heap_t*     heap)   /*!< in: memory heap */
 
603
        __attribute__((nonnull));
 
604
/***********************************************************//**
 
605
Sets a secondary index record's delete mark to the given value. This
 
606
function is only used by the insert buffer merge mechanism. */
 
607
UNIV_INTERN
 
608
void
 
609
btr_cur_set_deleted_flag_for_ibuf(
 
610
/*==============================*/
 
611
        rec_t*          rec,            /*!< in/out: record */
 
612
        page_zip_des_t* page_zip,       /*!< in/out: compressed page
 
613
                                        corresponding to rec, or NULL
 
614
                                        when the tablespace is
 
615
                                        uncompressed */
 
616
        ibool           val,            /*!< in: value to set */
 
617
        mtr_t*          mtr);           /*!< in: mtr */
 
618
/*######################################################################*/
 
619
 
 
620
/** In the pessimistic delete, if the page data size drops below this
 
621
limit, merging it to a neighbor is tried */
 
622
#define BTR_CUR_PAGE_COMPRESS_LIMIT     (UNIV_PAGE_SIZE / 2)
 
623
 
 
624
/** A slot in the path array. We store here info on a search path down the
 
625
tree. Each slot contains data on a single level of the tree. */
 
626
 
 
627
typedef struct btr_path_struct  btr_path_t;
 
628
struct btr_path_struct{
 
629
        ulint   nth_rec;        /*!< index of the record
 
630
                                where the page cursor stopped on
 
631
                                this level (index in alphabetical
 
632
                                order); value ULINT_UNDEFINED
 
633
                                denotes array end */
 
634
        ulint   n_recs;         /*!< number of records on the page */
 
635
        ulint   page_no;        /*!< no of the page containing the record */
 
636
        ulint   page_level;     /*!< level of the page, if later we fetch
 
637
                                the page under page_no and it is no different
 
638
                                level then we know that the tree has been
 
639
                                reorganized */
 
640
};
 
641
 
 
642
#define BTR_PATH_ARRAY_N_SLOTS  250     /*!< size of path array (in slots) */
 
643
 
 
644
/** Values for the flag documenting the used search method */
 
645
enum btr_cur_method {
 
646
        BTR_CUR_HASH = 1,       /*!< successful shortcut using
 
647
                                the hash index */
 
648
        BTR_CUR_HASH_FAIL,      /*!< failure using hash, success using
 
649
                                binary search: the misleading hash
 
650
                                reference is stored in the field
 
651
                                hash_node, and might be necessary to
 
652
                                update */
 
653
        BTR_CUR_BINARY,         /*!< success using the binary search */
 
654
        BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
 
655
                                the insert buffer */
 
656
        BTR_CUR_DEL_MARK_IBUF,  /*!< performed the intended delete
 
657
                                mark in the insert/delete buffer */
 
658
        BTR_CUR_DELETE_IBUF,    /*!< performed the intended delete in
 
659
                                the insert/delete buffer */
 
660
        BTR_CUR_DELETE_REF      /*!< row_purge_poss_sec() failed */
 
661
};
 
662
 
 
663
/** The tree cursor: the definition appears here only for the compiler
 
664
to know struct size! */
 
665
struct btr_cur_struct {
 
666
        dict_index_t*   index;          /*!< index where positioned */
 
667
        page_cur_t      page_cur;       /*!< page cursor */
 
668
        purge_node_t*   purge_node;     /*!< purge node, for BTR_DELETE */
 
669
        buf_block_t*    left_block;     /*!< this field is used to store
 
670
                                        a pointer to the left neighbor
 
671
                                        page, in the cases
 
672
                                        BTR_SEARCH_PREV and
 
673
                                        BTR_MODIFY_PREV */
 
674
        /*------------------------------*/
 
675
        que_thr_t*      thr;            /*!< this field is only used
 
676
                                        when btr_cur_search_to_nth_level
 
677
                                        is called for an index entry
 
678
                                        insertion: the calling query
 
679
                                        thread is passed here to be
 
680
                                        used in the insert buffer */
 
681
        /*------------------------------*/
 
682
        /** The following fields are used in
 
683
        btr_cur_search_to_nth_level to pass information: */
 
684
        /* @{ */
 
685
        enum btr_cur_method     flag;   /*!< Search method used */
 
686
        ulint           tree_height;    /*!< Tree height if the search is done
 
687
                                        for a pessimistic insert or update
 
688
                                        operation */
 
689
        ulint           up_match;       /*!< If the search mode was PAGE_CUR_LE,
 
690
                                        the number of matched fields to the
 
691
                                        the first user record to the right of
 
692
                                        the cursor record after
 
693
                                        btr_cur_search_to_nth_level;
 
694
                                        for the mode PAGE_CUR_GE, the matched
 
695
                                        fields to the first user record AT THE
 
696
                                        CURSOR or to the right of it;
 
697
                                        NOTE that the up_match and low_match
 
698
                                        values may exceed the correct values
 
699
                                        for comparison to the adjacent user
 
700
                                        record if that record is on a
 
701
                                        different leaf page! (See the note in
 
702
                                        row_ins_duplicate_key.) */
 
703
        ulint           up_bytes;       /*!< number of matched bytes to the
 
704
                                        right at the time cursor positioned;
 
705
                                        only used internally in searches: not
 
706
                                        defined after the search */
 
707
        ulint           low_match;      /*!< if search mode was PAGE_CUR_LE,
 
708
                                        the number of matched fields to the
 
709
                                        first user record AT THE CURSOR or
 
710
                                        to the left of it after
 
711
                                        btr_cur_search_to_nth_level;
 
712
                                        NOT defined for PAGE_CUR_GE or any
 
713
                                        other search modes; see also the NOTE
 
714
                                        in up_match! */
 
715
        ulint           low_bytes;      /*!< number of matched bytes to the
 
716
                                        right at the time cursor positioned;
 
717
                                        only used internally in searches: not
 
718
                                        defined after the search */
 
719
        ulint           n_fields;       /*!< prefix length used in a hash
 
720
                                        search if hash_node != NULL */
 
721
        ulint           n_bytes;        /*!< hash prefix bytes if hash_node !=
 
722
                                        NULL */
 
723
        ulint           fold;           /*!< fold value used in the search if
 
724
                                        flag is BTR_CUR_HASH */
 
725
        /*----- Delete buffering -------*/
 
726
        ulint           ibuf_cnt;       /* in searches done on insert buffer
 
727
                                        trees, this contains the "counter"
 
728
                                        value (the first two bytes of the
 
729
                                        fourth field) extracted from the
 
730
                                        page above the leaf page, from the
 
731
                                        father node pointer that pointed to
 
732
                                        the leaf page. in other words, it
 
733
                                        contains the minimum counter value
 
734
                                        for records to be inserted on the
 
735
                                        chosen leaf page. If for some reason
 
736
                                        this can't be read, or if the search
 
737
                                        ended on the leftmost leaf page in
 
738
                                        the tree (in which case the father
 
739
                                        node pointer had the 'minimum
 
740
                                        record' flag set), this is
 
741
                                        ULINT_UNDEFINED. */
 
742
        /*------------------------------*/
 
743
        /* @} */
 
744
        btr_path_t*     path_arr;       /*!< in estimating the number of
 
745
                                        rows in range, we store in this array
 
746
                                        information of the path through
 
747
                                        the tree */
 
748
};
 
749
 
 
750
/** If pessimistic delete fails because of lack of file space, there
 
751
is still a good change of success a little later.  Try this many
 
752
times. */
 
753
#define BTR_CUR_RETRY_DELETE_N_TIMES    100
 
754
/** If pessimistic delete fails because of lack of file space, there
 
755
is still a good change of success a little later.  Sleep this many
 
756
microseconds between retries. */
 
757
#define BTR_CUR_RETRY_SLEEP_TIME        50000
 
758
 
 
759
/** The reference in a field for which data is stored on a different page.
 
760
The reference is at the end of the 'locally' stored part of the field.
 
761
'Locally' means storage in the index record.
 
762
We store locally a long enough prefix of each column so that we can determine
 
763
the ordering parts of each index record without looking into the externally
 
764
stored part. */
 
765
/*-------------------------------------- @{ */
 
766
#define BTR_EXTERN_SPACE_ID             0       /*!< space id where stored */
 
767
#define BTR_EXTERN_PAGE_NO              4       /*!< page no where stored */
 
768
#define BTR_EXTERN_OFFSET               8       /*!< offset of BLOB header
 
769
                                                on that page */
 
770
#define BTR_EXTERN_LEN                  12      /*!< 8 bytes containing the
 
771
                                                length of the externally
 
772
                                                stored part of the BLOB.
 
773
                                                The 2 highest bits are
 
774
                                                reserved to the flags below. */
 
775
/*-------------------------------------- @} */
 
776
/* #define BTR_EXTERN_FIELD_REF_SIZE    20 // moved to btr0types.h */
 
777
 
 
778
/** The most significant bit of BTR_EXTERN_LEN (i.e., the most
 
779
significant bit of the byte at smallest address) is set to 1 if this
 
780
field does not 'own' the externally stored field; only the owner field
 
781
is allowed to free the field in purge! */
 
782
#define BTR_EXTERN_OWNER_FLAG           128
 
783
/** If the second most significant bit of BTR_EXTERN_LEN (i.e., the
 
784
second most significant bit of the byte at smallest address) is 1 then
 
785
it means that the externally stored field was inherited from an
 
786
earlier version of the row.  In rollback we are not allowed to free an
 
787
inherited external field. */
 
788
#define BTR_EXTERN_INHERITED_FLAG       64
 
789
 
 
790
/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
 
791
extern ulint    btr_cur_n_non_sea;
 
792
/** Number of successful adaptive hash index lookups in
 
793
btr_cur_search_to_nth_level(). */
 
794
extern ulint    btr_cur_n_sea;
 
795
/** Old value of btr_cur_n_non_sea.  Copied by
 
796
srv_refresh_innodb_monitor_stats().  Referenced by
 
797
srv_printf_innodb_monitor(). */
 
798
extern ulint    btr_cur_n_non_sea_old;
 
799
/** Old value of btr_cur_n_sea.  Copied by
 
800
srv_refresh_innodb_monitor_stats().  Referenced by
 
801
srv_printf_innodb_monitor(). */
 
802
extern ulint    btr_cur_n_sea_old;
 
803
#endif /* !UNIV_HOTBACKUP */
 
804
 
 
805
#ifndef UNIV_NONINL
 
806
#include "btr0cur.ic"
 
807
#endif
 
808
 
 
809
#endif