1
/*****************************************************************************
3
Copyright (C) 1997, 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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/ibuf0ibuf.h
23
Created 7/19/1997 Heikki Tuuri
24
*******************************************************/
35
#ifndef UNIV_HOTBACKUP
36
# include "ibuf0types.h"
38
/* Possible operations buffered in the insert/whatever buffer. See
39
ibuf_insert(). DO NOT CHANGE THE VALUES OF THESE, THEY ARE STORED ON DISK. */
42
IBUF_OP_DELETE_MARK = 1,
45
/* Number of different operation types. */
49
/** Combinations of operations that can be buffered. Because the enum
50
values are used for indexing innobase_change_buffering_values[], they
51
should start at 0 and there should not be any gaps. */
54
IBUF_USE_INSERT, /* insert */
55
IBUF_USE_DELETE_MARK, /* delete */
56
IBUF_USE_INSERT_DELETE_MARK, /* insert+delete */
57
IBUF_USE_DELETE, /* delete+purge */
58
IBUF_USE_ALL, /* insert+delete+purge */
60
IBUF_USE_COUNT /* number of entries in ibuf_use_t */
63
/** Operations that can currently be buffered. */
64
extern ibuf_use_t ibuf_use;
66
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
67
/** Flag to control insert buffer debugging. */
68
extern uint ibuf_debug;
69
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
71
/** The insert buffer control structure */
74
/* The purpose of the insert buffer is to reduce random disk access.
75
When we wish to insert a record into a non-unique secondary index and
76
the B-tree leaf page where the record belongs to is not in the buffer
77
pool, we insert the record into the insert buffer B-tree, indexed by
78
(space_id, page_no). When the page is eventually read into the buffer
79
pool, we look up the insert buffer B-tree for any modifications to the
80
page, and apply these upon the completion of the read operation. This
81
is called the insert buffer merge. */
83
/* The insert buffer merge must always succeed. To guarantee this,
84
the insert buffer subsystem keeps track of the free space in pages for
85
which it can buffer operations. Two bits per page in the insert
86
buffer bitmap indicate the available space in coarse increments. The
87
free bits in the insert buffer bitmap must never exceed the free space
88
on a page. It is safe to decrement or reset the bits in the bitmap in
89
a mini-transaction that is committed before the mini-transaction that
90
affects the free space. It is unsafe to increment the bits in a
91
separately committed mini-transaction, because in crash recovery, the
92
free bits could momentarily be set too high. */
94
/******************************************************************//**
95
Creates the insert buffer data structure at a database startup. */
98
ibuf_init_at_db_start(void);
99
/*=======================*/
100
/*********************************************************************//**
101
Reads the biggest tablespace id from the high end of the insert buffer
102
tree and updates the counter in fil_system. */
105
ibuf_update_max_tablespace_id(void);
106
/*===============================*/
107
/*********************************************************************//**
108
Initializes an ibuf bitmap page. */
111
ibuf_bitmap_page_init(
112
/*==================*/
113
buf_block_t* block, /*!< in: bitmap page */
114
mtr_t* mtr); /*!< in: mtr */
115
/************************************************************************//**
116
Resets the free bits of the page in the ibuf bitmap. This is done in a
117
separate mini-transaction, hence this operation does not restrict
118
further work to only ibuf bitmap operations, which would result if the
119
latch to the bitmap page were kept. NOTE: The free bits in the insert
120
buffer bitmap must never exceed the free space on a page. It is safe
121
to decrement or reset the bits in the bitmap in a mini-transaction
122
that is committed before the mini-transaction that affects the free
126
ibuf_reset_free_bits(
127
/*=================*/
128
buf_block_t* block); /*!< in: index page; free bits are set to 0
129
if the index is a non-clustered
130
non-unique, and page level is 0 */
131
/************************************************************************//**
132
Updates the free bits of an uncompressed page in the ibuf bitmap if
133
there is not enough free on the page any more. This is done in a
134
separate mini-transaction, hence this operation does not restrict
135
further work to only ibuf bitmap operations, which would result if the
136
latch to the bitmap page were kept. NOTE: The free bits in the insert
137
buffer bitmap must never exceed the free space on a page. It is
138
unsafe to increment the bits in a separately committed
139
mini-transaction, because in crash recovery, the free bits could
140
momentarily be set too high. It is only safe to use this function for
141
decrementing the free bits. Should more free space become available,
142
we must not update the free bits here, because that would break crash
146
ibuf_update_free_bits_if_full(
147
/*==========================*/
148
buf_block_t* block, /*!< in: index page to which we have added new
149
records; the free bits are updated if the
150
index is non-clustered and non-unique and
151
the page level is 0, and the page becomes
153
ulint max_ins_size,/*!< in: value of maximum insert size with
154
reorganize before the latest operation
155
performed to the page */
156
ulint increase);/*!< in: upper limit for the additional space
157
used in the latest operation, if known, or
159
/**********************************************************************//**
160
Updates the free bits for an uncompressed page to reflect the present
161
state. Does this in the mtr given, which means that the latching
162
order rules virtually prevent any further operations for this OS
163
thread until mtr is committed. NOTE: The free bits in the insert
164
buffer bitmap must never exceed the free space on a page. It is safe
165
to set the free bits in the same mini-transaction that updated the
169
ibuf_update_free_bits_low(
170
/*======================*/
171
const buf_block_t* block, /*!< in: index page */
172
ulint max_ins_size, /*!< in: value of
174
with reorganize before
176
performed to the page */
177
mtr_t* mtr); /*!< in/out: mtr */
178
/**********************************************************************//**
179
Updates the free bits for a compressed page to reflect the present
180
state. Does this in the mtr given, which means that the latching
181
order rules virtually prevent any further operations for this OS
182
thread until mtr is committed. NOTE: The free bits in the insert
183
buffer bitmap must never exceed the free space on a page. It is safe
184
to set the free bits in the same mini-transaction that updated the
188
ibuf_update_free_bits_zip(
189
/*======================*/
190
buf_block_t* block, /*!< in/out: index page */
191
mtr_t* mtr); /*!< in/out: mtr */
192
/**********************************************************************//**
193
Updates the free bits for the two pages to reflect the present state.
194
Does this in the mtr given, which means that the latching order rules
195
virtually prevent any further operations until mtr is committed.
196
NOTE: The free bits in the insert buffer bitmap must never exceed the
197
free space on a page. It is safe to set the free bits in the same
198
mini-transaction that updated the pages. */
201
ibuf_update_free_bits_for_two_pages_low(
202
/*====================================*/
203
ulint zip_size,/*!< in: compressed page size in bytes;
204
0 for uncompressed pages */
205
buf_block_t* block1, /*!< in: index page */
206
buf_block_t* block2, /*!< in: index page */
207
mtr_t* mtr); /*!< in: mtr */
208
/**********************************************************************//**
209
A basic partial test if an insert to the insert buffer could be possible and
215
dict_index_t* index, /*!< in: index where to insert */
216
ulint ignore_sec_unique); /*!< in: if != 0, we should
217
ignore UNIQUE constraint on
218
a secondary index when we
220
/******************************************************************//**
221
Returns TRUE if the current OS thread is performing an insert buffer
224
For instance, a read-ahead of non-ibuf pages is forbidden by threads
225
that are executing an insert buffer routine.
226
@return TRUE if inside an insert buffer routine */
231
/***********************************************************************//**
232
Checks if a page address is an ibuf bitmap page (level 3 page) address.
233
@return TRUE if a bitmap page */
238
ulint zip_size,/*!< in: compressed page size in bytes;
239
0 for uncompressed pages */
240
ulint page_no);/*!< in: page number */
241
/***********************************************************************//**
242
Checks if a page is a level 2 or 3 page in the ibuf hierarchy of pages.
243
Must not be called when recv_no_ibuf_operations==TRUE.
244
@return TRUE if level 2 or level 3 page */
249
ulint space, /*!< in: space id */
250
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
251
ulint page_no,/*!< in: page number */
252
mtr_t* mtr); /*!< in: mtr which will contain an x-latch to the
253
bitmap page if the page is not one of the fixed
254
address ibuf pages, or NULL, in which case a new
255
transaction is created. */
256
/***********************************************************************//**
257
Frees excess pages from the ibuf free list. This function is called when an OS
258
thread calls fsp services to allocate a new file segment, or a new page to a
259
file segment, and the thread did not own the fsp latch before this call. */
262
ibuf_free_excess_pages(void);
263
/*========================*/
264
/*********************************************************************//**
265
Buffer an operation in the insert/delete buffer, instead of doing it
266
directly to the disk page, if this is possible. Does not do it if the index
267
is clustered or unique.
268
@return TRUE if success */
273
ibuf_op_t op, /*!< in: operation type */
274
const dtuple_t* entry, /*!< in: index entry to insert */
275
dict_index_t* index, /*!< in: index where to insert */
276
ulint space, /*!< in: space id where to insert */
277
ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
278
ulint page_no,/*!< in: page number where to insert */
279
que_thr_t* thr); /*!< in: query thread */
280
/*********************************************************************//**
281
When an index page is read from a disk to the buffer pool, this function
282
applies any buffered operations to the page and deletes the entries from the
283
insert buffer. If the page is not read, but created in the buffer pool, this
284
function deletes its buffered entries from the insert buffer; there can
285
exist entries for such a page if the page belonged to an index which
286
subsequently was dropped. */
289
ibuf_merge_or_delete_for_page(
290
/*==========================*/
291
buf_block_t* block, /*!< in: if page has been read from
292
disk, pointer to the page x-latched,
294
ulint space, /*!< in: space id of the index page */
295
ulint page_no,/*!< in: page number of the index page */
296
ulint zip_size,/*!< in: compressed page size in bytes,
298
ibool update_ibuf_bitmap);/*!< in: normally this is set
299
to TRUE, but if we have deleted or are
300
deleting the tablespace, then we
301
naturally do not want to update a
302
non-existent bitmap page */
303
/*********************************************************************//**
304
Deletes all entries in the insert buffer for a given space id. This is used
305
in DISCARD TABLESPACE and IMPORT TABLESPACE.
306
NOTE: this does not update the page free bitmaps in the space. The space will
307
become CORRUPT when you call this function! */
310
ibuf_delete_for_discarded_space(
311
/*============================*/
312
ulint space); /*!< in: space id */
313
/*********************************************************************//**
314
Contracts insert buffer trees by reading pages to the buffer pool.
315
@return a lower limit for the combined size in bytes of entries which
316
will be merged from ibuf trees to the pages read, 0 if ibuf is
322
ibool sync); /*!< in: TRUE if the caller wants to wait for the
323
issued read with the highest tablespace address
325
/*********************************************************************//**
326
Contracts insert buffer trees by reading pages to the buffer pool.
327
@return a lower limit for the combined size in bytes of entries which
328
will be merged from ibuf trees to the pages read, 0 if ibuf is
332
ibuf_contract_for_n_pages(
333
/*======================*/
334
ibool sync, /*!< in: TRUE if the caller wants to wait for the
335
issued read with the highest tablespace address
337
ulint n_pages);/*!< in: try to read at least this many pages to
338
the buffer pool and merge the ibuf contents to
340
#endif /* !UNIV_HOTBACKUP */
341
/*********************************************************************//**
342
Parses a redo log record of an ibuf bitmap page init.
343
@return end of log record or NULL */
346
ibuf_parse_bitmap_init(
347
/*===================*/
348
byte* ptr, /*!< in: buffer */
349
byte* end_ptr,/*!< in: buffer end */
350
buf_block_t* block, /*!< in: block or NULL */
351
mtr_t* mtr); /*!< in: mtr or NULL */
352
#ifndef UNIV_HOTBACKUP
353
#ifdef UNIV_IBUF_COUNT_DEBUG
354
/******************************************************************//**
355
Gets the ibuf count for a given page.
356
@return number of entries in the insert buffer currently buffered for
362
ulint space, /*!< in: space id */
363
ulint page_no);/*!< in: page number */
365
/******************************************************************//**
366
Looks if the insert buffer is empty.
367
@return TRUE if empty */
372
/******************************************************************//**
373
Prints info of ibuf. */
378
FILE* file); /*!< in: file where to print */
379
/********************************************************************
380
Read the first two bytes from a record's fourth field (counter field in new
381
records; something else in older records).
382
@return "counter" field, or ULINT_UNDEFINED if for some reason it can't be read */
385
ibuf_rec_get_counter(
386
/*=================*/
387
const rec_t* rec); /*!< in: ibuf record */
388
/******************************************************************//**
389
Closes insert buffer and frees the data structures. */
395
#define IBUF_HEADER_PAGE_NO FSP_IBUF_HEADER_PAGE_NO
396
#define IBUF_TREE_ROOT_PAGE_NO FSP_IBUF_TREE_ROOT_PAGE_NO
398
#endif /* !UNIV_HOTBACKUP */
400
/* The ibuf header page currently contains only the file segment header
401
for the file segment from which the pages for the ibuf tree are allocated */
402
#define IBUF_HEADER PAGE_DATA
403
#define IBUF_TREE_SEG_HEADER 0 /* fseg header for ibuf tree */
405
/* The insert buffer tree itself is always located in space 0. */
406
#define IBUF_SPACE_ID 0
409
#include "ibuf0ibuf.ic"