mirror of
https://github.com/MariaDB/server.git
synced 2025-02-24 06:13:09 +01:00
branches/zip: Clean up the insert buffer subsystem.
Originally, there were provisions in InnoDB for multiple insert buffer B-trees, apparently one for each tablespace. When Heikki implemented innodb_file_per_table (multiple InnoDB tablespaces) in MySQL 4.1, he made the insert buffer live only in the system tablespace (space 0) but left the provisions in the code. When Osku Salerma implemented delete buffering, he also cleaned up the insert buffer subsystem so that only one insert buffer B-tree exists. This patch applies the clean-up to the InnoDB Plugin. Having a separate patch of the insert buffer clean-up should help us better compare the essential changes of the InnoDB Plugin and InnoDB+ and to track down bugs that are specific to InnoDB+. IBUF_SPACE_ID: New constant, defined as 0. ibuf_data_t: Remove. ibuf_t: Add the applicable fields from ibuf_data_t. There is only one insert buffer tree from now on. ibuf_page_low(), ibuf_page(): Merge to a single function ibuf_page(). fil_space_t: Remove ibuf_data. fil_space_get_ibuf_data(): Remove. There is only one ibuf_data, for space IBUF_SPACE_ID. fil_ibuf_init_at_db_start(): Remove. ibuf_init_at_db_start(): Fuse with ibuf_data_init_for_space(). ibuf_validate_low(): Remove. There is only one ibuf tree. ibuf_free_excess_pages(), ibuf_header_page_get(), ibuf_free_excess_pages(): Remove the parameter space, which was always 0. ibuf_tree_root_get(): Remove the parameters space and data. There is only one ibuf tree, for space IBUF_SPACE_ID. ibuf_data_sizes_update(): Rename to ibuf_size_update(), and remove the parameter data. There is only one ibuf data struct. ibuf_build_entry_pre_4_1_x(): New function, refactored from ibuf_build_entry_from_ibuf_rec(). ibuf_data_enough_free_for_insert(), ibuf_data_too_much_free(): Remove the parameter data. There is only one insert buffer tree. ibuf_add_free_page(), ibuf_remove_free_page(): Remove the parameters space and data. There is only one insert buffer tree. ibuf_get_merge_page_nos(): Add parenthesis, to reduce diffs to branches/innodb+. ibuf_contract_ext(): Do not pick an insert buffer tree at random. There is only one. ibuf_print(): Print the single insert buffer tree. rb://19 approved by Heikki on IM
This commit is contained in:
parent
c7ecb3fea7
commit
8513a278cb
8 changed files with 380 additions and 651 deletions
|
@ -1817,7 +1817,7 @@ buf_page_get_gen(
|
|||
|| (mode == BUF_GET_NO_LATCH) || (mode == BUF_GET_NOWAIT));
|
||||
ut_ad(zip_size == fil_space_get_zip_size(space));
|
||||
#ifndef UNIV_LOG_DEBUG
|
||||
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset));
|
||||
ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
|
||||
#endif
|
||||
buf_pool->n_page_gets++;
|
||||
loop:
|
||||
|
@ -2180,7 +2180,7 @@ buf_page_optimistic_get_func(
|
|||
ut_ad(!ibuf_inside()
|
||||
|| ibuf_page(buf_block_get_space(block),
|
||||
buf_block_get_zip_size(block),
|
||||
buf_block_get_page_no(block)));
|
||||
buf_block_get_page_no(block), NULL));
|
||||
|
||||
if (rw_latch == RW_S_LATCH) {
|
||||
success = rw_lock_s_lock_func_nowait(&(block->lock),
|
||||
|
@ -2574,7 +2574,8 @@ buf_page_init_for_read(
|
|||
|
||||
mtr_start(&mtr);
|
||||
|
||||
if (!ibuf_page_low(space, zip_size, offset, &mtr)) {
|
||||
if (!recv_no_ibuf_operations
|
||||
&& !ibuf_page(space, zip_size, offset, &mtr)) {
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
|
|
|
@ -191,8 +191,6 @@ struct fil_space_struct {
|
|||
currently in the list above */
|
||||
UT_LIST_NODE_T(fil_space_t) space_list;
|
||||
/* list of all spaces */
|
||||
ibuf_data_t* ibuf_data;
|
||||
/* insert buffer data */
|
||||
ulint magic_n;
|
||||
};
|
||||
|
||||
|
@ -475,33 +473,6 @@ fil_space_get_type(
|
|||
return(space->purpose);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Returns the ibuf data of a file space. */
|
||||
UNIV_INTERN
|
||||
ibuf_data_t*
|
||||
fil_space_get_ibuf_data(
|
||||
/*====================*/
|
||||
/* out: ibuf data for this space */
|
||||
ulint id) /* in: space id */
|
||||
{
|
||||
fil_system_t* system = fil_system;
|
||||
fil_space_t* space;
|
||||
|
||||
ut_ad(system);
|
||||
|
||||
ut_a(id == 0);
|
||||
|
||||
mutex_enter(&(system->mutex));
|
||||
|
||||
space = fil_space_get_by_id(id);
|
||||
|
||||
mutex_exit(&(system->mutex));
|
||||
|
||||
ut_a(space);
|
||||
|
||||
return(space->ibuf_data);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Checks if all the file nodes in a space are flushed. The caller must hold
|
||||
the fil_system mutex. */
|
||||
|
@ -1192,8 +1163,6 @@ try_again:
|
|||
UT_LIST_INIT(space->chain);
|
||||
space->magic_n = FIL_SPACE_MAGIC_N;
|
||||
|
||||
space->ibuf_data = NULL;
|
||||
|
||||
rw_lock_create(&space->latch, SYNC_FSP);
|
||||
|
||||
HASH_INSERT(fil_space_t, hash, system->spaces, id, space);
|
||||
|
@ -1680,25 +1649,6 @@ fil_set_max_space_id_if_bigger(
|
|||
mutex_exit(&(system->mutex));
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Initializes the ibuf data structure for space 0 == the system tablespace.
|
||||
This can be called after the file space headers have been created and the
|
||||
dictionary system has been initialized. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_ibuf_init_at_db_start(void)
|
||||
/*===========================*/
|
||||
{
|
||||
fil_space_t* space;
|
||||
|
||||
space = UT_LIST_GET_FIRST(fil_system->space_list);
|
||||
|
||||
ut_a(space);
|
||||
ut_a(space->purpose == FIL_TABLESPACE);
|
||||
|
||||
space->ibuf_data = ibuf_data_init_for_space(space->id);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Writes the flushed lsn and the latest archived log number to the page header
|
||||
of the first page of a data file of the system tablespace (space 0),
|
||||
|
@ -4313,14 +4263,15 @@ fil_io(
|
|||
|| !ibuf_bitmap_page(zip_size, block_offset)
|
||||
|| sync || is_log);
|
||||
ut_ad(!ibuf_inside() || is_log || (type == OS_FILE_WRITE)
|
||||
|| ibuf_page(space_id, zip_size, block_offset));
|
||||
|| ibuf_page(space_id, zip_size, block_offset, NULL));
|
||||
#endif
|
||||
if (sync) {
|
||||
mode = OS_AIO_SYNC;
|
||||
} else if (is_log) {
|
||||
mode = OS_AIO_LOG;
|
||||
} else if (type == OS_FILE_READ
|
||||
&& ibuf_page(space_id, zip_size, block_offset)) {
|
||||
&& !recv_no_ibuf_operations
|
||||
&& ibuf_page(space_id, zip_size, block_offset, NULL)) {
|
||||
mode = OS_AIO_IBUF;
|
||||
} else {
|
||||
mode = OS_AIO_NORMAL;
|
||||
|
|
|
@ -2211,8 +2211,8 @@ fseg_create_general(
|
|||
/* This thread did not own the latch before this call: free
|
||||
excess pages from the insert buffer free list */
|
||||
|
||||
if (space == 0) {
|
||||
ibuf_free_excess_pages(0);
|
||||
if (space == IBUF_SPACE_ID) {
|
||||
ibuf_free_excess_pages();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2788,8 +2788,8 @@ fseg_alloc_free_page_general(
|
|||
/* This thread did not own the latch before this call: free
|
||||
excess pages from the insert buffer free list */
|
||||
|
||||
if (space == 0) {
|
||||
ibuf_free_excess_pages(0);
|
||||
if (space == IBUF_SPACE_ID) {
|
||||
ibuf_free_excess_pages();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
860
ibuf/ibuf0ibuf.c
860
ibuf/ibuf0ibuf.c
File diff suppressed because it is too large
Load diff
|
@ -12,7 +12,6 @@ Created 10/25/1995 Heikki Tuuri
|
|||
#include "univ.i"
|
||||
#include "sync0rw.h"
|
||||
#include "dict0types.h"
|
||||
#include "ibuf0types.h"
|
||||
#include "ut0byte.h"
|
||||
#include "os0file.h"
|
||||
|
||||
|
@ -158,14 +157,6 @@ fil_space_get_type(
|
|||
/* out: FIL_TABLESPACE or FIL_LOG */
|
||||
ulint id); /* in: space id */
|
||||
/***********************************************************************
|
||||
Returns the ibuf data of a file space. */
|
||||
UNIV_INTERN
|
||||
ibuf_data_t*
|
||||
fil_space_get_ibuf_data(
|
||||
/*====================*/
|
||||
/* out: ibuf data for this space */
|
||||
ulint id); /* in: space id */
|
||||
/***********************************************************************
|
||||
Appends a new file to the chain of files of a space. File must be closed. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
|
@ -283,14 +274,6 @@ fil_set_max_space_id_if_bigger(
|
|||
/*===========================*/
|
||||
ulint max_id);/* in: maximum known id */
|
||||
/********************************************************************
|
||||
Initializes the ibuf data structure for space 0 == the system tablespace.
|
||||
This can be called after the file space headers have been created and the
|
||||
dictionary system has been initialized. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_ibuf_init_at_db_start(void);
|
||||
/*===========================*/
|
||||
/********************************************************************
|
||||
Writes the flushed lsn and the latest archived log number to the page
|
||||
header of the first page of each data file in the system tablespace. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -40,18 +40,6 @@ affects the free space. It is unsafe to increment the bits in a
|
|||
separately committed mini-transaction, because in crash recovery, the
|
||||
free bits could momentarily be set too high. */
|
||||
|
||||
/**********************************************************************
|
||||
Creates the insert buffer data struct for a single tablespace. Reads the
|
||||
root page of the insert buffer tree in the tablespace. This function can
|
||||
be called only after the dictionary system has been initialized, as this
|
||||
creates also the insert buffer table and index for this tablespace. */
|
||||
UNIV_INTERN
|
||||
ibuf_data_t*
|
||||
ibuf_data_init_for_space(
|
||||
/*=====================*/
|
||||
/* out, own: ibuf data struct, linked to the list
|
||||
in ibuf control structure. */
|
||||
ulint space); /* in: space id */
|
||||
/**********************************************************************
|
||||
Creates the insert buffer data structure at a database startup and
|
||||
initializes the data structures for the insert buffer of each tablespace. */
|
||||
|
@ -199,7 +187,8 @@ ibuf_bitmap_page(
|
|||
0 for uncompressed pages */
|
||||
ulint page_no);/* in: page number */
|
||||
/***************************************************************************
|
||||
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */
|
||||
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
|
||||
Must not be called when recv_no_ibuf_operations==TRUE. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
ibuf_page(
|
||||
|
@ -207,29 +196,19 @@ ibuf_page(
|
|||
/* out: TRUE if level 2 or level 3 page */
|
||||
ulint space, /* in: space id */
|
||||
ulint zip_size,/* in: compressed page size in bytes, or 0 */
|
||||
ulint page_no);/* in: page number */
|
||||
/***************************************************************************
|
||||
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
ibuf_page_low(
|
||||
/*==========*/
|
||||
/* out: TRUE if level 2 or level 3 page */
|
||||
ulint space, /* in: space id */
|
||||
ulint zip_size,/* in: compressed page size in bytes, or 0 */
|
||||
ulint page_no,/* in: page number */
|
||||
mtr_t* mtr); /* in: mtr which will contain an x-latch to the
|
||||
bitmap page if the page is not one of the fixed
|
||||
address ibuf pages */
|
||||
address ibuf pages, or NULL, in which case a new
|
||||
transaction is created. */
|
||||
/***************************************************************************
|
||||
Frees excess pages from the ibuf free list. This function is called when an OS
|
||||
thread calls fsp services to allocate a new file segment, or a new page to a
|
||||
file segment, and the thread did not own the fsp latch before this call. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_free_excess_pages(
|
||||
/*===================*/
|
||||
ulint space); /* in: space id */
|
||||
ibuf_free_excess_pages(void);
|
||||
/*========================*/
|
||||
/*************************************************************************
|
||||
Makes an index insert to the insert buffer, instead of directly to the disk
|
||||
page, if this is possible. Does not do insert if the index is clustered
|
||||
|
@ -351,6 +330,9 @@ for the file segment from which the pages for the ibuf tree are allocated */
|
|||
#define IBUF_HEADER PAGE_DATA
|
||||
#define IBUF_TREE_SEG_HEADER 0 /* fseg header for ibuf tree */
|
||||
|
||||
/* The insert buffer tree itself is always located in space 0. */
|
||||
#define IBUF_SPACE_ID 0
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "ibuf0ibuf.ic"
|
||||
#endif
|
||||
|
|
|
@ -18,36 +18,29 @@ If there is this much of free space, the corresponding bits are set in the
|
|||
ibuf bitmap. */
|
||||
#define IBUF_PAGE_SIZE_PER_FREE_SPACE 32
|
||||
|
||||
/* Insert buffer data struct for a single tablespace */
|
||||
struct ibuf_data_struct{
|
||||
ulint space; /* space id */
|
||||
ulint seg_size;/* allocated pages if the file segment
|
||||
containing ibuf header and tree */
|
||||
ulint size; /* size of the insert buffer tree in pages */
|
||||
ibool empty; /* after an insert to the ibuf tree is
|
||||
performed, this is set to FALSE, and if a
|
||||
contract operation finds the tree empty, this
|
||||
is set to TRUE */
|
||||
ulint free_list_len;
|
||||
/* length of the free list */
|
||||
ulint height; /* tree height */
|
||||
dict_index_t* index; /* insert buffer index */
|
||||
UT_LIST_NODE_T(ibuf_data_t) data_list;
|
||||
/* list of ibuf data structs */
|
||||
ulint n_inserts;/* number of inserts made to the insert
|
||||
buffer */
|
||||
ulint n_merges;/* number of pages merged */
|
||||
ulint n_merged_recs;/* number of records merged */
|
||||
};
|
||||
/* Insert buffer struct */
|
||||
|
||||
struct ibuf_struct{
|
||||
ulint size; /* current size of the ibuf index
|
||||
trees in pages */
|
||||
ulint max_size; /* recommended maximum size in pages
|
||||
for the ibuf index tree */
|
||||
UT_LIST_BASE_NODE_T(ibuf_data_t) data_list;
|
||||
/* list of ibuf data structs for
|
||||
each tablespace */
|
||||
tree, in pages */
|
||||
ulint max_size; /* recommended maximum size of the
|
||||
ibuf index tree, in pages */
|
||||
ulint seg_size; /* allocated pages of the file
|
||||
segment containing ibuf header and
|
||||
tree */
|
||||
ibool empty; /* after an insert to the ibuf tree
|
||||
is performed, this is set to FALSE,
|
||||
and if a contract operation finds
|
||||
the tree empty, this is set to
|
||||
TRUE */
|
||||
ulint free_list_len; /* length of the free list */
|
||||
ulint height; /* tree height */
|
||||
dict_index_t* index; /* insert buffer index */
|
||||
|
||||
ulint n_inserts; /* number of inserts made to
|
||||
the insert buffer */
|
||||
ulint n_merges; /* number of pages merged */
|
||||
ulint n_merged_recs; /* number of records merged */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -9,7 +9,6 @@ Created 7/29/1997 Heikki Tuuri
|
|||
#ifndef ibuf0types_h
|
||||
#define ibuf0types_h
|
||||
|
||||
typedef struct ibuf_data_struct ibuf_data_t;
|
||||
typedef struct ibuf_struct ibuf_t;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue