1
/*****************************************************************************
3
Copyright (c) 1994, 2009, 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., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 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
BTR_INSERT and BTR_ESTIMATE;
142
cursor->left_block is used to store a pointer
143
to the left neighbor page, in the cases
144
BTR_SEARCH_PREV and BTR_MODIFY_PREV;
145
NOTE that if has_search_latch
146
is != 0, we maybe do not have a latch set
147
on the cursor page, we assume
148
the caller uses his search latch
149
to protect the record! */
150
btr_cur_t* cursor, /*!< in/out: tree cursor; the cursor page is
151
s- or x-latched, but see also above! */
152
ulint has_search_latch,/*!< in: latch mode the caller
153
currently has on btr_search_latch:
155
mtr_t* mtr); /*!< in: mtr */
156
/*****************************************************************//**
157
Opens a cursor at either end of an index. */
160
btr_cur_open_at_index_side(
161
/*=======================*/
162
ibool from_left, /*!< in: TRUE if open to the low end,
163
FALSE if to the high end */
164
dict_index_t* index, /*!< in: index */
165
ulint latch_mode, /*!< in: latch mode */
166
btr_cur_t* cursor, /*!< in: cursor */
167
mtr_t* mtr); /*!< in: mtr */
168
/**********************************************************************//**
169
Positions a cursor at a randomly chosen position within a B-tree. */
172
btr_cur_open_at_rnd_pos(
173
/*====================*/
174
dict_index_t* index, /*!< in: index */
175
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
176
btr_cur_t* cursor, /*!< in/out: B-tree cursor */
177
mtr_t* mtr); /*!< in: mtr */
178
/*************************************************************//**
179
Tries to perform an insert to a page in an index tree, next to cursor.
180
It is assumed that mtr holds an x-latch on the page. The operation does
181
not succeed if there is too little space on the page. If there is just
182
one record on the page, the insert will always succeed; this is to
183
prevent trying to split a page with just one record.
184
@return DB_SUCCESS, DB_WAIT_LOCK, DB_FAIL, or error number */
187
btr_cur_optimistic_insert(
188
/*======================*/
189
ulint flags, /*!< in: undo logging and locking flags: if not
190
zero, the parameters index and thr should be
192
btr_cur_t* cursor, /*!< in: cursor on page after which to insert;
193
cursor stays valid */
194
dtuple_t* entry, /*!< in/out: entry to insert */
195
rec_t** rec, /*!< out: pointer to inserted record if
197
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
198
be stored externally by the caller, or
200
ulint n_ext, /*!< in: number of externally stored columns */
201
que_thr_t* thr, /*!< in: query thread or NULL */
202
mtr_t* mtr); /*!< in: mtr; if this function returns
203
DB_SUCCESS on a leaf page of a secondary
204
index in a compressed tablespace, the
205
mtr must be committed before latching
207
/*************************************************************//**
208
Performs an insert on a page of an index tree. It is assumed that mtr
209
holds an x-latch on the tree and on the cursor page. If the insert is
210
made on the leaf level, to avoid deadlocks, mtr must also own x-latches
211
to brothers of page, if those brothers exist.
212
@return DB_SUCCESS or error number */
215
btr_cur_pessimistic_insert(
216
/*=======================*/
217
ulint flags, /*!< in: undo logging and locking flags: if not
218
zero, the parameter thr should be
219
specified; if no undo logging is specified,
220
then the caller must have reserved enough
221
free extents in the file space so that the
222
insertion will certainly succeed */
223
btr_cur_t* cursor, /*!< in: cursor after which to insert;
224
cursor stays valid */
225
dtuple_t* entry, /*!< in/out: entry to insert */
226
rec_t** rec, /*!< out: pointer to inserted record if
228
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
229
be stored externally by the caller, or
231
ulint n_ext, /*!< in: number of externally stored columns */
232
que_thr_t* thr, /*!< in: query thread or NULL */
233
mtr_t* mtr); /*!< in: mtr */
234
/*************************************************************//**
235
Updates a record when the update causes no size changes in its fields.
236
@return DB_SUCCESS or error number */
239
btr_cur_update_in_place(
240
/*====================*/
241
ulint flags, /*!< in: undo logging and locking flags */
242
btr_cur_t* cursor, /*!< in: cursor on the record to update;
243
cursor stays valid and positioned on the
245
const upd_t* update, /*!< in: update vector */
246
ulint cmpl_info,/*!< in: compiler info on secondary index
248
que_thr_t* thr, /*!< in: query thread */
249
mtr_t* mtr); /*!< in: mtr; must be committed before
250
latching any further pages */
251
/*************************************************************//**
252
Tries to update a record on a page in an index tree. It is assumed that mtr
253
holds an x-latch on the page. The operation does not succeed if there is too
254
little space on the page or if the update would result in too empty a page,
255
so that tree compression is recommended.
256
@return DB_SUCCESS, or DB_OVERFLOW if the updated record does not fit,
257
DB_UNDERFLOW if the page would become too empty, or DB_ZIP_OVERFLOW if
258
there is not enough space left on the compressed page */
261
btr_cur_optimistic_update(
262
/*======================*/
263
ulint flags, /*!< in: undo logging and locking flags */
264
btr_cur_t* cursor, /*!< in: cursor on the record to update;
265
cursor stays valid and positioned on the
267
const upd_t* update, /*!< in: update vector; this must also
268
contain trx id and roll ptr fields */
269
ulint cmpl_info,/*!< in: compiler info on secondary index
271
que_thr_t* thr, /*!< in: query thread */
272
mtr_t* mtr); /*!< in: mtr; must be committed before
273
latching any further pages */
274
/*************************************************************//**
275
Performs an update of a record on a page of a tree. It is assumed
276
that mtr holds an x-latch on the tree and on the cursor page. If the
277
update is made on the leaf level, to avoid deadlocks, mtr must also
278
own x-latches to brothers of page, if those brothers exist.
279
@return DB_SUCCESS or error code */
282
btr_cur_pessimistic_update(
283
/*=======================*/
284
ulint flags, /*!< in: undo logging, locking, and rollback
286
btr_cur_t* cursor, /*!< in: cursor on the record to update */
287
mem_heap_t** heap, /*!< in/out: pointer to memory heap, or NULL */
288
big_rec_t** big_rec,/*!< out: big rec vector whose fields have to
289
be stored externally by the caller, or NULL */
290
const upd_t* update, /*!< in: update vector; this is allowed also
291
contain trx id and roll ptr fields, but
292
the values in update vector have no effect */
293
ulint cmpl_info,/*!< in: compiler info on secondary index
295
que_thr_t* thr, /*!< in: query thread */
296
mtr_t* mtr); /*!< in: mtr; must be committed before
297
latching any further pages */
298
/***********************************************************//**
299
Marks a clustered index record deleted. Writes an undo log record to
300
undo log on this delete marking. Writes in the trx id field the id
301
of the deleting transaction, and in the roll ptr field pointer to the
302
undo log record created.
303
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
306
btr_cur_del_mark_set_clust_rec(
307
/*===========================*/
308
ulint flags, /*!< in: undo logging and locking flags */
309
btr_cur_t* cursor, /*!< in: cursor */
310
ibool val, /*!< in: value to set */
311
que_thr_t* thr, /*!< in: query thread */
312
mtr_t* mtr); /*!< in: mtr */
313
/***********************************************************//**
314
Sets a secondary index record delete mark to TRUE or FALSE.
315
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
318
btr_cur_del_mark_set_sec_rec(
319
/*=========================*/
320
ulint flags, /*!< in: locking flag */
321
btr_cur_t* cursor, /*!< in: cursor */
322
ibool val, /*!< in: value to set */
323
que_thr_t* thr, /*!< in: query thread */
324
mtr_t* mtr); /*!< in: mtr */
325
/***********************************************************//**
326
Clear a secondary index record's delete mark. This function is only
327
used by the insert buffer insert merge mechanism. */
330
btr_cur_del_unmark_for_ibuf(
331
/*========================*/
332
rec_t* rec, /*!< in/out: record to delete unmark */
333
page_zip_des_t* page_zip, /*!< in/out: compressed page
334
corresponding to rec, or NULL
335
when the tablespace is
337
mtr_t* mtr); /*!< in: mtr */
338
/*************************************************************//**
339
Tries to compress a page of the tree if it seems useful. It is assumed
340
that mtr holds an x-latch on the tree and on the cursor page. To avoid
341
deadlocks, mtr must also own x-latches to brothers of page, if those
342
brothers exist. NOTE: it is assumed that the caller has reserved enough
343
free extents so that the compression will always succeed if done!
344
@return TRUE if compression occurred */
347
btr_cur_compress_if_useful(
348
/*=======================*/
349
btr_cur_t* cursor, /*!< in: cursor on the page to compress;
350
cursor does not stay valid if compression
352
mtr_t* mtr); /*!< in: mtr */
353
/*******************************************************//**
354
Removes the record on which the tree cursor is positioned. It is assumed
355
that the mtr has an x-latch on the page where the cursor is positioned,
356
but no latch on the whole tree.
357
@return TRUE if success, i.e., the page did not become too empty */
360
btr_cur_optimistic_delete(
361
/*======================*/
362
btr_cur_t* cursor, /*!< in: cursor on the record to delete;
363
cursor stays valid: if deletion succeeds,
364
on function exit it points to the successor
365
of the deleted record */
366
mtr_t* mtr); /*!< in: mtr; if this function returns
367
TRUE on a leaf page of a secondary
368
index, the mtr must be committed
369
before latching any further pages */
370
/*************************************************************//**
371
Removes the record on which the tree cursor is positioned. Tries
372
to compress the page if its fillfactor drops below a threshold
373
or if it is the only page on the level. It is assumed that mtr holds
374
an x-latch on the tree and on the cursor page. To avoid deadlocks,
375
mtr must also own x-latches to brothers of page, if those brothers
377
@return TRUE if compression occurred */
380
btr_cur_pessimistic_delete(
381
/*=======================*/
382
ulint* err, /*!< out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
383
the latter may occur because we may have
384
to update node pointers on upper levels,
385
and in the case of variable length keys
386
these may actually grow in size */
387
ibool has_reserved_extents, /*!< in: TRUE if the
388
caller has already reserved enough free
389
extents so that he knows that the operation
391
btr_cur_t* cursor, /*!< in: cursor on the record to delete;
392
if compression does not occur, the cursor
393
stays valid: it points to successor of
394
deleted record on function exit */
395
enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
396
mtr_t* mtr); /*!< in: mtr */
397
#endif /* !UNIV_HOTBACKUP */
398
/***********************************************************//**
399
Parses a redo log record of updating a record in-place.
400
@return end of log record or NULL */
403
btr_cur_parse_update_in_place(
404
/*==========================*/
405
byte* ptr, /*!< in: buffer */
406
byte* end_ptr,/*!< in: buffer end */
407
page_t* page, /*!< in/out: page or NULL */
408
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
409
dict_index_t* index); /*!< in: index corresponding to page */
410
/****************************************************************//**
411
Parses the redo log record for delete marking or unmarking of a clustered
413
@return end of log record or NULL */
416
btr_cur_parse_del_mark_set_clust_rec(
417
/*=================================*/
418
byte* ptr, /*!< in: buffer */
419
byte* end_ptr,/*!< in: buffer end */
420
page_t* page, /*!< in/out: page or NULL */
421
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
422
dict_index_t* index); /*!< in: index corresponding to page */
423
/****************************************************************//**
424
Parses the redo log record for delete marking or unmarking of a secondary
426
@return end of log record or NULL */
429
btr_cur_parse_del_mark_set_sec_rec(
430
/*===============================*/
431
byte* ptr, /*!< in: buffer */
432
byte* end_ptr,/*!< in: buffer end */
433
page_t* page, /*!< in/out: page or NULL */
434
page_zip_des_t* page_zip);/*!< in/out: compressed page, or NULL */
435
#ifndef UNIV_HOTBACKUP
436
/*******************************************************************//**
437
Estimates the number of rows in a given index range.
438
@return estimated number of rows */
441
btr_estimate_n_rows_in_range(
442
/*=========================*/
443
dict_index_t* index, /*!< in: index */
444
const dtuple_t* tuple1, /*!< in: range start, may also be empty tuple */
445
ulint mode1, /*!< in: search mode for range start */
446
const dtuple_t* tuple2, /*!< in: range end, may also be empty tuple */
447
ulint mode2); /*!< in: search mode for range end */
448
/*******************************************************************//**
449
Estimates the number of different key values in a given index, for
450
each n-column prefix of the index where n <= dict_index_get_n_unique(index).
451
The estimates are stored in the array index->stat_n_diff_key_vals. */
454
btr_estimate_number_of_different_key_vals(
455
/*======================================*/
456
dict_index_t* index); /*!< in: index */
457
/*******************************************************************//**
458
Marks not updated extern fields as not-owned by this record. The ownership
459
is transferred to the updated record which is inserted elsewhere in the
460
index tree. In purge only the owner of externally stored field is allowed
461
to free the field. */
464
btr_cur_mark_extern_inherited_fields(
465
/*=================================*/
466
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
467
part will be updated, or NULL */
468
rec_t* rec, /*!< in/out: record in a clustered index */
469
dict_index_t* index, /*!< in: index of the page */
470
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
471
const upd_t* update, /*!< in: update vector */
472
mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
473
/*******************************************************************//**
474
The complement of the previous function: in an update entry may inherit
475
some externally stored fields from a record. We must mark them as inherited
476
in entry, so that they are not freed in a rollback. */
479
btr_cur_mark_dtuple_inherited_extern(
480
/*=================================*/
481
dtuple_t* entry, /*!< in/out: updated entry to be
482
inserted to clustered index */
483
const upd_t* update); /*!< in: update vector */
484
/*******************************************************************//**
485
Marks all extern fields in a dtuple as owned by the record. */
488
btr_cur_unmark_dtuple_extern_fields(
489
/*================================*/
490
dtuple_t* entry); /*!< in/out: clustered index entry */
491
/*******************************************************************//**
492
Stores the fields in big_rec_vec to the tablespace and puts pointers to
493
them in rec. The extern flags in rec will have to be set beforehand.
494
The fields are stored on pages allocated from leaf node
495
file segment of the index tree.
496
@return DB_SUCCESS or error */
499
btr_store_big_rec_extern_fields(
500
/*============================*/
501
dict_index_t* index, /*!< in: index of rec; the index tree
503
buf_block_t* rec_block, /*!< in/out: block containing rec */
504
rec_t* rec, /*!< in: record */
505
const ulint* offsets, /*!< in: rec_get_offsets(rec, index);
506
the "external storage" flags in offsets
507
will not correspond to rec when
508
this function returns */
509
big_rec_t* big_rec_vec, /*!< in: vector containing fields
510
to be stored externally */
511
mtr_t* local_mtr); /*!< in: mtr containing the latch to
512
rec and to the tree */
513
/*******************************************************************//**
514
Frees the space in an externally stored field to the file space
515
management if the field in data is owned the externally stored field,
516
in a rollback we may have the additional condition that the field must
520
btr_free_externally_stored_field(
521
/*=============================*/
522
dict_index_t* index, /*!< in: index of the data, the index
523
tree MUST be X-latched; if the tree
524
height is 1, then also the root page
525
must be X-latched! (this is relevant
526
in the case this function is called
527
from purge where 'data' is located on
528
an undo log page, not an index
530
byte* field_ref, /*!< in/out: field reference */
531
const rec_t* rec, /*!< in: record containing field_ref, for
532
page_zip_write_blob_ptr(), or NULL */
533
const ulint* offsets, /*!< in: rec_get_offsets(rec, index),
535
page_zip_des_t* page_zip, /*!< in: compressed page corresponding
536
to rec, or NULL if rec == NULL */
537
ulint i, /*!< in: field number of field_ref;
538
ignored if rec == NULL */
539
enum trx_rb_ctx rb_ctx, /*!< in: rollback context */
540
mtr_t* local_mtr); /*!< in: mtr containing the latch to
541
data an an X-latch to the index
543
/*******************************************************************//**
544
Copies the prefix of an externally stored field of a record. The
545
clustered index record must be protected by a lock or a page latch.
546
@return the length of the copied field, or 0 if the column was being
547
or has been deleted */
550
btr_copy_externally_stored_field_prefix(
551
/*====================================*/
552
byte* buf, /*!< out: the field, or a prefix of it */
553
ulint len, /*!< in: length of buf, in bytes */
554
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
555
zero for uncompressed BLOBs */
556
const byte* data, /*!< in: 'internally' stored part of the
557
field containing also the reference to
558
the external part; must be protected by
559
a lock or a page latch */
560
ulint local_len);/*!< in: length of data, in bytes */
561
/*******************************************************************//**
562
Copies an externally stored field of a record to mem heap.
563
@return the field copied to heap */
566
btr_rec_copy_externally_stored_field(
567
/*=================================*/
568
const rec_t* rec, /*!< in: record in a clustered index;
569
must be protected by a lock or a page latch */
570
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
571
ulint zip_size,/*!< in: nonzero=compressed BLOB page size,
572
zero for uncompressed BLOBs */
573
ulint no, /*!< in: field number */
574
ulint* len, /*!< out: length of the field */
575
mem_heap_t* heap); /*!< in: mem heap */
576
/*******************************************************************//**
577
Flags the data tuple fields that are marked as extern storage in the
578
update vector. We use this function to remember which fields we must
579
mark as extern storage in a record inserted for an update.
580
@return number of flagged external columns */
583
btr_push_update_extern_fields(
584
/*==========================*/
585
dtuple_t* tuple, /*!< in/out: data tuple */
586
const upd_t* update, /*!< in: update vector */
587
mem_heap_t* heap) /*!< in: memory heap */
588
__attribute__((nonnull));
590
/*######################################################################*/
592
/** In the pessimistic delete, if the page data size drops below this
593
limit, merging it to a neighbor is tried */
594
#define BTR_CUR_PAGE_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 2)
596
/** A slot in the path array. We store here info on a search path down the
597
tree. Each slot contains data on a single level of the tree. */
599
typedef struct btr_path_struct btr_path_t;
600
struct btr_path_struct{
601
ulint nth_rec; /*!< index of the record
602
where the page cursor stopped on
603
this level (index in alphabetical
604
order); value ULINT_UNDEFINED
606
ulint n_recs; /*!< number of records on the page */
609
#define BTR_PATH_ARRAY_N_SLOTS 250 /*!< size of path array (in slots) */
611
/** Values for the flag documenting the used search method */
612
enum btr_cur_method {
613
BTR_CUR_HASH = 1, /*!< successful shortcut using
615
BTR_CUR_HASH_FAIL, /*!< failure using hash, success using
616
binary search: the misleading hash
617
reference is stored in the field
618
hash_node, and might be necessary to
620
BTR_CUR_BINARY, /*!< success using the binary search */
621
BTR_CUR_INSERT_TO_IBUF /*!< performed the intended insert to
625
/** The tree cursor: the definition appears here only for the compiler
626
to know struct size! */
627
struct btr_cur_struct {
628
dict_index_t* index; /*!< index where positioned */
629
page_cur_t page_cur; /*!< page cursor */
630
buf_block_t* left_block; /*!< this field is used to store
631
a pointer to the left neighbor
635
/*------------------------------*/
636
que_thr_t* thr; /*!< this field is only used
637
when btr_cur_search_to_nth_level
638
is called for an index entry
639
insertion: the calling query
640
thread is passed here to be
641
used in the insert buffer */
642
/*------------------------------*/
643
/** The following fields are used in
644
btr_cur_search_to_nth_level to pass information: */
646
enum btr_cur_method flag; /*!< Search method used */
647
ulint tree_height; /*!< Tree height if the search is done
648
for a pessimistic insert or update
650
ulint up_match; /*!< If the search mode was PAGE_CUR_LE,
651
the number of matched fields to the
652
the first user record to the right of
653
the cursor record after
654
btr_cur_search_to_nth_level;
655
for the mode PAGE_CUR_GE, the matched
656
fields to the first user record AT THE
657
CURSOR or to the right of it;
658
NOTE that the up_match and low_match
659
values may exceed the correct values
660
for comparison to the adjacent user
661
record if that record is on a
662
different leaf page! (See the note in
663
row_ins_duplicate_key.) */
664
ulint up_bytes; /*!< number of matched bytes to the
665
right at the time cursor positioned;
666
only used internally in searches: not
667
defined after the search */
668
ulint low_match; /*!< if search mode was PAGE_CUR_LE,
669
the number of matched fields to the
670
first user record AT THE CURSOR or
671
to the left of it after
672
btr_cur_search_to_nth_level;
673
NOT defined for PAGE_CUR_GE or any
674
other search modes; see also the NOTE
676
ulint low_bytes; /*!< number of matched bytes to the
677
right at the time cursor positioned;
678
only used internally in searches: not
679
defined after the search */
680
ulint n_fields; /*!< prefix length used in a hash
681
search if hash_node != NULL */
682
ulint n_bytes; /*!< hash prefix bytes if hash_node !=
684
ulint fold; /*!< fold value used in the search if
685
flag is BTR_CUR_HASH */
686
/*------------------------------*/
688
btr_path_t* path_arr; /*!< in estimating the number of
689
rows in range, we store in this array
690
information of the path through
694
/** If pessimistic delete fails because of lack of file space, there
695
is still a good change of success a little later. Try this many
697
#define BTR_CUR_RETRY_DELETE_N_TIMES 100
698
/** If pessimistic delete fails because of lack of file space, there
699
is still a good change of success a little later. Sleep this many
700
microseconds between retries. */
701
#define BTR_CUR_RETRY_SLEEP_TIME 50000
703
/** The reference in a field for which data is stored on a different page.
704
The reference is at the end of the 'locally' stored part of the field.
705
'Locally' means storage in the index record.
706
We store locally a long enough prefix of each column so that we can determine
707
the ordering parts of each index record without looking into the externally
709
/*-------------------------------------- @{ */
710
#define BTR_EXTERN_SPACE_ID 0 /*!< space id where stored */
711
#define BTR_EXTERN_PAGE_NO 4 /*!< page no where stored */
712
#define BTR_EXTERN_OFFSET 8 /*!< offset of BLOB header
714
#define BTR_EXTERN_LEN 12 /*!< 8 bytes containing the
715
length of the externally
716
stored part of the BLOB.
717
The 2 highest bits are
718
reserved to the flags below. */
719
/*-------------------------------------- @} */
720
/* #define BTR_EXTERN_FIELD_REF_SIZE 20 // moved to btr0types.h */
722
/** The most significant bit of BTR_EXTERN_LEN (i.e., the most
723
significant bit of the byte at smallest address) is set to 1 if this
724
field does not 'own' the externally stored field; only the owner field
725
is allowed to free the field in purge! */
726
#define BTR_EXTERN_OWNER_FLAG 128
727
/** If the second most significant bit of BTR_EXTERN_LEN (i.e., the
728
second most significant bit of the byte at smallest address) is 1 then
729
it means that the externally stored field was inherited from an
730
earlier version of the row. In rollback we are not allowed to free an
731
inherited external field. */
732
#define BTR_EXTERN_INHERITED_FLAG 64
734
/** Number of searches down the B-tree in btr_cur_search_to_nth_level(). */
735
extern ulint btr_cur_n_non_sea;
736
/** Number of successful adaptive hash index lookups in
737
btr_cur_search_to_nth_level(). */
738
extern ulint btr_cur_n_sea;
739
/** Old value of btr_cur_n_non_sea. Copied by
740
srv_refresh_innodb_monitor_stats(). Referenced by
741
srv_printf_innodb_monitor(). */
742
extern ulint btr_cur_n_non_sea_old;
743
/** Old value of btr_cur_n_sea. Copied by
744
srv_refresh_innodb_monitor_stats(). Referenced by
745
srv_printf_innodb_monitor(). */
746
extern ulint btr_cur_n_sea_old;
747
#endif /* !UNIV_HOTBACKUP */
750
#include "btr0cur.ic"