641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
1 |
/*****************************************************************************
|
2 |
||
1819.5.221
by vasil
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6749 from MySQL InnoDB |
3 |
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
4 |
|
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.
|
|
8 |
||
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.
|
|
12 |
||
13 |
You should have received a copy of the GNU General Public License along with
|
|
1802.10.2
by Monty Taylor
Update all of the copyright headers to include the correct address. |
14 |
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
15 |
St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
16 |
|
17 |
*****************************************************************************/
|
|
18 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
19 |
/******************************************************************//**
|
20 |
@file fsp/fsp0fsp.c
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
21 |
File space management
|
22 |
||
23 |
Created 11/29/1995 Heikki Tuuri
|
|
24 |
***********************************************************************/
|
|
25 |
||
26 |
#include "fsp0fsp.h" |
|
27 |
||
28 |
#ifdef UNIV_NONINL
|
|
29 |
#include "fsp0fsp.ic" |
|
30 |
#endif
|
|
31 |
||
32 |
#include "buf0buf.h" |
|
33 |
#include "fil0fil.h" |
|
34 |
#include "mtr0log.h" |
|
35 |
#include "ut0byte.h" |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
36 |
#include "page0page.h" |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
37 |
#include "page0zip.h" |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
38 |
#ifdef UNIV_HOTBACKUP
|
39 |
# include "fut0lst.h"
|
|
40 |
#else /* UNIV_HOTBACKUP */ |
|
41 |
# include "sync0sync.h"
|
|
42 |
# include "fut0fut.h"
|
|
43 |
# include "srv0srv.h"
|
|
44 |
# include "ibuf0ibuf.h"
|
|
45 |
# include "btr0btr.h"
|
|
46 |
# include "btr0sea.h"
|
|
47 |
# include "dict0boot.h"
|
|
48 |
# include "log0log.h"
|
|
49 |
#endif /* UNIV_HOTBACKUP */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
50 |
#include "dict0mem.h" |
51 |
||
52 |
||
53 |
#define FSP_HEADER_OFFSET FIL_PAGE_DATA /* Offset of the space header |
|
54 |
within a file page */
|
|
55 |
||
56 |
/* The data structures in files are defined just as byte strings in C */
|
|
57 |
typedef byte fsp_header_t; |
|
58 |
typedef byte xdes_t; |
|
59 |
||
60 |
/* SPACE HEADER
|
|
61 |
============
|
|
62 |
||
63 |
File space header data structure: this data structure is contained in the
|
|
64 |
first page of a space. The space for this header is reserved in every extent
|
|
65 |
descriptor page, but used only in the first. */
|
|
66 |
||
67 |
/*-------------------------------------*/
|
|
68 |
#define FSP_SPACE_ID 0 /* space id */ |
|
69 |
#define FSP_NOT_USED 4 /* this field contained a value up to |
|
70 |
which we know that the modifications
|
|
71 |
in the database have been flushed to
|
|
72 |
the file space; not used now */
|
|
73 |
#define FSP_SIZE 8 /* Current size of the space in |
|
74 |
pages */
|
|
75 |
#define FSP_FREE_LIMIT 12 /* Minimum page number for which the |
|
76 |
free list has not been initialized:
|
|
77 |
the pages >= this limit are, by
|
|
78 |
definition, free; note that in a
|
|
79 |
single-table tablespace where size
|
|
80 |
< 64 pages, this number is 64, i.e.,
|
|
81 |
we have initialized the space
|
|
82 |
about the first extent, but have not
|
|
83 |
physically allocted those pages to the
|
|
84 |
file */
|
|
85 |
#define FSP_SPACE_FLAGS 16 /* table->flags & ~DICT_TF_COMPACT */ |
|
86 |
#define FSP_FRAG_N_USED 20 /* number of used pages in the |
|
87 |
FSP_FREE_FRAG list */
|
|
88 |
#define FSP_FREE 24 /* list of free extents */ |
|
89 |
#define FSP_FREE_FRAG (24 + FLST_BASE_NODE_SIZE)
|
|
90 |
/* list of partially free extents not
|
|
91 |
belonging to any segment */
|
|
92 |
#define FSP_FULL_FRAG (24 + 2 * FLST_BASE_NODE_SIZE)
|
|
93 |
/* list of full extents not belonging
|
|
94 |
to any segment */
|
|
95 |
#define FSP_SEG_ID (24 + 3 * FLST_BASE_NODE_SIZE)
|
|
96 |
/* 8 bytes which give the first unused
|
|
97 |
segment id */
|
|
98 |
#define FSP_SEG_INODES_FULL (32 + 3 * FLST_BASE_NODE_SIZE)
|
|
99 |
/* list of pages containing segment
|
|
100 |
headers, where all the segment inode
|
|
101 |
slots are reserved */
|
|
102 |
#define FSP_SEG_INODES_FREE (32 + 4 * FLST_BASE_NODE_SIZE)
|
|
103 |
/* list of pages containing segment
|
|
104 |
headers, where not all the segment
|
|
105 |
header slots are reserved */
|
|
106 |
/*-------------------------------------*/
|
|
107 |
/* File space header size */
|
|
108 |
#define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE)
|
|
109 |
||
110 |
#define FSP_FREE_ADD 4 /* this many free extents are added |
|
111 |
to the free list from above
|
|
112 |
FSP_FREE_LIMIT at a time */
|
|
113 |
||
114 |
/* FILE SEGMENT INODE
|
|
115 |
==================
|
|
116 |
||
117 |
Segment inode which is created for each segment in a tablespace. NOTE: in
|
|
118 |
purge we assume that a segment having only one currently used page can be
|
|
119 |
freed in a few steps, so that the freeing cannot fill the file buffer with
|
|
120 |
bufferfixed file pages. */
|
|
121 |
||
122 |
typedef byte fseg_inode_t; |
|
123 |
||
124 |
#define FSEG_INODE_PAGE_NODE FSEG_PAGE_DATA
|
|
125 |
/* the list node for linking
|
|
126 |
segment inode pages */
|
|
127 |
||
128 |
#define FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE)
|
|
129 |
/*-------------------------------------*/
|
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
130 |
#define FSEG_ID 0 /* 8 bytes of segment id: if this is 0, |
131 |
it means that the header is unused */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
132 |
#define FSEG_NOT_FULL_N_USED 8
|
133 |
/* number of used segment pages in
|
|
134 |
the FSEG_NOT_FULL list */
|
|
135 |
#define FSEG_FREE 12
|
|
136 |
/* list of free extents of this
|
|
137 |
segment */
|
|
138 |
#define FSEG_NOT_FULL (12 + FLST_BASE_NODE_SIZE)
|
|
139 |
/* list of partially free extents */
|
|
140 |
#define FSEG_FULL (12 + 2 * FLST_BASE_NODE_SIZE)
|
|
141 |
/* list of full extents */
|
|
142 |
#define FSEG_MAGIC_N (12 + 3 * FLST_BASE_NODE_SIZE)
|
|
143 |
/* magic number used in debugging */
|
|
144 |
#define FSEG_FRAG_ARR (16 + 3 * FLST_BASE_NODE_SIZE)
|
|
145 |
/* array of individual pages
|
|
146 |
belonging to this segment in fsp
|
|
147 |
fragment extent lists */
|
|
148 |
#define FSEG_FRAG_ARR_N_SLOTS (FSP_EXTENT_SIZE / 2)
|
|
149 |
/* number of slots in the array for
|
|
150 |
the fragment pages */
|
|
151 |
#define FSEG_FRAG_SLOT_SIZE 4 /* a fragment page slot contains its |
|
152 |
page number within space, FIL_NULL
|
|
153 |
means that the slot is not in use */
|
|
154 |
/*-------------------------------------*/
|
|
155 |
#define FSEG_INODE_SIZE \
|
|
156 |
(16 + 3 * FLST_BASE_NODE_SIZE \
|
|
157 |
+ FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
|
|
158 |
||
159 |
#define FSP_SEG_INODES_PER_PAGE(zip_size) \
|
|
160 |
(((zip_size ? zip_size : UNIV_PAGE_SIZE) \
|
|
161 |
- FSEG_ARR_OFFSET - 10) / FSEG_INODE_SIZE)
|
|
162 |
/* Number of segment inodes which fit on a
|
|
163 |
single page */
|
|
164 |
||
165 |
#define FSEG_MAGIC_N_VALUE 97937874
|
|
166 |
||
167 |
#define FSEG_FILLFACTOR 8 /* If this value is x, then if |
|
168 |
the number of unused but reserved
|
|
169 |
pages in a segment is less than
|
|
170 |
reserved pages * 1/x, and there are
|
|
171 |
at least FSEG_FRAG_LIMIT used pages,
|
|
172 |
then we allow a new empty extent to
|
|
173 |
be added to the segment in
|
|
174 |
fseg_alloc_free_page. Otherwise, we
|
|
175 |
use unused pages of the segment. */
|
|
176 |
||
177 |
#define FSEG_FRAG_LIMIT FSEG_FRAG_ARR_N_SLOTS
|
|
178 |
/* If the segment has >= this many
|
|
179 |
used pages, it may be expanded by
|
|
180 |
allocating extents to the segment;
|
|
181 |
until that only individual fragment
|
|
182 |
pages are allocated from the space */
|
|
183 |
||
184 |
#define FSEG_FREE_LIST_LIMIT 40 /* If the reserved size of a segment |
|
185 |
is at least this many extents, we
|
|
186 |
allow extents to be put to the free
|
|
187 |
list of the extent: at most
|
|
188 |
FSEG_FREE_LIST_MAX_LEN many */
|
|
189 |
#define FSEG_FREE_LIST_MAX_LEN 4
|
|
190 |
||
191 |
||
192 |
/* EXTENT DESCRIPTOR
|
|
193 |
=================
|
|
194 |
||
195 |
File extent descriptor data structure: contains bits to tell which pages in
|
|
196 |
the extent are free and which contain old tuple version to clean. */
|
|
197 |
||
198 |
/*-------------------------------------*/
|
|
199 |
#define XDES_ID 0 /* The identifier of the segment |
|
200 |
to which this extent belongs */
|
|
201 |
#define XDES_FLST_NODE 8 /* The list node data structure |
|
202 |
for the descriptors */
|
|
203 |
#define XDES_STATE (FLST_NODE_SIZE + 8)
|
|
204 |
/* contains state information
|
|
205 |
of the extent */
|
|
206 |
#define XDES_BITMAP (FLST_NODE_SIZE + 12)
|
|
207 |
/* Descriptor bitmap of the pages
|
|
208 |
in the extent */
|
|
209 |
/*-------------------------------------*/
|
|
210 |
||
211 |
#define XDES_BITS_PER_PAGE 2 /* How many bits are there per page */ |
|
212 |
#define XDES_FREE_BIT 0 /* Index of the bit which tells if |
|
213 |
the page is free */
|
|
214 |
#define XDES_CLEAN_BIT 1 /* NOTE: currently not used! |
|
215 |
Index of the bit which tells if
|
|
216 |
there are old versions of tuples
|
|
217 |
on the page */
|
|
218 |
/* States of a descriptor */
|
|
219 |
#define XDES_FREE 1 /* extent is in free list of space */ |
|
220 |
#define XDES_FREE_FRAG 2 /* extent is in free fragment list of |
|
221 |
space */
|
|
222 |
#define XDES_FULL_FRAG 3 /* extent is in full fragment list of |
|
223 |
space */
|
|
224 |
#define XDES_FSEG 4 /* extent belongs to a segment */ |
|
225 |
||
226 |
/* File extent data structure size in bytes. */
|
|
227 |
#define XDES_SIZE \
|
|
228 |
(XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE))
|
|
229 |
||
230 |
/* Offset of the descriptor array on a descriptor page */
|
|
231 |
#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
|
|
232 |
||
1819.5.73
by stewart at flamingspork
[patch 073/129] Merge patch for revision 1871 from InnoDB SVN: |
233 |
#ifndef UNIV_HOTBACKUP
|
1819.5.67
by stewart at flamingspork
[patch 067/129] Merge patch for revision 1862 from InnoDB SVN: |
234 |
/* Flag to indicate if we have printed the tablespace full error. */
|
235 |
static ibool fsp_tbs_full_error_printed = FALSE; |
|
236 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
237 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
238 |
Returns an extent to the free list of a space. */
|
239 |
static
|
|
240 |
void
|
|
241 |
fsp_free_extent( |
|
242 |
/*============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
243 |
ulint space, /*!< in: space id */ |
244 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
245 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
246 |
ulint page, /*!< in: page offset in the extent */ |
247 |
mtr_t* mtr); /*!< in: mtr */ |
|
248 |
/**********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
249 |
Frees an extent of a segment to the space free list. */
|
250 |
static
|
|
251 |
void
|
|
252 |
fseg_free_extent( |
|
253 |
/*=============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
254 |
fseg_inode_t* seg_inode, /*!< in: segment inode */ |
255 |
ulint space, /*!< in: space id */ |
|
256 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
257 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
258 |
ulint page, /*!< in: page offset in the extent */ |
259 |
mtr_t* mtr); /*!< in: mtr handle */ |
|
260 |
/**********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
261 |
Calculates the number of pages reserved by a segment, and how
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
262 |
many pages are currently used.
|
263 |
@return number of reserved pages */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
264 |
static
|
265 |
ulint
|
|
266 |
fseg_n_reserved_pages_low( |
|
267 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
268 |
fseg_inode_t* header, /*!< in: segment inode */ |
269 |
ulint* used, /*!< out: number of pages used (not |
|
270 |
more than reserved) */
|
|
271 |
mtr_t* mtr); /*!< in: mtr handle */ |
|
272 |
/********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
273 |
Marks a page used. The page must reside within the extents of the given
|
274 |
segment. */
|
|
275 |
static
|
|
276 |
void
|
|
277 |
fseg_mark_page_used( |
|
278 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
279 |
fseg_inode_t* seg_inode,/*!< in: segment inode */ |
280 |
ulint space, /*!< in: space id */ |
|
281 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
282 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
283 |
ulint page, /*!< in: page offset */ |
284 |
mtr_t* mtr); /*!< in: mtr */ |
|
285 |
/**********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
286 |
Returns the first extent descriptor for a segment. We think of the extent
|
287 |
lists of the segment catenated in the order FSEG_FULL -> FSEG_NOT_FULL
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
288 |
-> FSEG_FREE.
|
289 |
@return the first extent descriptor, or NULL if none */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
290 |
static
|
291 |
xdes_t* |
|
292 |
fseg_get_first_extent( |
|
293 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
294 |
fseg_inode_t* inode, /*!< in: segment inode */ |
295 |
ulint space, /*!< in: space id */ |
|
296 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
297 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
298 |
mtr_t* mtr); /*!< in: mtr */ |
299 |
/**********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
300 |
Puts new extents to the free list if
|
301 |
there are free extents above the free limit. If an extent happens
|
|
302 |
to contain an extent descriptor page, the extent is put to
|
|
303 |
the FSP_FREE_FRAG list with the page marked as used. */
|
|
304 |
static
|
|
305 |
void
|
|
306 |
fsp_fill_free_list( |
|
307 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
308 |
ibool init_space, /*!< in: TRUE if this is a single-table |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
309 |
tablespace and we are only initing
|
310 |
the tablespace's first extent
|
|
311 |
descriptor page and ibuf bitmap page;
|
|
312 |
then we do not allocate more extents */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
313 |
ulint space, /*!< in: space */ |
314 |
fsp_header_t* header, /*!< in: space header */ |
|
315 |
mtr_t* mtr); /*!< in: mtr */ |
|
316 |
/**********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
317 |
Allocates a single free page from a segment. This function implements
|
318 |
the intelligent allocation strategy which tries to minimize file space
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
319 |
fragmentation.
|
320 |
@return the allocated page number, FIL_NULL if no page could be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
321 |
static
|
322 |
ulint
|
|
323 |
fseg_alloc_free_page_low( |
|
324 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
325 |
ulint space, /*!< in: space */ |
326 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
327 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
328 |
fseg_inode_t* seg_inode, /*!< in: segment inode */ |
329 |
ulint hint, /*!< in: hint of which page would be desirable */ |
|
330 |
byte direction, /*!< in: if the new page is needed because |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
331 |
of an index page split, and records are
|
332 |
inserted there in order, into which
|
|
333 |
direction they go alphabetically: FSP_DOWN,
|
|
334 |
FSP_UP, FSP_NO_DIR */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
335 |
mtr_t* mtr); /*!< in: mtr handle */ |
336 |
#endif /* !UNIV_HOTBACKUP */ |
|
337 |
||
338 |
/**********************************************************************//**
|
|
339 |
Reads the file space size stored in the header page.
|
|
340 |
@return tablespace size stored in the space header */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
341 |
UNIV_INTERN
|
342 |
ulint
|
|
343 |
fsp_get_size_low( |
|
344 |
/*=============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
345 |
page_t* page) /*!< in: header page (page 0 in the tablespace) */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
346 |
{
|
347 |
return(mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SIZE)); |
|
348 |
}
|
|
349 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
350 |
#ifndef UNIV_HOTBACKUP
|
351 |
/**********************************************************************//**
|
|
352 |
Gets a pointer to the space header and x-locks its page.
|
|
353 |
@return pointer to the space header, page x-locked */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
354 |
UNIV_INLINE
|
355 |
fsp_header_t* |
|
356 |
fsp_get_space_header( |
|
357 |
/*=================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
358 |
ulint id, /*!< in: space id */ |
359 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
360 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
361 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
362 |
{
|
363 |
buf_block_t* block; |
|
364 |
fsp_header_t* header; |
|
365 |
||
366 |
ut_ad(ut_is_2pow(zip_size)); |
|
367 |
ut_ad(zip_size <= UNIV_PAGE_SIZE); |
|
368 |
ut_ad(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE); |
|
369 |
ut_ad(id || !zip_size); |
|
370 |
||
371 |
block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr); |
|
372 |
header = FSP_HEADER_OFFSET + buf_block_get_frame(block); |
|
373 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
374 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
375 |
ut_ad(id == mach_read_from_4(FSP_SPACE_ID + header)); |
376 |
ut_ad(zip_size == dict_table_flags_to_zip_size( |
|
377 |
mach_read_from_4(FSP_SPACE_FLAGS + header))); |
|
378 |
return(header); |
|
379 |
}
|
|
380 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
381 |
/**********************************************************************//**
|
382 |
Gets a descriptor bit of a page.
|
|
383 |
@return TRUE if free */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
384 |
UNIV_INLINE
|
385 |
ibool
|
|
386 |
xdes_get_bit( |
|
387 |
/*=========*/
|
|
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
388 |
const xdes_t* descr, /*!< in: descriptor */ |
389 |
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */ |
|
390 |
ulint offset, /*!< in: page offset within extent: |
|
391 |
0 ... FSP_EXTENT_SIZE - 1 */
|
|
392 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
393 |
{
|
394 |
ulint index; |
|
395 |
ulint byte_index; |
|
396 |
ulint bit_index; |
|
397 |
||
398 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
399 |
ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT)); |
|
400 |
ut_ad(offset < FSP_EXTENT_SIZE); |
|
401 |
||
402 |
index = bit + XDES_BITS_PER_PAGE * offset; |
|
403 |
||
404 |
byte_index = index / 8; |
|
405 |
bit_index = index % 8; |
|
406 |
||
407 |
return(ut_bit_get_nth(mtr_read_ulint(descr + XDES_BITMAP + byte_index, |
|
408 |
MLOG_1BYTE, mtr), |
|
409 |
bit_index)); |
|
410 |
}
|
|
411 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
412 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
413 |
Sets a descriptor bit of a page. */
|
414 |
UNIV_INLINE
|
|
415 |
void
|
|
416 |
xdes_set_bit( |
|
417 |
/*=========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
418 |
xdes_t* descr, /*!< in: descriptor */ |
419 |
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */ |
|
420 |
ulint offset, /*!< in: page offset within extent: |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
421 |
0 ... FSP_EXTENT_SIZE - 1 */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
422 |
ibool val, /*!< in: bit value */ |
423 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
424 |
{
|
425 |
ulint index; |
|
426 |
ulint byte_index; |
|
427 |
ulint bit_index; |
|
428 |
ulint descr_byte; |
|
429 |
||
430 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
431 |
ut_ad((bit == XDES_FREE_BIT) || (bit == XDES_CLEAN_BIT)); |
|
432 |
ut_ad(offset < FSP_EXTENT_SIZE); |
|
433 |
||
434 |
index = bit + XDES_BITS_PER_PAGE * offset; |
|
435 |
||
436 |
byte_index = index / 8; |
|
437 |
bit_index = index % 8; |
|
438 |
||
439 |
descr_byte = mtr_read_ulint(descr + XDES_BITMAP + byte_index, |
|
440 |
MLOG_1BYTE, mtr); |
|
441 |
descr_byte = ut_bit_set_nth(descr_byte, bit_index, val); |
|
442 |
||
443 |
mlog_write_ulint(descr + XDES_BITMAP + byte_index, descr_byte, |
|
444 |
MLOG_1BYTE, mtr); |
|
445 |
}
|
|
446 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
447 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
448 |
Looks for a descriptor bit having the desired value. Starts from hint
|
449 |
and scans upward; at the end of the extent the search is wrapped to
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
450 |
the start of the extent.
|
451 |
@return bit index of the bit, ULINT_UNDEFINED if not found */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
452 |
UNIV_INLINE
|
453 |
ulint
|
|
454 |
xdes_find_bit( |
|
455 |
/*==========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
456 |
xdes_t* descr, /*!< in: descriptor */ |
457 |
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */ |
|
458 |
ibool val, /*!< in: desired bit value */ |
|
459 |
ulint hint, /*!< in: hint of which bit position would be desirable */ |
|
460 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
461 |
{
|
462 |
ulint i; |
|
463 |
||
464 |
ut_ad(descr && mtr); |
|
465 |
ut_ad(val <= TRUE); |
|
466 |
ut_ad(hint < FSP_EXTENT_SIZE); |
|
467 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
468 |
for (i = hint; i < FSP_EXTENT_SIZE; i++) { |
|
469 |
if (val == xdes_get_bit(descr, bit, i, mtr)) { |
|
470 |
||
471 |
return(i); |
|
472 |
}
|
|
473 |
}
|
|
474 |
||
475 |
for (i = 0; i < hint; i++) { |
|
476 |
if (val == xdes_get_bit(descr, bit, i, mtr)) { |
|
477 |
||
478 |
return(i); |
|
479 |
}
|
|
480 |
}
|
|
481 |
||
482 |
return(ULINT_UNDEFINED); |
|
483 |
}
|
|
484 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
485 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
486 |
Looks for a descriptor bit having the desired value. Scans the extent in
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
487 |
a direction opposite to xdes_find_bit.
|
488 |
@return bit index of the bit, ULINT_UNDEFINED if not found */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
489 |
UNIV_INLINE
|
490 |
ulint
|
|
491 |
xdes_find_bit_downward( |
|
492 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
493 |
xdes_t* descr, /*!< in: descriptor */ |
494 |
ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */ |
|
495 |
ibool val, /*!< in: desired bit value */ |
|
496 |
ulint hint, /*!< in: hint of which bit position would be desirable */ |
|
497 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
498 |
{
|
499 |
ulint i; |
|
500 |
||
501 |
ut_ad(descr && mtr); |
|
502 |
ut_ad(val <= TRUE); |
|
503 |
ut_ad(hint < FSP_EXTENT_SIZE); |
|
504 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
505 |
for (i = hint + 1; i > 0; i--) { |
|
506 |
if (val == xdes_get_bit(descr, bit, i - 1, mtr)) { |
|
507 |
||
508 |
return(i - 1); |
|
509 |
}
|
|
510 |
}
|
|
511 |
||
512 |
for (i = FSP_EXTENT_SIZE - 1; i > hint; i--) { |
|
513 |
if (val == xdes_get_bit(descr, bit, i, mtr)) { |
|
514 |
||
515 |
return(i); |
|
516 |
}
|
|
517 |
}
|
|
518 |
||
519 |
return(ULINT_UNDEFINED); |
|
520 |
}
|
|
521 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
522 |
/**********************************************************************//**
|
523 |
Returns the number of used pages in a descriptor.
|
|
524 |
@return number of pages used */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
525 |
UNIV_INLINE
|
526 |
ulint
|
|
527 |
xdes_get_n_used( |
|
528 |
/*============*/
|
|
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
529 |
const xdes_t* descr, /*!< in: descriptor */ |
530 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
531 |
{
|
532 |
ulint i; |
|
533 |
ulint count = 0; |
|
534 |
||
535 |
ut_ad(descr && mtr); |
|
536 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
537 |
for (i = 0; i < FSP_EXTENT_SIZE; i++) { |
|
538 |
if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) { |
|
539 |
count++; |
|
540 |
}
|
|
541 |
}
|
|
542 |
||
543 |
return(count); |
|
544 |
}
|
|
545 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
546 |
/**********************************************************************//**
|
547 |
Returns true if extent contains no used pages.
|
|
548 |
@return TRUE if totally free */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
549 |
UNIV_INLINE
|
550 |
ibool
|
|
551 |
xdes_is_free( |
|
552 |
/*=========*/
|
|
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
553 |
const xdes_t* descr, /*!< in: descriptor */ |
554 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
555 |
{
|
556 |
if (0 == xdes_get_n_used(descr, mtr)) { |
|
557 |
||
558 |
return(TRUE); |
|
559 |
}
|
|
560 |
||
561 |
return(FALSE); |
|
562 |
}
|
|
563 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
564 |
/**********************************************************************//**
|
565 |
Returns true if extent contains no free pages.
|
|
566 |
@return TRUE if full */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
567 |
UNIV_INLINE
|
568 |
ibool
|
|
569 |
xdes_is_full( |
|
570 |
/*=========*/
|
|
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
571 |
const xdes_t* descr, /*!< in: descriptor */ |
572 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
573 |
{
|
574 |
if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) { |
|
575 |
||
576 |
return(TRUE); |
|
577 |
}
|
|
578 |
||
579 |
return(FALSE); |
|
580 |
}
|
|
581 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
582 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
583 |
Sets the state of an xdes. */
|
584 |
UNIV_INLINE
|
|
585 |
void
|
|
586 |
xdes_set_state( |
|
587 |
/*===========*/
|
|
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
588 |
xdes_t* descr, /*!< in/out: descriptor */ |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
589 |
ulint state, /*!< in: state to set */ |
590 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
591 |
{
|
592 |
ut_ad(descr && mtr); |
|
593 |
ut_ad(state >= XDES_FREE); |
|
594 |
ut_ad(state <= XDES_FSEG); |
|
595 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
596 |
||
597 |
mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr); |
|
598 |
}
|
|
599 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
600 |
/**********************************************************************//**
|
601 |
Gets the state of an xdes.
|
|
602 |
@return state */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
603 |
UNIV_INLINE
|
604 |
ulint
|
|
605 |
xdes_get_state( |
|
606 |
/*===========*/
|
|
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
607 |
const xdes_t* descr, /*!< in: descriptor */ |
608 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
609 |
{
|
610 |
ulint state; |
|
611 |
||
612 |
ut_ad(descr && mtr); |
|
613 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
614 |
||
615 |
state = mtr_read_ulint(descr + XDES_STATE, MLOG_4BYTES, mtr); |
|
616 |
ut_ad(state - 1 < XDES_FSEG); |
|
617 |
return(state); |
|
618 |
}
|
|
619 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
620 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
621 |
Inits an extent descriptor to the free and clean state. */
|
622 |
UNIV_INLINE
|
|
623 |
void
|
|
624 |
xdes_init( |
|
625 |
/*======*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
626 |
xdes_t* descr, /*!< in: descriptor */ |
627 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
628 |
{
|
629 |
ulint i; |
|
630 |
||
631 |
ut_ad(descr && mtr); |
|
632 |
ut_ad(mtr_memo_contains_page(mtr, descr, MTR_MEMO_PAGE_X_FIX)); |
|
633 |
ut_ad((XDES_SIZE - XDES_BITMAP) % 4 == 0); |
|
634 |
||
635 |
for (i = XDES_BITMAP; i < XDES_SIZE; i += 4) { |
|
636 |
mlog_write_ulint(descr + i, 0xFFFFFFFFUL, MLOG_4BYTES, mtr); |
|
637 |
}
|
|
638 |
||
639 |
xdes_set_state(descr, XDES_FREE, mtr); |
|
640 |
}
|
|
641 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
642 |
/********************************************************************//**
|
643 |
Calculates the page where the descriptor of a page resides.
|
|
644 |
@return descriptor page offset */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
645 |
UNIV_INLINE
|
646 |
ulint
|
|
647 |
xdes_calc_descriptor_page( |
|
648 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
649 |
ulint zip_size, /*!< in: compressed page size in bytes; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
650 |
0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
651 |
ulint offset) /*!< in: page offset */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
652 |
{
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
653 |
#ifndef DOXYGEN /* Doxygen gets confused of these */ |
654 |
# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
655 |
+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
656 |
# error
|
657 |
# endif
|
|
658 |
# if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
659 |
+ (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
660 |
# error
|
661 |
# endif
|
|
662 |
#endif /* !DOXYGEN */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
663 |
ut_ad(ut_is_2pow(zip_size)); |
664 |
||
665 |
if (!zip_size) { |
|
666 |
return(ut_2pow_round(offset, UNIV_PAGE_SIZE)); |
|
667 |
} else { |
|
668 |
ut_ad(zip_size > XDES_ARR_OFFSET |
|
669 |
+ (zip_size / FSP_EXTENT_SIZE) * XDES_SIZE); |
|
670 |
return(ut_2pow_round(offset, zip_size)); |
|
671 |
}
|
|
672 |
}
|
|
673 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
674 |
/********************************************************************//**
|
675 |
Calculates the descriptor index within a descriptor page.
|
|
676 |
@return descriptor index */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
677 |
UNIV_INLINE
|
678 |
ulint
|
|
679 |
xdes_calc_descriptor_index( |
|
680 |
/*=======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
681 |
ulint zip_size, /*!< in: compressed page size in bytes; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
682 |
0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
683 |
ulint offset) /*!< in: page offset */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
684 |
{
|
685 |
ut_ad(ut_is_2pow(zip_size)); |
|
686 |
||
687 |
if (!zip_size) { |
|
688 |
return(ut_2pow_remainder(offset, UNIV_PAGE_SIZE) |
|
689 |
/ FSP_EXTENT_SIZE); |
|
690 |
} else { |
|
691 |
return(ut_2pow_remainder(offset, zip_size) / FSP_EXTENT_SIZE); |
|
692 |
}
|
|
693 |
}
|
|
694 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
695 |
/********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
696 |
Gets pointer to a the extent descriptor of a page. The page where the extent
|
697 |
descriptor resides is x-locked. If the page offset is equal to the free limit
|
|
698 |
of the space, adds new extents from above the free limit to the space free
|
|
699 |
list, if not free limit == space size. This adding is necessary to make the
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
700 |
descriptor defined, as they are uninitialized above the free limit.
|
701 |
@return pointer to the extent descriptor, NULL if the page does not
|
|
702 |
exist in the space or if the offset exceeds the free limit */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
703 |
UNIV_INLINE
|
704 |
xdes_t* |
|
705 |
xdes_get_descriptor_with_space_hdr( |
|
706 |
/*===============================*/
|
|
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
707 |
fsp_header_t* sp_header,/*!< in/out: space header, x-latched */ |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
708 |
ulint space, /*!< in: space id */ |
709 |
ulint offset, /*!< in: page offset; |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
710 |
if equal to the free limit,
|
711 |
we try to add new extents to
|
|
712 |
the space free list */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
713 |
mtr_t* mtr) /*!< in: mtr handle */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
714 |
{
|
715 |
ulint limit; |
|
716 |
ulint size; |
|
717 |
ulint zip_size; |
|
718 |
ulint descr_page_no; |
|
719 |
page_t* descr_page; |
|
720 |
||
721 |
ut_ad(mtr); |
|
722 |
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL), |
|
723 |
MTR_MEMO_X_LOCK)); |
|
724 |
ut_ad(mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_S_FIX) |
|
725 |
|| mtr_memo_contains_page(mtr, sp_header, MTR_MEMO_PAGE_X_FIX)); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
726 |
ut_ad(page_offset(sp_header) == FSP_HEADER_OFFSET); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
727 |
/* Read free limit and space size */
|
728 |
limit = mach_read_from_4(sp_header + FSP_FREE_LIMIT); |
|
729 |
size = mach_read_from_4(sp_header + FSP_SIZE); |
|
730 |
zip_size = dict_table_flags_to_zip_size( |
|
731 |
mach_read_from_4(sp_header + FSP_SPACE_FLAGS)); |
|
732 |
||
733 |
/* If offset is >= size or > limit, return NULL */
|
|
734 |
||
735 |
if ((offset >= size) || (offset > limit)) { |
|
736 |
||
737 |
return(NULL); |
|
738 |
}
|
|
739 |
||
740 |
/* If offset is == limit, fill free list of the space. */
|
|
741 |
||
742 |
if (offset == limit) { |
|
743 |
fsp_fill_free_list(FALSE, space, sp_header, mtr); |
|
744 |
}
|
|
745 |
||
746 |
descr_page_no = xdes_calc_descriptor_page(zip_size, offset); |
|
747 |
||
748 |
if (descr_page_no == 0) { |
|
749 |
/* It is on the space header page */
|
|
750 |
||
751 |
descr_page = page_align(sp_header); |
|
752 |
} else { |
|
753 |
buf_block_t* block; |
|
754 |
||
755 |
block = buf_page_get(space, zip_size, descr_page_no, |
|
756 |
RW_X_LATCH, mtr); |
|
757 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
758 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
759 |
descr_page = buf_block_get_frame(block); |
760 |
}
|
|
761 |
||
762 |
return(descr_page + XDES_ARR_OFFSET |
|
763 |
+ XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset)); |
|
764 |
}
|
|
765 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
766 |
/********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
767 |
Gets pointer to a the extent descriptor of a page. The page where the
|
768 |
extent descriptor resides is x-locked. If the page offset is equal to
|
|
769 |
the free limit of the space, adds new extents from above the free limit
|
|
770 |
to the space free list, if not free limit == space size. This adding
|
|
771 |
is necessary to make the descriptor defined, as they are uninitialized
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
772 |
above the free limit.
|
773 |
@return pointer to the extent descriptor, NULL if the page does not
|
|
774 |
exist in the space or if the offset exceeds the free limit */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
775 |
static
|
776 |
xdes_t* |
|
777 |
xdes_get_descriptor( |
|
778 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
779 |
ulint space, /*!< in: space id */ |
780 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
781 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
782 |
ulint offset, /*!< in: page offset; if equal to the free limit, |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
783 |
we try to add new extents to the space free list */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
784 |
mtr_t* mtr) /*!< in: mtr handle */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
785 |
{
|
786 |
buf_block_t* block; |
|
787 |
fsp_header_t* sp_header; |
|
788 |
||
789 |
block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr); |
|
790 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
791 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
792 |
sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block); |
793 |
return(xdes_get_descriptor_with_space_hdr(sp_header, space, offset, |
|
794 |
mtr)); |
|
795 |
}
|
|
796 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
797 |
/********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
798 |
Gets pointer to a the extent descriptor if the file address
|
799 |
of the descriptor list node is known. The page where the
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
800 |
extent descriptor resides is x-locked.
|
801 |
@return pointer to the extent descriptor */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
802 |
UNIV_INLINE
|
803 |
xdes_t* |
|
804 |
xdes_lst_get_descriptor( |
|
805 |
/*====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
806 |
ulint space, /*!< in: space id */ |
807 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
808 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
809 |
fil_addr_t lst_node,/*!< in: file address of the list node |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
810 |
contained in the descriptor */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
811 |
mtr_t* mtr) /*!< in: mtr handle */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
812 |
{
|
813 |
xdes_t* descr; |
|
814 |
||
815 |
ut_ad(mtr); |
|
816 |
ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL), |
|
817 |
MTR_MEMO_X_LOCK)); |
|
818 |
descr = fut_get_ptr(space, zip_size, lst_node, RW_X_LATCH, mtr) |
|
819 |
- XDES_FLST_NODE; |
|
820 |
||
821 |
return(descr); |
|
822 |
}
|
|
823 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
824 |
/********************************************************************//**
|
825 |
Returns page offset of the first page in extent described by a descriptor.
|
|
826 |
@return offset of the first page in extent */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
827 |
UNIV_INLINE
|
828 |
ulint
|
|
829 |
xdes_get_offset( |
|
830 |
/*============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
831 |
xdes_t* descr) /*!< in: extent descriptor */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
832 |
{
|
833 |
ut_ad(descr); |
|
834 |
||
835 |
return(page_get_page_no(page_align(descr)) |
|
836 |
+ ((page_offset(descr) - XDES_ARR_OFFSET) / XDES_SIZE) |
|
837 |
* FSP_EXTENT_SIZE); |
|
838 |
}
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
839 |
#endif /* !UNIV_HOTBACKUP */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
840 |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
841 |
/***********************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
842 |
Inits a file page whose prior contents should be ignored. */
|
843 |
static
|
|
844 |
void
|
|
845 |
fsp_init_file_page_low( |
|
846 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
847 |
buf_block_t* block) /*!< in: pointer to a page */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
848 |
{
|
849 |
page_t* page = buf_block_get_frame(block); |
|
850 |
page_zip_des_t* page_zip= buf_block_get_page_zip(block); |
|
851 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
852 |
#ifndef UNIV_HOTBACKUP
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
853 |
block->check_index_page_at_flush = FALSE; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
854 |
#endif /* !UNIV_HOTBACKUP */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
855 |
|
856 |
if (UNIV_LIKELY_NULL(page_zip)) { |
|
857 |
memset(page, 0, UNIV_PAGE_SIZE); |
|
858 |
memset(page_zip->data, 0, page_zip_get_size(page_zip)); |
|
859 |
mach_write_to_4(page + FIL_PAGE_OFFSET, |
|
860 |
buf_block_get_page_no(block)); |
|
861 |
mach_write_to_4(page |
|
862 |
+ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, |
|
863 |
buf_block_get_space(block)); |
|
864 |
memcpy(page_zip->data + FIL_PAGE_OFFSET, |
|
865 |
page + FIL_PAGE_OFFSET, 4); |
|
866 |
memcpy(page_zip->data + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, |
|
867 |
page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, 4); |
|
868 |
return; |
|
869 |
}
|
|
870 |
||
1819.7.93
by Vasil Dimov
Merge Revision revid:vasil.dimov@oracle.com-20100504135709-j4vbpx8o4asagm0u from MySQL InnoDB |
871 |
memset(page, 0, UNIV_PAGE_SIZE); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
872 |
mach_write_to_4(page + FIL_PAGE_OFFSET, buf_block_get_page_no(block)); |
873 |
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, |
|
874 |
buf_block_get_space(block)); |
|
875 |
}
|
|
876 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
877 |
#ifndef UNIV_HOTBACKUP
|
878 |
/***********************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
879 |
Inits a file page whose prior contents should be ignored. */
|
880 |
static
|
|
881 |
void
|
|
882 |
fsp_init_file_page( |
|
883 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
884 |
buf_block_t* block, /*!< in: pointer to a page */ |
885 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
886 |
{
|
887 |
fsp_init_file_page_low(block); |
|
888 |
||
889 |
mlog_write_initial_log_record(buf_block_get_frame(block), |
|
890 |
MLOG_INIT_FILE_PAGE, mtr); |
|
891 |
}
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
892 |
#endif /* !UNIV_HOTBACKUP */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
893 |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
894 |
/***********************************************************//**
|
895 |
Parses a redo log record of a file page init.
|
|
896 |
@return end of log record or NULL */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
897 |
UNIV_INTERN
|
898 |
byte* |
|
899 |
fsp_parse_init_file_page( |
|
900 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
901 |
byte* ptr, /*!< in: buffer */ |
902 |
byte* end_ptr __attribute__((unused)), /*!< in: buffer end */ |
|
903 |
buf_block_t* block) /*!< in: block or NULL */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
904 |
{
|
905 |
ut_ad(ptr && end_ptr); |
|
906 |
||
907 |
if (block) { |
|
908 |
fsp_init_file_page_low(block); |
|
909 |
}
|
|
910 |
||
911 |
return(ptr); |
|
912 |
}
|
|
913 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
914 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
915 |
Initializes the fsp system. */
|
916 |
UNIV_INTERN
|
|
917 |
void
|
|
918 |
fsp_init(void) |
|
919 |
/*==========*/
|
|
920 |
{
|
|
921 |
/* Does nothing at the moment */
|
|
922 |
}
|
|
923 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
924 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
925 |
Writes the space id and compressed page size to a tablespace header.
|
926 |
This function is used past the buffer pool when we in fil0fil.c create
|
|
927 |
a new single-table tablespace. */
|
|
928 |
UNIV_INTERN
|
|
929 |
void
|
|
930 |
fsp_header_init_fields( |
|
931 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
932 |
page_t* page, /*!< in/out: first page in the space */ |
933 |
ulint space_id, /*!< in: space id */ |
|
934 |
ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS): |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
935 |
0, or table->flags if newer than COMPACT */
|
936 |
{
|
|
937 |
/* The tablespace flags (FSP_SPACE_FLAGS) should be 0 for
|
|
938 |
ROW_FORMAT=COMPACT (table->flags == DICT_TF_COMPACT) and
|
|
939 |
ROW_FORMAT=REDUNDANT (table->flags == 0). For any other
|
|
940 |
format, the tablespace flags should equal table->flags. */
|
|
941 |
ut_a(flags != DICT_TF_COMPACT); |
|
942 |
||
943 |
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page, |
|
944 |
space_id); |
|
945 |
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page, |
|
946 |
flags); |
|
947 |
}
|
|
948 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
949 |
#ifndef UNIV_HOTBACKUP
|
950 |
/**********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
951 |
Initializes the space header of a new created space and creates also the
|
952 |
insert buffer tree root if space == 0. */
|
|
953 |
UNIV_INTERN
|
|
954 |
void
|
|
955 |
fsp_header_init( |
|
956 |
/*============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
957 |
ulint space, /*!< in: space id */ |
958 |
ulint size, /*!< in: current size in blocks */ |
|
959 |
mtr_t* mtr) /*!< in: mini-transaction handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
960 |
{
|
961 |
fsp_header_t* header; |
|
962 |
buf_block_t* block; |
|
963 |
page_t* page; |
|
964 |
ulint flags; |
|
965 |
ulint zip_size; |
|
966 |
||
967 |
ut_ad(mtr); |
|
968 |
||
969 |
mtr_x_lock(fil_space_get_latch(space, &flags), mtr); |
|
970 |
||
971 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
972 |
block = buf_page_create(space, 0, zip_size, mtr); |
|
973 |
buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr); |
|
974 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
975 |
||
976 |
/* The prior contents of the file page should be ignored */
|
|
977 |
||
978 |
fsp_init_file_page(block, mtr); |
|
979 |
page = buf_block_get_frame(block); |
|
980 |
||
981 |
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_FSP_HDR, |
|
982 |
MLOG_2BYTES, mtr); |
|
983 |
||
984 |
header = FSP_HEADER_OFFSET + page; |
|
985 |
||
986 |
mlog_write_ulint(header + FSP_SPACE_ID, space, MLOG_4BYTES, mtr); |
|
987 |
mlog_write_ulint(header + FSP_NOT_USED, 0, MLOG_4BYTES, mtr); |
|
988 |
||
989 |
mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr); |
|
990 |
mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr); |
|
991 |
mlog_write_ulint(header + FSP_SPACE_FLAGS, flags, |
|
992 |
MLOG_4BYTES, mtr); |
|
993 |
mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr); |
|
994 |
||
995 |
flst_init(header + FSP_FREE, mtr); |
|
996 |
flst_init(header + FSP_FREE_FRAG, mtr); |
|
997 |
flst_init(header + FSP_FULL_FRAG, mtr); |
|
998 |
flst_init(header + FSP_SEG_INODES_FULL, mtr); |
|
999 |
flst_init(header + FSP_SEG_INODES_FREE, mtr); |
|
1000 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
1001 |
mlog_write_ull(header + FSP_SEG_ID, 1, mtr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1002 |
if (space == 0) { |
1003 |
fsp_fill_free_list(FALSE, space, header, mtr); |
|
1004 |
btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
1005 |
0, 0, DICT_IBUF_ID_MIN + space, |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1006 |
dict_ind_redundant, mtr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1007 |
} else { |
1008 |
fsp_fill_free_list(TRUE, space, header, mtr); |
|
1009 |
}
|
|
1010 |
}
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1011 |
#endif /* !UNIV_HOTBACKUP */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1012 |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1013 |
/**********************************************************************//**
|
1014 |
Reads the space id from the first page of a tablespace.
|
|
1015 |
@return space id, ULINT UNDEFINED if error */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1016 |
UNIV_INTERN
|
1017 |
ulint
|
|
1018 |
fsp_header_get_space_id( |
|
1019 |
/*====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1020 |
const page_t* page) /*!< in: first page of a tablespace */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1021 |
{
|
1022 |
ulint fsp_id; |
|
1023 |
ulint id; |
|
1024 |
||
1025 |
fsp_id = mach_read_from_4(FSP_HEADER_OFFSET + page + FSP_SPACE_ID); |
|
1026 |
||
1027 |
id = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); |
|
1028 |
||
1029 |
if (id != fsp_id) { |
|
1030 |
fprintf(stderr, |
|
1031 |
"InnoDB: Error: space id in fsp header %lu,"
|
|
1032 |
" but in the page header %lu\n", |
|
1033 |
(ulong) fsp_id, (ulong) id); |
|
1034 |
||
1035 |
return(ULINT_UNDEFINED); |
|
1036 |
}
|
|
1037 |
||
1038 |
return(id); |
|
1039 |
}
|
|
1040 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1041 |
/**********************************************************************//**
|
1042 |
Reads the space flags from the first page of a tablespace.
|
|
1043 |
@return flags */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1044 |
UNIV_INTERN
|
1045 |
ulint
|
|
1046 |
fsp_header_get_flags( |
|
1047 |
/*=================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1048 |
const page_t* page) /*!< in: first page of a tablespace */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1049 |
{
|
1050 |
ut_ad(!page_offset(page)); |
|
1051 |
||
1052 |
return(mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page)); |
|
1053 |
}
|
|
1054 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1055 |
/**********************************************************************//**
|
1056 |
Reads the compressed page size from the first page of a tablespace.
|
|
1057 |
@return compressed page size in bytes, or 0 if uncompressed */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1058 |
UNIV_INTERN
|
1059 |
ulint
|
|
1060 |
fsp_header_get_zip_size( |
|
1061 |
/*====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1062 |
const page_t* page) /*!< in: first page of a tablespace */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1063 |
{
|
1064 |
ulint flags = fsp_header_get_flags(page); |
|
1065 |
||
1066 |
return(dict_table_flags_to_zip_size(flags)); |
|
1067 |
}
|
|
1068 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1069 |
#ifndef UNIV_HOTBACKUP
|
1070 |
/**********************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1071 |
Increases the space size field of a space. */
|
1072 |
UNIV_INTERN
|
|
1073 |
void
|
|
1074 |
fsp_header_inc_size( |
|
1075 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1076 |
ulint space, /*!< in: space id */ |
1077 |
ulint size_inc,/*!< in: size increment in pages */ |
|
1078 |
mtr_t* mtr) /*!< in: mini-transaction handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1079 |
{
|
1080 |
fsp_header_t* header; |
|
1081 |
ulint size; |
|
1082 |
ulint flags; |
|
1083 |
||
1084 |
ut_ad(mtr); |
|
1085 |
||
1086 |
mtr_x_lock(fil_space_get_latch(space, &flags), mtr); |
|
1087 |
||
1088 |
header = fsp_get_space_header(space, |
|
1089 |
dict_table_flags_to_zip_size(flags), |
|
1090 |
mtr); |
|
1091 |
||
1092 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
1093 |
||
1094 |
mlog_write_ulint(header + FSP_SIZE, size + size_inc, MLOG_4BYTES, |
|
1095 |
mtr); |
|
1096 |
}
|
|
1097 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1098 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1099 |
Gets the current free limit of the system tablespace. The free limit
|
1100 |
means the place of the first page which has never been put to the the
|
|
1101 |
free list for allocation. The space above that address is initialized
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1102 |
to zero. Sets also the global variable log_fsp_current_free_limit.
|
1103 |
@return free limit in megabytes */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1104 |
UNIV_INTERN
|
1105 |
ulint
|
|
1106 |
fsp_header_get_free_limit(void) |
|
1107 |
/*===========================*/
|
|
1108 |
{
|
|
1109 |
fsp_header_t* header; |
|
1110 |
ulint limit; |
|
1111 |
mtr_t mtr; |
|
1112 |
||
1113 |
mtr_start(&mtr); |
|
1114 |
||
1115 |
mtr_x_lock(fil_space_get_latch(0, NULL), &mtr); |
|
1116 |
||
1117 |
header = fsp_get_space_header(0, 0, &mtr); |
|
1118 |
||
1119 |
limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, &mtr); |
|
1120 |
||
1121 |
limit /= ((1024 * 1024) / UNIV_PAGE_SIZE); |
|
1122 |
||
1123 |
log_fsp_current_free_limit_set_and_checkpoint(limit); |
|
1124 |
||
1125 |
mtr_commit(&mtr); |
|
1126 |
||
1127 |
return(limit); |
|
1128 |
}
|
|
1129 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1130 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1131 |
Gets the size of the system tablespace from the tablespace header. If
|
1132 |
we do not have an auto-extending data file, this should be equal to
|
|
1133 |
the size of the data files. If there is an auto-extending data file,
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1134 |
this can be smaller.
|
1135 |
@return size in pages */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1136 |
UNIV_INTERN
|
1137 |
ulint
|
|
1138 |
fsp_header_get_tablespace_size(void) |
|
1139 |
/*================================*/
|
|
1140 |
{
|
|
1141 |
fsp_header_t* header; |
|
1142 |
ulint size; |
|
1143 |
mtr_t mtr; |
|
1144 |
||
1145 |
mtr_start(&mtr); |
|
1146 |
||
1147 |
mtr_x_lock(fil_space_get_latch(0, NULL), &mtr); |
|
1148 |
||
1149 |
header = fsp_get_space_header(0, 0, &mtr); |
|
1150 |
||
1151 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr); |
|
1152 |
||
1153 |
mtr_commit(&mtr); |
|
1154 |
||
1155 |
return(size); |
|
1156 |
}
|
|
1157 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1158 |
/***********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1159 |
Tries to extend a single-table tablespace so that a page would fit in the
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1160 |
data file.
|
1161 |
@return TRUE if success */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1162 |
static
|
1163 |
ibool
|
|
1164 |
fsp_try_extend_data_file_with_pages( |
|
1165 |
/*================================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1166 |
ulint space, /*!< in: space */ |
1167 |
ulint page_no, /*!< in: page number */ |
|
1168 |
fsp_header_t* header, /*!< in: space header */ |
|
1169 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1170 |
{
|
1171 |
ibool success; |
|
1172 |
ulint actual_size; |
|
1173 |
ulint size; |
|
1174 |
||
1175 |
ut_a(space != 0); |
|
1176 |
||
1177 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
1178 |
||
1179 |
ut_a(page_no >= size); |
|
1180 |
||
1181 |
success = fil_extend_space_to_desired_size(&actual_size, space, |
|
1182 |
page_no + 1); |
|
1183 |
/* actual_size now has the space size in pages; it may be less than
|
|
1184 |
we wanted if we ran out of disk space */
|
|
1185 |
||
1186 |
mlog_write_ulint(header + FSP_SIZE, actual_size, MLOG_4BYTES, mtr); |
|
1187 |
||
1188 |
return(success); |
|
1189 |
}
|
|
1190 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1191 |
/***********************************************************************//**
|
1192 |
Tries to extend the last data file of a tablespace if it is auto-extending.
|
|
1193 |
@return FALSE if not auto-extending */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1194 |
static
|
1195 |
ibool
|
|
1196 |
fsp_try_extend_data_file( |
|
1197 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1198 |
ulint* actual_increase,/*!< out: actual increase in pages, where |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1199 |
we measure the tablespace size from
|
1200 |
what the header field says; it may be
|
|
1201 |
the actual file size rounded down to
|
|
1202 |
megabyte */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1203 |
ulint space, /*!< in: space */ |
1204 |
fsp_header_t* header, /*!< in: space header */ |
|
1205 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1206 |
{
|
1207 |
ulint size; |
|
1208 |
ulint zip_size; |
|
1209 |
ulint new_size; |
|
1210 |
ulint old_size; |
|
1211 |
ulint size_increase; |
|
1212 |
ulint actual_size; |
|
1213 |
ibool success; |
|
1214 |
||
1215 |
*actual_increase = 0; |
|
1216 |
||
1217 |
if (space == 0 && !srv_auto_extend_last_data_file) { |
|
1218 |
||
1819.5.67
by stewart at flamingspork
[patch 067/129] Merge patch for revision 1862 from InnoDB SVN: |
1219 |
/* We print the error message only once to avoid
|
1220 |
spamming the error log. Note that we don't need
|
|
1221 |
to reset the flag to FALSE as dealing with this
|
|
1222 |
error requires server restart. */
|
|
1223 |
if (fsp_tbs_full_error_printed == FALSE) { |
|
1224 |
fprintf(stderr, |
|
1225 |
"InnoDB: Error: Data file(s) ran"
|
|
1226 |
" out of space.\n" |
|
1227 |
"Please add another data file or"
|
|
1228 |
" use \'autoextend\' for the last" |
|
1229 |
" data file.\n"); |
|
1230 |
fsp_tbs_full_error_printed = TRUE; |
|
1231 |
}
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1232 |
return(FALSE); |
1233 |
}
|
|
1234 |
||
1235 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
1236 |
zip_size = dict_table_flags_to_zip_size( |
|
1237 |
mach_read_from_4(header + FSP_SPACE_FLAGS)); |
|
1238 |
||
1239 |
old_size = size; |
|
1240 |
||
1241 |
if (space == 0) { |
|
1242 |
if (!srv_last_file_size_max) { |
|
1243 |
size_increase = SRV_AUTO_EXTEND_INCREMENT; |
|
1244 |
} else { |
|
1245 |
if (srv_last_file_size_max |
|
1246 |
< srv_data_file_sizes[srv_n_data_files - 1]) { |
|
1247 |
||
1248 |
fprintf(stderr, |
|
1249 |
"InnoDB: Error: Last data file size"
|
|
1250 |
" is %lu, max size allowed %lu\n", |
|
1251 |
(ulong) srv_data_file_sizes[ |
|
1252 |
srv_n_data_files - 1], |
|
1253 |
(ulong) srv_last_file_size_max); |
|
1254 |
}
|
|
1255 |
||
1256 |
size_increase = srv_last_file_size_max |
|
1257 |
- srv_data_file_sizes[srv_n_data_files - 1]; |
|
1258 |
if (size_increase > SRV_AUTO_EXTEND_INCREMENT) { |
|
1259 |
size_increase = SRV_AUTO_EXTEND_INCREMENT; |
|
1260 |
}
|
|
1261 |
}
|
|
1262 |
} else { |
|
1263 |
/* We extend single-table tablespaces first one extent
|
|
1264 |
at a time, but for bigger tablespaces more. It is not
|
|
1265 |
enough to extend always by one extent, because some
|
|
1266 |
extents are frag page extents. */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1267 |
ulint extent_size; /*!< one megabyte, in pages */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1268 |
|
1269 |
if (!zip_size) { |
|
1270 |
extent_size = FSP_EXTENT_SIZE; |
|
1271 |
} else { |
|
1272 |
extent_size = FSP_EXTENT_SIZE |
|
1273 |
* UNIV_PAGE_SIZE / zip_size; |
|
1274 |
}
|
|
1275 |
||
1276 |
if (size < extent_size) { |
|
1277 |
/* Let us first extend the file to extent_size */
|
|
1278 |
success = fsp_try_extend_data_file_with_pages( |
|
1279 |
space, extent_size - 1, header, mtr); |
|
1280 |
if (!success) { |
|
1281 |
new_size = mtr_read_ulint(header + FSP_SIZE, |
|
1282 |
MLOG_4BYTES, mtr); |
|
1283 |
||
1284 |
*actual_increase = new_size - old_size; |
|
1285 |
||
1286 |
return(FALSE); |
|
1287 |
}
|
|
1288 |
||
1289 |
size = extent_size; |
|
1290 |
}
|
|
1291 |
||
1292 |
if (size < 32 * extent_size) { |
|
1293 |
size_increase = extent_size; |
|
1294 |
} else { |
|
1295 |
/* Below in fsp_fill_free_list() we assume
|
|
1296 |
that we add at most FSP_FREE_ADD extents at
|
|
1297 |
a time */
|
|
1298 |
size_increase = FSP_FREE_ADD * extent_size; |
|
1299 |
}
|
|
1300 |
}
|
|
1301 |
||
1302 |
if (size_increase == 0) { |
|
1303 |
||
1304 |
return(TRUE); |
|
1305 |
}
|
|
1306 |
||
1307 |
success = fil_extend_space_to_desired_size(&actual_size, space, |
|
1308 |
size + size_increase); |
|
1309 |
/* We ignore any fragments of a full megabyte when storing the size
|
|
1310 |
to the space header */
|
|
1311 |
||
1312 |
if (!zip_size) { |
|
1313 |
new_size = ut_calc_align_down(actual_size, |
|
1314 |
(1024 * 1024) / UNIV_PAGE_SIZE); |
|
1315 |
} else { |
|
1316 |
new_size = ut_calc_align_down(actual_size, |
|
1317 |
(1024 * 1024) / zip_size); |
|
1318 |
}
|
|
1319 |
mlog_write_ulint(header + FSP_SIZE, new_size, MLOG_4BYTES, mtr); |
|
1320 |
||
1321 |
*actual_increase = new_size - old_size; |
|
1322 |
||
1323 |
return(TRUE); |
|
1324 |
}
|
|
1325 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1326 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1327 |
Puts new extents to the free list if there are free extents above the free
|
1328 |
limit. If an extent happens to contain an extent descriptor page, the extent
|
|
1329 |
is put to the FSP_FREE_FRAG list with the page marked as used. */
|
|
1330 |
static
|
|
1331 |
void
|
|
1332 |
fsp_fill_free_list( |
|
1333 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1334 |
ibool init_space, /*!< in: TRUE if this is a single-table |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1335 |
tablespace and we are only initing
|
1336 |
the tablespace's first extent
|
|
1337 |
descriptor page and ibuf bitmap page;
|
|
1338 |
then we do not allocate more extents */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1339 |
ulint space, /*!< in: space */ |
1819.5.150
by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6277 from MySQL InnoDB |
1340 |
fsp_header_t* header, /*!< in/out: space header */ |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1341 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1342 |
{
|
1343 |
ulint limit; |
|
1344 |
ulint size; |
|
1345 |
ulint zip_size; |
|
1346 |
xdes_t* descr; |
|
1347 |
ulint count = 0; |
|
1348 |
ulint frag_n_used; |
|
1349 |
ulint actual_increase; |
|
1350 |
ulint i; |
|
1351 |
mtr_t ibuf_mtr; |
|
1352 |
||
1353 |
ut_ad(header && mtr); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1354 |
ut_ad(page_offset(header) == FSP_HEADER_OFFSET); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1355 |
|
1356 |
/* Check if we can fill free list from above the free list limit */
|
|
1357 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
1358 |
limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr); |
|
1359 |
||
1360 |
zip_size = dict_table_flags_to_zip_size( |
|
1361 |
mach_read_from_4(FSP_SPACE_FLAGS + header)); |
|
1362 |
ut_a(ut_is_2pow(zip_size)); |
|
1363 |
ut_a(zip_size <= UNIV_PAGE_SIZE); |
|
1364 |
ut_a(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE); |
|
1365 |
||
1366 |
if (space == 0 && srv_auto_extend_last_data_file |
|
1367 |
&& size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) { |
|
1368 |
||
1369 |
/* Try to increase the last data file size */
|
|
1370 |
fsp_try_extend_data_file(&actual_increase, space, header, mtr); |
|
1371 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
1372 |
}
|
|
1373 |
||
1374 |
if (space != 0 && !init_space |
|
1375 |
&& size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) { |
|
1376 |
||
1377 |
/* Try to increase the .ibd file size */
|
|
1378 |
fsp_try_extend_data_file(&actual_increase, space, header, mtr); |
|
1379 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
1380 |
}
|
|
1381 |
||
1382 |
i = limit; |
|
1383 |
||
1384 |
while ((init_space && i < 1) |
|
1385 |
|| ((i + FSP_EXTENT_SIZE <= size) && (count < FSP_FREE_ADD))) { |
|
1386 |
||
1387 |
ibool init_xdes; |
|
1388 |
if (zip_size) { |
|
1389 |
init_xdes = ut_2pow_remainder(i, zip_size) == 0; |
|
1390 |
} else { |
|
1391 |
init_xdes = ut_2pow_remainder(i, UNIV_PAGE_SIZE) == 0; |
|
1392 |
}
|
|
1393 |
||
1394 |
mlog_write_ulint(header + FSP_FREE_LIMIT, i + FSP_EXTENT_SIZE, |
|
1395 |
MLOG_4BYTES, mtr); |
|
1396 |
||
1397 |
/* Update the free limit info in the log system and make
|
|
1398 |
a checkpoint */
|
|
1399 |
if (space == 0) { |
|
1400 |
ut_a(!zip_size); |
|
1401 |
log_fsp_current_free_limit_set_and_checkpoint( |
|
1402 |
(i + FSP_EXTENT_SIZE) |
|
1403 |
/ ((1024 * 1024) / UNIV_PAGE_SIZE)); |
|
1404 |
}
|
|
1405 |
||
1406 |
if (UNIV_UNLIKELY(init_xdes)) { |
|
1407 |
||
1408 |
buf_block_t* block; |
|
1409 |
||
1410 |
/* We are going to initialize a new descriptor page
|
|
1411 |
and a new ibuf bitmap page: the prior contents of the
|
|
1412 |
pages should be ignored. */
|
|
1413 |
||
1414 |
if (i > 0) { |
|
1415 |
block = buf_page_create( |
|
1416 |
space, i, zip_size, mtr); |
|
1417 |
buf_page_get(space, zip_size, i, |
|
1418 |
RW_X_LATCH, mtr); |
|
1419 |
buf_block_dbg_add_level(block, |
|
1420 |
SYNC_FSP_PAGE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1421 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1422 |
fsp_init_file_page(block, mtr); |
1423 |
mlog_write_ulint(buf_block_get_frame(block) |
|
1424 |
+ FIL_PAGE_TYPE, |
|
1425 |
FIL_PAGE_TYPE_XDES, |
|
1426 |
MLOG_2BYTES, mtr); |
|
1427 |
}
|
|
1428 |
||
1429 |
/* Initialize the ibuf bitmap page in a separate
|
|
1430 |
mini-transaction because it is low in the latching
|
|
1431 |
order, and we must be able to release its latch
|
|
1432 |
before returning from the fsp routine */
|
|
1433 |
||
1434 |
mtr_start(&ibuf_mtr); |
|
1435 |
||
1436 |
block = buf_page_create(space, |
|
1437 |
i + FSP_IBUF_BITMAP_OFFSET, |
|
1438 |
zip_size, &ibuf_mtr); |
|
1439 |
buf_page_get(space, zip_size, |
|
1440 |
i + FSP_IBUF_BITMAP_OFFSET, |
|
1441 |
RW_X_LATCH, &ibuf_mtr); |
|
1442 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1443 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1444 |
fsp_init_file_page(block, &ibuf_mtr); |
1445 |
||
1446 |
ibuf_bitmap_page_init(block, &ibuf_mtr); |
|
1447 |
||
1448 |
mtr_commit(&ibuf_mtr); |
|
1449 |
}
|
|
1450 |
||
1451 |
descr = xdes_get_descriptor_with_space_hdr(header, space, i, |
|
1452 |
mtr); |
|
1453 |
xdes_init(descr, mtr); |
|
1454 |
||
1455 |
#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
|
|
1456 |
# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
|
|
1457 |
#endif
|
|
1458 |
#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
|
|
1459 |
# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
|
|
1460 |
#endif
|
|
1461 |
||
1462 |
if (UNIV_UNLIKELY(init_xdes)) { |
|
1463 |
||
1464 |
/* The first page in the extent is a descriptor page
|
|
1465 |
and the second is an ibuf bitmap page: mark them
|
|
1466 |
used */
|
|
1467 |
||
1468 |
xdes_set_bit(descr, XDES_FREE_BIT, 0, FALSE, mtr); |
|
1469 |
xdes_set_bit(descr, XDES_FREE_BIT, |
|
1470 |
FSP_IBUF_BITMAP_OFFSET, FALSE, mtr); |
|
1471 |
xdes_set_state(descr, XDES_FREE_FRAG, mtr); |
|
1472 |
||
1473 |
flst_add_last(header + FSP_FREE_FRAG, |
|
1474 |
descr + XDES_FLST_NODE, mtr); |
|
1475 |
frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, |
|
1476 |
MLOG_4BYTES, mtr); |
|
1477 |
mlog_write_ulint(header + FSP_FRAG_N_USED, |
|
1478 |
frag_n_used + 2, MLOG_4BYTES, mtr); |
|
1479 |
} else { |
|
1480 |
flst_add_last(header + FSP_FREE, |
|
1481 |
descr + XDES_FLST_NODE, mtr); |
|
1482 |
count++; |
|
1483 |
}
|
|
1484 |
||
1485 |
i += FSP_EXTENT_SIZE; |
|
1486 |
}
|
|
1487 |
}
|
|
1488 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1489 |
/**********************************************************************//**
|
1490 |
Allocates a new free extent.
|
|
1491 |
@return extent descriptor, NULL if cannot be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1492 |
static
|
1493 |
xdes_t* |
|
1494 |
fsp_alloc_free_extent( |
|
1495 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1496 |
ulint space, /*!< in: space id */ |
1497 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1498 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1499 |
ulint hint, /*!< in: hint of which extent would be desirable: any |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1500 |
page offset in the extent goes; the hint must not
|
1501 |
be > FSP_FREE_LIMIT */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1502 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1503 |
{
|
1504 |
fsp_header_t* header; |
|
1505 |
fil_addr_t first; |
|
1506 |
xdes_t* descr; |
|
1507 |
||
1508 |
ut_ad(mtr); |
|
1509 |
||
1510 |
header = fsp_get_space_header(space, zip_size, mtr); |
|
1511 |
||
1512 |
descr = xdes_get_descriptor_with_space_hdr(header, space, hint, mtr); |
|
1513 |
||
1514 |
if (descr && (xdes_get_state(descr, mtr) == XDES_FREE)) { |
|
1515 |
/* Ok, we can take this extent */
|
|
1516 |
} else { |
|
1517 |
/* Take the first extent in the free list */
|
|
1518 |
first = flst_get_first(header + FSP_FREE, mtr); |
|
1519 |
||
1520 |
if (fil_addr_is_null(first)) { |
|
1521 |
fsp_fill_free_list(FALSE, space, header, mtr); |
|
1522 |
||
1523 |
first = flst_get_first(header + FSP_FREE, mtr); |
|
1524 |
}
|
|
1525 |
||
1526 |
if (fil_addr_is_null(first)) { |
|
1527 |
||
1528 |
return(NULL); /* No free extents left */ |
|
1529 |
}
|
|
1530 |
||
1531 |
descr = xdes_lst_get_descriptor(space, zip_size, first, mtr); |
|
1532 |
}
|
|
1533 |
||
1534 |
flst_remove(header + FSP_FREE, descr + XDES_FLST_NODE, mtr); |
|
1535 |
||
1536 |
return(descr); |
|
1537 |
}
|
|
1538 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1539 |
/**********************************************************************//**
|
1540 |
Allocates a single free page from a space. The page is marked as used.
|
|
1541 |
@return the page offset, FIL_NULL if no page could be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1542 |
static
|
1543 |
ulint
|
|
1544 |
fsp_alloc_free_page( |
|
1545 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1546 |
ulint space, /*!< in: space id */ |
1547 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1548 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1549 |
ulint hint, /*!< in: hint of which page would be desirable */ |
1550 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1551 |
{
|
1552 |
fsp_header_t* header; |
|
1553 |
fil_addr_t first; |
|
1554 |
xdes_t* descr; |
|
1555 |
buf_block_t* block; |
|
1556 |
ulint free; |
|
1557 |
ulint frag_n_used; |
|
1558 |
ulint page_no; |
|
1559 |
ulint space_size; |
|
1560 |
ibool success; |
|
1561 |
||
1562 |
ut_ad(mtr); |
|
1563 |
||
1564 |
header = fsp_get_space_header(space, zip_size, mtr); |
|
1565 |
||
1566 |
/* Get the hinted descriptor */
|
|
1567 |
descr = xdes_get_descriptor_with_space_hdr(header, space, hint, mtr); |
|
1568 |
||
1569 |
if (descr && (xdes_get_state(descr, mtr) == XDES_FREE_FRAG)) { |
|
1570 |
/* Ok, we can take this extent */
|
|
1571 |
} else { |
|
1572 |
/* Else take the first extent in free_frag list */
|
|
1573 |
first = flst_get_first(header + FSP_FREE_FRAG, mtr); |
|
1574 |
||
1575 |
if (fil_addr_is_null(first)) { |
|
1576 |
/* There are no partially full fragments: allocate
|
|
1577 |
a free extent and add it to the FREE_FRAG list. NOTE
|
|
1578 |
that the allocation may have as a side-effect that an
|
|
1579 |
extent containing a descriptor page is added to the
|
|
1580 |
FREE_FRAG list. But we will allocate our page from the
|
|
1581 |
the free extent anyway. */
|
|
1582 |
||
1583 |
descr = fsp_alloc_free_extent(space, zip_size, |
|
1584 |
hint, mtr); |
|
1585 |
||
1586 |
if (descr == NULL) { |
|
1587 |
/* No free space left */
|
|
1588 |
||
1589 |
return(FIL_NULL); |
|
1590 |
}
|
|
1591 |
||
1592 |
xdes_set_state(descr, XDES_FREE_FRAG, mtr); |
|
1593 |
flst_add_last(header + FSP_FREE_FRAG, |
|
1594 |
descr + XDES_FLST_NODE, mtr); |
|
1595 |
} else { |
|
1596 |
descr = xdes_lst_get_descriptor(space, zip_size, |
|
1597 |
first, mtr); |
|
1598 |
}
|
|
1599 |
||
1600 |
/* Reset the hint */
|
|
1601 |
hint = 0; |
|
1602 |
}
|
|
1603 |
||
1604 |
/* Now we have in descr an extent with at least one free page. Look
|
|
1605 |
for a free page in the extent. */
|
|
1606 |
||
1607 |
free = xdes_find_bit(descr, XDES_FREE_BIT, TRUE, |
|
1608 |
hint % FSP_EXTENT_SIZE, mtr); |
|
1609 |
if (free == ULINT_UNDEFINED) { |
|
1610 |
||
1611 |
ut_print_buf(stderr, ((byte*)descr) - 500, 1000); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1612 |
putc('\n', stderr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1613 |
|
1614 |
ut_error; |
|
1615 |
}
|
|
1616 |
||
1617 |
page_no = xdes_get_offset(descr) + free; |
|
1618 |
||
1619 |
space_size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
1620 |
||
1621 |
if (space_size <= page_no) { |
|
1622 |
/* It must be that we are extending a single-table tablespace
|
|
1623 |
whose size is still < 64 pages */
|
|
1624 |
||
1625 |
ut_a(space != 0); |
|
1626 |
if (page_no >= FSP_EXTENT_SIZE) { |
|
1627 |
fprintf(stderr, |
|
1628 |
"InnoDB: Error: trying to extend a"
|
|
1629 |
" single-table tablespace %lu\n" |
|
1630 |
"InnoDB: by single page(s) though the"
|
|
1631 |
" space size %lu. Page no %lu.\n", |
|
1632 |
(ulong) space, (ulong) space_size, |
|
1633 |
(ulong) page_no); |
|
1634 |
return(FIL_NULL); |
|
1635 |
}
|
|
1636 |
success = fsp_try_extend_data_file_with_pages(space, page_no, |
|
1637 |
header, mtr); |
|
1638 |
if (!success) { |
|
1639 |
/* No disk space left */
|
|
1640 |
return(FIL_NULL); |
|
1641 |
}
|
|
1642 |
}
|
|
1643 |
||
1644 |
xdes_set_bit(descr, XDES_FREE_BIT, free, FALSE, mtr); |
|
1645 |
||
1646 |
/* Update the FRAG_N_USED field */
|
|
1647 |
frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES, |
|
1648 |
mtr); |
|
1649 |
frag_n_used++; |
|
1650 |
mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used, MLOG_4BYTES, |
|
1651 |
mtr); |
|
1652 |
if (xdes_is_full(descr, mtr)) { |
|
1653 |
/* The fragment is full: move it to another list */
|
|
1654 |
flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE, |
|
1655 |
mtr); |
|
1656 |
xdes_set_state(descr, XDES_FULL_FRAG, mtr); |
|
1657 |
||
1658 |
flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE, |
|
1659 |
mtr); |
|
1660 |
mlog_write_ulint(header + FSP_FRAG_N_USED, |
|
1661 |
frag_n_used - FSP_EXTENT_SIZE, MLOG_4BYTES, |
|
1662 |
mtr); |
|
1663 |
}
|
|
1664 |
||
1665 |
/* Initialize the allocated page to the buffer pool, so that it can
|
|
1666 |
be obtained immediately with buf_page_get without need for a disk
|
|
1667 |
read. */
|
|
1668 |
||
1669 |
buf_page_create(space, page_no, zip_size, mtr); |
|
1670 |
||
1671 |
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr); |
|
1672 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
1673 |
||
1674 |
/* Prior contents of the page should be ignored */
|
|
1675 |
fsp_init_file_page(block, mtr); |
|
1676 |
||
1677 |
return(page_no); |
|
1678 |
}
|
|
1679 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1680 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1681 |
Frees a single page of a space. The page is marked as free and clean. */
|
1682 |
static
|
|
1683 |
void
|
|
1684 |
fsp_free_page( |
|
1685 |
/*==========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1686 |
ulint space, /*!< in: space id */ |
1687 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1688 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1689 |
ulint page, /*!< in: page offset */ |
1690 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1691 |
{
|
1692 |
fsp_header_t* header; |
|
1693 |
xdes_t* descr; |
|
1694 |
ulint state; |
|
1695 |
ulint frag_n_used; |
|
1696 |
||
1697 |
ut_ad(mtr); |
|
1698 |
||
1699 |
/* fprintf(stderr, "Freeing page %lu in space %lu\n", page, space); */
|
|
1700 |
||
1701 |
header = fsp_get_space_header(space, zip_size, mtr); |
|
1702 |
||
1703 |
descr = xdes_get_descriptor_with_space_hdr(header, space, page, mtr); |
|
1704 |
||
1705 |
state = xdes_get_state(descr, mtr); |
|
1706 |
||
1707 |
if (state != XDES_FREE_FRAG && state != XDES_FULL_FRAG) { |
|
1708 |
fprintf(stderr, |
|
1709 |
"InnoDB: Error: File space extent descriptor"
|
|
1710 |
" of page %lu has state %lu\n", |
|
1711 |
(ulong) page, |
|
1712 |
(ulong) state); |
|
1713 |
fputs("InnoDB: Dump of descriptor: ", stderr); |
|
1714 |
ut_print_buf(stderr, ((byte*)descr) - 50, 200); |
|
1715 |
putc('\n', stderr); |
|
1716 |
||
1717 |
if (state == XDES_FREE) { |
|
1718 |
/* We put here some fault tolerance: if the page
|
|
1719 |
is already free, return without doing anything! */
|
|
1720 |
||
1721 |
return; |
|
1722 |
}
|
|
1723 |
||
1724 |
ut_error; |
|
1725 |
}
|
|
1726 |
||
1727 |
if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) { |
|
1728 |
fprintf(stderr, |
|
1729 |
"InnoDB: Error: File space extent descriptor"
|
|
1730 |
" of page %lu says it is free\n" |
|
1731 |
"InnoDB: Dump of descriptor: ", (ulong) page); |
|
1732 |
ut_print_buf(stderr, ((byte*)descr) - 50, 200); |
|
1733 |
putc('\n', stderr); |
|
1734 |
||
1735 |
/* We put here some fault tolerance: if the page
|
|
1736 |
is already free, return without doing anything! */
|
|
1737 |
||
1738 |
return; |
|
1739 |
}
|
|
1740 |
||
1741 |
xdes_set_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr); |
|
1742 |
xdes_set_bit(descr, XDES_CLEAN_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr); |
|
1743 |
||
1744 |
frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES, |
|
1745 |
mtr); |
|
1746 |
if (state == XDES_FULL_FRAG) { |
|
1747 |
/* The fragment was full: move it to another list */
|
|
1748 |
flst_remove(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE, |
|
1749 |
mtr); |
|
1750 |
xdes_set_state(descr, XDES_FREE_FRAG, mtr); |
|
1751 |
flst_add_last(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE, |
|
1752 |
mtr); |
|
1753 |
mlog_write_ulint(header + FSP_FRAG_N_USED, |
|
1754 |
frag_n_used + FSP_EXTENT_SIZE - 1, |
|
1755 |
MLOG_4BYTES, mtr); |
|
1756 |
} else { |
|
1757 |
ut_a(frag_n_used > 0); |
|
1758 |
mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used - 1, |
|
1759 |
MLOG_4BYTES, mtr); |
|
1760 |
}
|
|
1761 |
||
1762 |
if (xdes_is_free(descr, mtr)) { |
|
1763 |
/* The extent has become free: move it to another list */
|
|
1764 |
flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE, |
|
1765 |
mtr); |
|
1766 |
fsp_free_extent(space, zip_size, page, mtr); |
|
1767 |
}
|
|
1768 |
}
|
|
1769 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1770 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1771 |
Returns an extent to the free list of a space. */
|
1772 |
static
|
|
1773 |
void
|
|
1774 |
fsp_free_extent( |
|
1775 |
/*============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1776 |
ulint space, /*!< in: space id */ |
1777 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1778 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1779 |
ulint page, /*!< in: page offset in the extent */ |
1780 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1781 |
{
|
1782 |
fsp_header_t* header; |
|
1783 |
xdes_t* descr; |
|
1784 |
||
1785 |
ut_ad(mtr); |
|
1786 |
||
1787 |
header = fsp_get_space_header(space, zip_size, mtr); |
|
1788 |
||
1789 |
descr = xdes_get_descriptor_with_space_hdr(header, space, page, mtr); |
|
1790 |
||
1791 |
if (xdes_get_state(descr, mtr) == XDES_FREE) { |
|
1792 |
||
1793 |
ut_print_buf(stderr, (byte*)descr - 500, 1000); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1794 |
putc('\n', stderr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1795 |
|
1796 |
ut_error; |
|
1797 |
}
|
|
1798 |
||
1799 |
xdes_init(descr, mtr); |
|
1800 |
||
1801 |
flst_add_last(header + FSP_FREE, descr + XDES_FLST_NODE, mtr); |
|
1802 |
}
|
|
1803 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1804 |
/**********************************************************************//**
|
1805 |
Returns the nth inode slot on an inode page.
|
|
1806 |
@return segment inode */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1807 |
UNIV_INLINE
|
1808 |
fseg_inode_t* |
|
1809 |
fsp_seg_inode_page_get_nth_inode( |
|
1810 |
/*=============================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1811 |
page_t* page, /*!< in: segment inode page */ |
1812 |
ulint i, /*!< in: inode index on page */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1813 |
ulint zip_size __attribute__((unused)), |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1814 |
/*!< in: compressed page size, or 0 */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1815 |
mtr_t* mtr __attribute__((unused))) |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1816 |
/*!< in: mini-transaction handle */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1817 |
{
|
1818 |
ut_ad(i < FSP_SEG_INODES_PER_PAGE(zip_size)); |
|
1819 |
ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX)); |
|
1820 |
||
1821 |
return(page + FSEG_ARR_OFFSET + FSEG_INODE_SIZE * i); |
|
1822 |
}
|
|
1823 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1824 |
/**********************************************************************//**
|
1825 |
Looks for a used segment inode on a segment inode page.
|
|
1826 |
@return segment inode index, or ULINT_UNDEFINED if not found */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1827 |
static
|
1828 |
ulint
|
|
1829 |
fsp_seg_inode_page_find_used( |
|
1830 |
/*=========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1831 |
page_t* page, /*!< in: segment inode page */ |
1832 |
ulint zip_size,/*!< in: compressed page size, or 0 */ |
|
1833 |
mtr_t* mtr) /*!< in: mini-transaction handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1834 |
{
|
1835 |
ulint i; |
|
1836 |
fseg_inode_t* inode; |
|
1837 |
||
1838 |
for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) { |
|
1839 |
||
1840 |
inode = fsp_seg_inode_page_get_nth_inode( |
|
1841 |
page, i, zip_size, mtr); |
|
1842 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
1843 |
if (mach_read_from_8(inode + FSEG_ID)) { |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1844 |
/* This is used */
|
1845 |
||
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
1846 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) |
1847 |
== FSEG_MAGIC_N_VALUE); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1848 |
return(i); |
1849 |
}
|
|
1850 |
}
|
|
1851 |
||
1852 |
return(ULINT_UNDEFINED); |
|
1853 |
}
|
|
1854 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1855 |
/**********************************************************************//**
|
1856 |
Looks for an unused segment inode on a segment inode page.
|
|
1857 |
@return segment inode index, or ULINT_UNDEFINED if not found */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1858 |
static
|
1859 |
ulint
|
|
1860 |
fsp_seg_inode_page_find_free( |
|
1861 |
/*=========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1862 |
page_t* page, /*!< in: segment inode page */ |
1863 |
ulint i, /*!< in: search forward starting from this index */ |
|
1864 |
ulint zip_size,/*!< in: compressed page size, or 0 */ |
|
1865 |
mtr_t* mtr) /*!< in: mini-transaction handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1866 |
{
|
1867 |
fseg_inode_t* inode; |
|
1868 |
||
1869 |
for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) { |
|
1870 |
||
1871 |
inode = fsp_seg_inode_page_get_nth_inode( |
|
1872 |
page, i, zip_size, mtr); |
|
1873 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
1874 |
if (!mach_read_from_8(inode + FSEG_ID)) { |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1875 |
/* This is unused */
|
1876 |
||
1877 |
return(i); |
|
1878 |
}
|
|
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
1879 |
|
1880 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) |
|
1881 |
== FSEG_MAGIC_N_VALUE); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1882 |
}
|
1883 |
||
1884 |
return(ULINT_UNDEFINED); |
|
1885 |
}
|
|
1886 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1887 |
/**********************************************************************//**
|
1888 |
Allocates a new file segment inode page.
|
|
1889 |
@return TRUE if could be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1890 |
static
|
1891 |
ibool
|
|
1892 |
fsp_alloc_seg_inode_page( |
|
1893 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1894 |
fsp_header_t* space_header, /*!< in: space header */ |
1895 |
mtr_t* mtr) /*!< in: mini-transaction handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1896 |
{
|
1897 |
fseg_inode_t* inode; |
|
1898 |
buf_block_t* block; |
|
1899 |
page_t* page; |
|
1900 |
ulint page_no; |
|
1901 |
ulint space; |
|
1902 |
ulint zip_size; |
|
1903 |
ulint i; |
|
1904 |
||
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1905 |
ut_ad(page_offset(space_header) == FSP_HEADER_OFFSET); |
1906 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1907 |
space = page_get_space_id(page_align(space_header)); |
1908 |
zip_size = dict_table_flags_to_zip_size( |
|
1909 |
mach_read_from_4(FSP_SPACE_FLAGS + space_header)); |
|
1910 |
||
1911 |
page_no = fsp_alloc_free_page(space, zip_size, 0, mtr); |
|
1912 |
||
1913 |
if (page_no == FIL_NULL) { |
|
1914 |
||
1915 |
return(FALSE); |
|
1916 |
}
|
|
1917 |
||
1918 |
block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr); |
|
1919 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
1920 |
||
1921 |
block->check_index_page_at_flush = FALSE; |
|
1922 |
||
1923 |
page = buf_block_get_frame(block); |
|
1924 |
||
1925 |
mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_INODE, |
|
1926 |
MLOG_2BYTES, mtr); |
|
1927 |
||
1928 |
for (i = 0; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) { |
|
1929 |
||
1930 |
inode = fsp_seg_inode_page_get_nth_inode(page, i, |
|
1931 |
zip_size, mtr); |
|
1932 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
1933 |
mlog_write_ull(inode + FSEG_ID, 0, mtr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1934 |
}
|
1935 |
||
1936 |
flst_add_last(space_header + FSP_SEG_INODES_FREE, |
|
1937 |
page + FSEG_INODE_PAGE_NODE, mtr); |
|
1938 |
return(TRUE); |
|
1939 |
}
|
|
1940 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1941 |
/**********************************************************************//**
|
1942 |
Allocates a new file segment inode.
|
|
1943 |
@return segment inode, or NULL if not enough space */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1944 |
static
|
1945 |
fseg_inode_t* |
|
1946 |
fsp_alloc_seg_inode( |
|
1947 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
1948 |
fsp_header_t* space_header, /*!< in: space header */ |
1949 |
mtr_t* mtr) /*!< in: mini-transaction handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1950 |
{
|
1951 |
ulint page_no; |
|
1952 |
buf_block_t* block; |
|
1953 |
page_t* page; |
|
1954 |
fseg_inode_t* inode; |
|
1955 |
ibool success; |
|
1956 |
ulint zip_size; |
|
1957 |
ulint n; |
|
1958 |
||
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1959 |
ut_ad(page_offset(space_header) == FSP_HEADER_OFFSET); |
1960 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1961 |
if (flst_get_len(space_header + FSP_SEG_INODES_FREE, mtr) == 0) { |
1962 |
/* Allocate a new segment inode page */
|
|
1963 |
||
1964 |
success = fsp_alloc_seg_inode_page(space_header, mtr); |
|
1965 |
||
1966 |
if (!success) { |
|
1967 |
||
1968 |
return(NULL); |
|
1969 |
}
|
|
1970 |
}
|
|
1971 |
||
1972 |
page_no = flst_get_first(space_header + FSP_SEG_INODES_FREE, mtr).page; |
|
1973 |
||
1974 |
zip_size = dict_table_flags_to_zip_size( |
|
1975 |
mach_read_from_4(FSP_SPACE_FLAGS + space_header)); |
|
1976 |
block = buf_page_get(page_get_space_id(page_align(space_header)), |
|
1977 |
zip_size, page_no, RW_X_LATCH, mtr); |
|
1978 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
1979 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
1980 |
page = buf_block_get_frame(block); |
1981 |
||
1982 |
n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr); |
|
1983 |
||
1984 |
ut_a(n != ULINT_UNDEFINED); |
|
1985 |
||
1986 |
inode = fsp_seg_inode_page_get_nth_inode(page, n, zip_size, mtr); |
|
1987 |
||
1988 |
if (ULINT_UNDEFINED == fsp_seg_inode_page_find_free(page, n + 1, |
|
1989 |
zip_size, mtr)) { |
|
1990 |
/* There are no other unused headers left on the page: move it
|
|
1991 |
to another list */
|
|
1992 |
||
1993 |
flst_remove(space_header + FSP_SEG_INODES_FREE, |
|
1994 |
page + FSEG_INODE_PAGE_NODE, mtr); |
|
1995 |
||
1996 |
flst_add_last(space_header + FSP_SEG_INODES_FULL, |
|
1997 |
page + FSEG_INODE_PAGE_NODE, mtr); |
|
1998 |
}
|
|
1999 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2000 |
ut_ad(!mach_read_from_8(inode + FSEG_ID) |
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
2001 |
|| mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2002 |
return(inode); |
2003 |
}
|
|
2004 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2005 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2006 |
Frees a file segment inode. */
|
2007 |
static
|
|
2008 |
void
|
|
2009 |
fsp_free_seg_inode( |
|
2010 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2011 |
ulint space, /*!< in: space id */ |
2012 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2013 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2014 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2015 |
mtr_t* mtr) /*!< in: mini-transaction handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2016 |
{
|
2017 |
page_t* page; |
|
2018 |
fsp_header_t* space_header; |
|
2019 |
||
2020 |
page = page_align(inode); |
|
2021 |
||
2022 |
space_header = fsp_get_space_header(space, zip_size, mtr); |
|
2023 |
||
2024 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
|
2025 |
||
2026 |
if (ULINT_UNDEFINED |
|
2027 |
== fsp_seg_inode_page_find_free(page, 0, zip_size, mtr)) { |
|
2028 |
||
2029 |
/* Move the page to another list */
|
|
2030 |
||
2031 |
flst_remove(space_header + FSP_SEG_INODES_FULL, |
|
2032 |
page + FSEG_INODE_PAGE_NODE, mtr); |
|
2033 |
||
2034 |
flst_add_last(space_header + FSP_SEG_INODES_FREE, |
|
2035 |
page + FSEG_INODE_PAGE_NODE, mtr); |
|
2036 |
}
|
|
2037 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2038 |
mlog_write_ull(inode + FSEG_ID, 0, mtr); |
1819.5.86
by stewart at flamingspork
[patch 086/129] Merge patch for revision 1885 from InnoDB SVN: |
2039 |
mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2040 |
|
2041 |
if (ULINT_UNDEFINED |
|
2042 |
== fsp_seg_inode_page_find_used(page, zip_size, mtr)) { |
|
2043 |
||
2044 |
/* There are no other used headers left on the page: free it */
|
|
2045 |
||
2046 |
flst_remove(space_header + FSP_SEG_INODES_FREE, |
|
2047 |
page + FSEG_INODE_PAGE_NODE, mtr); |
|
2048 |
||
2049 |
fsp_free_page(space, zip_size, page_get_page_no(page), mtr); |
|
2050 |
}
|
|
2051 |
}
|
|
2052 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2053 |
/**********************************************************************//**
|
2054 |
Returns the file segment inode, page x-latched.
|
|
1819.5.86
by stewart at flamingspork
[patch 086/129] Merge patch for revision 1885 from InnoDB SVN: |
2055 |
@return segment inode, page x-latched; NULL if the inode is free */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2056 |
static
|
2057 |
fseg_inode_t* |
|
1819.5.86
by stewart at flamingspork
[patch 086/129] Merge patch for revision 1885 from InnoDB SVN: |
2058 |
fseg_inode_try_get( |
2059 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2060 |
fseg_header_t* header, /*!< in: segment header */ |
2061 |
ulint space, /*!< in: space id */ |
|
2062 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2063 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2064 |
mtr_t* mtr) /*!< in: mtr handle */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2065 |
{
|
2066 |
fil_addr_t inode_addr; |
|
2067 |
fseg_inode_t* inode; |
|
2068 |
||
2069 |
inode_addr.page = mach_read_from_4(header + FSEG_HDR_PAGE_NO); |
|
2070 |
inode_addr.boffset = mach_read_from_2(header + FSEG_HDR_OFFSET); |
|
2071 |
ut_ad(space == mach_read_from_4(header + FSEG_HDR_SPACE)); |
|
2072 |
||
2073 |
inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr); |
|
2074 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2075 |
if (UNIV_UNLIKELY(!mach_read_from_8(inode + FSEG_ID))) { |
1819.5.86
by stewart at flamingspork
[patch 086/129] Merge patch for revision 1885 from InnoDB SVN: |
2076 |
|
2077 |
inode = NULL; |
|
2078 |
} else { |
|
2079 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) |
|
2080 |
== FSEG_MAGIC_N_VALUE); |
|
2081 |
}
|
|
2082 |
||
2083 |
return(inode); |
|
2084 |
}
|
|
2085 |
||
2086 |
/**********************************************************************//**
|
|
2087 |
Returns the file segment inode, page x-latched.
|
|
2088 |
@return segment inode, page x-latched */
|
|
2089 |
static
|
|
2090 |
fseg_inode_t* |
|
2091 |
fseg_inode_get( |
|
2092 |
/*===========*/
|
|
2093 |
fseg_header_t* header, /*!< in: segment header */ |
|
2094 |
ulint space, /*!< in: space id */ |
|
2095 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
2096 |
or 0 for uncompressed pages */
|
|
2097 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
2098 |
{
|
|
2099 |
fseg_inode_t* inode |
|
2100 |
= fseg_inode_try_get(header, space, zip_size, mtr); |
|
2101 |
ut_a(inode); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2102 |
return(inode); |
2103 |
}
|
|
2104 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2105 |
/**********************************************************************//**
|
2106 |
Gets the page number from the nth fragment page slot.
|
|
2107 |
@return page number, FIL_NULL if not in use */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2108 |
UNIV_INLINE
|
2109 |
ulint
|
|
2110 |
fseg_get_nth_frag_page_no( |
|
2111 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2112 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2113 |
ulint n, /*!< in: slot index */ |
|
2114 |
mtr_t* mtr __attribute__((unused))) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2115 |
{
|
2116 |
ut_ad(inode && mtr); |
|
2117 |
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS); |
|
2118 |
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX)); |
|
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
2119 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2120 |
return(mach_read_from_4(inode + FSEG_FRAG_ARR |
2121 |
+ n * FSEG_FRAG_SLOT_SIZE)); |
|
2122 |
}
|
|
2123 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2124 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2125 |
Sets the page number in the nth fragment page slot. */
|
2126 |
UNIV_INLINE
|
|
2127 |
void
|
|
2128 |
fseg_set_nth_frag_page_no( |
|
2129 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2130 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2131 |
ulint n, /*!< in: slot index */ |
|
2132 |
ulint page_no,/*!< in: page number to set */ |
|
2133 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2134 |
{
|
2135 |
ut_ad(inode && mtr); |
|
2136 |
ut_ad(n < FSEG_FRAG_ARR_N_SLOTS); |
|
2137 |
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX)); |
|
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
2138 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2139 |
|
2140 |
mlog_write_ulint(inode + FSEG_FRAG_ARR + n * FSEG_FRAG_SLOT_SIZE, |
|
2141 |
page_no, MLOG_4BYTES, mtr); |
|
2142 |
}
|
|
2143 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2144 |
/**********************************************************************//**
|
2145 |
Finds a fragment page slot which is free.
|
|
2146 |
@return slot index; ULINT_UNDEFINED if none found */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2147 |
static
|
2148 |
ulint
|
|
2149 |
fseg_find_free_frag_page_slot( |
|
2150 |
/*==========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2151 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2152 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2153 |
{
|
2154 |
ulint i; |
|
2155 |
ulint page_no; |
|
2156 |
||
2157 |
ut_ad(inode && mtr); |
|
2158 |
||
2159 |
for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) { |
|
2160 |
page_no = fseg_get_nth_frag_page_no(inode, i, mtr); |
|
2161 |
||
2162 |
if (page_no == FIL_NULL) { |
|
2163 |
||
2164 |
return(i); |
|
2165 |
}
|
|
2166 |
}
|
|
2167 |
||
2168 |
return(ULINT_UNDEFINED); |
|
2169 |
}
|
|
2170 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2171 |
/**********************************************************************//**
|
2172 |
Finds a fragment page slot which is used and last in the array.
|
|
2173 |
@return slot index; ULINT_UNDEFINED if none found */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2174 |
static
|
2175 |
ulint
|
|
2176 |
fseg_find_last_used_frag_page_slot( |
|
2177 |
/*===============================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2178 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2179 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2180 |
{
|
2181 |
ulint i; |
|
2182 |
ulint page_no; |
|
2183 |
||
2184 |
ut_ad(inode && mtr); |
|
2185 |
||
2186 |
for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) { |
|
2187 |
page_no = fseg_get_nth_frag_page_no( |
|
2188 |
inode, FSEG_FRAG_ARR_N_SLOTS - i - 1, mtr); |
|
2189 |
||
2190 |
if (page_no != FIL_NULL) { |
|
2191 |
||
2192 |
return(FSEG_FRAG_ARR_N_SLOTS - i - 1); |
|
2193 |
}
|
|
2194 |
}
|
|
2195 |
||
2196 |
return(ULINT_UNDEFINED); |
|
2197 |
}
|
|
2198 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2199 |
/**********************************************************************//**
|
2200 |
Calculates reserved fragment page slots.
|
|
2201 |
@return number of fragment pages */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2202 |
static
|
2203 |
ulint
|
|
2204 |
fseg_get_n_frag_pages( |
|
2205 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2206 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2207 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2208 |
{
|
2209 |
ulint i; |
|
2210 |
ulint count = 0; |
|
2211 |
||
2212 |
ut_ad(inode && mtr); |
|
2213 |
||
2214 |
for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) { |
|
2215 |
if (FIL_NULL != fseg_get_nth_frag_page_no(inode, i, mtr)) { |
|
2216 |
count++; |
|
2217 |
}
|
|
2218 |
}
|
|
2219 |
||
2220 |
return(count); |
|
2221 |
}
|
|
2222 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2223 |
/**********************************************************************//**
|
2224 |
Creates a new segment.
|
|
2225 |
@return the block where the segment header is placed, x-latched, NULL
|
|
2226 |
if could not create segment because of lack of space */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2227 |
UNIV_INTERN
|
2228 |
buf_block_t* |
|
2229 |
fseg_create_general( |
|
2230 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2231 |
ulint space, /*!< in: space id */ |
2232 |
ulint page, /*!< in: page where the segment header is placed: if |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2233 |
this is != 0, the page must belong to another segment,
|
2234 |
if this is 0, a new page will be allocated and it
|
|
2235 |
will belong to the created segment */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2236 |
ulint byte_offset, /*!< in: byte offset of the created segment header |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2237 |
on the page */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2238 |
ibool has_done_reservation, /*!< in: TRUE if the caller has already |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2239 |
done the reservation for the pages with
|
2240 |
fsp_reserve_free_extents (at least 2 extents: one for
|
|
2241 |
the inode and the other for the segment) then there is
|
|
2242 |
no need to do the check for this individual
|
|
2243 |
operation */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2244 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2245 |
{
|
2246 |
ulint flags; |
|
2247 |
ulint zip_size; |
|
2248 |
fsp_header_t* space_header; |
|
2249 |
fseg_inode_t* inode; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2250 |
ib_id_t seg_id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2251 |
buf_block_t* block = 0; /* remove warning */ |
2252 |
fseg_header_t* header = 0; /* remove warning */ |
|
2253 |
rw_lock_t* latch; |
|
2254 |
ibool success; |
|
2255 |
ulint n_reserved; |
|
2256 |
ulint i; |
|
2257 |
||
2258 |
ut_ad(mtr); |
|
2259 |
ut_ad(byte_offset + FSEG_HEADER_SIZE |
|
2260 |
<= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END); |
|
2261 |
||
2262 |
latch = fil_space_get_latch(space, &flags); |
|
2263 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
2264 |
||
2265 |
if (page != 0) { |
|
2266 |
block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr); |
|
2267 |
header = byte_offset + buf_block_get_frame(block); |
|
2268 |
}
|
|
2269 |
||
2270 |
ut_ad(!mutex_own(&kernel_mutex) |
|
2271 |
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK)); |
|
2272 |
||
2273 |
mtr_x_lock(latch, mtr); |
|
2274 |
||
2275 |
if (rw_lock_get_x_lock_count(latch) == 1) { |
|
2276 |
/* This thread did not own the latch before this call: free
|
|
2277 |
excess pages from the insert buffer free list */
|
|
2278 |
||
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
2279 |
if (space == IBUF_SPACE_ID) { |
2280 |
ibuf_free_excess_pages(); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2281 |
}
|
2282 |
}
|
|
2283 |
||
2284 |
if (!has_done_reservation) { |
|
2285 |
success = fsp_reserve_free_extents(&n_reserved, space, 2, |
|
2286 |
FSP_NORMAL, mtr); |
|
2287 |
if (!success) { |
|
2288 |
return(NULL); |
|
2289 |
}
|
|
2290 |
}
|
|
2291 |
||
2292 |
space_header = fsp_get_space_header(space, zip_size, mtr); |
|
2293 |
||
2294 |
inode = fsp_alloc_seg_inode(space_header, mtr); |
|
2295 |
||
2296 |
if (inode == NULL) { |
|
2297 |
||
2298 |
goto funct_exit; |
|
2299 |
}
|
|
2300 |
||
2301 |
/* Read the next segment id from space header and increment the
|
|
2302 |
value in space header */
|
|
2303 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2304 |
seg_id = mach_read_from_8(space_header + FSP_SEG_ID); |
2305 |
||
2306 |
mlog_write_ull(space_header + FSP_SEG_ID, seg_id + 1, mtr); |
|
2307 |
||
2308 |
mlog_write_ull(inode + FSEG_ID, seg_id, mtr); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2309 |
mlog_write_ulint(inode + FSEG_NOT_FULL_N_USED, 0, MLOG_4BYTES, mtr); |
2310 |
||
2311 |
flst_init(inode + FSEG_FREE, mtr); |
|
2312 |
flst_init(inode + FSEG_NOT_FULL, mtr); |
|
2313 |
flst_init(inode + FSEG_FULL, mtr); |
|
2314 |
||
2315 |
mlog_write_ulint(inode + FSEG_MAGIC_N, FSEG_MAGIC_N_VALUE, |
|
2316 |
MLOG_4BYTES, mtr); |
|
2317 |
for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) { |
|
2318 |
fseg_set_nth_frag_page_no(inode, i, FIL_NULL, mtr); |
|
2319 |
}
|
|
2320 |
||
2321 |
if (page == 0) { |
|
2322 |
page = fseg_alloc_free_page_low(space, zip_size, |
|
2323 |
inode, 0, FSP_UP, mtr); |
|
2324 |
||
2325 |
if (page == FIL_NULL) { |
|
2326 |
||
2327 |
fsp_free_seg_inode(space, zip_size, inode, mtr); |
|
2328 |
||
2329 |
goto funct_exit; |
|
2330 |
}
|
|
2331 |
||
2332 |
block = buf_page_get(space, zip_size, page, RW_X_LATCH, mtr); |
|
2333 |
header = byte_offset + buf_block_get_frame(block); |
|
2334 |
mlog_write_ulint(header - byte_offset + FIL_PAGE_TYPE, |
|
2335 |
FIL_PAGE_TYPE_SYS, MLOG_2BYTES, mtr); |
|
2336 |
}
|
|
2337 |
||
2338 |
mlog_write_ulint(header + FSEG_HDR_OFFSET, |
|
2339 |
page_offset(inode), MLOG_2BYTES, mtr); |
|
2340 |
||
2341 |
mlog_write_ulint(header + FSEG_HDR_PAGE_NO, |
|
2342 |
page_get_page_no(page_align(inode)), |
|
2343 |
MLOG_4BYTES, mtr); |
|
2344 |
||
2345 |
mlog_write_ulint(header + FSEG_HDR_SPACE, space, MLOG_4BYTES, mtr); |
|
2346 |
||
2347 |
funct_exit: |
|
2348 |
if (!has_done_reservation) { |
|
2349 |
||
2350 |
fil_space_release_free_extents(space, n_reserved); |
|
2351 |
}
|
|
2352 |
||
2353 |
return(block); |
|
2354 |
}
|
|
2355 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2356 |
/**********************************************************************//**
|
2357 |
Creates a new segment.
|
|
2358 |
@return the block where the segment header is placed, x-latched, NULL
|
|
2359 |
if could not create segment because of lack of space */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2360 |
UNIV_INTERN
|
2361 |
buf_block_t* |
|
2362 |
fseg_create( |
|
2363 |
/*========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2364 |
ulint space, /*!< in: space id */ |
2365 |
ulint page, /*!< in: page where the segment header is placed: if |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2366 |
this is != 0, the page must belong to another segment,
|
2367 |
if this is 0, a new page will be allocated and it
|
|
2368 |
will belong to the created segment */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2369 |
ulint byte_offset, /*!< in: byte offset of the created segment header |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2370 |
on the page */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2371 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2372 |
{
|
2373 |
return(fseg_create_general(space, page, byte_offset, FALSE, mtr)); |
|
2374 |
}
|
|
2375 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2376 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2377 |
Calculates the number of pages reserved by a segment, and how many pages are
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2378 |
currently used.
|
2379 |
@return number of reserved pages */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2380 |
static
|
2381 |
ulint
|
|
2382 |
fseg_n_reserved_pages_low( |
|
2383 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2384 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2385 |
ulint* used, /*!< out: number of pages used (not |
|
2386 |
more than reserved) */
|
|
2387 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2388 |
{
|
2389 |
ulint ret; |
|
2390 |
||
2391 |
ut_ad(inode && used && mtr); |
|
2392 |
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX)); |
|
2393 |
||
2394 |
*used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr) |
|
2395 |
+ FSP_EXTENT_SIZE * flst_get_len(inode + FSEG_FULL, mtr) |
|
2396 |
+ fseg_get_n_frag_pages(inode, mtr); |
|
2397 |
||
2398 |
ret = fseg_get_n_frag_pages(inode, mtr) |
|
2399 |
+ FSP_EXTENT_SIZE * flst_get_len(inode + FSEG_FREE, mtr) |
|
2400 |
+ FSP_EXTENT_SIZE * flst_get_len(inode + FSEG_NOT_FULL, mtr) |
|
2401 |
+ FSP_EXTENT_SIZE * flst_get_len(inode + FSEG_FULL, mtr); |
|
2402 |
||
2403 |
return(ret); |
|
2404 |
}
|
|
2405 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2406 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2407 |
Calculates the number of pages reserved by a segment, and how many pages are
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2408 |
currently used.
|
2409 |
@return number of reserved pages */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2410 |
UNIV_INTERN
|
2411 |
ulint
|
|
2412 |
fseg_n_reserved_pages( |
|
2413 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2414 |
fseg_header_t* header, /*!< in: segment header */ |
2415 |
ulint* used, /*!< out: number of pages used (<= reserved) */ |
|
2416 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2417 |
{
|
2418 |
ulint ret; |
|
2419 |
fseg_inode_t* inode; |
|
2420 |
ulint space; |
|
2421 |
ulint flags; |
|
2422 |
ulint zip_size; |
|
2423 |
rw_lock_t* latch; |
|
2424 |
||
2425 |
space = page_get_space_id(page_align(header)); |
|
2426 |
latch = fil_space_get_latch(space, &flags); |
|
2427 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
2428 |
||
2429 |
ut_ad(!mutex_own(&kernel_mutex) |
|
2430 |
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK)); |
|
2431 |
||
2432 |
mtr_x_lock(latch, mtr); |
|
2433 |
||
2434 |
inode = fseg_inode_get(header, space, zip_size, mtr); |
|
2435 |
||
2436 |
ret = fseg_n_reserved_pages_low(inode, used, mtr); |
|
2437 |
||
2438 |
return(ret); |
|
2439 |
}
|
|
2440 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2441 |
/*********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2442 |
Tries to fill the free list of a segment with consecutive free extents.
|
2443 |
This happens if the segment is big enough to allow extents in the free list,
|
|
2444 |
the free list is empty, and the extents can be allocated consecutively from
|
|
2445 |
the hint onward. */
|
|
2446 |
static
|
|
2447 |
void
|
|
2448 |
fseg_fill_free_list( |
|
2449 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2450 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2451 |
ulint space, /*!< in: space id */ |
|
2452 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2453 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2454 |
ulint hint, /*!< in: hint which extent would be good as |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2455 |
the first extent */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2456 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2457 |
{
|
2458 |
xdes_t* descr; |
|
2459 |
ulint i; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2460 |
ib_id_t seg_id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2461 |
ulint reserved; |
2462 |
ulint used; |
|
2463 |
||
2464 |
ut_ad(inode && mtr); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
2465 |
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2466 |
|
2467 |
reserved = fseg_n_reserved_pages_low(inode, &used, mtr); |
|
2468 |
||
2469 |
if (reserved < FSEG_FREE_LIST_LIMIT * FSP_EXTENT_SIZE) { |
|
2470 |
||
2471 |
/* The segment is too small to allow extents in free list */
|
|
2472 |
||
2473 |
return; |
|
2474 |
}
|
|
2475 |
||
2476 |
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) { |
|
2477 |
/* Free list is not empty */
|
|
2478 |
||
2479 |
return; |
|
2480 |
}
|
|
2481 |
||
2482 |
for (i = 0; i < FSEG_FREE_LIST_MAX_LEN; i++) { |
|
2483 |
descr = xdes_get_descriptor(space, zip_size, hint, mtr); |
|
2484 |
||
2485 |
if ((descr == NULL) |
|
2486 |
|| (XDES_FREE != xdes_get_state(descr, mtr))) { |
|
2487 |
||
2488 |
/* We cannot allocate the desired extent: stop */
|
|
2489 |
||
2490 |
return; |
|
2491 |
}
|
|
2492 |
||
2493 |
descr = fsp_alloc_free_extent(space, zip_size, hint, mtr); |
|
2494 |
||
2495 |
xdes_set_state(descr, XDES_FSEG, mtr); |
|
2496 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2497 |
seg_id = mach_read_from_8(inode + FSEG_ID); |
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
2498 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) |
2499 |
== FSEG_MAGIC_N_VALUE); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2500 |
mlog_write_ull(descr + XDES_ID, seg_id, mtr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2501 |
|
2502 |
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr); |
|
2503 |
hint += FSP_EXTENT_SIZE; |
|
2504 |
}
|
|
2505 |
}
|
|
2506 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2507 |
/*********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2508 |
Allocates a free extent for the segment: looks first in the free list of the
|
2509 |
segment, then tries to allocate from the space free list. NOTE that the extent
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2510 |
returned still resides in the segment free list, it is not yet taken off it!
|
2511 |
@return allocated extent, still placed in the segment free list, NULL
|
|
2512 |
if could not be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2513 |
static
|
2514 |
xdes_t* |
|
2515 |
fseg_alloc_free_extent( |
|
2516 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2517 |
fseg_inode_t* inode, /*!< in: segment inode */ |
2518 |
ulint space, /*!< in: space id */ |
|
2519 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2520 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2521 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2522 |
{
|
2523 |
xdes_t* descr; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2524 |
ib_id_t seg_id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2525 |
fil_addr_t first; |
2526 |
||
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
2527 |
ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); |
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
2528 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
2529 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2530 |
if (flst_get_len(inode + FSEG_FREE, mtr) > 0) { |
2531 |
/* Segment free list is not empty, allocate from it */
|
|
2532 |
||
2533 |
first = flst_get_first(inode + FSEG_FREE, mtr); |
|
2534 |
||
2535 |
descr = xdes_lst_get_descriptor(space, zip_size, first, mtr); |
|
2536 |
} else { |
|
2537 |
/* Segment free list was empty, allocate from space */
|
|
2538 |
descr = fsp_alloc_free_extent(space, zip_size, 0, mtr); |
|
2539 |
||
2540 |
if (descr == NULL) { |
|
2541 |
||
2542 |
return(NULL); |
|
2543 |
}
|
|
2544 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2545 |
seg_id = mach_read_from_8(inode + FSEG_ID); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2546 |
|
2547 |
xdes_set_state(descr, XDES_FSEG, mtr); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2548 |
mlog_write_ull(descr + XDES_ID, seg_id, mtr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2549 |
flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr); |
2550 |
||
2551 |
/* Try to fill the segment free list */
|
|
2552 |
fseg_fill_free_list(inode, space, zip_size, |
|
2553 |
xdes_get_offset(descr) + FSP_EXTENT_SIZE, |
|
2554 |
mtr); |
|
2555 |
}
|
|
2556 |
||
2557 |
return(descr); |
|
2558 |
}
|
|
2559 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2560 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2561 |
Allocates a single free page from a segment. This function implements
|
2562 |
the intelligent allocation strategy which tries to minimize file space
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2563 |
fragmentation.
|
2564 |
@return the allocated page number, FIL_NULL if no page could be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2565 |
static
|
2566 |
ulint
|
|
2567 |
fseg_alloc_free_page_low( |
|
2568 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2569 |
ulint space, /*!< in: space */ |
2570 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2571 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2572 |
fseg_inode_t* seg_inode, /*!< in: segment inode */ |
2573 |
ulint hint, /*!< in: hint of which page would be desirable */ |
|
2574 |
byte direction, /*!< in: if the new page is needed because |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2575 |
of an index page split, and records are
|
2576 |
inserted there in order, into which
|
|
2577 |
direction they go alphabetically: FSP_DOWN,
|
|
2578 |
FSP_UP, FSP_NO_DIR */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2579 |
mtr_t* mtr) /*!< in: mtr handle */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2580 |
{
|
2581 |
fsp_header_t* space_header; |
|
2582 |
ulint space_size; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2583 |
ib_id_t seg_id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2584 |
ulint used; |
2585 |
ulint reserved; |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2586 |
xdes_t* descr; /*!< extent of the hinted page */ |
2587 |
ulint ret_page; /*!< the allocated page offset, FIL_NULL |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2588 |
if could not be allocated */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2589 |
xdes_t* ret_descr; /*!< the extent of the allocated page */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2590 |
ibool frag_page_allocated = FALSE; |
2591 |
ibool success; |
|
2592 |
ulint n; |
|
2593 |
||
2594 |
ut_ad(mtr); |
|
2595 |
ut_ad((direction >= FSP_UP) && (direction <= FSP_NO_DIR)); |
|
2596 |
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) |
|
2597 |
== FSEG_MAGIC_N_VALUE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
2598 |
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); |
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2599 |
seg_id = mach_read_from_8(seg_inode + FSEG_ID); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2600 |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2601 |
ut_ad(seg_id); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2602 |
|
2603 |
reserved = fseg_n_reserved_pages_low(seg_inode, &used, mtr); |
|
2604 |
||
2605 |
space_header = fsp_get_space_header(space, zip_size, mtr); |
|
2606 |
||
2607 |
descr = xdes_get_descriptor_with_space_hdr(space_header, space, |
|
2608 |
hint, mtr); |
|
2609 |
if (descr == NULL) { |
|
2610 |
/* Hint outside space or too high above free limit: reset
|
|
2611 |
hint */
|
|
2612 |
hint = 0; |
|
2613 |
descr = xdes_get_descriptor(space, zip_size, hint, mtr); |
|
2614 |
}
|
|
2615 |
||
2616 |
/* In the big if-else below we look for ret_page and ret_descr */
|
|
2617 |
/*-------------------------------------------------------------*/
|
|
2618 |
if ((xdes_get_state(descr, mtr) == XDES_FSEG) |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2619 |
&& mach_read_from_8(descr + XDES_ID) == seg_id |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2620 |
&& (xdes_get_bit(descr, XDES_FREE_BIT, |
2621 |
hint % FSP_EXTENT_SIZE, mtr) == TRUE)) { |
|
2622 |
||
2623 |
/* 1. We can take the hinted page
|
|
2624 |
=================================*/
|
|
2625 |
ret_descr = descr; |
|
2626 |
ret_page = hint; |
|
2627 |
/*-----------------------------------------------------------*/
|
|
2628 |
} else if ((xdes_get_state(descr, mtr) == XDES_FREE) |
|
2629 |
&& ((reserved - used) < reserved / FSEG_FILLFACTOR) |
|
2630 |
&& (used >= FSEG_FRAG_LIMIT)) { |
|
2631 |
||
2632 |
/* 2. We allocate the free extent from space and can take
|
|
2633 |
=========================================================
|
|
2634 |
the hinted page
|
|
2635 |
===============*/
|
|
2636 |
ret_descr = fsp_alloc_free_extent(space, zip_size, hint, mtr); |
|
2637 |
||
2638 |
ut_a(ret_descr == descr); |
|
2639 |
||
2640 |
xdes_set_state(ret_descr, XDES_FSEG, mtr); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2641 |
mlog_write_ull(ret_descr + XDES_ID, seg_id, mtr); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2642 |
flst_add_last(seg_inode + FSEG_FREE, |
2643 |
ret_descr + XDES_FLST_NODE, mtr); |
|
2644 |
||
2645 |
/* Try to fill the segment free list */
|
|
2646 |
fseg_fill_free_list(seg_inode, space, zip_size, |
|
2647 |
hint + FSP_EXTENT_SIZE, mtr); |
|
2648 |
ret_page = hint; |
|
2649 |
/*-----------------------------------------------------------*/
|
|
2650 |
} else if ((direction != FSP_NO_DIR) |
|
2651 |
&& ((reserved - used) < reserved / FSEG_FILLFACTOR) |
|
2652 |
&& (used >= FSEG_FRAG_LIMIT) |
|
2653 |
&& (!!(ret_descr |
|
2654 |
= fseg_alloc_free_extent(seg_inode, |
|
2655 |
space, zip_size, mtr)))) { |
|
2656 |
||
2657 |
/* 3. We take any free extent (which was already assigned above
|
|
2658 |
===============================================================
|
|
2659 |
in the if-condition to ret_descr) and take the lowest or
|
|
2660 |
========================================================
|
|
2661 |
highest page in it, depending on the direction
|
|
2662 |
==============================================*/
|
|
2663 |
ret_page = xdes_get_offset(ret_descr); |
|
2664 |
||
2665 |
if (direction == FSP_DOWN) { |
|
2666 |
ret_page += FSP_EXTENT_SIZE - 1; |
|
2667 |
}
|
|
2668 |
/*-----------------------------------------------------------*/
|
|
2669 |
} else if ((xdes_get_state(descr, mtr) == XDES_FSEG) |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
2670 |
&& mach_read_from_8(descr + XDES_ID) == seg_id |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2671 |
&& (!xdes_is_full(descr, mtr))) { |
2672 |
||
2673 |
/* 4. We can take the page from the same extent as the
|
|
2674 |
======================================================
|
|
2675 |
hinted page (and the extent already belongs to the
|
|
2676 |
==================================================
|
|
2677 |
segment)
|
|
2678 |
========*/
|
|
2679 |
ret_descr = descr; |
|
2680 |
ret_page = xdes_get_offset(ret_descr) |
|
2681 |
+ xdes_find_bit(ret_descr, XDES_FREE_BIT, TRUE, |
|
2682 |
hint % FSP_EXTENT_SIZE, mtr); |
|
2683 |
/*-----------------------------------------------------------*/
|
|
2684 |
} else if (reserved - used > 0) { |
|
2685 |
/* 5. We take any unused page from the segment
|
|
2686 |
==============================================*/
|
|
2687 |
fil_addr_t first; |
|
2688 |
||
2689 |
if (flst_get_len(seg_inode + FSEG_NOT_FULL, mtr) > 0) { |
|
2690 |
first = flst_get_first(seg_inode + FSEG_NOT_FULL, |
|
2691 |
mtr); |
|
2692 |
} else if (flst_get_len(seg_inode + FSEG_FREE, mtr) > 0) { |
|
2693 |
first = flst_get_first(seg_inode + FSEG_FREE, mtr); |
|
2694 |
} else { |
|
2695 |
ut_error; |
|
2696 |
return(FIL_NULL); |
|
2697 |
}
|
|
2698 |
||
2699 |
ret_descr = xdes_lst_get_descriptor(space, zip_size, |
|
2700 |
first, mtr); |
|
2701 |
ret_page = xdes_get_offset(ret_descr) |
|
2702 |
+ xdes_find_bit(ret_descr, XDES_FREE_BIT, TRUE, |
|
2703 |
0, mtr); |
|
2704 |
/*-----------------------------------------------------------*/
|
|
2705 |
} else if (used < FSEG_FRAG_LIMIT) { |
|
2706 |
/* 6. We allocate an individual page from the space
|
|
2707 |
===================================================*/
|
|
2708 |
ret_page = fsp_alloc_free_page(space, zip_size, hint, mtr); |
|
2709 |
ret_descr = NULL; |
|
2710 |
||
2711 |
frag_page_allocated = TRUE; |
|
2712 |
||
2713 |
if (ret_page != FIL_NULL) { |
|
2714 |
/* Put the page in the fragment page array of the
|
|
2715 |
segment */
|
|
2716 |
n = fseg_find_free_frag_page_slot(seg_inode, mtr); |
|
2717 |
ut_a(n != FIL_NULL); |
|
2718 |
||
2719 |
fseg_set_nth_frag_page_no(seg_inode, n, ret_page, |
|
2720 |
mtr); |
|
2721 |
}
|
|
2722 |
/*-----------------------------------------------------------*/
|
|
2723 |
} else { |
|
2724 |
/* 7. We allocate a new extent and take its first page
|
|
2725 |
======================================================*/
|
|
2726 |
ret_descr = fseg_alloc_free_extent(seg_inode, |
|
2727 |
space, zip_size, mtr); |
|
2728 |
||
2729 |
if (ret_descr == NULL) { |
|
2730 |
ret_page = FIL_NULL; |
|
2731 |
} else { |
|
2732 |
ret_page = xdes_get_offset(ret_descr); |
|
2733 |
}
|
|
2734 |
}
|
|
2735 |
||
2736 |
if (ret_page == FIL_NULL) { |
|
2737 |
/* Page could not be allocated */
|
|
2738 |
||
2739 |
return(FIL_NULL); |
|
2740 |
}
|
|
2741 |
||
2742 |
if (space != 0) { |
|
2743 |
space_size = fil_space_get_size(space); |
|
2744 |
||
2745 |
if (space_size <= ret_page) { |
|
2746 |
/* It must be that we are extending a single-table
|
|
2747 |
tablespace whose size is still < 64 pages */
|
|
2748 |
||
2749 |
if (ret_page >= FSP_EXTENT_SIZE) { |
|
2750 |
fprintf(stderr, |
|
2751 |
"InnoDB: Error (2): trying to extend"
|
|
2752 |
" a single-table tablespace %lu\n" |
|
2753 |
"InnoDB: by single page(s) though"
|
|
2754 |
" the space size %lu. Page no %lu.\n", |
|
2755 |
(ulong) space, (ulong) space_size, |
|
2756 |
(ulong) ret_page); |
|
2757 |
return(FIL_NULL); |
|
2758 |
}
|
|
2759 |
||
2760 |
success = fsp_try_extend_data_file_with_pages( |
|
2761 |
space, ret_page, space_header, mtr); |
|
2762 |
if (!success) { |
|
2763 |
/* No disk space left */
|
|
2764 |
return(FIL_NULL); |
|
2765 |
}
|
|
2766 |
}
|
|
2767 |
}
|
|
2768 |
||
2769 |
if (!frag_page_allocated) { |
|
2770 |
/* Initialize the allocated page to buffer pool, so that it
|
|
2771 |
can be obtained immediately with buf_page_get without need
|
|
2772 |
for a disk read */
|
|
2773 |
buf_block_t* block; |
|
2774 |
ulint zip_size = dict_table_flags_to_zip_size( |
|
2775 |
mach_read_from_4(FSP_SPACE_FLAGS + space_header)); |
|
2776 |
||
2777 |
block = buf_page_create(space, ret_page, zip_size, mtr); |
|
2778 |
buf_block_dbg_add_level(block, SYNC_FSP_PAGE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
2779 |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2780 |
if (UNIV_UNLIKELY(block != buf_page_get(space, zip_size, |
2781 |
ret_page, RW_X_LATCH, |
|
2782 |
mtr))) { |
|
2783 |
ut_error; |
|
2784 |
}
|
|
2785 |
||
2786 |
/* The prior contents of the page should be ignored */
|
|
2787 |
fsp_init_file_page(block, mtr); |
|
2788 |
||
2789 |
/* At this point we know the extent and the page offset.
|
|
2790 |
The extent is still in the appropriate list (FSEG_NOT_FULL
|
|
2791 |
or FSEG_FREE), and the page is not yet marked as used. */
|
|
2792 |
||
2793 |
ut_ad(xdes_get_descriptor(space, zip_size, ret_page, mtr) |
|
2794 |
== ret_descr); |
|
2795 |
ut_ad(xdes_get_bit(ret_descr, XDES_FREE_BIT, |
|
2796 |
ret_page % FSP_EXTENT_SIZE, mtr) == TRUE); |
|
2797 |
||
2798 |
fseg_mark_page_used(seg_inode, space, zip_size, ret_page, mtr); |
|
2799 |
}
|
|
2800 |
||
2801 |
buf_reset_check_index_page_at_flush(space, ret_page); |
|
2802 |
||
2803 |
return(ret_page); |
|
2804 |
}
|
|
2805 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2806 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2807 |
Allocates a single free page from a segment. This function implements
|
2808 |
the intelligent allocation strategy which tries to minimize file space
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2809 |
fragmentation.
|
2810 |
@return allocated page offset, FIL_NULL if no page could be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2811 |
UNIV_INTERN
|
2812 |
ulint
|
|
2813 |
fseg_alloc_free_page_general( |
|
2814 |
/*=========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2815 |
fseg_header_t* seg_header,/*!< in: segment header */ |
2816 |
ulint hint, /*!< in: hint of which page would be desirable */ |
|
2817 |
byte direction,/*!< in: if the new page is needed because |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2818 |
of an index page split, and records are
|
2819 |
inserted there in order, into which
|
|
2820 |
direction they go alphabetically: FSP_DOWN,
|
|
2821 |
FSP_UP, FSP_NO_DIR */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2822 |
ibool has_done_reservation, /*!< in: TRUE if the caller has |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2823 |
already done the reservation for the page
|
2824 |
with fsp_reserve_free_extents, then there
|
|
2825 |
is no need to do the check for this individual
|
|
2826 |
page */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2827 |
mtr_t* mtr) /*!< in: mtr handle */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2828 |
{
|
2829 |
fseg_inode_t* inode; |
|
2830 |
ulint space; |
|
2831 |
ulint flags; |
|
2832 |
ulint zip_size; |
|
2833 |
rw_lock_t* latch; |
|
2834 |
ibool success; |
|
2835 |
ulint page_no; |
|
2836 |
ulint n_reserved; |
|
2837 |
||
2838 |
space = page_get_space_id(page_align(seg_header)); |
|
2839 |
||
2840 |
latch = fil_space_get_latch(space, &flags); |
|
2841 |
||
2842 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
2843 |
||
2844 |
ut_ad(!mutex_own(&kernel_mutex) |
|
2845 |
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK)); |
|
2846 |
||
2847 |
mtr_x_lock(latch, mtr); |
|
2848 |
||
2849 |
if (rw_lock_get_x_lock_count(latch) == 1) { |
|
2850 |
/* This thread did not own the latch before this call: free
|
|
2851 |
excess pages from the insert buffer free list */
|
|
2852 |
||
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
2853 |
if (space == IBUF_SPACE_ID) { |
2854 |
ibuf_free_excess_pages(); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2855 |
}
|
2856 |
}
|
|
2857 |
||
2858 |
inode = fseg_inode_get(seg_header, space, zip_size, mtr); |
|
2859 |
||
2860 |
if (!has_done_reservation) { |
|
2861 |
success = fsp_reserve_free_extents(&n_reserved, space, 2, |
|
2862 |
FSP_NORMAL, mtr); |
|
2863 |
if (!success) { |
|
2864 |
return(FIL_NULL); |
|
2865 |
}
|
|
2866 |
}
|
|
2867 |
||
2868 |
page_no = fseg_alloc_free_page_low(space, zip_size, |
|
2869 |
inode, hint, direction, mtr); |
|
2870 |
if (!has_done_reservation) { |
|
2871 |
fil_space_release_free_extents(space, n_reserved); |
|
2872 |
}
|
|
2873 |
||
2874 |
return(page_no); |
|
2875 |
}
|
|
2876 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2877 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2878 |
Allocates a single free page from a segment. This function implements
|
2879 |
the intelligent allocation strategy which tries to minimize file space
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2880 |
fragmentation.
|
2881 |
@return allocated page offset, FIL_NULL if no page could be allocated */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2882 |
UNIV_INTERN
|
2883 |
ulint
|
|
2884 |
fseg_alloc_free_page( |
|
2885 |
/*=================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2886 |
fseg_header_t* seg_header,/*!< in: segment header */ |
2887 |
ulint hint, /*!< in: hint of which page would be desirable */ |
|
2888 |
byte direction,/*!< in: if the new page is needed because |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2889 |
of an index page split, and records are
|
2890 |
inserted there in order, into which
|
|
2891 |
direction they go alphabetically: FSP_DOWN,
|
|
2892 |
FSP_UP, FSP_NO_DIR */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2893 |
mtr_t* mtr) /*!< in: mtr handle */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2894 |
{
|
2895 |
return(fseg_alloc_free_page_general(seg_header, hint, direction, |
|
2896 |
FALSE, mtr)); |
|
2897 |
}
|
|
2898 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2899 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2900 |
Checks that we have at least 2 frag pages free in the first extent of a
|
2901 |
single-table tablespace, and they are also physically initialized to the data
|
|
2902 |
file. That is we have already extended the data file so that those pages are
|
|
2903 |
inside the data file. If not, this function extends the tablespace with
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2904 |
pages.
|
2905 |
@return TRUE if there were >= 3 free pages, or we were able to extend */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2906 |
static
|
2907 |
ibool
|
|
2908 |
fsp_reserve_free_pages( |
|
2909 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2910 |
ulint space, /*!< in: space id, must be != 0 */ |
2911 |
fsp_header_t* space_header, /*!< in: header of that space, |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2912 |
x-latched */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2913 |
ulint size, /*!< in: size of the tablespace in pages, |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2914 |
must be < FSP_EXTENT_SIZE / 2 */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2915 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2916 |
{
|
2917 |
xdes_t* descr; |
|
2918 |
ulint n_used; |
|
2919 |
||
2920 |
ut_a(space != 0); |
|
2921 |
ut_a(size < FSP_EXTENT_SIZE / 2); |
|
2922 |
||
2923 |
descr = xdes_get_descriptor_with_space_hdr(space_header, space, 0, |
|
2924 |
mtr); |
|
2925 |
n_used = xdes_get_n_used(descr, mtr); |
|
2926 |
||
2927 |
ut_a(n_used <= size); |
|
2928 |
||
2929 |
if (size >= n_used + 2) { |
|
2930 |
||
2931 |
return(TRUE); |
|
2932 |
}
|
|
2933 |
||
2934 |
return(fsp_try_extend_data_file_with_pages(space, n_used + 1, |
|
2935 |
space_header, mtr)); |
|
2936 |
}
|
|
2937 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2938 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2939 |
Reserves free pages from a tablespace. All mini-transactions which may
|
2940 |
use several pages from the tablespace should call this function beforehand
|
|
2941 |
and reserve enough free extents so that they certainly will be able
|
|
2942 |
to do their operation, like a B-tree page split, fully. Reservations
|
|
2943 |
must be released with function fil_space_release_free_extents!
|
|
2944 |
||
2945 |
The alloc_type below has the following meaning: FSP_NORMAL means an
|
|
2946 |
operation which will probably result in more space usage, like an
|
|
2947 |
insert in a B-tree; FSP_UNDO means allocation to undo logs: if we are
|
|
2948 |
deleting rows, then this allocation will in the long run result in
|
|
2949 |
less space usage (after a purge); FSP_CLEANING means allocation done
|
|
2950 |
in a physical record delete (like in a purge) or other cleaning operation
|
|
2951 |
which will result in less space usage in the long run. We prefer the latter
|
|
2952 |
two types of allocation: when space is scarce, FSP_NORMAL allocations
|
|
2953 |
will not succeed, but the latter two allocations will succeed, if possible.
|
|
2954 |
The purpose is to avoid dead end where the database is full but the
|
|
2955 |
user cannot free any space because these freeing operations temporarily
|
|
2956 |
reserve some space.
|
|
2957 |
||
2958 |
Single-table tablespaces whose size is < 32 pages are a special case. In this
|
|
2959 |
function we would liberally reserve several 64 page extents for every page
|
|
2960 |
split or merge in a B-tree. But we do not want to waste disk space if the table
|
|
2961 |
only occupies < 32 pages. That is why we apply different rules in that special
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2962 |
case, just ensuring that there are 3 free pages available.
|
2963 |
@return TRUE if we were able to make the reservation */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2964 |
UNIV_INTERN
|
2965 |
ibool
|
|
2966 |
fsp_reserve_free_extents( |
|
2967 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2968 |
ulint* n_reserved,/*!< out: number of extents actually reserved; if we |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2969 |
return TRUE and the tablespace size is < 64 pages,
|
2970 |
then this can be 0, otherwise it is n_ext */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
2971 |
ulint space, /*!< in: space id */ |
2972 |
ulint n_ext, /*!< in: number of extents to reserve */ |
|
2973 |
ulint alloc_type,/*!< in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */ |
|
2974 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
2975 |
{
|
2976 |
fsp_header_t* space_header; |
|
2977 |
rw_lock_t* latch; |
|
2978 |
ulint n_free_list_ext; |
|
2979 |
ulint free_limit; |
|
2980 |
ulint size; |
|
2981 |
ulint flags; |
|
2982 |
ulint zip_size; |
|
2983 |
ulint n_free; |
|
2984 |
ulint n_free_up; |
|
2985 |
ulint reserve; |
|
2986 |
ibool success; |
|
2987 |
ulint n_pages_added; |
|
2988 |
||
2989 |
ut_ad(mtr); |
|
2990 |
*n_reserved = n_ext; |
|
2991 |
||
2992 |
latch = fil_space_get_latch(space, &flags); |
|
2993 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
2994 |
||
2995 |
ut_ad(!mutex_own(&kernel_mutex) |
|
2996 |
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK)); |
|
2997 |
||
2998 |
mtr_x_lock(latch, mtr); |
|
2999 |
||
3000 |
space_header = fsp_get_space_header(space, zip_size, mtr); |
|
3001 |
try_again: |
|
3002 |
size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, mtr); |
|
3003 |
||
3004 |
if (size < FSP_EXTENT_SIZE / 2) { |
|
3005 |
/* Use different rules for small single-table tablespaces */
|
|
3006 |
*n_reserved = 0; |
|
3007 |
return(fsp_reserve_free_pages(space, space_header, size, mtr)); |
|
3008 |
}
|
|
3009 |
||
3010 |
n_free_list_ext = flst_get_len(space_header + FSP_FREE, mtr); |
|
3011 |
||
3012 |
free_limit = mtr_read_ulint(space_header + FSP_FREE_LIMIT, |
|
3013 |
MLOG_4BYTES, mtr); |
|
3014 |
||
3015 |
/* Below we play safe when counting free extents above the free limit:
|
|
3016 |
some of them will contain extent descriptor pages, and therefore
|
|
3017 |
will not be free extents */
|
|
3018 |
||
3019 |
n_free_up = (size - free_limit) / FSP_EXTENT_SIZE; |
|
3020 |
||
3021 |
if (n_free_up > 0) { |
|
3022 |
n_free_up--; |
|
3023 |
if (!zip_size) { |
|
3024 |
n_free_up -= n_free_up |
|
3025 |
/ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE); |
|
3026 |
} else { |
|
3027 |
n_free_up -= n_free_up |
|
3028 |
/ (zip_size / FSP_EXTENT_SIZE); |
|
3029 |
}
|
|
3030 |
}
|
|
3031 |
||
3032 |
n_free = n_free_list_ext + n_free_up; |
|
3033 |
||
3034 |
if (alloc_type == FSP_NORMAL) { |
|
3035 |
/* We reserve 1 extent + 0.5 % of the space size to undo logs
|
|
3036 |
and 1 extent + 0.5 % to cleaning operations; NOTE: this source
|
|
3037 |
code is duplicated in the function below! */
|
|
3038 |
||
3039 |
reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200; |
|
3040 |
||
3041 |
if (n_free <= reserve + n_ext) { |
|
3042 |
||
3043 |
goto try_to_extend; |
|
3044 |
}
|
|
3045 |
} else if (alloc_type == FSP_UNDO) { |
|
3046 |
/* We reserve 0.5 % of the space size to cleaning operations */
|
|
3047 |
||
3048 |
reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 200; |
|
3049 |
||
3050 |
if (n_free <= reserve + n_ext) { |
|
3051 |
||
3052 |
goto try_to_extend; |
|
3053 |
}
|
|
3054 |
} else { |
|
3055 |
ut_a(alloc_type == FSP_CLEANING); |
|
3056 |
}
|
|
3057 |
||
3058 |
success = fil_space_reserve_free_extents(space, n_free, n_ext); |
|
3059 |
||
3060 |
if (success) { |
|
3061 |
return(TRUE); |
|
3062 |
}
|
|
3063 |
try_to_extend: |
|
3064 |
success = fsp_try_extend_data_file(&n_pages_added, space, |
|
3065 |
space_header, mtr); |
|
3066 |
if (success && n_pages_added > 0) { |
|
3067 |
||
3068 |
goto try_again; |
|
3069 |
}
|
|
3070 |
||
3071 |
return(FALSE); |
|
3072 |
}
|
|
3073 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3074 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3075 |
This function should be used to get information on how much we still
|
3076 |
will be able to insert new data to the database without running out the
|
|
3077 |
tablespace. Only free extents are taken into account and we also subtract
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3078 |
the safety margin required by the above function fsp_reserve_free_extents.
|
3079 |
@return available space in kB */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3080 |
UNIV_INTERN
|
3081 |
ullint
|
|
3082 |
fsp_get_available_space_in_free_extents( |
|
3083 |
/*====================================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3084 |
ulint space) /*!< in: space id */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3085 |
{
|
3086 |
fsp_header_t* space_header; |
|
3087 |
ulint n_free_list_ext; |
|
3088 |
ulint free_limit; |
|
3089 |
ulint size; |
|
3090 |
ulint flags; |
|
3091 |
ulint zip_size; |
|
3092 |
ulint n_free; |
|
3093 |
ulint n_free_up; |
|
3094 |
ulint reserve; |
|
3095 |
rw_lock_t* latch; |
|
3096 |
mtr_t mtr; |
|
3097 |
||
3098 |
ut_ad(!mutex_own(&kernel_mutex)); |
|
3099 |
||
3100 |
mtr_start(&mtr); |
|
3101 |
||
3102 |
latch = fil_space_get_latch(space, &flags); |
|
3103 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3104 |
||
3105 |
mtr_x_lock(latch, &mtr); |
|
3106 |
||
3107 |
space_header = fsp_get_space_header(space, zip_size, &mtr); |
|
3108 |
||
3109 |
size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, &mtr); |
|
3110 |
||
3111 |
n_free_list_ext = flst_get_len(space_header + FSP_FREE, &mtr); |
|
3112 |
||
3113 |
free_limit = mtr_read_ulint(space_header + FSP_FREE_LIMIT, |
|
3114 |
MLOG_4BYTES, &mtr); |
|
3115 |
mtr_commit(&mtr); |
|
3116 |
||
3117 |
if (size < FSP_EXTENT_SIZE) { |
|
3118 |
ut_a(space != 0); /* This must be a single-table |
|
3119 |
tablespace */
|
|
3120 |
||
3121 |
return(0); /* TODO: count free frag pages and |
|
3122 |
return a value based on that */
|
|
3123 |
}
|
|
3124 |
||
3125 |
/* Below we play safe when counting free extents above the free limit:
|
|
3126 |
some of them will contain extent descriptor pages, and therefore
|
|
3127 |
will not be free extents */
|
|
3128 |
||
3129 |
n_free_up = (size - free_limit) / FSP_EXTENT_SIZE; |
|
3130 |
||
3131 |
if (n_free_up > 0) { |
|
3132 |
n_free_up--; |
|
3133 |
if (!zip_size) { |
|
3134 |
n_free_up -= n_free_up |
|
3135 |
/ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE); |
|
3136 |
} else { |
|
3137 |
n_free_up -= n_free_up |
|
3138 |
/ (zip_size / FSP_EXTENT_SIZE); |
|
3139 |
}
|
|
3140 |
}
|
|
3141 |
||
3142 |
n_free = n_free_list_ext + n_free_up; |
|
3143 |
||
3144 |
/* We reserve 1 extent + 0.5 % of the space size to undo logs
|
|
3145 |
and 1 extent + 0.5 % to cleaning operations; NOTE: this source
|
|
3146 |
code is duplicated in the function above! */
|
|
3147 |
||
3148 |
reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200; |
|
3149 |
||
3150 |
if (reserve > n_free) { |
|
3151 |
return(0); |
|
3152 |
}
|
|
3153 |
||
3154 |
if (!zip_size) { |
|
3155 |
return((ullint) (n_free - reserve) |
|
3156 |
* FSP_EXTENT_SIZE |
|
3157 |
* (UNIV_PAGE_SIZE / 1024)); |
|
3158 |
} else { |
|
3159 |
return((ullint) (n_free - reserve) |
|
3160 |
* FSP_EXTENT_SIZE |
|
3161 |
* (zip_size / 1024)); |
|
3162 |
}
|
|
3163 |
}
|
|
3164 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3165 |
/********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3166 |
Marks a page used. The page must reside within the extents of the given
|
3167 |
segment. */
|
|
3168 |
static
|
|
3169 |
void
|
|
3170 |
fseg_mark_page_used( |
|
3171 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3172 |
fseg_inode_t* seg_inode,/*!< in: segment inode */ |
3173 |
ulint space, /*!< in: space id */ |
|
3174 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3175 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3176 |
ulint page, /*!< in: page offset */ |
3177 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3178 |
{
|
3179 |
xdes_t* descr; |
|
3180 |
ulint not_full_n_used; |
|
3181 |
||
3182 |
ut_ad(seg_inode && mtr); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
3183 |
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); |
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
3184 |
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) |
3185 |
== FSEG_MAGIC_N_VALUE); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3186 |
|
3187 |
descr = xdes_get_descriptor(space, zip_size, page, mtr); |
|
3188 |
||
3189 |
ut_ad(mtr_read_ulint(seg_inode + FSEG_ID, MLOG_4BYTES, mtr) |
|
3190 |
== mtr_read_ulint(descr + XDES_ID, MLOG_4BYTES, mtr)); |
|
3191 |
||
3192 |
if (xdes_is_free(descr, mtr)) { |
|
3193 |
/* We move the extent from the free list to the
|
|
3194 |
NOT_FULL list */
|
|
3195 |
flst_remove(seg_inode + FSEG_FREE, descr + XDES_FLST_NODE, |
|
3196 |
mtr); |
|
3197 |
flst_add_last(seg_inode + FSEG_NOT_FULL, |
|
3198 |
descr + XDES_FLST_NODE, mtr); |
|
3199 |
}
|
|
3200 |
||
3201 |
ut_ad(xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr) |
|
3202 |
== TRUE); |
|
3203 |
/* We mark the page as used */
|
|
3204 |
xdes_set_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, FALSE, mtr); |
|
3205 |
||
3206 |
not_full_n_used = mtr_read_ulint(seg_inode + FSEG_NOT_FULL_N_USED, |
|
3207 |
MLOG_4BYTES, mtr); |
|
3208 |
not_full_n_used++; |
|
3209 |
mlog_write_ulint(seg_inode + FSEG_NOT_FULL_N_USED, not_full_n_used, |
|
3210 |
MLOG_4BYTES, mtr); |
|
3211 |
if (xdes_is_full(descr, mtr)) { |
|
3212 |
/* We move the extent from the NOT_FULL list to the
|
|
3213 |
FULL list */
|
|
3214 |
flst_remove(seg_inode + FSEG_NOT_FULL, |
|
3215 |
descr + XDES_FLST_NODE, mtr); |
|
3216 |
flst_add_last(seg_inode + FSEG_FULL, |
|
3217 |
descr + XDES_FLST_NODE, mtr); |
|
3218 |
||
3219 |
mlog_write_ulint(seg_inode + FSEG_NOT_FULL_N_USED, |
|
3220 |
not_full_n_used - FSP_EXTENT_SIZE, |
|
3221 |
MLOG_4BYTES, mtr); |
|
3222 |
}
|
|
3223 |
}
|
|
3224 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3225 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3226 |
Frees a single page of a segment. */
|
3227 |
static
|
|
3228 |
void
|
|
3229 |
fseg_free_page_low( |
|
3230 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3231 |
fseg_inode_t* seg_inode, /*!< in: segment inode */ |
3232 |
ulint space, /*!< in: space id */ |
|
3233 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3234 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3235 |
ulint page, /*!< in: page offset */ |
3236 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3237 |
{
|
3238 |
xdes_t* descr; |
|
3239 |
ulint not_full_n_used; |
|
3240 |
ulint state; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3241 |
ib_id_t descr_id; |
3242 |
ib_id_t seg_id; |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3243 |
ulint i; |
3244 |
||
3245 |
ut_ad(seg_inode && mtr); |
|
3246 |
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) |
|
3247 |
== FSEG_MAGIC_N_VALUE); |
|
641.2.1
by Monty Taylor
InnoDB Plugin 1.0.2 |
3248 |
ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3249 |
|
3250 |
/* Drop search system page hash index if the page is found in
|
|
3251 |
the pool and is hashed */
|
|
3252 |
||
3253 |
btr_search_drop_page_hash_when_freed(space, zip_size, page); |
|
3254 |
||
3255 |
descr = xdes_get_descriptor(space, zip_size, page, mtr); |
|
3256 |
||
3257 |
ut_a(descr); |
|
3258 |
if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) { |
|
3259 |
fputs("InnoDB: Dump of the tablespace extent descriptor: ", |
|
3260 |
stderr); |
|
3261 |
ut_print_buf(stderr, descr, 40); |
|
3262 |
||
3263 |
fprintf(stderr, "\n" |
|
3264 |
"InnoDB: Serious error! InnoDB is trying to"
|
|
3265 |
" free page %lu\n" |
|
3266 |
"InnoDB: though it is already marked as free"
|
|
3267 |
" in the tablespace!\n" |
|
3268 |
"InnoDB: The tablespace free space info is corrupt.\n" |
|
3269 |
"InnoDB: You may need to dump your"
|
|
3270 |
" InnoDB tables and recreate the whole\n" |
|
3271 |
"InnoDB: database!\n", (ulong) page); |
|
3272 |
crash: |
|
3273 |
fputs("InnoDB: Please refer to\n" |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3274 |
"InnoDB: " REFMAN "forcing-recovery.html\n" |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3275 |
"InnoDB: about forcing recovery.\n", stderr); |
3276 |
ut_error; |
|
3277 |
}
|
|
3278 |
||
3279 |
state = xdes_get_state(descr, mtr); |
|
3280 |
||
3281 |
if (state != XDES_FSEG) { |
|
3282 |
/* The page is in the fragment pages of the segment */
|
|
3283 |
||
3284 |
for (i = 0;; i++) { |
|
3285 |
if (fseg_get_nth_frag_page_no(seg_inode, i, mtr) |
|
3286 |
== page) { |
|
3287 |
||
3288 |
fseg_set_nth_frag_page_no(seg_inode, i, |
|
3289 |
FIL_NULL, mtr); |
|
3290 |
break; |
|
3291 |
}
|
|
3292 |
}
|
|
3293 |
||
3294 |
fsp_free_page(space, zip_size, page, mtr); |
|
3295 |
||
3296 |
return; |
|
3297 |
}
|
|
3298 |
||
3299 |
/* If we get here, the page is in some extent of the segment */
|
|
3300 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3301 |
descr_id = mach_read_from_8(descr + XDES_ID); |
3302 |
seg_id = mach_read_from_8(seg_inode + FSEG_ID); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3303 |
#if 0
|
3304 |
fprintf(stderr,
|
|
3305 |
"InnoDB: InnoDB is freeing space %lu page %lu,\n"
|
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3306 |
"InnoDB: which belongs to descr seg %llu\n"
|
3307 |
"InnoDB: segment %llu.\n",
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3308 |
(ulong) space, (ulong) page,
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3309 |
(ullint) descr_id,
|
3310 |
(ullint) seg_id);
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3311 |
#endif /* 0 */
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3312 |
if (UNIV_UNLIKELY(descr_id != seg_id)) { |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3313 |
fputs("InnoDB: Dump of the tablespace extent descriptor: ", |
3314 |
stderr); |
|
3315 |
ut_print_buf(stderr, descr, 40); |
|
3316 |
fputs("\nInnoDB: Dump of the segment inode: ", stderr); |
|
3317 |
ut_print_buf(stderr, seg_inode, 40); |
|
3318 |
putc('\n', stderr); |
|
3319 |
||
3320 |
fprintf(stderr, |
|
3321 |
"InnoDB: Serious error: InnoDB is trying to"
|
|
3322 |
" free space %lu page %lu,\n" |
|
3323 |
"InnoDB: which does not belong to"
|
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3324 |
" segment %llu but belongs\n" |
3325 |
"InnoDB: to segment %llu.\n", |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3326 |
(ulong) space, (ulong) page, |
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3327 |
(ullint) descr_id, |
3328 |
(ullint) seg_id); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3329 |
goto crash; |
3330 |
}
|
|
3331 |
||
3332 |
not_full_n_used = mtr_read_ulint(seg_inode + FSEG_NOT_FULL_N_USED, |
|
3333 |
MLOG_4BYTES, mtr); |
|
3334 |
if (xdes_is_full(descr, mtr)) { |
|
3335 |
/* The fragment is full: move it to another list */
|
|
3336 |
flst_remove(seg_inode + FSEG_FULL, |
|
3337 |
descr + XDES_FLST_NODE, mtr); |
|
3338 |
flst_add_last(seg_inode + FSEG_NOT_FULL, |
|
3339 |
descr + XDES_FLST_NODE, mtr); |
|
3340 |
mlog_write_ulint(seg_inode + FSEG_NOT_FULL_N_USED, |
|
3341 |
not_full_n_used + FSP_EXTENT_SIZE - 1, |
|
3342 |
MLOG_4BYTES, mtr); |
|
3343 |
} else { |
|
3344 |
ut_a(not_full_n_used > 0); |
|
3345 |
mlog_write_ulint(seg_inode + FSEG_NOT_FULL_N_USED, |
|
3346 |
not_full_n_used - 1, MLOG_4BYTES, mtr); |
|
3347 |
}
|
|
3348 |
||
3349 |
xdes_set_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr); |
|
3350 |
xdes_set_bit(descr, XDES_CLEAN_BIT, page % FSP_EXTENT_SIZE, TRUE, mtr); |
|
3351 |
||
3352 |
if (xdes_is_free(descr, mtr)) { |
|
3353 |
/* The extent has become free: free it to space */
|
|
3354 |
flst_remove(seg_inode + FSEG_NOT_FULL, |
|
3355 |
descr + XDES_FLST_NODE, mtr); |
|
3356 |
fsp_free_extent(space, zip_size, page, mtr); |
|
3357 |
}
|
|
3358 |
}
|
|
3359 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3360 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3361 |
Frees a single page of a segment. */
|
3362 |
UNIV_INTERN
|
|
3363 |
void
|
|
3364 |
fseg_free_page( |
|
3365 |
/*===========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3366 |
fseg_header_t* seg_header, /*!< in: segment header */ |
3367 |
ulint space, /*!< in: space id */ |
|
3368 |
ulint page, /*!< in: page offset */ |
|
3369 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3370 |
{
|
3371 |
ulint flags; |
|
3372 |
ulint zip_size; |
|
3373 |
fseg_inode_t* seg_inode; |
|
3374 |
rw_lock_t* latch; |
|
3375 |
||
3376 |
latch = fil_space_get_latch(space, &flags); |
|
3377 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3378 |
||
3379 |
ut_ad(!mutex_own(&kernel_mutex) |
|
3380 |
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK)); |
|
3381 |
||
3382 |
mtr_x_lock(latch, mtr); |
|
3383 |
||
3384 |
seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr); |
|
3385 |
||
3386 |
fseg_free_page_low(seg_inode, space, zip_size, page, mtr); |
|
3387 |
||
3388 |
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
|
3389 |
buf_page_set_file_page_was_freed(space, page); |
|
3390 |
#endif
|
|
3391 |
}
|
|
3392 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3393 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3394 |
Frees an extent of a segment to the space free list. */
|
3395 |
static
|
|
3396 |
void
|
|
3397 |
fseg_free_extent( |
|
3398 |
/*=============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3399 |
fseg_inode_t* seg_inode, /*!< in: segment inode */ |
3400 |
ulint space, /*!< in: space id */ |
|
3401 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3402 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3403 |
ulint page, /*!< in: a page in the extent */ |
3404 |
mtr_t* mtr) /*!< in: mtr handle */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3405 |
{
|
3406 |
ulint first_page_in_extent; |
|
3407 |
xdes_t* descr; |
|
3408 |
ulint not_full_n_used; |
|
3409 |
ulint descr_n_used; |
|
3410 |
ulint i; |
|
3411 |
||
3412 |
ut_ad(seg_inode && mtr); |
|
3413 |
||
3414 |
descr = xdes_get_descriptor(space, zip_size, page, mtr); |
|
3415 |
||
3416 |
ut_a(xdes_get_state(descr, mtr) == XDES_FSEG); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3417 |
ut_a(!memcmp(descr + XDES_ID, seg_inode + FSEG_ID, 8)); |
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
3418 |
ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) |
3419 |
== FSEG_MAGIC_N_VALUE); |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3420 |
|
3421 |
first_page_in_extent = page - (page % FSP_EXTENT_SIZE); |
|
3422 |
||
3423 |
for (i = 0; i < FSP_EXTENT_SIZE; i++) { |
|
3424 |
if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) { |
|
3425 |
||
3426 |
/* Drop search system page hash index if the page is
|
|
3427 |
found in the pool and is hashed */
|
|
3428 |
||
3429 |
btr_search_drop_page_hash_when_freed( |
|
3430 |
space, zip_size, first_page_in_extent + i); |
|
3431 |
}
|
|
3432 |
}
|
|
3433 |
||
3434 |
if (xdes_is_full(descr, mtr)) { |
|
3435 |
flst_remove(seg_inode + FSEG_FULL, |
|
3436 |
descr + XDES_FLST_NODE, mtr); |
|
3437 |
} else if (xdes_is_free(descr, mtr)) { |
|
3438 |
flst_remove(seg_inode + FSEG_FREE, |
|
3439 |
descr + XDES_FLST_NODE, mtr); |
|
3440 |
} else { |
|
3441 |
flst_remove(seg_inode + FSEG_NOT_FULL, |
|
3442 |
descr + XDES_FLST_NODE, mtr); |
|
3443 |
||
3444 |
not_full_n_used = mtr_read_ulint( |
|
3445 |
seg_inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr); |
|
3446 |
||
3447 |
descr_n_used = xdes_get_n_used(descr, mtr); |
|
3448 |
ut_a(not_full_n_used >= descr_n_used); |
|
3449 |
mlog_write_ulint(seg_inode + FSEG_NOT_FULL_N_USED, |
|
3450 |
not_full_n_used - descr_n_used, |
|
3451 |
MLOG_4BYTES, mtr); |
|
3452 |
}
|
|
3453 |
||
3454 |
fsp_free_extent(space, zip_size, page, mtr); |
|
3455 |
||
3456 |
#ifdef UNIV_DEBUG_FILE_ACCESSES
|
|
3457 |
for (i = 0; i < FSP_EXTENT_SIZE; i++) { |
|
3458 |
||
3459 |
buf_page_set_file_page_was_freed(space, |
|
3460 |
first_page_in_extent + i); |
|
3461 |
}
|
|
3462 |
#endif
|
|
3463 |
}
|
|
3464 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3465 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3466 |
Frees part of a segment. This function can be used to free a segment by
|
3467 |
repeatedly calling this function in different mini-transactions. Doing
|
|
3468 |
the freeing in a single mini-transaction might result in too big a
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3469 |
mini-transaction.
|
3470 |
@return TRUE if freeing completed */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3471 |
UNIV_INTERN
|
3472 |
ibool
|
|
3473 |
fseg_free_step( |
|
3474 |
/*===========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3475 |
fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3476 |
resides on the first page of the frag list
|
3477 |
of the segment, this pointer becomes obsolete
|
|
3478 |
after the last freeing step */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3479 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3480 |
{
|
3481 |
ulint n; |
|
3482 |
ulint page; |
|
3483 |
xdes_t* descr; |
|
3484 |
fseg_inode_t* inode; |
|
3485 |
ulint space; |
|
3486 |
ulint flags; |
|
3487 |
ulint zip_size; |
|
3488 |
ulint header_page; |
|
3489 |
rw_lock_t* latch; |
|
3490 |
||
3491 |
space = page_get_space_id(page_align(header)); |
|
3492 |
header_page = page_get_page_no(page_align(header)); |
|
3493 |
||
3494 |
latch = fil_space_get_latch(space, &flags); |
|
3495 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3496 |
||
3497 |
ut_ad(!mutex_own(&kernel_mutex) |
|
3498 |
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK)); |
|
3499 |
||
3500 |
mtr_x_lock(latch, mtr); |
|
3501 |
||
3502 |
descr = xdes_get_descriptor(space, zip_size, header_page, mtr); |
|
3503 |
||
3504 |
/* Check that the header resides on a page which has not been
|
|
3505 |
freed yet */
|
|
3506 |
||
3507 |
ut_a(descr); |
|
3508 |
ut_a(xdes_get_bit(descr, XDES_FREE_BIT, |
|
3509 |
header_page % FSP_EXTENT_SIZE, mtr) == FALSE); |
|
1819.5.86
by stewart at flamingspork
[patch 086/129] Merge patch for revision 1885 from InnoDB SVN: |
3510 |
inode = fseg_inode_try_get(header, space, zip_size, mtr); |
3511 |
||
3512 |
if (UNIV_UNLIKELY(inode == NULL)) { |
|
3513 |
fprintf(stderr, "double free of inode from %u:%u\n", |
|
3514 |
(unsigned) space, (unsigned) header_page); |
|
3515 |
return(TRUE); |
|
3516 |
}
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3517 |
|
3518 |
descr = fseg_get_first_extent(inode, space, zip_size, mtr); |
|
3519 |
||
3520 |
if (descr != NULL) { |
|
3521 |
/* Free the extent held by the segment */
|
|
3522 |
page = xdes_get_offset(descr); |
|
3523 |
||
3524 |
fseg_free_extent(inode, space, zip_size, page, mtr); |
|
3525 |
||
3526 |
return(FALSE); |
|
3527 |
}
|
|
3528 |
||
3529 |
/* Free a frag page */
|
|
3530 |
n = fseg_find_last_used_frag_page_slot(inode, mtr); |
|
3531 |
||
3532 |
if (n == ULINT_UNDEFINED) { |
|
3533 |
/* Freeing completed: free the segment inode */
|
|
3534 |
fsp_free_seg_inode(space, zip_size, inode, mtr); |
|
3535 |
||
3536 |
return(TRUE); |
|
3537 |
}
|
|
3538 |
||
3539 |
fseg_free_page_low(inode, space, zip_size, |
|
3540 |
fseg_get_nth_frag_page_no(inode, n, mtr), mtr); |
|
3541 |
||
3542 |
n = fseg_find_last_used_frag_page_slot(inode, mtr); |
|
3543 |
||
3544 |
if (n == ULINT_UNDEFINED) { |
|
3545 |
/* Freeing completed: free the segment inode */
|
|
3546 |
fsp_free_seg_inode(space, zip_size, inode, mtr); |
|
3547 |
||
3548 |
return(TRUE); |
|
3549 |
}
|
|
3550 |
||
3551 |
return(FALSE); |
|
3552 |
}
|
|
3553 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3554 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3555 |
Frees part of a segment. Differs from fseg_free_step because this function
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3556 |
leaves the header page unfreed.
|
3557 |
@return TRUE if freeing completed, except the header page */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3558 |
UNIV_INTERN
|
3559 |
ibool
|
|
3560 |
fseg_free_step_not_header( |
|
3561 |
/*======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3562 |
fseg_header_t* header, /*!< in: segment header which must reside on |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3563 |
the first fragment page of the segment */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3564 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3565 |
{
|
3566 |
ulint n; |
|
3567 |
ulint page; |
|
3568 |
xdes_t* descr; |
|
3569 |
fseg_inode_t* inode; |
|
3570 |
ulint space; |
|
3571 |
ulint flags; |
|
3572 |
ulint zip_size; |
|
3573 |
ulint page_no; |
|
3574 |
rw_lock_t* latch; |
|
3575 |
||
3576 |
space = page_get_space_id(page_align(header)); |
|
3577 |
||
3578 |
latch = fil_space_get_latch(space, &flags); |
|
3579 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3580 |
||
3581 |
ut_ad(!mutex_own(&kernel_mutex) |
|
3582 |
|| mtr_memo_contains(mtr, latch, MTR_MEMO_X_LOCK)); |
|
3583 |
||
3584 |
mtr_x_lock(latch, mtr); |
|
3585 |
||
3586 |
inode = fseg_inode_get(header, space, zip_size, mtr); |
|
3587 |
||
3588 |
descr = fseg_get_first_extent(inode, space, zip_size, mtr); |
|
3589 |
||
3590 |
if (descr != NULL) { |
|
3591 |
/* Free the extent held by the segment */
|
|
3592 |
page = xdes_get_offset(descr); |
|
3593 |
||
3594 |
fseg_free_extent(inode, space, zip_size, page, mtr); |
|
3595 |
||
3596 |
return(FALSE); |
|
3597 |
}
|
|
3598 |
||
3599 |
/* Free a frag page */
|
|
3600 |
||
3601 |
n = fseg_find_last_used_frag_page_slot(inode, mtr); |
|
3602 |
||
3603 |
if (n == ULINT_UNDEFINED) { |
|
3604 |
ut_error; |
|
3605 |
}
|
|
3606 |
||
3607 |
page_no = fseg_get_nth_frag_page_no(inode, n, mtr); |
|
3608 |
||
3609 |
if (page_no == page_get_page_no(page_align(header))) { |
|
3610 |
||
3611 |
return(TRUE); |
|
3612 |
}
|
|
3613 |
||
3614 |
fseg_free_page_low(inode, space, zip_size, page_no, mtr); |
|
3615 |
||
3616 |
return(FALSE); |
|
3617 |
}
|
|
3618 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3619 |
/**********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3620 |
Returns the first extent descriptor for a segment. We think of the extent
|
3621 |
lists of the segment catenated in the order FSEG_FULL -> FSEG_NOT_FULL
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3622 |
-> FSEG_FREE.
|
3623 |
@return the first extent descriptor, or NULL if none */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3624 |
static
|
3625 |
xdes_t* |
|
3626 |
fseg_get_first_extent( |
|
3627 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3628 |
fseg_inode_t* inode, /*!< in: segment inode */ |
3629 |
ulint space, /*!< in: space id */ |
|
3630 |
ulint zip_size,/*!< in: compressed page size in bytes |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3631 |
or 0 for uncompressed pages */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3632 |
mtr_t* mtr) /*!< in: mtr */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3633 |
{
|
3634 |
fil_addr_t first; |
|
3635 |
xdes_t* descr; |
|
3636 |
||
3637 |
ut_ad(inode && mtr); |
|
3638 |
||
3639 |
ut_ad(space == page_get_space_id(page_align(inode))); |
|
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
3640 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3641 |
|
3642 |
first = fil_addr_null; |
|
3643 |
||
3644 |
if (flst_get_len(inode + FSEG_FULL, mtr) > 0) { |
|
3645 |
||
3646 |
first = flst_get_first(inode + FSEG_FULL, mtr); |
|
3647 |
||
3648 |
} else if (flst_get_len(inode + FSEG_NOT_FULL, mtr) > 0) { |
|
3649 |
||
3650 |
first = flst_get_first(inode + FSEG_NOT_FULL, mtr); |
|
3651 |
||
3652 |
} else if (flst_get_len(inode + FSEG_FREE, mtr) > 0) { |
|
3653 |
||
3654 |
first = flst_get_first(inode + FSEG_FREE, mtr); |
|
3655 |
}
|
|
3656 |
||
3657 |
if (first.page == FIL_NULL) { |
|
3658 |
||
3659 |
return(NULL); |
|
3660 |
}
|
|
3661 |
descr = xdes_lst_get_descriptor(space, zip_size, first, mtr); |
|
3662 |
||
3663 |
return(descr); |
|
3664 |
}
|
|
3665 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3666 |
/*******************************************************************//**
|
3667 |
Validates a segment.
|
|
3668 |
@return TRUE if ok */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3669 |
static
|
3670 |
ibool
|
|
3671 |
fseg_validate_low( |
|
3672 |
/*==============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3673 |
fseg_inode_t* inode, /*!< in: segment inode */ |
3674 |
mtr_t* mtr2) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3675 |
{
|
3676 |
ulint space; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3677 |
ib_id_t seg_id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3678 |
mtr_t mtr; |
3679 |
xdes_t* descr; |
|
3680 |
fil_addr_t node_addr; |
|
3681 |
ulint n_used = 0; |
|
3682 |
ulint n_used2 = 0; |
|
3683 |
||
3684 |
ut_ad(mtr_memo_contains_page(mtr2, inode, MTR_MEMO_PAGE_X_FIX)); |
|
3685 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
|
3686 |
||
3687 |
space = page_get_space_id(page_align(inode)); |
|
3688 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3689 |
seg_id = mach_read_from_8(inode + FSEG_ID); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3690 |
n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, |
3691 |
MLOG_4BYTES, mtr2); |
|
3692 |
flst_validate(inode + FSEG_FREE, mtr2); |
|
3693 |
flst_validate(inode + FSEG_NOT_FULL, mtr2); |
|
3694 |
flst_validate(inode + FSEG_FULL, mtr2); |
|
3695 |
||
3696 |
/* Validate FSEG_FREE list */
|
|
3697 |
node_addr = flst_get_first(inode + FSEG_FREE, mtr2); |
|
3698 |
||
3699 |
while (!fil_addr_is_null(node_addr)) { |
|
3700 |
ulint flags; |
|
3701 |
ulint zip_size; |
|
3702 |
||
3703 |
mtr_start(&mtr); |
|
3704 |
mtr_x_lock(fil_space_get_latch(space, &flags), &mtr); |
|
3705 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3706 |
||
3707 |
descr = xdes_lst_get_descriptor(space, zip_size, |
|
3708 |
node_addr, &mtr); |
|
3709 |
||
3710 |
ut_a(xdes_get_n_used(descr, &mtr) == 0); |
|
3711 |
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3712 |
ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3713 |
|
3714 |
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); |
|
3715 |
mtr_commit(&mtr); |
|
3716 |
}
|
|
3717 |
||
3718 |
/* Validate FSEG_NOT_FULL list */
|
|
3719 |
||
3720 |
node_addr = flst_get_first(inode + FSEG_NOT_FULL, mtr2); |
|
3721 |
||
3722 |
while (!fil_addr_is_null(node_addr)) { |
|
3723 |
ulint flags; |
|
3724 |
ulint zip_size; |
|
3725 |
||
3726 |
mtr_start(&mtr); |
|
3727 |
mtr_x_lock(fil_space_get_latch(space, &flags), &mtr); |
|
3728 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3729 |
||
3730 |
descr = xdes_lst_get_descriptor(space, zip_size, |
|
3731 |
node_addr, &mtr); |
|
3732 |
||
3733 |
ut_a(xdes_get_n_used(descr, &mtr) > 0); |
|
3734 |
ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE); |
|
3735 |
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3736 |
ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3737 |
|
3738 |
n_used2 += xdes_get_n_used(descr, &mtr); |
|
3739 |
||
3740 |
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); |
|
3741 |
mtr_commit(&mtr); |
|
3742 |
}
|
|
3743 |
||
3744 |
/* Validate FSEG_FULL list */
|
|
3745 |
||
3746 |
node_addr = flst_get_first(inode + FSEG_FULL, mtr2); |
|
3747 |
||
3748 |
while (!fil_addr_is_null(node_addr)) { |
|
3749 |
ulint flags; |
|
3750 |
ulint zip_size; |
|
3751 |
||
3752 |
mtr_start(&mtr); |
|
3753 |
mtr_x_lock(fil_space_get_latch(space, &flags), &mtr); |
|
3754 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3755 |
||
3756 |
descr = xdes_lst_get_descriptor(space, zip_size, |
|
3757 |
node_addr, &mtr); |
|
3758 |
||
3759 |
ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE); |
|
3760 |
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3761 |
ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3762 |
|
3763 |
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); |
|
3764 |
mtr_commit(&mtr); |
|
3765 |
}
|
|
3766 |
||
3767 |
ut_a(n_used == n_used2); |
|
3768 |
||
3769 |
return(TRUE); |
|
3770 |
}
|
|
3771 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3772 |
#ifdef UNIV_DEBUG
|
3773 |
/*******************************************************************//**
|
|
3774 |
Validates a segment.
|
|
3775 |
@return TRUE if ok */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3776 |
UNIV_INTERN
|
3777 |
ibool
|
|
3778 |
fseg_validate( |
|
3779 |
/*==========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3780 |
fseg_header_t* header, /*!< in: segment header */ |
3781 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3782 |
{
|
3783 |
fseg_inode_t* inode; |
|
3784 |
ibool ret; |
|
3785 |
ulint space; |
|
3786 |
ulint flags; |
|
3787 |
ulint zip_size; |
|
3788 |
||
3789 |
space = page_get_space_id(page_align(header)); |
|
3790 |
||
3791 |
mtr_x_lock(fil_space_get_latch(space, &flags), mtr); |
|
3792 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3793 |
||
3794 |
inode = fseg_inode_get(header, space, zip_size, mtr); |
|
3795 |
||
3796 |
ret = fseg_validate_low(inode, mtr); |
|
3797 |
||
3798 |
return(ret); |
|
3799 |
}
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3800 |
#endif /* UNIV_DEBUG */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3801 |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3802 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3803 |
Writes info of a segment. */
|
3804 |
static
|
|
3805 |
void
|
|
3806 |
fseg_print_low( |
|
3807 |
/*===========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3808 |
fseg_inode_t* inode, /*!< in: segment inode */ |
3809 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3810 |
{
|
3811 |
ulint space; |
|
3812 |
ulint n_used; |
|
3813 |
ulint n_frag; |
|
3814 |
ulint n_free; |
|
3815 |
ulint n_not_full; |
|
3816 |
ulint n_full; |
|
3817 |
ulint reserved; |
|
3818 |
ulint used; |
|
3819 |
ulint page_no; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3820 |
ib_id_t seg_id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3821 |
|
3822 |
ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX)); |
|
3823 |
space = page_get_space_id(page_align(inode)); |
|
3824 |
page_no = page_get_page_no(page_align(inode)); |
|
3825 |
||
3826 |
reserved = fseg_n_reserved_pages_low(inode, &used, mtr); |
|
3827 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3828 |
seg_id = mach_read_from_8(inode + FSEG_ID); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3829 |
|
3830 |
n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, |
|
3831 |
MLOG_4BYTES, mtr); |
|
3832 |
n_frag = fseg_get_n_frag_pages(inode, mtr); |
|
3833 |
n_free = flst_get_len(inode + FSEG_FREE, mtr); |
|
3834 |
n_not_full = flst_get_len(inode + FSEG_NOT_FULL, mtr); |
|
3835 |
n_full = flst_get_len(inode + FSEG_FULL, mtr); |
|
3836 |
||
3837 |
fprintf(stderr, |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3838 |
"SEGMENT id %llu space %lu; page %lu;"
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3839 |
" res %lu used %lu; full ext %lu\n" |
3840 |
"fragm pages %lu; free extents %lu;"
|
|
3841 |
" not full extents %lu: pages %lu\n", |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
3842 |
(ullint) seg_id, |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3843 |
(ulong) space, (ulong) page_no, |
3844 |
(ulong) reserved, (ulong) used, (ulong) n_full, |
|
3845 |
(ulong) n_frag, (ulong) n_free, (ulong) n_not_full, |
|
3846 |
(ulong) n_used); |
|
1819.5.83
by stewart at flamingspork
[patch 083/129] Merge patch for revision 1882 from InnoDB SVN: |
3847 |
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3848 |
}
|
3849 |
||
3850 |
#ifdef UNIV_BTR_PRINT
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3851 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3852 |
Writes info of a segment. */
|
3853 |
UNIV_INTERN
|
|
3854 |
void
|
|
3855 |
fseg_print( |
|
3856 |
/*=======*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3857 |
fseg_header_t* header, /*!< in: segment header */ |
3858 |
mtr_t* mtr) /*!< in: mtr */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3859 |
{
|
3860 |
fseg_inode_t* inode; |
|
3861 |
ulint space; |
|
3862 |
ulint flags; |
|
3863 |
ulint zip_size; |
|
3864 |
||
3865 |
space = page_get_space_id(page_align(header)); |
|
3866 |
||
3867 |
mtr_x_lock(fil_space_get_latch(space, &flags), mtr); |
|
3868 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3869 |
||
3870 |
inode = fseg_inode_get(header, space, zip_size, mtr); |
|
3871 |
||
3872 |
fseg_print_low(inode, mtr); |
|
3873 |
}
|
|
3874 |
#endif /* UNIV_BTR_PRINT */ |
|
3875 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3876 |
/*******************************************************************//**
|
3877 |
Validates the file space system and its segments.
|
|
3878 |
@return TRUE if ok */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3879 |
UNIV_INTERN
|
3880 |
ibool
|
|
3881 |
fsp_validate( |
|
3882 |
/*=========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
3883 |
ulint space) /*!< in: space id */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
3884 |
{
|
3885 |
fsp_header_t* header; |
|
3886 |
fseg_inode_t* seg_inode; |
|
3887 |
page_t* seg_inode_page; |
|
3888 |
rw_lock_t* latch; |
|
3889 |
ulint size; |
|
3890 |
ulint flags; |
|
3891 |
ulint zip_size; |
|
3892 |
ulint free_limit; |
|
3893 |
ulint frag_n_used; |
|
3894 |
mtr_t mtr; |
|
3895 |
mtr_t mtr2; |
|
3896 |
xdes_t* descr; |
|
3897 |
fil_addr_t node_addr; |
|
3898 |
fil_addr_t next_node_addr; |
|
3899 |
ulint descr_count = 0; |
|
3900 |
ulint n_used = 0; |
|
3901 |
ulint n_used2 = 0; |
|
3902 |
ulint n_full_frag_pages; |
|
3903 |
ulint n; |
|
3904 |
ulint seg_inode_len_free; |
|
3905 |
ulint seg_inode_len_full; |
|
3906 |
||
3907 |
latch = fil_space_get_latch(space, &flags); |
|
3908 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
3909 |
ut_a(ut_is_2pow(zip_size)); |
|
3910 |
ut_a(zip_size <= UNIV_PAGE_SIZE); |
|
3911 |
ut_a(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE); |
|
3912 |
||
3913 |
/* Start first a mini-transaction mtr2 to lock out all other threads
|
|
3914 |
from the fsp system */
|
|
3915 |
mtr_start(&mtr2); |
|
3916 |
mtr_x_lock(latch, &mtr2); |
|
3917 |
||
3918 |
mtr_start(&mtr); |
|
3919 |
mtr_x_lock(latch, &mtr); |
|
3920 |
||
3921 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
3922 |
||
3923 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr); |
|
3924 |
free_limit = mtr_read_ulint(header + FSP_FREE_LIMIT, |
|
3925 |
MLOG_4BYTES, &mtr); |
|
3926 |
frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, |
|
3927 |
MLOG_4BYTES, &mtr); |
|
3928 |
||
3929 |
n_full_frag_pages = FSP_EXTENT_SIZE |
|
3930 |
* flst_get_len(header + FSP_FULL_FRAG, &mtr); |
|
3931 |
||
3932 |
if (UNIV_UNLIKELY(free_limit > size)) { |
|
3933 |
||
3934 |
ut_a(space != 0); |
|
3935 |
ut_a(size < FSP_EXTENT_SIZE); |
|
3936 |
}
|
|
3937 |
||
3938 |
flst_validate(header + FSP_FREE, &mtr); |
|
3939 |
flst_validate(header + FSP_FREE_FRAG, &mtr); |
|
3940 |
flst_validate(header + FSP_FULL_FRAG, &mtr); |
|
3941 |
||
3942 |
mtr_commit(&mtr); |
|
3943 |
||
3944 |
/* Validate FSP_FREE list */
|
|
3945 |
mtr_start(&mtr); |
|
3946 |
mtr_x_lock(latch, &mtr); |
|
3947 |
||
3948 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
3949 |
node_addr = flst_get_first(header + FSP_FREE, &mtr); |
|
3950 |
||
3951 |
mtr_commit(&mtr); |
|
3952 |
||
3953 |
while (!fil_addr_is_null(node_addr)) { |
|
3954 |
mtr_start(&mtr); |
|
3955 |
mtr_x_lock(latch, &mtr); |
|
3956 |
||
3957 |
descr_count++; |
|
3958 |
descr = xdes_lst_get_descriptor(space, zip_size, |
|
3959 |
node_addr, &mtr); |
|
3960 |
||
3961 |
ut_a(xdes_get_n_used(descr, &mtr) == 0); |
|
3962 |
ut_a(xdes_get_state(descr, &mtr) == XDES_FREE); |
|
3963 |
||
3964 |
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); |
|
3965 |
mtr_commit(&mtr); |
|
3966 |
}
|
|
3967 |
||
3968 |
/* Validate FSP_FREE_FRAG list */
|
|
3969 |
mtr_start(&mtr); |
|
3970 |
mtr_x_lock(latch, &mtr); |
|
3971 |
||
3972 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
3973 |
node_addr = flst_get_first(header + FSP_FREE_FRAG, &mtr); |
|
3974 |
||
3975 |
mtr_commit(&mtr); |
|
3976 |
||
3977 |
while (!fil_addr_is_null(node_addr)) { |
|
3978 |
mtr_start(&mtr); |
|
3979 |
mtr_x_lock(latch, &mtr); |
|
3980 |
||
3981 |
descr_count++; |
|
3982 |
descr = xdes_lst_get_descriptor(space, zip_size, |
|
3983 |
node_addr, &mtr); |
|
3984 |
||
3985 |
ut_a(xdes_get_n_used(descr, &mtr) > 0); |
|
3986 |
ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE); |
|
3987 |
ut_a(xdes_get_state(descr, &mtr) == XDES_FREE_FRAG); |
|
3988 |
||
3989 |
n_used += xdes_get_n_used(descr, &mtr); |
|
3990 |
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); |
|
3991 |
||
3992 |
mtr_commit(&mtr); |
|
3993 |
}
|
|
3994 |
||
3995 |
/* Validate FSP_FULL_FRAG list */
|
|
3996 |
mtr_start(&mtr); |
|
3997 |
mtr_x_lock(latch, &mtr); |
|
3998 |
||
3999 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
4000 |
node_addr = flst_get_first(header + FSP_FULL_FRAG, &mtr); |
|
4001 |
||
4002 |
mtr_commit(&mtr); |
|
4003 |
||
4004 |
while (!fil_addr_is_null(node_addr)) { |
|
4005 |
mtr_start(&mtr); |
|
4006 |
mtr_x_lock(latch, &mtr); |
|
4007 |
||
4008 |
descr_count++; |
|
4009 |
descr = xdes_lst_get_descriptor(space, zip_size, |
|
4010 |
node_addr, &mtr); |
|
4011 |
||
4012 |
ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE); |
|
4013 |
ut_a(xdes_get_state(descr, &mtr) == XDES_FULL_FRAG); |
|
4014 |
||
4015 |
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); |
|
4016 |
mtr_commit(&mtr); |
|
4017 |
}
|
|
4018 |
||
4019 |
/* Validate segments */
|
|
4020 |
mtr_start(&mtr); |
|
4021 |
mtr_x_lock(latch, &mtr); |
|
4022 |
||
4023 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
4024 |
||
4025 |
node_addr = flst_get_first(header + FSP_SEG_INODES_FULL, &mtr); |
|
4026 |
||
4027 |
seg_inode_len_full = flst_get_len(header + FSP_SEG_INODES_FULL, &mtr); |
|
4028 |
||
4029 |
mtr_commit(&mtr); |
|
4030 |
||
4031 |
while (!fil_addr_is_null(node_addr)) { |
|
4032 |
||
4033 |
n = 0; |
|
4034 |
do { |
|
4035 |
mtr_start(&mtr); |
|
4036 |
mtr_x_lock(latch, &mtr); |
|
4037 |
||
4038 |
seg_inode_page = fut_get_ptr( |
|
4039 |
space, zip_size, node_addr, RW_X_LATCH, &mtr) |
|
4040 |
- FSEG_INODE_PAGE_NODE; |
|
4041 |
||
4042 |
seg_inode = fsp_seg_inode_page_get_nth_inode( |
|
4043 |
seg_inode_page, n, zip_size, &mtr); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4044 |
ut_a(mach_read_from_8(seg_inode + FSEG_ID) != 0); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4045 |
fseg_validate_low(seg_inode, &mtr); |
4046 |
||
4047 |
descr_count += flst_get_len(seg_inode + FSEG_FREE, |
|
4048 |
&mtr); |
|
4049 |
descr_count += flst_get_len(seg_inode + FSEG_FULL, |
|
4050 |
&mtr); |
|
4051 |
descr_count += flst_get_len(seg_inode + FSEG_NOT_FULL, |
|
4052 |
&mtr); |
|
4053 |
||
4054 |
n_used2 += fseg_get_n_frag_pages(seg_inode, &mtr); |
|
4055 |
||
4056 |
next_node_addr = flst_get_next_addr( |
|
4057 |
seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr); |
|
4058 |
mtr_commit(&mtr); |
|
4059 |
} while (++n < FSP_SEG_INODES_PER_PAGE(zip_size)); |
|
4060 |
||
4061 |
node_addr = next_node_addr; |
|
4062 |
}
|
|
4063 |
||
4064 |
mtr_start(&mtr); |
|
4065 |
mtr_x_lock(latch, &mtr); |
|
4066 |
||
4067 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
4068 |
||
4069 |
node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr); |
|
4070 |
||
4071 |
seg_inode_len_free = flst_get_len(header + FSP_SEG_INODES_FREE, &mtr); |
|
4072 |
||
4073 |
mtr_commit(&mtr); |
|
4074 |
||
4075 |
while (!fil_addr_is_null(node_addr)) { |
|
4076 |
||
4077 |
n = 0; |
|
4078 |
||
4079 |
do { |
|
4080 |
mtr_start(&mtr); |
|
4081 |
mtr_x_lock(latch, &mtr); |
|
4082 |
||
4083 |
seg_inode_page = fut_get_ptr( |
|
4084 |
space, zip_size, node_addr, RW_X_LATCH, &mtr) |
|
4085 |
- FSEG_INODE_PAGE_NODE; |
|
4086 |
||
4087 |
seg_inode = fsp_seg_inode_page_get_nth_inode( |
|
4088 |
seg_inode_page, n, zip_size, &mtr); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4089 |
if (mach_read_from_8(seg_inode + FSEG_ID)) { |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4090 |
fseg_validate_low(seg_inode, &mtr); |
4091 |
||
4092 |
descr_count += flst_get_len( |
|
4093 |
seg_inode + FSEG_FREE, &mtr); |
|
4094 |
descr_count += flst_get_len( |
|
4095 |
seg_inode + FSEG_FULL, &mtr); |
|
4096 |
descr_count += flst_get_len( |
|
4097 |
seg_inode + FSEG_NOT_FULL, &mtr); |
|
4098 |
n_used2 += fseg_get_n_frag_pages( |
|
4099 |
seg_inode, &mtr); |
|
4100 |
}
|
|
4101 |
||
4102 |
next_node_addr = flst_get_next_addr( |
|
4103 |
seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr); |
|
4104 |
mtr_commit(&mtr); |
|
4105 |
} while (++n < FSP_SEG_INODES_PER_PAGE(zip_size)); |
|
4106 |
||
4107 |
node_addr = next_node_addr; |
|
4108 |
}
|
|
4109 |
||
4110 |
ut_a(descr_count * FSP_EXTENT_SIZE == free_limit); |
|
4111 |
if (!zip_size) { |
|
4112 |
ut_a(n_used + n_full_frag_pages |
|
4113 |
== n_used2 + 2 * ((free_limit + (UNIV_PAGE_SIZE - 1)) |
|
4114 |
/ UNIV_PAGE_SIZE) |
|
4115 |
+ seg_inode_len_full + seg_inode_len_free); |
|
4116 |
} else { |
|
4117 |
ut_a(n_used + n_full_frag_pages |
|
4118 |
== n_used2 + 2 * ((free_limit + (zip_size - 1)) |
|
4119 |
/ zip_size) |
|
4120 |
+ seg_inode_len_full + seg_inode_len_free); |
|
4121 |
}
|
|
4122 |
ut_a(frag_n_used == n_used); |
|
4123 |
||
4124 |
mtr_commit(&mtr2); |
|
4125 |
||
4126 |
return(TRUE); |
|
4127 |
}
|
|
4128 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
4129 |
/*******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4130 |
Prints info of a file space. */
|
4131 |
UNIV_INTERN
|
|
4132 |
void
|
|
4133 |
fsp_print( |
|
4134 |
/*======*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
4135 |
ulint space) /*!< in: space id */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4136 |
{
|
4137 |
fsp_header_t* header; |
|
4138 |
fseg_inode_t* seg_inode; |
|
4139 |
page_t* seg_inode_page; |
|
4140 |
rw_lock_t* latch; |
|
4141 |
ulint flags; |
|
4142 |
ulint zip_size; |
|
4143 |
ulint size; |
|
4144 |
ulint free_limit; |
|
4145 |
ulint frag_n_used; |
|
4146 |
fil_addr_t node_addr; |
|
4147 |
fil_addr_t next_node_addr; |
|
4148 |
ulint n_free; |
|
4149 |
ulint n_free_frag; |
|
4150 |
ulint n_full_frag; |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4151 |
ib_id_t seg_id; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4152 |
ulint n; |
4153 |
ulint n_segs = 0; |
|
4154 |
mtr_t mtr; |
|
4155 |
mtr_t mtr2; |
|
4156 |
||
4157 |
latch = fil_space_get_latch(space, &flags); |
|
4158 |
zip_size = dict_table_flags_to_zip_size(flags); |
|
4159 |
||
4160 |
/* Start first a mini-transaction mtr2 to lock out all other threads
|
|
4161 |
from the fsp system */
|
|
4162 |
||
4163 |
mtr_start(&mtr2); |
|
4164 |
||
4165 |
mtr_x_lock(latch, &mtr2); |
|
4166 |
||
4167 |
mtr_start(&mtr); |
|
4168 |
||
4169 |
mtr_x_lock(latch, &mtr); |
|
4170 |
||
4171 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
4172 |
||
4173 |
size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr); |
|
4174 |
||
4175 |
free_limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, |
|
4176 |
&mtr); |
|
4177 |
frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES, |
|
4178 |
&mtr); |
|
4179 |
n_free = flst_get_len(header + FSP_FREE, &mtr); |
|
4180 |
n_free_frag = flst_get_len(header + FSP_FREE_FRAG, &mtr); |
|
4181 |
n_full_frag = flst_get_len(header + FSP_FULL_FRAG, &mtr); |
|
4182 |
||
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4183 |
seg_id = mach_read_from_8(header + FSP_SEG_ID); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4184 |
|
4185 |
fprintf(stderr, |
|
4186 |
"FILE SPACE INFO: id %lu\n" |
|
4187 |
"size %lu, free limit %lu, free extents %lu\n" |
|
4188 |
"not full frag extents %lu: used pages %lu,"
|
|
4189 |
" full frag extents %lu\n" |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4190 |
"first seg id not used %llu\n", |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4191 |
(ulong) space, |
4192 |
(ulong) size, (ulong) free_limit, (ulong) n_free, |
|
4193 |
(ulong) n_free_frag, (ulong) frag_n_used, (ulong) n_full_frag, |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4194 |
(ullint) seg_id); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4195 |
|
4196 |
mtr_commit(&mtr); |
|
4197 |
||
4198 |
/* Print segments */
|
|
4199 |
||
4200 |
mtr_start(&mtr); |
|
4201 |
mtr_x_lock(latch, &mtr); |
|
4202 |
||
4203 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
4204 |
||
4205 |
node_addr = flst_get_first(header + FSP_SEG_INODES_FULL, &mtr); |
|
4206 |
||
4207 |
mtr_commit(&mtr); |
|
4208 |
||
4209 |
while (!fil_addr_is_null(node_addr)) { |
|
4210 |
||
4211 |
n = 0; |
|
4212 |
||
4213 |
do { |
|
4214 |
||
4215 |
mtr_start(&mtr); |
|
4216 |
mtr_x_lock(latch, &mtr); |
|
4217 |
||
4218 |
seg_inode_page = fut_get_ptr( |
|
4219 |
space, zip_size, node_addr, RW_X_LATCH, &mtr) |
|
4220 |
- FSEG_INODE_PAGE_NODE; |
|
4221 |
||
4222 |
seg_inode = fsp_seg_inode_page_get_nth_inode( |
|
4223 |
seg_inode_page, n, zip_size, &mtr); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4224 |
ut_a(mach_read_from_8(seg_inode + FSEG_ID) != 0); |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4225 |
fseg_print_low(seg_inode, &mtr); |
4226 |
||
4227 |
n_segs++; |
|
4228 |
||
4229 |
next_node_addr = flst_get_next_addr( |
|
4230 |
seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr); |
|
4231 |
mtr_commit(&mtr); |
|
4232 |
} while (++n < FSP_SEG_INODES_PER_PAGE(zip_size)); |
|
4233 |
||
4234 |
node_addr = next_node_addr; |
|
4235 |
}
|
|
4236 |
||
4237 |
mtr_start(&mtr); |
|
4238 |
mtr_x_lock(latch, &mtr); |
|
4239 |
||
4240 |
header = fsp_get_space_header(space, zip_size, &mtr); |
|
4241 |
||
4242 |
node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr); |
|
4243 |
||
4244 |
mtr_commit(&mtr); |
|
4245 |
||
4246 |
while (!fil_addr_is_null(node_addr)) { |
|
4247 |
||
4248 |
n = 0; |
|
4249 |
||
4250 |
do { |
|
4251 |
||
4252 |
mtr_start(&mtr); |
|
4253 |
mtr_x_lock(latch, &mtr); |
|
4254 |
||
4255 |
seg_inode_page = fut_get_ptr( |
|
4256 |
space, zip_size, node_addr, RW_X_LATCH, &mtr) |
|
4257 |
- FSEG_INODE_PAGE_NODE; |
|
4258 |
||
4259 |
seg_inode = fsp_seg_inode_page_get_nth_inode( |
|
4260 |
seg_inode_page, n, zip_size, &mtr); |
|
1819.9.31
by Marko Mäkelä, Stewart Smith
Merge Revision revid:marko.makela@oracle.com-20100623110659-pk5bqnmo0j7hj6md from MySQL InnoDB |
4261 |
if (mach_read_from_8(seg_inode + FSEG_ID)) { |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
4262 |
|
4263 |
fseg_print_low(seg_inode, &mtr); |
|
4264 |
n_segs++; |
|
4265 |
}
|
|
4266 |
||
4267 |
next_node_addr = flst_get_next_addr( |
|
4268 |
seg_inode_page + FSEG_INODE_PAGE_NODE, &mtr); |
|
4269 |
mtr_commit(&mtr); |
|
4270 |
} while (++n < FSP_SEG_INODES_PER_PAGE(zip_size)); |
|
4271 |
||
4272 |
node_addr = next_node_addr; |
|
4273 |
}
|
|
4274 |
||
4275 |
mtr_commit(&mtr2); |
|
4276 |
||
4277 |
fprintf(stderr, "NUMBER of file segments: %lu\n", (ulong) n_segs); |
|
4278 |
}
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
4279 |
#endif /* !UNIV_HOTBACKUP */ |