1
/*****************************************************************************
3
Copyright (C) 1994, 2010, Innobase Oy. All Rights Reserved.
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.
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.
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
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/btr0cur.h
23
Created 10/16/1994 Heikki Tuuri
24
*******************************************************/
30
#include "dict0dict.h"
32
#include "btr0types.h"
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 */
40
#ifndef UNIV_HOTBACKUP
41
#include "que0types.h"
42
#include "row0types.h"
46
#define BTR_CUR_HASH_ADAPT
49
/*********************************************************//**
50
Returns the page cursor component of a tree cursor.
51
@return pointer to page cursor component */
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 */
67
btr_cur_t* cursor);/*!< in: tree cursor */
68
/*********************************************************//**
69
Returns the record pointer of a tree cursor.
70
@return pointer to record */
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 */
83
btr_cur_t* cursor);/*!< in: tree cursor */
84
/*********************************************************//**
85
Invalidates a tree cursor by setting record pointer to NULL. */
90
btr_cur_t* cursor);/*!< in: tree cursor */
91
/*********************************************************//**
92
Returns the page of a tree cursor.
93
@return pointer to page */
98
btr_cur_t* cursor);/*!< in: tree cursor */
99
/*********************************************************//**
100
Returns the index of a cursor.
106
btr_cur_t* cursor);/*!< in: B-tree cursor */
107
/*********************************************************//**
108
Positions a tree cursor at a given record. */
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. */
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:
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. */
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. */
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 */
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
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
208
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
209
be stored externally by the caller, or
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
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 */
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
239
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
240
be stored externally by the caller, or
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
248
@return TRUE if enough place */
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 */
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
272
const upd_t* update, /*!< in: update vector */
273
ulint cmpl_info,/*!< in: compiler info on secondary index
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 */
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
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
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 */
309
btr_cur_pessimistic_update(
310
/*=======================*/
311
ulint flags, /*!< in: undo logging, locking, and rollback
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
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 */
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 */
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 */
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
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 */
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
391
@return TRUE if compression occurred */
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
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 */
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
427
@return end of log record or NULL */
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
440
@return end of log record or NULL */
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 */
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. */
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
476
@return TRUE if BLOB ownership was transferred */
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. */
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. */
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 */
514
btr_store_big_rec_extern_fields(
515
/*============================*/
516
dict_index_t* index, /*!< in: index of rec; the index tree
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
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
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),
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
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 */
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 */
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 */
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. */
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
616
ibool val, /*!< in: value to set */
617
mtr_t* mtr); /*!< in: mtr */
618
/*######################################################################*/
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)
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. */
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
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
642
#define BTR_PATH_ARRAY_N_SLOTS 250 /*!< size of path array (in slots) */
644
/** Values for the flag documenting the used search method */
645
enum btr_cur_method {
646
BTR_CUR_HASH = 1, /*!< successful shortcut using
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
653
BTR_CUR_BINARY, /*!< success using the binary search */
654
BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
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 */
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
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: */
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
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
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 !=
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
742
/*------------------------------*/
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
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
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
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
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
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 */
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
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 */
806
#include "btr0cur.ic"