32
15
#include "fut0lst.h"
33
16
#include "ut0byte.h"
34
17
#include "page0types.h"
35
#include "fsp0types.h"
37
/**********************************************************************//**
19
/* If records are inserted in order, there are the following
20
flags to tell this (their type is made byte for the compiler
21
to warn if direction and hint parameters are switched in
22
fseg_alloc_free_page): */
23
#define FSP_UP ((byte)111) /* alphabetically upwards */
24
#define FSP_DOWN ((byte)112) /* alphabetically downwards */
25
#define FSP_NO_DIR ((byte)113) /* no order */
27
/* File space extent size (one megabyte) in pages */
28
#define FSP_EXTENT_SIZE (1 << (20 - UNIV_PAGE_SIZE_SHIFT))
30
/* On a page of any file segment, data may be put starting from this offset: */
31
#define FSEG_PAGE_DATA FIL_PAGE_DATA
33
/* File segment header which points to the inode describing the file segment */
34
typedef byte fseg_header_t;
36
#define FSEG_HDR_SPACE 0 /* space id of the inode */
37
#define FSEG_HDR_PAGE_NO 4 /* page number of the inode */
38
#define FSEG_HDR_OFFSET 8 /* byte offset of the inode */
40
#define FSEG_HEADER_SIZE 10
42
/**************************************************************************
38
43
Initializes the file space system. */
43
/**********************************************************************//**
48
/**************************************************************************
44
49
Gets the current free limit of the system tablespace. The free limit
45
50
means the place of the first page which has never been put to the the
46
51
free list for allocation. The space above that address is initialized
47
to zero. Sets also the global variable log_fsp_current_free_limit.
48
@return free limit in megabytes */
52
to zero. Sets also the global variable log_fsp_current_free_limit. */
51
55
fsp_header_get_free_limit(void);
52
56
/*===========================*/
53
/**********************************************************************//**
57
/* out: free limit in megabytes */
58
/**************************************************************************
54
59
Gets the size of the system tablespace from the tablespace header. If
55
60
we do not have an auto-extending data file, this should be equal to
56
61
the size of the data files. If there is an auto-extending data file,
58
@return size in pages */
62
this can be smaller. */
61
65
fsp_header_get_tablespace_size(void);
62
66
/*================================*/
63
/**********************************************************************//**
64
Reads the file space size stored in the header page.
65
@return tablespace size stored in the space header */
67
/* out: size in pages */
68
/**************************************************************************
69
Reads the file space size stored in the header page. */
70
page_t* page); /*!< in: header page (page 0 in the tablespace) */
71
/**********************************************************************//**
72
Reads the space id from the first page of a tablespace.
73
@return space id, ULINT UNDEFINED if error */
74
/* out: tablespace size stored in the space header */
75
page_t* page); /* in: header page (page 0 in the tablespace) */
76
/**************************************************************************
77
Reads the space id from the first page of a tablespace. */
76
80
fsp_header_get_space_id(
77
81
/*====================*/
78
const page_t* page); /*!< in: first page of a tablespace */
79
/**********************************************************************//**
80
Reads the space flags from the first page of a tablespace.
82
/* out: space id, ULINT UNDEFINED if error */
83
const page_t* page); /* in: first page of a tablespace */
84
/**************************************************************************
85
Reads the space flags from the first page of a tablespace. */
84
88
fsp_header_get_flags(
85
89
/*=================*/
86
const page_t* page); /*!< in: first page of a tablespace */
87
/**********************************************************************//**
88
Reads the compressed page size from the first page of a tablespace.
89
@return compressed page size in bytes, or 0 if uncompressed */
91
const page_t* page); /* in: first page of a tablespace */
92
/**************************************************************************
93
Reads the compressed page size from the first page of a tablespace. */
92
96
fsp_header_get_zip_size(
93
97
/*====================*/
94
const page_t* page); /*!< in: first page of a tablespace */
95
/**********************************************************************//**
98
/* out: compressed page size in bytes,
99
or 0 if uncompressed */
100
const page_t* page); /* in: first page of a tablespace */
101
/**************************************************************************
96
102
Writes the space id and compressed page size to a tablespace header.
97
103
This function is used past the buffer pool when we in fil0fil.c create
98
104
a new single-table tablespace. */
101
107
fsp_header_init_fields(
102
108
/*===================*/
103
page_t* page, /*!< in/out: first page in the space */
104
ulint space_id, /*!< in: space id */
105
ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
109
page_t* page, /* in/out: first page in the space */
110
ulint space_id, /* in: space id */
111
ulint flags); /* in: tablespace flags (FSP_SPACE_FLAGS):
106
112
0, or table->flags if newer than COMPACT */
107
/**********************************************************************//**
113
/**************************************************************************
108
114
Initializes the space header of a new created space and creates also the
109
115
insert buffer tree root if space == 0. */
114
ulint space, /*!< in: space id */
115
ulint size, /*!< in: current size in blocks */
116
mtr_t* mtr); /*!< in: mini-transaction handle */
117
/**********************************************************************//**
120
ulint space, /* in: space id */
121
ulint size, /* in: current size in blocks */
122
mtr_t* mtr); /* in: mini-transaction handle */
123
/**************************************************************************
118
124
Increases the space size field of a space. */
121
127
fsp_header_inc_size(
122
128
/*================*/
123
ulint space, /*!< in: space id */
124
ulint size_inc,/*!< in: size increment in pages */
125
mtr_t* mtr); /*!< in: mini-transaction handle */
126
/**********************************************************************//**
127
Creates a new segment.
128
@return the block where the segment header is placed, x-latched, NULL
129
if could not create segment because of lack of space */
129
ulint space, /* in: space id */
130
ulint size_inc,/* in: size increment in pages */
131
mtr_t* mtr); /* in: mini-transaction handle */
132
/**************************************************************************
133
Creates a new segment. */
134
ulint space, /*!< in: space id */
135
ulint page, /*!< in: page where the segment header is placed: if
138
/* out: the block where the segment header is placed,
139
x-latched, NULL if could not create segment
140
because of lack of space */
141
ulint space, /* in: space id */
142
ulint page, /* in: page where the segment header is placed: if
136
143
this is != 0, the page must belong to another segment,
137
144
if this is 0, a new page will be allocated and it
138
145
will belong to the created segment */
139
ulint byte_offset, /*!< in: byte offset of the created segment header
146
ulint byte_offset, /* in: byte offset of the created segment header
141
mtr_t* mtr); /*!< in: mtr */
142
/**********************************************************************//**
143
Creates a new segment.
144
@return the block where the segment header is placed, x-latched, NULL
145
if could not create segment because of lack of space */
148
mtr_t* mtr); /* in: mtr */
149
/**************************************************************************
150
Creates a new segment. */
148
153
fseg_create_general(
149
154
/*================*/
150
ulint space, /*!< in: space id */
151
ulint page, /*!< in: page where the segment header is placed: if
155
/* out: the block where the segment header is placed,
156
x-latched, NULL if could not create segment
157
because of lack of space */
158
ulint space, /* in: space id */
159
ulint page, /* in: page where the segment header is placed: if
152
160
this is != 0, the page must belong to another segment,
153
161
if this is 0, a new page will be allocated and it
154
162
will belong to the created segment */
155
ulint byte_offset, /*!< in: byte offset of the created segment header
163
ulint byte_offset, /* in: byte offset of the created segment header
157
ibool has_done_reservation, /*!< in: TRUE if the caller has already
165
ibool has_done_reservation, /* in: TRUE if the caller has already
158
166
done the reservation for the pages with
159
167
fsp_reserve_free_extents (at least 2 extents: one for
160
168
the inode and the other for the segment) then there is
161
169
no need to do the check for this individual
163
mtr_t* mtr); /*!< in: mtr */
164
/**********************************************************************//**
171
mtr_t* mtr); /* in: mtr */
172
/**************************************************************************
165
173
Calculates the number of pages reserved by a segment, and how many pages are
167
@return number of reserved pages */
170
177
fseg_n_reserved_pages(
171
178
/*==================*/
172
fseg_header_t* header, /*!< in: segment header */
173
ulint* used, /*!< out: number of pages used (<= reserved) */
174
mtr_t* mtr); /*!< in: mtr handle */
175
/**********************************************************************//**
179
/* out: number of reserved pages */
180
fseg_header_t* header, /* in: segment header */
181
ulint* used, /* out: number of pages used (<= reserved) */
182
mtr_t* mtr); /* in: mtr handle */
183
/**************************************************************************
176
184
Allocates a single free page from a segment. This function implements
177
185
the intelligent allocation strategy which tries to minimize
178
file space fragmentation.
179
@return the allocated page offset FIL_NULL if no page could be allocated */
186
file space fragmentation. */
182
189
fseg_alloc_free_page(
183
190
/*=================*/
184
fseg_header_t* seg_header, /*!< in: segment header */
185
ulint hint, /*!< in: hint of which page would be desirable */
186
byte direction, /*!< in: if the new page is needed because
191
/* out: the allocated page offset
192
FIL_NULL if no page could be allocated */
193
fseg_header_t* seg_header, /* in: segment header */
194
ulint hint, /* in: hint of which page would be desirable */
195
byte direction, /* in: if the new page is needed because
187
196
of an index page split, and records are
188
197
inserted there in order, into which
189
198
direction they go alphabetically: FSP_DOWN,
190
199
FSP_UP, FSP_NO_DIR */
191
mtr_t* mtr); /*!< in: mtr handle */
192
/**********************************************************************//**
200
mtr_t* mtr); /* in: mtr handle */
201
/**************************************************************************
193
202
Allocates a single free page from a segment. This function implements
194
203
the intelligent allocation strategy which tries to minimize file space
196
@return allocated page offset, FIL_NULL if no page could be allocated */
199
207
fseg_alloc_free_page_general(
200
208
/*=========================*/
201
fseg_header_t* seg_header,/*!< in: segment header */
202
ulint hint, /*!< in: hint of which page would be desirable */
203
byte direction,/*!< in: if the new page is needed because
209
/* out: allocated page offset, FIL_NULL if no
210
page could be allocated */
211
fseg_header_t* seg_header,/* in: segment header */
212
ulint hint, /* in: hint of which page would be desirable */
213
byte direction,/* in: if the new page is needed because
204
214
of an index page split, and records are
205
215
inserted there in order, into which
206
216
direction they go alphabetically: FSP_DOWN,
207
217
FSP_UP, FSP_NO_DIR */
208
ibool has_done_reservation, /*!< in: TRUE if the caller has
218
ibool has_done_reservation, /* in: TRUE if the caller has
209
219
already done the reservation for the page
210
220
with fsp_reserve_free_extents, then there
211
221
is no need to do the check for this individual
213
mtr_t* mtr); /*!< in: mtr handle */
214
/**********************************************************************//**
223
mtr_t* mtr); /* in: mtr handle */
224
/**************************************************************************
215
225
Reserves free pages from a tablespace. All mini-transactions which may
216
226
use several pages from the tablespace should call this function beforehand
217
227
and reserve enough free extents so that they certainly will be able
235
245
function we would liberally reserve several 64 page extents for every page
236
246
split or merge in a B-tree. But we do not want to waste disk space if the table
237
247
only occupies < 32 pages. That is why we apply different rules in that special
238
case, just ensuring that there are 3 free pages available.
239
@return TRUE if we were able to make the reservation */
248
case, just ensuring that there are 3 free pages available. */
242
251
fsp_reserve_free_extents(
243
252
/*=====================*/
244
ulint* n_reserved,/*!< out: number of extents actually reserved; if we
253
/* out: TRUE if we were able to make the reservation */
254
ulint* n_reserved,/* out: number of extents actually reserved; if we
245
255
return TRUE and the tablespace size is < 64 pages,
246
256
then this can be 0, otherwise it is n_ext */
247
ulint space, /*!< in: space id */
248
ulint n_ext, /*!< in: number of extents to reserve */
249
ulint alloc_type,/*!< in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
250
mtr_t* mtr); /*!< in: mtr */
251
/**********************************************************************//**
257
ulint space, /* in: space id */
258
ulint n_ext, /* in: number of extents to reserve */
259
ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */
260
mtr_t* mtr); /* in: mtr */
261
/**************************************************************************
252
262
This function should be used to get information on how much we still
253
263
will be able to insert new data to the database without running out the
254
264
tablespace. Only free extents are taken into account and we also subtract
255
the safety margin required by the above function fsp_reserve_free_extents.
256
@return available space in kB */
265
the safety margin required by the above function fsp_reserve_free_extents. */
259
268
fsp_get_available_space_in_free_extents(
260
269
/*====================================*/
261
ulint space); /*!< in: space id */
262
/**********************************************************************//**
270
/* out: available space in kB */
271
ulint space); /* in: space id */
272
/**************************************************************************
263
273
Frees a single page of a segment. */
268
fseg_header_t* seg_header, /*!< in: segment header */
269
ulint space, /*!< in: space id */
270
ulint page, /*!< in: page offset */
271
mtr_t* mtr); /*!< in: mtr handle */
272
/**********************************************************************//**
278
fseg_header_t* seg_header, /* in: segment header */
279
ulint space, /* in: space id */
280
ulint page, /* in: page offset */
281
mtr_t* mtr); /* in: mtr handle */
282
/***********************************************************************
283
Frees a segment. The freeing is performed in several mini-transactions,
284
so that there is no danger of bufferfixing too many buffer pages. */
289
ulint space, /* in: space id */
290
ulint zip_size,/* in: compressed page size in bytes
291
or 0 for uncompressed pages */
292
ulint page_no,/* in: page number where the segment header is
294
ulint offset);/* in: byte offset of the segment header on that
296
/**************************************************************************
273
297
Frees part of a segment. This function can be used to free a segment
274
298
by repeatedly calling this function in different mini-transactions.
275
299
Doing the freeing in a single mini-transaction might result in
276
too big a mini-transaction.
277
@return TRUE if freeing completed */
300
too big a mini-transaction. */
282
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
305
/* out: TRUE if freeing completed */
306
fseg_header_t* header, /* in, own: segment header; NOTE: if the header
283
307
resides on the first page of the frag list
284
308
of the segment, this pointer becomes obsolete
285
309
after the last freeing step */
286
mtr_t* mtr); /*!< in: mtr */
287
/**********************************************************************//**
310
mtr_t* mtr); /* in: mtr */
311
/**************************************************************************
288
312
Frees part of a segment. Differs from fseg_free_step because this function
289
leaves the header page unfreed.
290
@return TRUE if freeing completed, except the header page */
313
leaves the header page unfreed. */
293
316
fseg_free_step_not_header(
294
317
/*======================*/
295
fseg_header_t* header, /*!< in: segment header which must reside on
318
/* out: TRUE if freeing completed, except the
320
fseg_header_t* header, /* in: segment header which must reside on
296
321
the first fragment page of the segment */
297
mtr_t* mtr); /*!< in: mtr */
298
/***********************************************************************//**
299
Checks if a page address is an extent descriptor page address.
300
@return TRUE if a descriptor page */
322
mtr_t* mtr); /* in: mtr */
323
/***************************************************************************
324
Checks if a page address is an extent descriptor page address. */
305
ulint zip_size,/*!< in: compressed page size in bytes;
329
/* out: TRUE if a descriptor page */
330
ulint zip_size,/* in: compressed page size in bytes;
306
331
0 for uncompressed pages */
307
ulint page_no);/*!< in: page number */
308
/***********************************************************//**
309
Parses a redo log record of a file page init.
310
@return end of log record or NULL */
332
ulint page_no);/* in: page number */
333
/***************************************************************
334
Parses a redo log record of a file page init. */
313
337
fsp_parse_init_file_page(
314
338
/*=====================*/
315
byte* ptr, /*!< in: buffer */
316
byte* end_ptr, /*!< in: buffer end */
317
buf_block_t* block); /*!< in: block or NULL */
318
/*******************************************************************//**
319
Validates the file space system and its segments.
320
@return TRUE if ok */
339
/* out: end of log record or NULL */
340
byte* ptr, /* in: buffer */
341
byte* end_ptr, /* in: buffer end */
342
buf_block_t* block); /* in: block or NULL */
343
/***********************************************************************
344
Validates the file space system and its segments. */
325
ulint space); /*!< in: space id */
326
/*******************************************************************//**
349
/* out: TRUE if ok */
350
ulint space); /* in: space id */
351
/***********************************************************************
327
352
Prints info of a file space. */
332
ulint space); /*!< in: space id */
334
/*******************************************************************//**
336
@return TRUE if ok */
357
ulint space); /* in: space id */
358
/***********************************************************************
359
Validates a segment. */
341
fseg_header_t* header, /*!< in: segment header */
342
mtr_t* mtr); /*!< in: mtr */
343
#endif /* UNIV_DEBUG */
364
/* out: TRUE if ok */
365
fseg_header_t* header, /* in: segment header */
366
mtr_t* mtr2); /* in: mtr */
344
367
#ifdef UNIV_BTR_PRINT
345
/*******************************************************************//**
368
/***********************************************************************
346
369
Writes info of a segment. */
351
fseg_header_t* header, /*!< in: segment header */
352
mtr_t* mtr); /*!< in: mtr */
374
fseg_header_t* header, /* in: segment header */
375
mtr_t* mtr); /* in: mtr */
353
376
#endif /* UNIV_BTR_PRINT */
378
/* Flags for fsp_reserve_free_extents */
379
#define FSP_NORMAL 1000000
380
#define FSP_UNDO 2000000
381
#define FSP_CLEANING 3000000
383
/* Number of pages described in a single descriptor page: currently each page
384
description takes less than 1 byte; a descriptor page is repeated every
385
this many file pages */
386
/* #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE */
387
/* This has been replaced with either UNIV_PAGE_SIZE or page_zip->size. */
389
/* The space low address page map */
390
/*--------------------------------------*/
391
/* The following two pages are repeated
392
every XDES_DESCRIBED_PER_PAGE pages in
394
#define FSP_XDES_OFFSET 0 /* extent descriptor */
395
#define FSP_IBUF_BITMAP_OFFSET 1 /* insert buffer bitmap */
396
/* The ibuf bitmap pages are the ones whose
397
page number is the number above plus a
398
multiple of XDES_DESCRIBED_PER_PAGE */
400
#define FSP_FIRST_INODE_PAGE_NO 2 /* in every tablespace */
401
/* The following pages exist
402
in the system tablespace (space 0). */
403
#define FSP_IBUF_HEADER_PAGE_NO 3 /* in tablespace 0 */
404
#define FSP_IBUF_TREE_ROOT_PAGE_NO 4 /* in tablespace 0 */
405
/* The ibuf tree root page number in
406
tablespace 0; its fseg inode is on the page
407
number FSP_FIRST_INODE_PAGE_NO */
408
#define FSP_TRX_SYS_PAGE_NO 5 /* in tablespace 0 */
409
#define FSP_FIRST_RSEG_PAGE_NO 6 /* in tablespace 0 */
410
#define FSP_DICT_HDR_PAGE_NO 7 /* in tablespace 0 */
411
/*--------------------------------------*/
355
413
#ifndef UNIV_NONINL
356
414
#include "fsp0fsp.ic"