2009-02-17 08:55:41 +00:00
|
|
|
/*****************************************************************************
|
|
|
|
|
|
|
|
Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
|
|
Foundation; version 2 of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
|
|
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
|
|
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************
|
|
|
|
The B-tree
|
|
|
|
|
|
|
|
Created 6/2/1994 Heikki Tuuri
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
#ifndef btr0btr_h
|
|
|
|
#define btr0btr_h
|
|
|
|
|
|
|
|
#include "univ.i"
|
|
|
|
|
|
|
|
#include "dict0dict.h"
|
|
|
|
#include "data0data.h"
|
|
|
|
#include "page0cur.h"
|
|
|
|
#include "mtr0mtr.h"
|
|
|
|
#include "btr0types.h"
|
|
|
|
|
2009-03-23 14:21:34 +00:00
|
|
|
#ifndef UNIV_HOTBACKUP
|
2005-10-27 07:29:40 +00:00
|
|
|
/* Maximum record size which can be stored on a page, without using the
|
|
|
|
special big record storage structure */
|
|
|
|
|
|
|
|
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
|
|
|
|
|
2006-10-25 11:19:12 +00:00
|
|
|
/* Maximum depth of a B-tree in InnoDB. Note that this isn't a maximum as
|
|
|
|
such; none of the tree operations avoid producing trees bigger than this. It
|
|
|
|
is instead a "max depth that other code must work with", useful for e.g.
|
|
|
|
fixed-size arrays that must store some information about each level in a
|
|
|
|
tree. In other words: if a B-tree with bigger depth than this is
|
|
|
|
encountered, it is not acceptable for it to lead to mysterious memory
|
|
|
|
corruption, but it is acceptable for the program to die with a clear assert
|
|
|
|
failure. */
|
|
|
|
#define BTR_MAX_LEVELS 100
|
|
|
|
|
|
|
|
/* Latching modes for btr_cur_search_to_nth_level(). */
|
2005-10-27 07:29:40 +00:00
|
|
|
#define BTR_SEARCH_LEAF RW_S_LATCH
|
|
|
|
#define BTR_MODIFY_LEAF RW_X_LATCH
|
|
|
|
#define BTR_NO_LATCHES RW_NO_LATCH
|
|
|
|
#define BTR_MODIFY_TREE 33
|
|
|
|
#define BTR_CONT_MODIFY_TREE 34
|
|
|
|
#define BTR_SEARCH_PREV 35
|
|
|
|
#define BTR_MODIFY_PREV 36
|
|
|
|
|
|
|
|
/* If this is ORed to the latch mode, it means that the search tuple will be
|
|
|
|
inserted to the index, at the searched position */
|
|
|
|
#define BTR_INSERT 512
|
|
|
|
|
|
|
|
/* This flag ORed to latch mode says that we do the search in query
|
|
|
|
optimization */
|
|
|
|
#define BTR_ESTIMATE 1024
|
|
|
|
|
|
|
|
/* This flag ORed to latch mode says that we can ignore possible
|
|
|
|
UNIQUE definition on secondary indexes when we decide if we can use the
|
|
|
|
insert buffer to speed up inserts */
|
2006-02-23 19:25:29 +00:00
|
|
|
#define BTR_IGNORE_SEC_UNIQUE 2048
|
2005-10-27 07:29:40 +00:00
|
|
|
|
|
|
|
/******************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the root node of a tree and x-latches it.
|
|
|
|
@return root page, x-latched */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
page_t*
|
|
|
|
btr_root_get(
|
|
|
|
/*=========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index tree */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
|
|
|
Gets a buffer page and declares its latching order level. */
|
|
|
|
UNIV_INLINE
|
2006-10-12 11:05:22 +00:00
|
|
|
buf_block_t*
|
|
|
|
btr_block_get(
|
|
|
|
/*==========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint space, /*!< in: space id */
|
|
|
|
ulint zip_size, /*!< in: compressed page size in bytes
|
2007-01-18 09:59:00 +00:00
|
|
|
or 0 for uncompressed pages */
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint page_no, /*!< in: page number */
|
|
|
|
ulint mode, /*!< in: latch mode */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2006-10-12 11:05:22 +00:00
|
|
|
/******************************************************************
|
|
|
|
Gets a buffer page and declares its latching order level. */
|
|
|
|
UNIV_INLINE
|
2005-10-27 07:29:40 +00:00
|
|
|
page_t*
|
|
|
|
btr_page_get(
|
|
|
|
/*=========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint space, /*!< in: space id */
|
|
|
|
ulint zip_size, /*!< in: compressed page size in bytes
|
2007-01-18 09:59:00 +00:00
|
|
|
or 0 for uncompressed pages */
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint page_no, /*!< in: page number */
|
|
|
|
ulint mode, /*!< in: latch mode */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2009-03-23 14:21:34 +00:00
|
|
|
#endif /* !UNIV_HOTBACKUP */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the index id field of a page.
|
|
|
|
@return index id */
|
2005-10-27 07:29:40 +00:00
|
|
|
UNIV_INLINE
|
|
|
|
dulint
|
|
|
|
btr_page_get_index_id(
|
|
|
|
/*==================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
const page_t* page); /*!< in: index page */
|
2009-03-23 14:21:34 +00:00
|
|
|
#ifndef UNIV_HOTBACKUP
|
2005-10-27 07:29:40 +00:00
|
|
|
/************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the node level field in an index page.
|
|
|
|
@return level, leaf level == 0 */
|
2005-10-27 07:29:40 +00:00
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
btr_page_get_level_low(
|
|
|
|
/*===================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
const page_t* page); /*!< in: index page */
|
2005-10-27 07:29:40 +00:00
|
|
|
/************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the node level field in an index page.
|
|
|
|
@return level, leaf level == 0 */
|
2005-10-27 07:29:40 +00:00
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
btr_page_get_level(
|
|
|
|
/*===============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
const page_t* page, /*!< in: index page */
|
|
|
|
mtr_t* mtr); /*!< in: mini-transaction handle */
|
2005-10-27 07:29:40 +00:00
|
|
|
/************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the next index page number.
|
|
|
|
@return next page number */
|
2005-10-27 07:29:40 +00:00
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
btr_page_get_next(
|
|
|
|
/*==============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
const page_t* page, /*!< in: index page */
|
|
|
|
mtr_t* mtr); /*!< in: mini-transaction handle */
|
2005-10-27 07:29:40 +00:00
|
|
|
/************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the previous index page number.
|
|
|
|
@return prev page number */
|
2005-10-27 07:29:40 +00:00
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
btr_page_get_prev(
|
|
|
|
/*==============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
const page_t* page, /*!< in: index page */
|
|
|
|
mtr_t* mtr); /*!< in: mini-transaction handle */
|
2005-10-27 07:29:40 +00:00
|
|
|
/*****************************************************************
|
|
|
|
Gets pointer to the previous user record in the tree. It is assumed
|
2009-05-25 05:30:14 +00:00
|
|
|
that the caller has appropriate latches on the page and its neighbor.
|
|
|
|
@return previous user record, NULL if there is none */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
rec_t*
|
|
|
|
btr_get_prev_user_rec(
|
|
|
|
/*==================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
rec_t* rec, /*!< in: record on leaf level */
|
|
|
|
mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
|
2005-10-27 07:29:40 +00:00
|
|
|
needed, also to the previous page */
|
|
|
|
/*****************************************************************
|
|
|
|
Gets pointer to the next user record in the tree. It is assumed
|
2009-05-25 05:30:14 +00:00
|
|
|
that the caller has appropriate latches on the page and its neighbor.
|
|
|
|
@return next user record, NULL if there is none */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
rec_t*
|
|
|
|
btr_get_next_user_rec(
|
|
|
|
/*==================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
rec_t* rec, /*!< in: record on leaf level */
|
|
|
|
mtr_t* mtr); /*!< in: mtr holding a latch on the page, and if
|
2005-10-27 07:29:40 +00:00
|
|
|
needed, also to the next page */
|
|
|
|
/******************************************************************
|
|
|
|
Releases the latch on a leaf page and bufferunfixes it. */
|
|
|
|
UNIV_INLINE
|
|
|
|
void
|
|
|
|
btr_leaf_page_release(
|
|
|
|
/*==================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
buf_block_t* block, /*!< in: buffer block */
|
|
|
|
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF or
|
2006-10-13 07:45:52 +00:00
|
|
|
BTR_MODIFY_LEAF */
|
2009-05-25 05:30:14 +00:00
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the child node file address in a node pointer.
|
|
|
|
@return child node address */
|
2005-10-27 07:29:40 +00:00
|
|
|
UNIV_INLINE
|
|
|
|
ulint
|
|
|
|
btr_node_ptr_get_child_page_no(
|
|
|
|
/*===========================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
const rec_t* rec, /*!< in: node pointer record */
|
|
|
|
const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
|
2005-10-27 07:29:40 +00:00
|
|
|
/****************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Creates the root node for a new index tree.
|
|
|
|
@return page number of the created root, FIL_NULL if did not succeed */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ulint
|
|
|
|
btr_create(
|
|
|
|
/*=======*/
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint type, /*!< in: type of the index */
|
|
|
|
ulint space, /*!< in: space where created */
|
|
|
|
ulint zip_size,/*!< in: compressed page size in bytes
|
2007-01-18 09:59:00 +00:00
|
|
|
or 0 for uncompressed pages */
|
2009-05-25 05:30:14 +00:00
|
|
|
dulint index_id,/*!< in: index id */
|
|
|
|
dict_index_t* index, /*!< in: index */
|
|
|
|
mtr_t* mtr); /*!< in: mini-transaction handle */
|
2005-10-27 07:29:40 +00:00
|
|
|
/****************************************************************
|
|
|
|
Frees a B-tree except the root page, which MUST be freed after this
|
|
|
|
by calling btr_free_root. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_free_but_not_root(
|
|
|
|
/*==================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint space, /*!< in: space where created */
|
|
|
|
ulint zip_size, /*!< in: compressed page size in bytes
|
2007-01-18 09:59:00 +00:00
|
|
|
or 0 for uncompressed pages */
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint root_page_no); /*!< in: root page number */
|
2005-10-27 07:29:40 +00:00
|
|
|
/****************************************************************
|
|
|
|
Frees the B-tree root page. Other tree MUST already have been freed. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_free_root(
|
|
|
|
/*==========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint space, /*!< in: space where created */
|
|
|
|
ulint zip_size, /*!< in: compressed page size in bytes
|
2007-01-18 09:59:00 +00:00
|
|
|
or 0 for uncompressed pages */
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint root_page_no, /*!< in: root page number */
|
|
|
|
mtr_t* mtr); /*!< in: a mini-transaction which has already
|
2005-10-27 07:29:40 +00:00
|
|
|
been started */
|
|
|
|
/*****************************************************************
|
|
|
|
Makes tree one level higher by splitting the root, and inserts
|
|
|
|
the tuple. It is assumed that mtr contains an x-latch on the tree.
|
|
|
|
NOTE that the operation of this function must always succeed,
|
|
|
|
we cannot reverse it: therefore enough free disk space must be
|
2009-05-25 05:30:14 +00:00
|
|
|
guaranteed to be available before this function is called.
|
|
|
|
@return inserted record */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
rec_t*
|
|
|
|
btr_root_raise_and_insert(
|
|
|
|
/*======================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
btr_cur_t* cursor, /*!< in: cursor at which to insert: must be
|
2005-10-27 07:29:40 +00:00
|
|
|
on the root page; when the function returns,
|
|
|
|
the cursor is positioned on the predecessor
|
|
|
|
of the inserted record */
|
2009-05-25 05:30:14 +00:00
|
|
|
const dtuple_t* tuple, /*!< in: tuple to insert */
|
|
|
|
ulint n_ext, /*!< in: number of externally stored columns */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/*****************************************************************
|
branches/zip: Document and obey the rules for modifying the free bits in
the insert buffer bitmap.
ibuf_set_free_bits_func(): Never disable redo logging.
ibuf_update_free_bits_zip(): Remove.
btr_page_reorganize_low(), page_zip_reorganize(): Do not update the insert
buffer bitmap. Instead, document that callers will have to take care of it,
and adapt the callers.
btr_compress(): On error, reset the insert buffer free bits.
btr_cur_insert_if_possible(): Do not modify the insert buffer bitmap.
btr_compress(), btr_cur_optimistic_insert(): On compressed pages,
reset the insert buffer bitmap. Document why.
btr_cur_update_alloc_zip(): Document why it is necessary and sufficient
to reset the insert buffer free bits.
btr_cur_update_in_place(), btr_cur_optimistic_update(),
btr_cur_pessimistic_update(): Update the free bits in the same
mini-transaction. Document that the mini-transaction must be
committed before latching any further pages. Verify that this
is the case in all execution paths.
row_ins_sec_index_entry_by_modify(), row_ins_clust_index_entry_by_modify(),
row_undo_mod_clust_low(): Because these functions call
btr_cur_update_in_place(), btr_cur_optimistic_update(), or
btr_cur_pessimistic_update(), document that the mini-transaction must be
committed before latching any further pages. Verify that this is the case
in all execution paths.
2007-05-16 09:23:53 +00:00
|
|
|
Reorganizes an index page.
|
|
|
|
IMPORTANT: if btr_page_reorganize() is invoked on a compressed leaf
|
|
|
|
page of a non-clustered index, the caller must update the insert
|
|
|
|
buffer free bits in the same mini-transaction in such a way that the
|
2009-05-25 05:30:14 +00:00
|
|
|
modification will be redo-logged.
|
|
|
|
@return TRUE on success, FALSE on failure */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2006-02-10 15:06:17 +00:00
|
|
|
ibool
|
2005-10-27 07:29:40 +00:00
|
|
|
btr_page_reorganize(
|
|
|
|
/*================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
buf_block_t* block, /*!< in: page to be reorganized */
|
|
|
|
dict_index_t* index, /*!< in: record descriptor */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/*****************************************************************
|
|
|
|
Decides if the page should be split at the convergence point of
|
2009-05-25 05:30:14 +00:00
|
|
|
inserts converging to left.
|
|
|
|
@return TRUE if split recommended */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ibool
|
|
|
|
btr_page_get_split_rec_to_left(
|
|
|
|
/*===========================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
btr_cur_t* cursor, /*!< in: cursor at which to insert */
|
|
|
|
rec_t** split_rec);/*!< out: if split recommended,
|
2005-10-27 07:29:40 +00:00
|
|
|
the first record on upper half page,
|
|
|
|
or NULL if tuple should be first */
|
|
|
|
/*****************************************************************
|
|
|
|
Decides if the page should be split at the convergence point of
|
2009-05-25 05:30:14 +00:00
|
|
|
inserts converging to right.
|
|
|
|
@return TRUE if split recommended */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ibool
|
|
|
|
btr_page_get_split_rec_to_right(
|
|
|
|
/*============================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
btr_cur_t* cursor, /*!< in: cursor at which to insert */
|
|
|
|
rec_t** split_rec);/*!< out: if split recommended,
|
2005-10-27 07:29:40 +00:00
|
|
|
the first record on upper half page,
|
|
|
|
or NULL if tuple should be first */
|
|
|
|
/*****************************************************************
|
|
|
|
Splits an index page to halves and inserts the tuple. It is assumed
|
2009-05-25 08:09:45 +00:00
|
|
|
that mtr holds an x-latch to the index tree. NOTE: the tree x-latch is
|
|
|
|
released within this function! NOTE that the operation of this
|
|
|
|
function must always succeed, we cannot reverse it: therefore enough
|
|
|
|
free disk space (2 pages) must be guaranteed to be available before
|
2009-05-25 05:30:14 +00:00
|
|
|
this function is called.
|
2009-05-25 08:09:45 +00:00
|
|
|
|
|
|
|
@return inserted record */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
rec_t*
|
|
|
|
btr_page_split_and_insert(
|
|
|
|
/*======================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
btr_cur_t* cursor, /*!< in: cursor at which to insert; when the
|
2005-10-27 07:29:40 +00:00
|
|
|
function returns, the cursor is positioned
|
|
|
|
on the predecessor of the inserted record */
|
2009-05-25 05:30:14 +00:00
|
|
|
const dtuple_t* tuple, /*!< in: tuple to insert */
|
|
|
|
ulint n_ext, /*!< in: number of externally stored columns */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/***********************************************************
|
|
|
|
Inserts a data tuple to a tree on a non-leaf level. It is assumed
|
|
|
|
that mtr holds an x-latch on the tree. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_insert_on_non_leaf_level(
|
|
|
|
/*=========================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index */
|
|
|
|
ulint level, /*!< in: level, must be > 0 */
|
|
|
|
dtuple_t* tuple, /*!< in: the record to be inserted */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2009-03-23 14:21:34 +00:00
|
|
|
#endif /* !UNIV_HOTBACKUP */
|
2005-10-27 07:29:40 +00:00
|
|
|
/********************************************************************
|
|
|
|
Sets a record as the predefined minimum record. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_set_min_rec_mark(
|
|
|
|
/*=================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
rec_t* rec, /*!< in/out: record */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2009-03-23 14:21:34 +00:00
|
|
|
#ifndef UNIV_HOTBACKUP
|
2005-10-27 07:29:40 +00:00
|
|
|
/*****************************************************************
|
|
|
|
Deletes on the upper level the node pointer to a page. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_node_ptr_delete(
|
|
|
|
/*================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index tree */
|
|
|
|
buf_block_t* block, /*!< in: page whose node pointer is deleted */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2006-02-23 19:25:29 +00:00
|
|
|
#ifdef UNIV_DEBUG
|
2005-10-27 07:29:40 +00:00
|
|
|
/****************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Checks that the node pointer to a page is appropriate.
|
|
|
|
@return TRUE */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ibool
|
|
|
|
btr_check_node_ptr(
|
|
|
|
/*===============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index tree */
|
|
|
|
buf_block_t* block, /*!< in: index page */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2006-02-23 19:25:29 +00:00
|
|
|
#endif /* UNIV_DEBUG */
|
2005-10-27 07:29:40 +00:00
|
|
|
/*****************************************************************
|
|
|
|
Tries to merge the page first to the left immediate brother if such a
|
|
|
|
brother exists, and the node pointers to the current page and to the
|
|
|
|
brother reside on the same page. If the left brother does not satisfy these
|
|
|
|
conditions, looks at the right brother. If the page is the only one on that
|
|
|
|
level lifts the records of the page to the father page, thus reducing the
|
|
|
|
tree height. It is assumed that mtr holds an x-latch on the tree and on the
|
|
|
|
page. If cursor is on the leaf level, mtr must also hold x-latches to
|
2009-05-25 05:30:14 +00:00
|
|
|
the brothers, if they exist.
|
|
|
|
@return TRUE on success */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 11:48:10 +00:00
|
|
|
ibool
|
2005-10-27 07:29:40 +00:00
|
|
|
btr_compress(
|
|
|
|
/*=========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
btr_cur_t* cursor, /*!< in: cursor on the page to merge or lift;
|
2005-10-27 07:29:40 +00:00
|
|
|
the page must not be empty: in record delete
|
|
|
|
use btr_discard_page if the page would become
|
|
|
|
empty */
|
2009-05-25 05:30:14 +00:00
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/*****************************************************************
|
|
|
|
Discards a page from a B-tree. This is used to remove the last record from
|
|
|
|
a B-tree page: the whole page must be removed at the same time. This cannot
|
|
|
|
be used for the root page, which is allowed to be empty. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_discard_page(
|
|
|
|
/*=============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
btr_cur_t* cursor, /*!< in: cursor on the page to discard: not on
|
2005-10-27 07:29:40 +00:00
|
|
|
the root page */
|
2009-05-25 05:30:14 +00:00
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2009-03-23 14:21:34 +00:00
|
|
|
#endif /* !UNIV_HOTBACKUP */
|
2005-10-27 07:29:40 +00:00
|
|
|
/********************************************************************
|
|
|
|
Parses the redo log record for setting an index record as the predefined
|
2009-05-25 05:30:14 +00:00
|
|
|
minimum record.
|
|
|
|
@return end of log record or NULL */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
byte*
|
|
|
|
btr_parse_set_min_rec_mark(
|
|
|
|
/*=======================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
byte* ptr, /*!< in: buffer */
|
|
|
|
byte* end_ptr,/*!< in: buffer end */
|
|
|
|
ulint comp, /*!< in: nonzero=compact page format */
|
|
|
|
page_t* page, /*!< in: page or NULL */
|
|
|
|
mtr_t* mtr); /*!< in: mtr or NULL */
|
2005-10-27 07:29:40 +00:00
|
|
|
/***************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Parses a redo log record of reorganizing a page.
|
|
|
|
@return end of log record or NULL */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
byte*
|
|
|
|
btr_parse_page_reorganize(
|
|
|
|
/*======================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
byte* ptr, /*!< in: buffer */
|
|
|
|
byte* end_ptr,/*!< in: buffer end */
|
|
|
|
dict_index_t* index, /*!< in: record descriptor */
|
|
|
|
buf_block_t* block, /*!< in: page to be reorganized, or NULL */
|
|
|
|
mtr_t* mtr); /*!< in: mtr or NULL */
|
2009-03-23 14:21:34 +00:00
|
|
|
#ifndef UNIV_HOTBACKUP
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Gets the number of pages in a B-tree.
|
|
|
|
@return number of pages */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ulint
|
|
|
|
btr_get_size(
|
|
|
|
/*=========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index */
|
|
|
|
ulint flag); /*!< in: BTR_N_LEAF_PAGES or BTR_TOTAL_SIZE */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
|
|
|
Allocates a new file page to be used in an index tree. NOTE: we assume
|
2009-05-25 05:30:14 +00:00
|
|
|
that the caller has made the reservation for free extents!
|
|
|
|
@return new allocated block, x-latched; NULL if out of space */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2006-10-12 11:05:22 +00:00
|
|
|
buf_block_t*
|
2005-10-27 07:29:40 +00:00
|
|
|
btr_page_alloc(
|
|
|
|
/*===========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index tree */
|
|
|
|
ulint hint_page_no, /*!< in: hint of a good page */
|
|
|
|
byte file_direction, /*!< in: direction where a possible
|
2005-10-27 07:29:40 +00:00
|
|
|
page split is made */
|
2009-05-25 05:30:14 +00:00
|
|
|
ulint level, /*!< in: level where the page is placed
|
2005-10-27 07:29:40 +00:00
|
|
|
in the tree */
|
2009-05-25 05:30:14 +00:00
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
|
|
|
Frees a file page used in an index tree. NOTE: cannot free field external
|
|
|
|
storage pages because the page must contain info on its level. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_page_free(
|
|
|
|
/*==========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index tree */
|
|
|
|
buf_block_t* block, /*!< in: block to be freed, x-latched */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
|
|
|
Frees a file page used in an index tree. Can be used also to BLOB
|
|
|
|
external storage pages, because the page level 0 can be given as an
|
|
|
|
argument. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_page_free_low(
|
|
|
|
/*==============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index tree */
|
|
|
|
buf_block_t* block, /*!< in: block to be freed, x-latched */
|
|
|
|
ulint level, /*!< in: page level */
|
|
|
|
mtr_t* mtr); /*!< in: mtr */
|
2005-10-27 07:29:40 +00:00
|
|
|
#ifdef UNIV_BTR_PRINT
|
|
|
|
/*****************************************************************
|
|
|
|
Prints size info of a B-tree. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
|
|
|
btr_print_size(
|
|
|
|
/*===========*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index); /*!< in: index tree */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
2006-09-19 10:14:07 +00:00
|
|
|
Prints directories and other info of all nodes in the index. */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
void
|
2006-09-19 10:14:07 +00:00
|
|
|
btr_print_index(
|
|
|
|
/*============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index */
|
|
|
|
ulint width); /*!< in: print this many entries from start
|
2005-10-27 07:29:40 +00:00
|
|
|
and end */
|
|
|
|
#endif /* UNIV_BTR_PRINT */
|
|
|
|
/****************************************************************
|
|
|
|
Checks the size and number of fields in a record based on the definition of
|
2009-05-25 05:30:14 +00:00
|
|
|
the index.
|
|
|
|
@return TRUE if ok */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ibool
|
|
|
|
btr_index_rec_validate(
|
2006-02-23 19:25:29 +00:00
|
|
|
/*===================*/
|
2009-05-25 05:30:14 +00:00
|
|
|
const rec_t* rec, /*!< in: index record */
|
|
|
|
const dict_index_t* index, /*!< in: index */
|
|
|
|
ibool dump_on_error); /*!< in: TRUE if the function
|
2008-03-13 09:29:22 +00:00
|
|
|
should print hex dump of record
|
|
|
|
and page on error */
|
2005-10-27 07:29:40 +00:00
|
|
|
/******************************************************************
|
2009-05-25 05:30:14 +00:00
|
|
|
Checks the consistency of an index tree.
|
|
|
|
@return TRUE if ok */
|
2008-02-18 18:38:33 +00:00
|
|
|
UNIV_INTERN
|
2005-10-27 07:29:40 +00:00
|
|
|
ibool
|
2006-09-19 10:14:07 +00:00
|
|
|
btr_validate_index(
|
|
|
|
/*===============*/
|
2009-05-25 05:30:14 +00:00
|
|
|
dict_index_t* index, /*!< in: index */
|
|
|
|
trx_t* trx); /*!< in: transaction or NULL */
|
2005-10-27 07:29:40 +00:00
|
|
|
|
2006-02-23 19:25:29 +00:00
|
|
|
#define BTR_N_LEAF_PAGES 1
|
2005-10-27 07:29:40 +00:00
|
|
|
#define BTR_TOTAL_SIZE 2
|
2009-03-23 14:21:34 +00:00
|
|
|
#endif /* !UNIV_HOTBACKUP */
|
2005-10-27 07:29:40 +00:00
|
|
|
|
|
|
|
#ifndef UNIV_NONINL
|
|
|
|
#include "btr0btr.ic"
|
|
|
|
#endif
|
|
|
|
|
2006-02-23 19:25:29 +00:00
|
|
|
#endif
|