1 /******************************************************
4 (c) 1994-1996 Innobase Oy
6 Created 10/16/1994 Heikki Tuuri
7 *******************************************************/
13 #include "dict0dict.h"
14 #include "data0data.h"
16 #include "btr0types.h"
17 #include "que0types.h"
18 #include "row0types.h"
21 /* Mode flags for btr_cur operations; these can be ORed */
22 #define BTR_NO_UNDO_LOG_FLAG 1 /* do no undo logging */
23 #define BTR_NO_LOCKING_FLAG 2 /* do no record lock checking */
24 #define BTR_KEEP_SYS_FLAG 4 /* sys fields will be found from the
25 update vector or inserted entry */
28 #define BTR_CUR_HASH_ADAPT
30 /*************************************************************
31 Returns the page cursor component of a tree cursor. */
36 /* out: pointer to page cursor component */
37 btr_cur_t
* cursor
);/* in: tree cursor */
38 /*************************************************************
39 Returns the record pointer of a tree cursor. */
44 /* out: pointer to record */
45 btr_cur_t
* cursor
);/* in: tree cursor */
46 /*************************************************************
47 Invalidates a tree cursor by setting record pointer to NULL. */
52 btr_cur_t
* cursor
);/* in: tree cursor */
53 /*************************************************************
54 Returns the page of a tree cursor. */
59 /* out: pointer to page */
60 btr_cur_t
* cursor
);/* in: tree cursor */
61 /*************************************************************
62 Returns the index of a cursor. */
68 btr_cur_t
* cursor
);/* in: B-tree cursor */
69 /*************************************************************
70 Positions a tree cursor at a given record. */
75 dict_index_t
* index
, /* in: index */
76 rec_t
* rec
, /* in: record in tree */
77 btr_cur_t
* cursor
);/* in: cursor */
78 /************************************************************************
79 Searches an index tree and positions a tree cursor on a given level.
80 NOTE: n_fields_cmp in tuple must be set so that it cannot be compared
81 to node pointer page number fields on the upper levels of the tree!
82 Note that if mode is PAGE_CUR_LE, which is used in inserts, then
83 cursor->up_match and cursor->low_match both will have sensible values.
84 If mode is PAGE_CUR_GE, then up_match will a have a sensible value. */
87 btr_cur_search_to_nth_level(
88 /*========================*/
89 dict_index_t
* index
, /* in: index */
90 ulint level
, /* in: the tree level of search */
91 dtuple_t
* tuple
, /* in: data tuple; NOTE: n_fields_cmp in
92 tuple must be set so that it cannot get
93 compared to the node ptr page number field! */
94 ulint mode
, /* in: PAGE_CUR_L, ...;
95 NOTE that if the search is made using a unique
96 prefix of a record, mode should be PAGE_CUR_LE,
97 not PAGE_CUR_GE, as the latter may end up on
98 the previous page of the record! Inserts
99 should always be made using PAGE_CUR_LE to
100 search the position! */
101 ulint latch_mode
, /* in: BTR_SEARCH_LEAF, ..., ORed with
102 BTR_INSERT and BTR_ESTIMATE;
103 cursor->left_page is used to store a pointer
104 to the left neighbor page, in the cases
105 BTR_SEARCH_PREV and BTR_MODIFY_PREV;
106 NOTE that if has_search_latch
107 is != 0, we maybe do not have a latch set
108 on the cursor page, we assume
109 the caller uses his search latch
110 to protect the record! */
111 btr_cur_t
* cursor
, /* in/out: tree cursor; the cursor page is
112 s- or x-latched, but see also above! */
113 ulint has_search_latch
,/* in: latch mode the caller
114 currently has on btr_search_latch:
116 mtr_t
* mtr
); /* in: mtr */
117 /*********************************************************************
118 Opens a cursor at either end of an index. */
121 btr_cur_open_at_index_side(
122 /*=======================*/
123 ibool from_left
, /* in: TRUE if open to the low end,
124 FALSE if to the high end */
125 dict_index_t
* index
, /* in: index */
126 ulint latch_mode
, /* in: latch mode */
127 btr_cur_t
* cursor
, /* in: cursor */
128 mtr_t
* mtr
); /* in: mtr */
129 /**************************************************************************
130 Positions a cursor at a randomly chosen position within a B-tree. */
133 btr_cur_open_at_rnd_pos(
134 /*====================*/
135 dict_index_t
* index
, /* in: index */
136 ulint latch_mode
, /* in: BTR_SEARCH_LEAF, ... */
137 btr_cur_t
* cursor
, /* in/out: B-tree cursor */
138 mtr_t
* mtr
); /* in: mtr */
139 /*****************************************************************
140 Tries to perform an insert to a page in an index tree, next to cursor.
141 It is assumed that mtr holds an x-latch on the page. The operation does
142 not succeed if there is too little space on the page. If there is just
143 one record on the page, the insert will always succeed; this is to
144 prevent trying to split a page with just one record. */
147 btr_cur_optimistic_insert(
148 /*======================*/
149 /* out: DB_SUCCESS, DB_WAIT_LOCK,
150 DB_FAIL, or error number */
151 ulint flags
, /* in: undo logging and locking flags: if not
152 zero, the parameters index and thr should be
154 btr_cur_t
* cursor
, /* in: cursor on page after which to insert;
155 cursor stays valid */
156 dtuple_t
* entry
, /* in: entry to insert */
157 rec_t
** rec
, /* out: pointer to inserted record if
159 big_rec_t
** big_rec
,/* out: big rec vector whose fields have to
160 be stored externally by the caller, or
162 que_thr_t
* thr
, /* in: query thread or NULL */
163 mtr_t
* mtr
); /* in: mtr */
164 /*****************************************************************
165 Performs an insert on a page of an index tree. It is assumed that mtr
166 holds an x-latch on the tree and on the cursor page. If the insert is
167 made on the leaf level, to avoid deadlocks, mtr must also own x-latches
168 to brothers of page, if those brothers exist. */
171 btr_cur_pessimistic_insert(
172 /*=======================*/
173 /* out: DB_SUCCESS or error number */
174 ulint flags
, /* in: undo logging and locking flags: if not
175 zero, the parameter thr should be
176 specified; if no undo logging is specified,
177 then the caller must have reserved enough
178 free extents in the file space so that the
179 insertion will certainly succeed */
180 btr_cur_t
* cursor
, /* in: cursor after which to insert;
181 cursor stays valid */
182 dtuple_t
* entry
, /* in: entry to insert */
183 rec_t
** rec
, /* out: pointer to inserted record if
185 big_rec_t
** big_rec
,/* out: big rec vector whose fields have to
186 be stored externally by the caller, or
188 que_thr_t
* thr
, /* in: query thread or NULL */
189 mtr_t
* mtr
); /* in: mtr */
190 /*****************************************************************
191 Updates a record when the update causes no size changes in its fields. */
194 btr_cur_update_in_place(
195 /*====================*/
196 /* out: DB_SUCCESS or error number */
197 ulint flags
, /* in: undo logging and locking flags */
198 btr_cur_t
* cursor
, /* in: cursor on the record to update;
199 cursor stays valid and positioned on the
201 upd_t
* update
, /* in: update vector */
202 ulint cmpl_info
,/* in: compiler info on secondary index
204 que_thr_t
* thr
, /* in: query thread */
205 mtr_t
* mtr
); /* in: mtr */
206 /*****************************************************************
207 Tries to update a record on a page in an index tree. It is assumed that mtr
208 holds an x-latch on the page. The operation does not succeed if there is too
209 little space on the page or if the update would result in too empty a page,
210 so that tree compression is recommended. */
213 btr_cur_optimistic_update(
214 /*======================*/
215 /* out: DB_SUCCESS, or DB_OVERFLOW if the
216 updated record does not fit, DB_UNDERFLOW
217 if the page would become too empty */
218 ulint flags
, /* in: undo logging and locking flags */
219 btr_cur_t
* cursor
, /* in: cursor on the record to update;
220 cursor stays valid and positioned on the
222 upd_t
* update
, /* in: update vector; this must also
223 contain trx id and roll ptr fields */
224 ulint cmpl_info
,/* in: compiler info on secondary index
226 que_thr_t
* thr
, /* in: query thread */
227 mtr_t
* mtr
); /* in: mtr */
228 /*****************************************************************
229 Performs an update of a record on a page of a tree. It is assumed
230 that mtr holds an x-latch on the tree and on the cursor page. If the
231 update is made on the leaf level, to avoid deadlocks, mtr must also
232 own x-latches to brothers of page, if those brothers exist. */
235 btr_cur_pessimistic_update(
236 /*=======================*/
237 /* out: DB_SUCCESS or error code */
238 ulint flags
, /* in: undo logging, locking, and rollback
240 btr_cur_t
* cursor
, /* in: cursor on the record to update */
241 big_rec_t
** big_rec
,/* out: big rec vector whose fields have to
242 be stored externally by the caller, or NULL */
243 upd_t
* update
, /* in: update vector; this is allowed also
244 contain trx id and roll ptr fields, but
245 the values in update vector have no effect */
246 ulint cmpl_info
,/* in: compiler info on secondary index
248 que_thr_t
* thr
, /* in: query thread */
249 mtr_t
* mtr
); /* in: mtr */
250 /***************************************************************
251 Marks a clustered index record deleted. Writes an undo log record to
252 undo log on this delete marking. Writes in the trx id field the id
253 of the deleting transaction, and in the roll ptr field pointer to the
254 undo log record created. */
257 btr_cur_del_mark_set_clust_rec(
258 /*===========================*/
259 /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
261 ulint flags
, /* in: undo logging and locking flags */
262 btr_cur_t
* cursor
, /* in: cursor */
263 ibool val
, /* in: value to set */
264 que_thr_t
* thr
, /* in: query thread */
265 mtr_t
* mtr
); /* in: mtr */
266 /***************************************************************
267 Sets a secondary index record delete mark to TRUE or FALSE. */
270 btr_cur_del_mark_set_sec_rec(
271 /*=========================*/
272 /* out: DB_SUCCESS, DB_LOCK_WAIT, or error
274 ulint flags
, /* in: locking flag */
275 btr_cur_t
* cursor
, /* in: cursor */
276 ibool val
, /* in: value to set */
277 que_thr_t
* thr
, /* in: query thread */
278 mtr_t
* mtr
); /* in: mtr */
279 /***************************************************************
280 Sets a secondary index record delete mark. This function is only
281 used by the insert buffer insert merge mechanism. */
284 btr_cur_set_deleted_flag_for_ibuf(
285 /*==============================*/
286 rec_t
* rec
, /* in: record to delete unmark */
287 ibool val
, /* in: value to set */
288 mtr_t
* mtr
); /* in: mtr */
289 /*****************************************************************
290 Tries to compress a page of the tree on the leaf level. It is assumed
291 that mtr holds an x-latch on the tree and on the cursor page. To avoid
292 deadlocks, mtr must also own x-latches to brothers of page, if those
293 brothers exist. NOTE: it is assumed that the caller has reserved enough
294 free extents so that the compression will always succeed if done! */
299 btr_cur_t
* cursor
, /* in: cursor on the page to compress;
300 cursor does not stay valid */
301 mtr_t
* mtr
); /* in: mtr */
302 /*****************************************************************
303 Tries to compress a page of the tree if it seems useful. It is assumed
304 that mtr holds an x-latch on the tree and on the cursor page. To avoid
305 deadlocks, mtr must also own x-latches to brothers of page, if those
306 brothers exist. NOTE: it is assumed that the caller has reserved enough
307 free extents so that the compression will always succeed if done! */
310 btr_cur_compress_if_useful(
311 /*=======================*/
312 /* out: TRUE if compression occurred */
313 btr_cur_t
* cursor
, /* in: cursor on the page to compress;
314 cursor does not stay valid if compression
316 mtr_t
* mtr
); /* in: mtr */
317 /***********************************************************
318 Removes the record on which the tree cursor is positioned. It is assumed
319 that the mtr has an x-latch on the page where the cursor is positioned,
320 but no latch on the whole tree. */
323 btr_cur_optimistic_delete(
324 /*======================*/
325 /* out: TRUE if success, i.e., the page
326 did not become too empty */
327 btr_cur_t
* cursor
, /* in: cursor on the record to delete;
328 cursor stays valid: if deletion succeeds,
329 on function exit it points to the successor
330 of the deleted record */
331 mtr_t
* mtr
); /* in: mtr */
332 /*****************************************************************
333 Removes the record on which the tree cursor is positioned. Tries
334 to compress the page if its fillfactor drops below a threshold
335 or if it is the only page on the level. It is assumed that mtr holds
336 an x-latch on the tree and on the cursor page. To avoid deadlocks,
337 mtr must also own x-latches to brothers of page, if those brothers
341 btr_cur_pessimistic_delete(
342 /*=======================*/
343 /* out: TRUE if compression occurred */
344 ulint
* err
, /* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE;
345 the latter may occur because we may have
346 to update node pointers on upper levels,
347 and in the case of variable length keys
348 these may actually grow in size */
349 ibool has_reserved_extents
, /* in: TRUE if the
350 caller has already reserved enough free
351 extents so that he knows that the operation
353 btr_cur_t
* cursor
, /* in: cursor on the record to delete;
354 if compression does not occur, the cursor
355 stays valid: it points to successor of
356 deleted record on function exit */
357 ibool in_rollback
,/* in: TRUE if called in rollback */
358 mtr_t
* mtr
); /* in: mtr */
359 /***************************************************************
360 Parses a redo log record of updating a record in-place. */
363 btr_cur_parse_update_in_place(
364 /*==========================*/
365 /* out: end of log record or NULL */
366 byte
* ptr
, /* in: buffer */
367 byte
* end_ptr
,/* in: buffer end */
368 page_t
* page
, /* in: page or NULL */
369 dict_index_t
* index
); /* in: index corresponding to page */
370 /********************************************************************
371 Parses the redo log record for delete marking or unmarking of a clustered
375 btr_cur_parse_del_mark_set_clust_rec(
376 /*=================================*/
377 /* out: end of log record or NULL */
378 byte
* ptr
, /* in: buffer */
379 byte
* end_ptr
,/* in: buffer end */
380 dict_index_t
* index
, /* in: index corresponding to page */
381 page_t
* page
); /* in: page or NULL */
382 /********************************************************************
383 Parses the redo log record for delete marking or unmarking of a secondary
387 btr_cur_parse_del_mark_set_sec_rec(
388 /*===============================*/
389 /* out: end of log record or NULL */
390 byte
* ptr
, /* in: buffer */
391 byte
* end_ptr
,/* in: buffer end */
392 page_t
* page
); /* in: page or NULL */
393 /***********************************************************************
394 Estimates the number of rows in a given index range. */
397 btr_estimate_n_rows_in_range(
398 /*=========================*/
399 /* out: estimated number of rows */
400 dict_index_t
* index
, /* in: index */
401 dtuple_t
* tuple1
, /* in: range start, may also be empty tuple */
402 ulint mode1
, /* in: search mode for range start */
403 dtuple_t
* tuple2
, /* in: range end, may also be empty tuple */
404 ulint mode2
); /* in: search mode for range end */
405 /***********************************************************************
406 Estimates the number of different key values in a given index, for
407 each n-column prefix of the index where n <= dict_index_get_n_unique(index).
408 The estimates are stored in the array index->stat_n_diff_key_vals.
409 If innodb_stats_method is nulls_ignored, we also record the number of
410 non-null values for each prefix and stored the estimates in
411 array index->stat_n_non_null_key_vals. */
414 btr_estimate_number_of_different_key_vals(
415 /*======================================*/
416 dict_index_t
* index
); /* in: index */
417 /***********************************************************************
418 Marks not updated extern fields as not-owned by this record. The ownership
419 is transferred to the updated record which is inserted elsewhere in the
420 index tree. In purge only the owner of externally stored field is allowed
421 to free the field. */
424 btr_cur_mark_extern_inherited_fields(
425 /*=================================*/
426 rec_t
* rec
, /* in: record in a clustered index */
427 const ulint
* offsets
,/* in: array returned by rec_get_offsets() */
428 upd_t
* update
, /* in: update vector */
429 mtr_t
* mtr
); /* in: mtr */
430 /***********************************************************************
431 The complement of the previous function: in an update entry may inherit
432 some externally stored fields from a record. We must mark them as inherited
433 in entry, so that they are not freed in a rollback. */
436 btr_cur_mark_dtuple_inherited_extern(
437 /*=================================*/
438 dtuple_t
* entry
, /* in: updated entry to be inserted to
440 ulint
* ext_vec
, /* in: array of extern fields in the
442 ulint n_ext_vec
, /* in: number of elements in ext_vec */
443 upd_t
* update
); /* in: update vector */
444 /***********************************************************************
445 Marks all extern fields in a dtuple as owned by the record. */
448 btr_cur_unmark_dtuple_extern_fields(
449 /*================================*/
450 dtuple_t
* entry
, /* in: clustered index entry */
451 ulint
* ext_vec
, /* in: array of numbers of fields
452 which have been stored externally */
453 ulint n_ext_vec
); /* in: number of elements in ext_vec */
454 /***********************************************************************
455 Stores the fields in big_rec_vec to the tablespace and puts pointers to
456 them in rec. The fields are stored on pages allocated from leaf node
457 file segment of the index tree. */
460 btr_store_big_rec_extern_fields(
461 /*============================*/
462 /* out: DB_SUCCESS or error */
463 dict_index_t
* index
, /* in: index of rec; the index tree
465 rec_t
* rec
, /* in: record */
466 const ulint
* offsets
, /* in: rec_get_offsets(rec, index);
467 the "external storage" flags in offsets
468 will not correspond to rec when
469 this function returns */
470 big_rec_t
* big_rec_vec
, /* in: vector containing fields
471 to be stored externally */
472 mtr_t
* local_mtr
); /* in: mtr containing the latch to
473 rec and to the tree */
474 /***********************************************************************
475 Frees the space in an externally stored field to the file space
476 management if the field in data is owned the externally stored field,
477 in a rollback we may have the additional condition that the field must
481 btr_free_externally_stored_field(
482 /*=============================*/
483 dict_index_t
* index
, /* in: index of the data, the index
484 tree MUST be X-latched; if the tree
485 height is 1, then also the root page
486 must be X-latched! (this is relevant
487 in the case this function is called
488 from purge where 'data' is located on
489 an undo log page, not an index
491 byte
* data
, /* in: internally stored data
492 + reference to the externally
494 ulint local_len
, /* in: length of data */
495 ibool do_not_free_inherited
,/* in: TRUE if called in a
496 rollback and we do not want to free
498 mtr_t
* local_mtr
); /* in: mtr containing the latch to
499 data an an X-latch to the index
501 /***************************************************************
502 Frees the externally stored fields for a record. */
505 btr_rec_free_externally_stored_fields(
506 /*==================================*/
507 dict_index_t
* index
, /* in: index of the data, the index
508 tree MUST be X-latched */
509 rec_t
* rec
, /* in: record */
510 const ulint
* offsets
,/* in: rec_get_offsets(rec, index) */
511 ibool do_not_free_inherited
,/* in: TRUE if called in a
512 rollback and we do not want to free
514 mtr_t
* mtr
); /* in: mini-transaction handle which contains
515 an X-latch to record page and to the index
517 /***********************************************************************
518 Copies an externally stored field of a record to mem heap. */
521 btr_rec_copy_externally_stored_field(
522 /*=================================*/
523 /* out: the field copied to heap */
524 rec_t
* rec
, /* in: record */
525 const ulint
* offsets
,/* in: array returned by rec_get_offsets() */
526 ulint no
, /* in: field number */
527 ulint
* len
, /* out: length of the field */
528 mem_heap_t
* heap
); /* in: mem heap */
529 /***********************************************************************
530 Copies an externally stored field of a record to mem heap. Parameter
531 data contains a pointer to 'internally' stored part of the field:
532 possibly some data, and the reference to the externally stored part in
533 the last 20 bytes of data. */
536 btr_copy_externally_stored_field(
537 /*=============================*/
538 /* out: the whole field copied to heap */
539 ulint
* len
, /* out: length of the whole field */
540 byte
* data
, /* in: 'internally' stored part of the
541 field containing also the reference to
543 ulint local_len
,/* in: length of data */
544 mem_heap_t
* heap
); /* in: mem heap */
545 /***********************************************************************
546 Stores the positions of the fields marked as extern storage in the update
547 vector, and also those fields who are marked as extern storage in rec
548 and not mentioned in updated fields. We use this function to remember
549 which fields we must mark as extern storage in a record inserted for an
553 btr_push_update_extern_fields(
554 /*==========================*/
555 /* out: number of values stored in ext_vect */
556 ulint
* ext_vect
,/* in: array of ulints, must be preallocated
557 to have space for all fields in rec */
558 const ulint
* offsets
,/* in: array returned by rec_get_offsets() */
559 upd_t
* update
);/* in: update vector or NULL */
561 /***************************************************************
562 Writes a redo log record of updating a record in-place. */
565 btr_cur_update_in_place_log(
566 /*========================*/
567 ulint flags
, /* in: flags */
568 rec_t
* rec
, /* in: record */
569 dict_index_t
* index
, /* in: index where cursor positioned */
570 upd_t
* update
, /* in: update vector */
571 trx_t
* trx
, /* in: transaction */
572 dulint roll_ptr
, /* in: roll ptr */
573 mtr_t
* mtr
); /* in: mtr */
575 /*######################################################################*/
577 /* In the pessimistic delete, if the page data size drops below this
578 limit, merging it to a neighbor is tried */
580 #define BTR_CUR_PAGE_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 2)
582 /* A slot in the path array. We store here info on a search path down the
583 tree. Each slot contains data on a single level of the tree. */
585 typedef struct btr_path_struct btr_path_t
;
586 struct btr_path_struct
{
587 ulint nth_rec
; /* index of the record
588 where the page cursor stopped on
589 this level (index in alphabetical
590 order); value ULINT_UNDEFINED
592 ulint n_recs
; /* number of records on the page */
595 #define BTR_PATH_ARRAY_N_SLOTS 250 /* size of path array (in slots) */
597 /* The tree cursor: the definition appears here only for the compiler
598 to know struct size! */
600 struct btr_cur_struct
{
601 dict_index_t
* index
; /* index where positioned */
602 page_cur_t page_cur
; /* page cursor */
603 page_t
* left_page
; /* this field is used to store
604 a pointer to the left neighbor
608 /*------------------------------*/
609 que_thr_t
* thr
; /* this field is only used when
610 btr_cur_search_... is called for an
611 index entry insertion: the calling
612 query thread is passed here to be
613 used in the insert buffer */
614 /*------------------------------*/
615 /* The following fields are used in btr_cur_search... to pass
617 ulint flag
; /* BTR_CUR_HASH, BTR_CUR_HASH_FAIL,
619 BTR_CUR_INSERT_TO_IBUF */
620 ulint tree_height
; /* Tree height if the search is done
621 for a pessimistic insert or update
623 ulint up_match
; /* If the search mode was PAGE_CUR_LE,
624 the number of matched fields to the
625 the first user record to the right of
626 the cursor record after
628 for the mode PAGE_CUR_GE, the matched
629 fields to the first user record AT THE
630 CURSOR or to the right of it;
631 NOTE that the up_match and low_match
632 values may exceed the correct values
633 for comparison to the adjacent user
634 record if that record is on a
635 different leaf page! (See the note in
636 row_ins_duplicate_key.) */
637 ulint up_bytes
; /* number of matched bytes to the
638 right at the time cursor positioned;
639 only used internally in searches: not
640 defined after the search */
641 ulint low_match
; /* if search mode was PAGE_CUR_LE,
642 the number of matched fields to the
643 first user record AT THE CURSOR or
644 to the left of it after
646 NOT defined for PAGE_CUR_GE or any
647 other search modes; see also the NOTE
649 ulint low_bytes
; /* number of matched bytes to the
650 right at the time cursor positioned;
651 only used internally in searches: not
652 defined after the search */
653 ulint n_fields
; /* prefix length used in a hash
654 search if hash_node != NULL */
655 ulint n_bytes
; /* hash prefix bytes if hash_node !=
657 ulint fold
; /* fold value used in the search if
658 flag is BTR_CUR_HASH */
659 /*------------------------------*/
660 btr_path_t
* path_arr
; /* in estimating the number of
661 rows in range, we store in this array
662 information of the path through
666 /* Values for the flag documenting the used search method */
667 #define BTR_CUR_HASH 1 /* successful shortcut using the hash
669 #define BTR_CUR_HASH_FAIL 2 /* failure using hash, success using
670 binary search: the misleading hash
671 reference is stored in the field
672 hash_node, and might be necessary to
674 #define BTR_CUR_BINARY 3 /* success using the binary search */
675 #define BTR_CUR_INSERT_TO_IBUF 4 /* performed the intended insert to
678 /* If pessimistic delete fails because of lack of file space,
679 there is still a good change of success a little later: try this many times,
680 and sleep this many microseconds in between */
681 #define BTR_CUR_RETRY_DELETE_N_TIMES 100
682 #define BTR_CUR_RETRY_SLEEP_TIME 50000
684 /* The reference in a field for which data is stored on a different page.
685 The reference is at the end of the 'locally' stored part of the field.
686 'Locally' means storage in the index record.
687 We store locally a long enough prefix of each column so that we can determine
688 the ordering parts of each index record without looking into the externally
691 /*--------------------------------------*/
692 #define BTR_EXTERN_SPACE_ID 0 /* space id where stored */
693 #define BTR_EXTERN_PAGE_NO 4 /* page no where stored */
694 #define BTR_EXTERN_OFFSET 8 /* offset of BLOB header
696 #define BTR_EXTERN_LEN 12 /* 8 bytes containing the
697 length of the externally
698 stored part of the BLOB.
699 The 2 highest bits are
700 reserved to the flags below. */
701 /*--------------------------------------*/
702 #define BTR_EXTERN_FIELD_REF_SIZE 20
704 /* The highest bit of BTR_EXTERN_LEN (i.e., the highest bit of the byte
705 at lowest address) is set to 1 if this field does not 'own' the externally
706 stored field; only the owner field is allowed to free the field in purge!
707 If the 2nd highest bit is 1 then it means that the externally stored field
708 was inherited from an earlier version of the row. In rollback we are not
709 allowed to free an inherited external field. */
711 #define BTR_EXTERN_OWNER_FLAG 128
712 #define BTR_EXTERN_INHERITED_FLAG 64
714 extern ulint btr_cur_n_non_sea
;
715 extern ulint btr_cur_n_sea
;
716 extern ulint btr_cur_n_non_sea_old
;
717 extern ulint btr_cur_n_sea_old
;
720 /* Flag to limit optimistic insert records */
721 extern uint btr_cur_limit_optimistic_insert_debug
;
722 #endif /* UNIV_DEBUG */
725 #include "btr0cur.ic"