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
Updates a record when the update causes no size changes in its fields.
247
@return DB_SUCCESS or error number */
250
btr_cur_update_in_place(
251
/*====================*/
252
ulint flags, /*!< in: undo logging and locking flags */
253
btr_cur_t* cursor, /*!< in: cursor on the record to update;
254
cursor stays valid and positioned on the
256
const upd_t* update, /*!< in: update vector */
257
ulint cmpl_info,/*!< in: compiler info on secondary index
259
que_thr_t* thr, /*!< in: query thread */
260
mtr_t* mtr); /*!< in: mtr; must be committed before
261
latching any further pages */
262
/*************************************************************//**
263
Tries to update a record on a page in an index tree. It is assumed that mtr
264
holds an x-latch on the page. The operation does not succeed if there is too
265
little space on the page or if the update would result in too empty a page,
266
so that tree compression is recommended.
267
@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
268
DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
269
there is not enough space left on the compressed page */
272
btr_cur_optimistic_update(
273
/*======================*/
274
ulint flags, /*!< in: undo logging and locking flags */
275
btr_cur_t* cursor, /*!< in: cursor on the record to update;
276
cursor stays valid and positioned on the
278
const upd_t* update, /*!< in: update vector; this must also
279
contain trx id and roll ptr fields */
280
ulint cmpl_info,/*!< in: compiler info on secondary index
282
que_thr_t* thr, /*!< in: query thread */
283
mtr_t* mtr); /*!< in: mtr; must be committed before
284
latching any further pages */
285
/*************************************************************//**
286
Performs an update of a record on a page of a tree. It is assumed
287
that mtr holds an x-latch on the tree and on the cursor page. If the
288
update is made on the leaf level, to avoid deadlocks, mtr must also
289
own x-latches to brothers of page, if those brothers exist.
290
@return DB_SUCCESS or error code */
293
btr_cur_pessimistic_update(
294
/*=======================*/
295
ulint flags, /*!< in: undo logging, locking, and rollback
297
btr_cur_t* cursor, /*!< in: cursor on the record to update */
298
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
299
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
300
be stored externally by the caller, or NULL */
301
const upd_t* update, /*!< in: update vector; this is allowed also
302
contain trx id and roll ptr fields, but
303
the values in update vector have no effect */
304
ulint cmpl_info,/*!< in: compiler info on secondary index
306
que_thr_t* thr, /*!< in: query thread */
307
mtr_t* mtr); /*!< in: mtr; must be committed before
308
latching any further pages */
309
/***********************************************************//**
310
Marks a clustered index record deleted. Writes an undo log record to
311
undo log on this delete marking. Writes in the trx id field the id
312
of the deleting transaction, and in the roll ptr field pointer to the
313
undo log record created.
314
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
317
btr_cur_del_mark_set_clust_rec(
318
/*===========================*/
319
ulint flags, /*!< in: undo logging and locking flags */
320
btr_cur_t* cursor, /*!< in: cursor */
321
ibool val, /*!< in: value to set */
322
que_thr_t* thr, /*!< in: query thread */
323
mtr_t* mtr); /*!< in: mtr */
324
/***********************************************************//**
325
Sets a secondary index record delete mark to TRUE or FALSE.
326
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
329
btr_cur_del_mark_set_sec_rec(
330
/*=========================*/
331
ulint flags, /*!< in: locking flag */
332
btr_cur_t* cursor, /*!< in: cursor */
333
ibool val, /*!< in: value to set */
334
que_thr_t* thr, /*!< in: query thread */
335
mtr_t* mtr); /*!< in: mtr */
336
/*************************************************************//**
337
Tries to compress a page of the tree if it seems useful. It is assumed
338
that mtr holds an x-latch on the tree and on the cursor page. To avoid
339
deadlocks, mtr must also own x-latches to brothers of page, if those
340
brothers exist. NOTE: it is assumed that the caller has reserved enough
341
free extents so that the compression will always succeed if done!
342
@return TRUE if compression occurred */
345
btr_cur_compress_if_useful(
346
/*=======================*/
347
btr_cur_t* cursor, /*!< in: cursor on the page to compress;
348
cursor does not stay valid if compression
350
mtr_t* mtr); /*!< in: mtr */
351
/*******************************************************//**
352
Removes the record on which the tree cursor is positioned. It is assumed
353
that the mtr has an x-latch on the page where the cursor is positioned,
354
but no latch on the whole tree.
355
@return TRUE if success, i.e., the page did not become too empty */
358
btr_cur_optimistic_delete(
359
/*======================*/
360
btr_cur_t* cursor, /*!< in: cursor on the record to delete;
361
cursor stays valid: if deletion succeeds,
362
on function exit it points to the successor
363
of the deleted record */
364
mtr_t* mtr); /*!< in: mtr; if this function returns
365
TRUE on a leaf page of a secondary
366
index, the mtr must be committed
367
before latching any further pages */
368
/*************************************************************//**
369
Removes the record on which the tree cursor is positioned. Tries
370
to compress the page if its fillfactor drops below a threshold
371
or if it is the only page on the level. It is assumed that mtr holds
372
an x-latch on the tree and on the cursor page. To avoid deadlocks,
373
mtr must also own x-latches to brothers of page, if those brothers
375
@return TRUE if compression occurred */
378
btr_cur_pessimistic_delete(
379
/*=======================*/
380
ulint* err, /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
381
the latter may occur because we may have
382
to update node pointers on upper levels,
383
and in the case of variable length keys
384
these may actually grow in size */
385
ibool has_reserved_extents, /*!< in: TRUE if the
386
caller has already reserved enough free
387
extents so that he knows that the operation
389
btr_cur_t* cursor, /*!< in: cursor on the record to delete;
390
if compression does not occur, the cursor
391
stays valid: it points to successor of
392
deleted record on function exit */
393
enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
394
mtr_t* mtr); /*!< in: mtr */
395
#endif /* !UNIV_HOTBACKUP */
396
/***********************************************************//**
397
Parses a redo log record of updating a record in-place.
398
@return end of log record or NULL */
401
btr_cur_parse_update_in_place(
402
/*==========================*/
403
byte* ptr, /*!< in: buffer */
404
byte* end_ptr,/*!< in: buffer end */
405
page_t* page, /*!< in/out: page or NULL */
406
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
407
dict_index_t* index); /*!< in: index corresponding to page */
408
/****************************************************************//**
409
Parses the redo log record for delete marking or unmarking of a clustered
411
@return end of log record or NULL */
414
btr_cur_parse_del_mark_set_clust_rec(
415
/*=================================*/
416
byte* ptr, /*!< in: buffer */
417
byte* end_ptr,/*!< in: buffer end */
418
page_t* page, /*!< in/out: page or NULL */
419
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
420
dict_index_t* index); /*!< in: index corresponding to page */
421
/****************************************************************//**
422
Parses the redo log record for delete marking or unmarking of a secondary
424
@return end of log record or NULL */
427
btr_cur_parse_del_mark_set_sec_rec(
428
/*===============================*/
429
byte* ptr, /*!< in: buffer */
430
byte* end_ptr,/*!< in: buffer end */
431
page_t* page, /*!< in/out: page or NULL */
432
page_zip_des_t* page_zip);/*!< in/out: compressed page, or NULL */
433
#ifndef UNIV_HOTBACKUP
434
/*******************************************************************//**
435
Estimates the number of rows in a given index range.
436
@return estimated number of rows */
439
btr_estimate_n_rows_in_range(
440
/*=========================*/
441
dict_index_t* index, /*!< in: index */
442
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
443
ulint mode1, /*!< in: search mode for range start */
444
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
445
ulint mode2); /*!< in: search mode for range end */
446
/*******************************************************************//**
447
Estimates the number of different key values in a given index, for
448
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
449
The estimates are stored in the array index->stat_n_diff_key_vals. */
452
btr_estimate_number_of_different_key_vals(
453
/*======================================*/
454
dict_index_t* index); /*!< in: index */
455
/*******************************************************************//**
456
Marks not updated extern fields as not-owned by this record. The ownership
457
is transferred to the updated record which is inserted elsewhere in the
458
index tree. In purge only the owner of externally stored field is allowed
460
@return TRUE if BLOB ownership was transferred */
463
btr_cur_mark_extern_inherited_fields(
464
/*=================================*/
465
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
466
part will be updated, or NULL */
467
rec_t* rec, /*!< in/out: record in a clustered index */
468
dict_index_t* index, /*!< in: index of the page */
469
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
470
const upd_t* update, /*!< in: update vector */
471
mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
472
/*******************************************************************//**
473
The complement of the previous function: in an update entry may inherit
474
some externally stored fields from a record. We must mark them as inherited
475
in entry, so that they are not freed in a rollback. */
478
btr_cur_mark_dtuple_inherited_extern(
479
/*=================================*/
480
dtuple_t* entry, /*!< in/out: updated entry to be
481
inserted to clustered index */
482
const upd_t* update); /*!< in: update vector */
483
/*******************************************************************//**
484
Marks all extern fields in a dtuple as owned by the record. */
487
btr_cur_unmark_dtuple_extern_fields(
488
/*================================*/
489
dtuple_t* entry); /*!< in/out: clustered index entry */
490
/*******************************************************************//**
491
Stores the fields in big_rec_vec to the tablespace and puts pointers to
492
them in rec. The extern flags in rec will have to be set beforehand.
493
The fields are stored on pages allocated from leaf node
494
file segment of the index tree.
495
@return DB_SUCCESS or error */
498
btr_store_big_rec_extern_fields(
499
/*============================*/
500
dict_index_t* index, /*!< in: index of rec; the index tree
502
buf_block_t* rec_block, /*!< in/out: block containing rec */
503
rec_t* rec, /*!< in: record */
504
const ulint* offsets, /*!< in: rec_get_offsets(rec, index);
505
the "external storage" flags in offsets
506
will not correspond to rec when
507
this function returns */
508
big_rec_t* big_rec_vec, /*!< in: vector containing fields
509
to be stored externally */
510
mtr_t* local_mtr); /*!< in: mtr containing the latch to
511
rec and to the tree */
512
/*******************************************************************//**
513
Frees the space in an externally stored field to the file space
514
management if the field in data is owned the externally stored field,
515
in a rollback we may have the additional condition that the field must
519
btr_free_externally_stored_field(
520
/*=============================*/
521
dict_index_t* index, /*!< in: index of the data, the index
522
tree MUST be X-latched; if the tree
523
height is 1, then also the root page
524
must be X-latched! (this is relevant
525
in the case this function is called
526
from purge where 'data' is located on
527
an undo log page, not an index
529
byte* field_ref, /*!< in/out: field reference */
530
const rec_t* rec, /*!< in: record containing field_ref, for
531
page_zip_write_blob_ptr(), or NULL */
532
const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
534
page_zip_des_t* page_zip, /*!< in: compressed page corresponding
535
to rec, or NULL if rec == NULL */
536
ulint i, /*!< in: field number of field_ref;
537
ignored if rec == NULL */
538
enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
539
mtr_t* local_mtr); /*!< in: mtr containing the latch to
540
data an an X-latch to the index
542
/*******************************************************************//**
543
Copies the prefix of an externally stored field of a record. The
544
clustered index record must be protected by a lock or a page latch.
545
@return the length of the copied field, or 0 if the column was being
546
or has been deleted */
549
btr_copy_externally_stored_field_prefix(
550
/*====================================*/
551
byte* buf, /*!< out: the field, or a prefix of it */
552
ulint len, /*!< in: length of buf, in bytes */
553
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
554
zero for uncompressed BLOBs */
555
const byte* data, /*!< in: 'internally' stored part of the
556
field containing also the reference to
557
the external part; must be protected by
558
a lock or a page latch */
559
ulint local_len);/*!< in: length of data, in bytes */
560
/*******************************************************************//**
561
Copies an externally stored field of a record to mem heap.
562
@return the field copied to heap, or NULL if the field is incomplete */
565
btr_rec_copy_externally_stored_field(
566
/*=================================*/
567
const rec_t* rec, /*!< in: record in a clustered index;
568
must be protected by a lock or a page latch */
569
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
570
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
571
zero for uncompressed BLOBs */
572
ulint no, /*!< in: field number */
573
ulint* len, /*!< out: length of the field */
574
mem_heap_t* heap); /*!< in: mem heap */
575
/*******************************************************************//**
576
Flags the data tuple fields that are marked as extern storage in the
577
update vector. We use this function to remember which fields we must
578
mark as extern storage in a record inserted for an update.
579
@return number of flagged external columns */
582
btr_push_update_extern_fields(
583
/*==========================*/
584
dtuple_t* tuple, /*!< in/out: data tuple */
585
const upd_t* update, /*!< in: update vector */
586
mem_heap_t* heap) /*!< in: memory heap */
587
__attribute__((nonnull));
588
/***********************************************************//**
589
Sets a secondary index record's delete mark to the given value. This
590
function is only used by the insert buffer merge mechanism. */
593
btr_cur_set_deleted_flag_for_ibuf(
594
/*==============================*/
595
rec_t* rec, /*!< in/out: record */
596
page_zip_des_t* page_zip, /*!< in/out: compressed page
597
corresponding to rec, or NULL
598
when the tablespace is
600
ibool val, /*!< in: value to set */
601
mtr_t* mtr); /*!< in: mtr */
602
/*######################################################################*/
604
/** In the pessimistic delete, if the page data size drops below this
605
limit, merging it to a neighbor is tried */
606
#define BTR_CUR_PAGE_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 2)
608
/** A slot in the path array. We store here info on a search path down the
609
tree. Each slot contains data on a single level of the tree. */
611
typedef struct btr_path_struct btr_path_t;
612
struct btr_path_struct{
613
ulint nth_rec; /*!< index of the record
614
where the page cursor stopped on
615
this level (index in alphabetical
616
order); value ULINT_UNDEFINED
618
ulint n_recs; /*!< number of records on the page */
619
ulint page_no; /*!< no of the page containing the record */
620
ulint page_level; /*!< level of the page, if later we fetch
621
the page under page_no and it is no different
622
level then we know that the tree has been
626
#define BTR_PATH_ARRAY_N_SLOTS 250 /*!< size of path array (in slots) */
628
/** Values for the flag documenting the used search method */
629
enum btr_cur_method {
630
BTR_CUR_HASH = 1, /*!< successful shortcut using
632
BTR_CUR_HASH_FAIL, /*!< failure using hash, success using
633
binary search: the misleading hash
634
reference is stored in the field
635
hash_node, and might be necessary to
637
BTR_CUR_BINARY, /*!< success using the binary search */
638
BTR_CUR_INSERT_TO_IBUF, /*!< performed the intended insert to
640
BTR_CUR_DEL_MARK_IBUF, /*!< performed the intended delete
641
mark in the insert/delete buffer */
642
BTR_CUR_DELETE_IBUF, /*!< performed the intended delete in
643
the insert/delete buffer */
644
BTR_CUR_DELETE_REF /*!< row_purge_poss_sec() failed */
647
/** The tree cursor: the definition appears here only for the compiler
648
to know struct size! */
649
struct btr_cur_struct {
650
dict_index_t* index; /*!< index where positioned */
651
page_cur_t page_cur; /*!< page cursor */
652
purge_node_t* purge_node; /*!< purge node, for BTR_DELETE */
653
buf_block_t* left_block; /*!< this field is used to store
654
a pointer to the left neighbor
658
/*------------------------------*/
659
que_thr_t* thr; /*!< this field is only used
660
when btr_cur_search_to_nth_level
661
is called for an index entry
662
insertion: the calling query
663
thread is passed here to be
664
used in the insert buffer */
665
/*------------------------------*/
666
/** The following fields are used in
667
btr_cur_search_to_nth_level to pass information: */
669
enum btr_cur_method flag; /*!< Search method used */
670
ulint tree_height; /*!< Tree height if the search is done
671
for a pessimistic insert or update
673
ulint up_match; /*!< If the search mode was PAGE_CUR_LE,
674
the number of matched fields to the
675
the first user record to the right of
676
the cursor record after
677
btr_cur_search_to_nth_level;
678
for the mode PAGE_CUR_GE, the matched
679
fields to the first user record AT THE
680
CURSOR or to the right of it;
681
NOTE that the up_match and low_match
682
values may exceed the correct values
683
for comparison to the adjacent user
684
record if that record is on a
685
different leaf page! (See the note in
686
row_ins_duplicate_key.) */
687
ulint up_bytes; /*!< number of matched bytes to the
688
right at the time cursor positioned;
689
only used internally in searches: not
690
defined after the search */
691
ulint low_match; /*!< if search mode was PAGE_CUR_LE,
692
the number of matched fields to the
693
first user record AT THE CURSOR or
694
to the left of it after
695
btr_cur_search_to_nth_level;
696
NOT defined for PAGE_CUR_GE or any
697
other search modes; see also the NOTE
699
ulint low_bytes; /*!< number of matched bytes to the
700
right at the time cursor positioned;
701
only used internally in searches: not
702
defined after the search */
703
ulint n_fields; /*!< prefix length used in a hash
704
search if hash_node != NULL */
705
ulint n_bytes; /*!< hash prefix bytes if hash_node !=
707
ulint fold; /*!< fold value used in the search if
708
flag is BTR_CUR_HASH */
709
/*----- Delete buffering -------*/
710
ulint ibuf_cnt; /* in searches done on insert buffer
711
trees, this contains the "counter"
712
value (the first two bytes of the
713
fourth field) extracted from the
714
page above the leaf page, from the
715
father node pointer that pointed to
716
the leaf page. in other words, it
717
contains the minimum counter value
718
for records to be inserted on the
719
chosen leaf page. If for some reason
720
this can't be read, or if the search
721
ended on the leftmost leaf page in
722
the tree (in which case the father
723
node pointer had the 'minimum
724
record' flag set), this is
726
/*------------------------------*/
728
btr_path_t* path_arr; /*!< in estimating the number of
729
rows in range, we store in this array
730
information of the path through
734
/** If pessimistic delete fails because of lack of file space, there
735
is still a good change of success a little later. Try this many
737
#define BTR_CUR_RETRY_DELETE_N_TIMES 100
738
/** If pessimistic delete fails because of lack of file space, there
739
is still a good change of success a little later. Sleep this many
740
microseconds between retries. */
741
#define BTR_CUR_RETRY_SLEEP_TIME 50000
743
/** The reference in a field for which data is stored on a different page.
744
The reference is at the end of the 'locally' stored part of the field.
745
'Locally' means storage in the index record.
746
We store locally a long enough prefix of each column so that we can determine
747
the ordering parts of each index record without looking into the externally
749
/*-------------------------------------- @{ */
750
#define BTR_EXTERN_SPACE_ID 0 /*!< space id where stored */
751
#define BTR_EXTERN_PAGE_NO 4 /*!< page no where stored */
752
#define BTR_EXTERN_OFFSET 8 /*!< offset of BLOB header
754
#define BTR_EXTERN_LEN 12 /*!< 8 bytes containing the
755
length of the externally
756
stored part of the BLOB.
757
The 2 highest bits are
758
reserved to the flags below. */
759
/*-------------------------------------- @} */
760
/* #define BTR_EXTERN_FIELD_REF_SIZE 20 // moved to btr0types.h */
762
/** The most significant bit of BTR_EXTERN_LEN (i.e., the most
763
significant bit of the byte at smallest address) is set to 1 if this
764
field does not 'own' the externally stored field; only the owner field
765
is allowed to free the field in purge! */
766
#define BTR_EXTERN_OWNER_FLAG 128
767
/** If the second most significant bit of BTR_EXTERN_LEN (i.e., the
768
second most significant bit of the byte at smallest address) is 1 then
769
it means that the externally stored field was inherited from an
770
earlier version of the row. In rollback we are not allowed to free an
771
inherited external field. */
772
#define BTR_EXTERN_INHERITED_FLAG 64
774
/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
775
extern ulint btr_cur_n_non_sea;
776
/** Number of successful adaptive hash index lookups in
777
btr_cur_search_to_nth_level(). */
778
extern ulint btr_cur_n_sea;
779
/** Old value of btr_cur_n_non_sea. Copied by
780
srv_refresh_innodb_monitor_stats(). Referenced by
781
srv_printf_innodb_monitor(). */
782
extern ulint btr_cur_n_non_sea_old;
783
/** Old value of btr_cur_n_sea. Copied by
784
srv_refresh_innodb_monitor_stats(). Referenced by
785
srv_printf_innodb_monitor(). */
786
extern ulint btr_cur_n_sea_old;
787
#endif /* !UNIV_HOTBACKUP */
790
#include "btr0cur.ic"