1
/*****************************************************************************
3
Copyright (c) 1995, 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
/******************************************************
22
Created 12/18/1995 Heikki Tuuri
23
*******************************************************/
33
#include "page0types.h"
35
/* If records are inserted in order, there are the following
36
flags to tell this (their type is made byte for the compiler
37
to warn if direction and hint parameters are switched in
38
fseg_alloc_free_page): */
39
#define FSP_UP ((byte)111) /* alphabetically upwards */
40
#define FSP_DOWN ((byte)112) /* alphabetically downwards */
41
#define FSP_NO_DIR ((byte)113) /* no order */
43
/* File space extent size (one megabyte) in pages */
44
#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
46
/* On a page of any file segment, data may be put starting from this offset: */
47
#define FSEG_PAGE_DATA FIL_PAGE_DATA
49
/* File segment header which points to the inode describing the file segment */
50
typedef byte fseg_header_t;
52
#define FSEG_HDR_SPACE 0 /* space id of the inode */
53
#define FSEG_HDR_PAGE_NO 4 /* page number of the inode */
54
#define FSEG_HDR_OFFSET 8 /* byte offset of the inode */
56
#define FSEG_HEADER_SIZE 10
58
/**************************************************************************
59
Initializes the file space system. */
64
/**************************************************************************
65
Gets the current free limit of the system tablespace. The free limit
66
means the place of the first page which has never been put to the the
67
free list for allocation. The space above that address is initialized
68
to zero. Sets also the global variable log_fsp_current_free_limit. */
71
fsp_header_get_free_limit(void);
72
/*===========================*/
73
/* out: free limit in megabytes */
74
/**************************************************************************
75
Gets the size of the system tablespace from the tablespace header. If
76
we do not have an auto-extending data file, this should be equal to
77
the size of the data files. If there is an auto-extending data file,
78
this can be smaller. */
81
fsp_header_get_tablespace_size(void);
82
/*================================*/
83
/* out: size in pages */
84
/**************************************************************************
85
Reads the file space size stored in the header page. */
90
/* out: tablespace size stored in the space header */
91
page_t* page); /* in: header page (page 0 in the tablespace) */
92
/**************************************************************************
93
Reads the space id from the first page of a tablespace. */
96
fsp_header_get_space_id(
97
/*====================*/
98
/* out: space id, ULINT UNDEFINED if error */
99
const page_t* page); /* in: first page of a tablespace */
100
/**************************************************************************
101
Reads the space flags from the first page of a tablespace. */
104
fsp_header_get_flags(
105
/*=================*/
107
const page_t* page); /* in: first page of a tablespace */
108
/**************************************************************************
109
Reads the compressed page size from the first page of a tablespace. */
112
fsp_header_get_zip_size(
113
/*====================*/
114
/* out: compressed page size in bytes,
115
or 0 if uncompressed */
116
const page_t* page); /* in: first page of a tablespace */
117
/**************************************************************************
118
Writes the space id and compressed page size to a tablespace header.
119
This function is used past the buffer pool when we in fil0fil.c create
120
a new single-table tablespace. */
123
fsp_header_init_fields(
124
/*===================*/
125
page_t* page, /* in/out: first page in the space */
126
ulint space_id, /* in: space id */
127
ulint flags); /* in: tablespace flags (FSP_SPACE_FLAGS):
128
0, or table->flags if newer than COMPACT */
129
/**************************************************************************
130
Initializes the space header of a new created space and creates also the
131
insert buffer tree root if space == 0. */
136
ulint space, /* in: space id */
137
ulint size, /* in: current size in blocks */
138
mtr_t* mtr); /* in: mini-transaction handle */
139
/**************************************************************************
140
Increases the space size field of a space. */
145
ulint space, /* in: space id */
146
ulint size_inc,/* in: size increment in pages */
147
mtr_t* mtr); /* in: mini-transaction handle */
148
/**************************************************************************
149
Creates a new segment. */
154
/* out: the block where the segment header is placed,
155
x-latched, NULL if could not create segment
156
because of lack of space */
157
ulint space, /* in: space id */
158
ulint page, /* in: page where the segment header is placed: if
159
this is != 0, the page must belong to another segment,
160
if this is 0, a new page will be allocated and it
161
will belong to the created segment */
162
ulint byte_offset, /* in: byte offset of the created segment header
164
mtr_t* mtr); /* in: mtr */
165
/**************************************************************************
166
Creates a new segment. */
171
/* out: the block where the segment header is placed,
172
x-latched, NULL if could not create segment
173
because of lack of space */
174
ulint space, /* in: space id */
175
ulint page, /* in: page where the segment header is placed: if
176
this is != 0, the page must belong to another segment,
177
if this is 0, a new page will be allocated and it
178
will belong to the created segment */
179
ulint byte_offset, /* in: byte offset of the created segment header
181
ibool has_done_reservation, /* in: TRUE if the caller has already
182
done the reservation for the pages with
183
fsp_reserve_free_extents (at least 2 extents: one for
184
the inode and the other for the segment) then there is
185
no need to do the check for this individual
187
mtr_t* mtr); /* in: mtr */
188
/**************************************************************************
189
Calculates the number of pages reserved by a segment, and how many pages are
193
fseg_n_reserved_pages(
194
/*==================*/
195
/* out: number of reserved pages */
196
fseg_header_t* header, /* in: segment header */
197
ulint* used, /* out: number of pages used (<= reserved) */
198
mtr_t* mtr); /* in: mtr handle */
199
/**************************************************************************
200
Allocates a single free page from a segment. This function implements
201
the intelligent allocation strategy which tries to minimize
202
file space fragmentation. */
205
fseg_alloc_free_page(
206
/*=================*/
207
/* out: the allocated page offset
208
FIL_NULL if no page could be allocated */
209
fseg_header_t* seg_header, /* in: segment header */
210
ulint hint, /* in: hint of which page would be desirable */
211
byte direction, /* in: if the new page is needed because
212
of an index page split, and records are
213
inserted there in order, into which
214
direction they go alphabetically: FSP_DOWN,
215
FSP_UP, FSP_NO_DIR */
216
mtr_t* mtr); /* in: mtr handle */
217
/**************************************************************************
218
Allocates a single free page from a segment. This function implements
219
the intelligent allocation strategy which tries to minimize file space
223
fseg_alloc_free_page_general(
224
/*=========================*/
225
/* out: allocated page offset, FIL_NULL if no
226
page could be allocated */
227
fseg_header_t* seg_header,/* in: segment header */
228
ulint hint, /* in: hint of which page would be desirable */
229
byte direction,/* in: if the new page is needed because
230
of an index page split, and records are
231
inserted there in order, into which
232
direction they go alphabetically: FSP_DOWN,
233
FSP_UP, FSP_NO_DIR */
234
ibool has_done_reservation, /* in: TRUE if the caller has
235
already done the reservation for the page
236
with fsp_reserve_free_extents, then there
237
is no need to do the check for this individual
239
mtr_t* mtr); /* in: mtr handle */
240
/**************************************************************************
241
Reserves free pages from a tablespace. All mini-transactions which may
242
use several pages from the tablespace should call this function beforehand
243
and reserve enough free extents so that they certainly will be able
244
to do their operation, like a B-tree page split, fully. Reservations
245
must be released with function fil_space_release_free_extents!
247
The alloc_type below has the following meaning: FSP_NORMAL means an
248
operation which will probably result in more space usage, like an
249
insert in a B-tree; FSP_UNDO means allocation to undo logs: if we are
250
deleting rows, then this allocation will in the long run result in
251
less space usage (after a purge); FSP_CLEANING means allocation done
252
in a physical record delete (like in a purge) or other cleaning operation
253
which will result in less space usage in the long run. We prefer the latter
254
two types of allocation: when space is scarce, FSP_NORMAL allocations
255
will not succeed, but the latter two allocations will succeed, if possible.
256
The purpose is to avoid dead end where the database is full but the
257
user cannot free any space because these freeing operations temporarily
260
Single-table tablespaces whose size is < 32 pages are a special case. In this
261
function we would liberally reserve several 64 page extents for every page
262
split or merge in a B-tree. But we do not want to waste disk space if the table
263
only occupies < 32 pages. That is why we apply different rules in that special
264
case, just ensuring that there are 3 free pages available. */
267
fsp_reserve_free_extents(
268
/*=====================*/
269
/* out: TRUE if we were able to make the reservation */
270
ulint* n_reserved,/* out: number of extents actually reserved; if we
271
return TRUE and the tablespace size is < 64 pages,
272
then this can be 0, otherwise it is n_ext */
273
ulint space, /* in: space id */
274
ulint n_ext, /* in: number of extents to reserve */
275
ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
276
mtr_t* mtr); /* in: mtr */
277
/**************************************************************************
278
This function should be used to get information on how much we still
279
will be able to insert new data to the database without running out the
280
tablespace. Only free extents are taken into account and we also subtract
281
the safety margin required by the above function fsp_reserve_free_extents. */
284
fsp_get_available_space_in_free_extents(
285
/*====================================*/
286
/* out: available space in kB */
287
ulint space); /* in: space id */
288
/**************************************************************************
289
Frees a single page of a segment. */
294
fseg_header_t* seg_header, /* in: segment header */
295
ulint space, /* in: space id */
296
ulint page, /* in: page offset */
297
mtr_t* mtr); /* in: mtr handle */
298
/**************************************************************************
299
Frees part of a segment. This function can be used to free a segment
300
by repeatedly calling this function in different mini-transactions.
301
Doing the freeing in a single mini-transaction might result in
302
too big a mini-transaction. */
307
/* out: TRUE if freeing completed */
308
fseg_header_t* header, /* in, own: segment header; NOTE: if the header
309
resides on the first page of the frag list
310
of the segment, this pointer becomes obsolete
311
after the last freeing step */
312
mtr_t* mtr); /* in: mtr */
313
/**************************************************************************
314
Frees part of a segment. Differs from fseg_free_step because this function
315
leaves the header page unfreed. */
318
fseg_free_step_not_header(
319
/*======================*/
320
/* out: TRUE if freeing completed, except the
322
fseg_header_t* header, /* in: segment header which must reside on
323
the first fragment page of the segment */
324
mtr_t* mtr); /* in: mtr */
325
/***************************************************************************
326
Checks if a page address is an extent descriptor page address. */
331
/* out: TRUE if a descriptor page */
332
ulint zip_size,/* in: compressed page size in bytes;
333
0 for uncompressed pages */
334
ulint page_no);/* in: page number */
335
/***************************************************************
336
Parses a redo log record of a file page init. */
339
fsp_parse_init_file_page(
340
/*=====================*/
341
/* out: end of log record or NULL */
342
byte* ptr, /* in: buffer */
343
byte* end_ptr, /* in: buffer end */
344
buf_block_t* block); /* in: block or NULL */
345
/***********************************************************************
346
Validates the file space system and its segments. */
351
/* out: TRUE if ok */
352
ulint space); /* in: space id */
353
/***********************************************************************
354
Prints info of a file space. */
359
ulint space); /* in: space id */
360
#ifdef UNIV_BTR_PRINT
361
/***********************************************************************
362
Writes info of a segment. */
367
fseg_header_t* header, /* in: segment header */
368
mtr_t* mtr); /* in: mtr */
369
#endif /* UNIV_BTR_PRINT */
371
/* Flags for fsp_reserve_free_extents */
372
#define FSP_NORMAL 1000000
373
#define FSP_UNDO 2000000
374
#define FSP_CLEANING 3000000
376
/* Number of pages described in a single descriptor page: currently each page
377
description takes less than 1 byte; a descriptor page is repeated every
378
this many file pages */
379
/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
380
/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
382
/* The space low address page map */
383
/*--------------------------------------*/
384
/* The following two pages are repeated
385
every XDES_DESCRIBED_PER_PAGE pages in
387
#define FSP_XDES_OFFSET 0 /* extent descriptor */
388
#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */
389
/* The ibuf bitmap pages are the ones whose
390
page number is the number above plus a
391
multiple of XDES_DESCRIBED_PER_PAGE */
393
#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */
394
/* The following pages exist
395
in the system tablespace (space 0). */
396
#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */
397
#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */
398
/* The ibuf tree root page number in
399
tablespace 0; its fseg inode is on the page
400
number FSP_FIRST_INODE_PAGE_NO */
401
#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */
402
#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */
403
#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */
404
/*--------------------------------------*/
407
#include "fsp0fsp.ic"