]>
Commit | Line | Data |
---|---|---|
8c0fcd57 ER |
1 | # name : innodb_expand_import.patch |
2 | # introduced : 11 or before | |
3 | # maintainer : Yasufumi | |
4 | # | |
5 | #!!! notice !!! | |
6 | # Any small change to this file in the main branch | |
7 | # should be done or reviewed by the maintainer! | |
4eec3829 AM |
8 | --- a/storage/innodb_plugin/btr/btr0btr.c |
9 | +++ b/storage/innodb_plugin/btr/btr0btr.c | |
10 | @@ -837,7 +837,7 @@ | |
11 | /**************************************************************//** | |
12 | Creates a new index page (not the root, and also not | |
13 | used in page reorganization). @see btr_page_empty(). */ | |
14 | -static | |
15 | +UNIV_INTERN | |
16 | void | |
17 | btr_page_create( | |
18 | /*============*/ | |
19 | @@ -1704,7 +1704,7 @@ | |
20 | #ifndef UNIV_HOTBACKUP | |
21 | /*************************************************************//** | |
22 | Empties an index page. @see btr_page_create(). */ | |
23 | -static | |
24 | +UNIV_INTERN | |
25 | void | |
26 | btr_page_empty( | |
27 | /*===========*/ | |
28 | @@ -2266,7 +2266,7 @@ | |
29 | /**************************************************************//** | |
30 | Attaches the halves of an index page on the appropriate level in an | |
31 | index tree. */ | |
32 | -static | |
33 | +UNIV_INTERN | |
34 | void | |
35 | btr_attach_half_pages( | |
36 | /*==================*/ | |
37 | --- a/storage/innodb_plugin/fil/fil0fil.c | |
38 | +++ b/storage/innodb_plugin/fil/fil0fil.c | |
39 | @@ -40,6 +40,14 @@ | |
8c0fcd57 ER |
40 | #include "dict0dict.h" |
41 | #include "page0page.h" | |
42 | #include "page0zip.h" | |
43 | +#include "trx0trx.h" | |
44 | +#include "trx0sys.h" | |
45 | +#include "pars0pars.h" | |
46 | +#include "row0mysql.h" | |
47 | +#include "row0row.h" | |
48 | +#include "que0que.h" | |
4eec3829 AM |
49 | +#include "btr0btr.h" |
50 | +#include "btr0sea.h" | |
8c0fcd57 ER |
51 | #ifndef UNIV_HOTBACKUP |
52 | # include "buf0lru.h" | |
53 | # include "ibuf0ibuf.h" | |
4eec3829 AM |
54 | @@ -2984,6 +2992,84 @@ |
55 | } | |
56 | ||
57 | /********************************************************************//** | |
58 | +Checks if a page is corrupt. (for offline page) | |
59 | +*/ | |
60 | +static | |
61 | +ibool | |
62 | +fil_page_buf_page_is_corrupted_offline( | |
63 | +/*===================================*/ | |
64 | + const byte* page, /*!< in: a database page */ | |
65 | + ulint zip_size) /*!< in: size of compressed page; | |
66 | + 0 for uncompressed pages */ | |
67 | +{ | |
68 | + ulint checksum_field; | |
69 | + ulint old_checksum_field; | |
70 | + | |
71 | + if (!zip_size | |
72 | + && memcmp(page + FIL_PAGE_LSN + 4, | |
73 | + page + UNIV_PAGE_SIZE | |
74 | + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4)) { | |
75 | + return(TRUE); | |
76 | + } | |
77 | + | |
78 | + checksum_field = mach_read_from_4(page | |
79 | + + FIL_PAGE_SPACE_OR_CHKSUM); | |
80 | + | |
81 | + if (zip_size) { | |
82 | + return(checksum_field != BUF_NO_CHECKSUM_MAGIC | |
83 | + && checksum_field | |
84 | + != page_zip_calc_checksum(page, zip_size)); | |
85 | + } | |
86 | + | |
87 | + old_checksum_field = mach_read_from_4( | |
88 | + page + UNIV_PAGE_SIZE | |
89 | + - FIL_PAGE_END_LSN_OLD_CHKSUM); | |
90 | + | |
91 | + if (old_checksum_field != mach_read_from_4(page | |
92 | + + FIL_PAGE_LSN) | |
93 | + && old_checksum_field != BUF_NO_CHECKSUM_MAGIC | |
94 | + && old_checksum_field | |
95 | + != buf_calc_page_old_checksum(page)) { | |
96 | + return(TRUE); | |
97 | + } | |
98 | + | |
99 | + if (checksum_field != 0 | |
100 | + && checksum_field != BUF_NO_CHECKSUM_MAGIC | |
101 | + && checksum_field | |
102 | + != buf_calc_page_new_checksum(page)) { | |
103 | + return(TRUE); | |
104 | + } | |
105 | + | |
106 | + return(FALSE); | |
107 | +} | |
108 | + | |
109 | +/********************************************************************//** | |
110 | +*/ | |
111 | +static | |
112 | +void | |
113 | +fil_page_buf_page_store_checksum( | |
114 | +/*=============================*/ | |
115 | + byte* page, | |
116 | + ulint zip_size) | |
117 | +{ | |
118 | + if (!zip_size) { | |
119 | + mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, | |
120 | + srv_use_checksums | |
121 | + ? buf_calc_page_new_checksum(page) | |
122 | + : BUF_NO_CHECKSUM_MAGIC); | |
123 | + mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, | |
124 | + srv_use_checksums | |
125 | + ? buf_calc_page_old_checksum(page) | |
126 | + : BUF_NO_CHECKSUM_MAGIC); | |
127 | + } else { | |
128 | + mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, | |
129 | + srv_use_checksums | |
130 | + ? page_zip_calc_checksum(page, zip_size) | |
131 | + : BUF_NO_CHECKSUM_MAGIC); | |
132 | + } | |
133 | +} | |
134 | + | |
135 | +/********************************************************************//** | |
136 | Tries to open a single-table tablespace and optionally checks the space id is | |
137 | right in it. If does not succeed, prints an error message to the .err log. This | |
138 | function is used to open a tablespace when we start up mysqld, and also in | |
139 | @@ -3029,7 +3115,7 @@ | |
8c0fcd57 ER |
140 | ut_a(!(flags & (~0UL << DICT_TF_BITS))); |
141 | ||
142 | file = os_file_create_simple_no_error_handling( | |
143 | - filepath, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); | |
144 | + filepath, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success); | |
145 | if (!success) { | |
146 | /* The following call prints an error message */ | |
147 | os_file_get_last_error(TRUE); | |
4eec3829 | 148 | @@ -3076,6 +3162,445 @@ |
8c0fcd57 ER |
149 | space_id = fsp_header_get_space_id(page); |
150 | space_flags = fsp_header_get_flags(page); | |
151 | ||
74952c29 AM |
152 | + if (srv_expand_import) { |
153 | + | |
8c0fcd57 ER |
154 | + ibool file_is_corrupt = FALSE; |
155 | + byte* buf3; | |
156 | + byte* descr_page; | |
157 | + ibool descr_is_corrupt = FALSE; | |
158 | + dulint old_id[31]; | |
159 | + dulint new_id[31]; | |
160 | + ulint root_page[31]; | |
161 | + ulint n_index; | |
162 | + os_file_t info_file = -1; | |
163 | + char* info_file_path; | |
164 | + ulint i; | |
165 | + int len; | |
166 | + ib_uint64_t current_lsn; | |
167 | + ulint size_low, size_high, size, free_limit; | |
168 | + ib_int64_t size_bytes, free_limit_bytes; | |
169 | + dict_table_t* table; | |
170 | + dict_index_t* index; | |
171 | + fil_system_t* system; | |
172 | + fil_node_t* node = NULL; | |
173 | + fil_space_t* space; | |
4eec3829 | 174 | + ulint zip_size; |
8c0fcd57 ER |
175 | + |
176 | + buf3 = ut_malloc(2 * UNIV_PAGE_SIZE); | |
177 | + descr_page = ut_align(buf3, UNIV_PAGE_SIZE); | |
178 | + | |
179 | + current_lsn = log_get_lsn(); | |
180 | + | |
181 | + /* check the header page's consistency */ | |
182 | + if (buf_page_is_corrupted(page, | |
183 | + dict_table_flags_to_zip_size(space_flags))) { | |
184 | + fprintf(stderr, "InnoDB: page 0 of %s seems corrupt.\n", filepath); | |
185 | + file_is_corrupt = TRUE; | |
186 | + descr_is_corrupt = TRUE; | |
187 | + } | |
188 | + | |
189 | + /* store as first descr page */ | |
190 | + memcpy(descr_page, page, UNIV_PAGE_SIZE); | |
191 | + | |
4eec3829 AM |
192 | + zip_size = dict_table_flags_to_zip_size(flags); |
193 | + ut_a(zip_size == dict_table_flags_to_zip_size(space_flags)); | |
194 | + | |
8c0fcd57 ER |
195 | + /* get free limit (page number) of the table space */ |
196 | +/* these should be same to the definition in fsp0fsp.c */ | |
197 | +#define FSP_HEADER_OFFSET FIL_PAGE_DATA | |
198 | +#define FSP_FREE_LIMIT 12 | |
199 | + free_limit = mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT + page); | |
4eec3829 | 200 | + free_limit_bytes = (ib_int64_t)free_limit * (ib_int64_t)(zip_size ? zip_size : UNIV_PAGE_SIZE); |
8c0fcd57 ER |
201 | + |
202 | + /* overwrite fsp header */ | |
203 | + fsp_header_init_fields(page, id, flags); | |
204 | + mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id); | |
205 | + space_id = id; | |
206 | + space_flags = flags; | |
207 | + if (mach_read_ull(page + FIL_PAGE_FILE_FLUSH_LSN) > current_lsn) | |
208 | + mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn); | |
4eec3829 AM |
209 | + |
210 | + fil_page_buf_page_store_checksum(page, zip_size); | |
211 | + | |
8c0fcd57 ER |
212 | + success = os_file_write(filepath, file, page, 0, 0, UNIV_PAGE_SIZE); |
213 | + | |
214 | + /* get file size */ | |
215 | + os_file_get_size(file, &size_low, &size_high); | |
216 | + size_bytes = (((ib_int64_t)size_high) << 32) | |
217 | + + (ib_int64_t)size_low; | |
218 | + | |
219 | + if (size_bytes < free_limit_bytes) { | |
220 | + free_limit_bytes = size_bytes; | |
4eec3829 | 221 | + if (size_bytes >= (ib_int64_t) (FSP_EXTENT_SIZE * (zip_size ? zip_size : UNIV_PAGE_SIZE))) { |
967eb3b7 ER |
222 | + fprintf(stderr, "InnoDB: free limit of %s is larger than its real size.\n", filepath); |
223 | + file_is_corrupt = TRUE; | |
224 | + } | |
8c0fcd57 ER |
225 | + } |
226 | + | |
227 | + /* get cruster index information */ | |
228 | + table = dict_table_get_low(name); | |
229 | + index = dict_table_get_first_index(table); | |
230 | + ut_a(index->page==3); | |
231 | + | |
232 | + /* read metadata from .exp file */ | |
233 | + n_index = 0; | |
234 | + memset(old_id, 0, sizeof(old_id)); | |
235 | + memset(new_id, 0, sizeof(new_id)); | |
236 | + memset(root_page, 0, sizeof(root_page)); | |
237 | + | |
238 | + info_file_path = fil_make_ibd_name(name, FALSE); | |
239 | + len = strlen(info_file_path); | |
240 | + info_file_path[len - 3] = 'e'; | |
241 | + info_file_path[len - 2] = 'x'; | |
242 | + info_file_path[len - 1] = 'p'; | |
243 | + | |
244 | + info_file = os_file_create_simple_no_error_handling( | |
245 | + info_file_path, OS_FILE_OPEN, OS_FILE_READ_ONLY, &success); | |
246 | + if (!success) { | |
247 | + fprintf(stderr, "InnoDB: cannot open %s\n", info_file_path); | |
248 | + file_is_corrupt = TRUE; | |
249 | + goto skip_info; | |
250 | + } | |
251 | + success = os_file_read(info_file, page, 0, 0, UNIV_PAGE_SIZE); | |
252 | + if (!success) { | |
253 | + fprintf(stderr, "InnoDB: cannot read %s\n", info_file_path); | |
254 | + file_is_corrupt = TRUE; | |
255 | + goto skip_info; | |
256 | + } | |
257 | + if (mach_read_from_4(page) != 0x78706f72UL | |
258 | + || mach_read_from_4(page + 4) != 0x74696e66UL) { | |
259 | + fprintf(stderr, "InnoDB: %s seems not to be a correct .exp file\n", info_file_path); | |
260 | + file_is_corrupt = TRUE; | |
261 | + goto skip_info; | |
262 | + } | |
263 | + | |
264 | + fprintf(stderr, "InnoDB: import: extended import of %s is started.\n", name); | |
265 | + | |
266 | + n_index = mach_read_from_4(page + 8); | |
267 | + fprintf(stderr, "InnoDB: import: %lu indexes are detected.\n", (ulong)n_index); | |
268 | + for (i = 0; i < n_index; i++) { | |
269 | + new_id[i] = | |
270 | + dict_table_get_index_on_name(table, | |
271 | + (char*)(page + (i + 1) * 512 + 12))->id; | |
272 | + old_id[i] = mach_read_from_8(page + (i + 1) * 512); | |
273 | + root_page[i] = mach_read_from_4(page + (i + 1) * 512 + 8); | |
274 | + } | |
275 | + | |
276 | +skip_info: | |
277 | + if (info_file != -1) | |
278 | + os_file_close(info_file); | |
279 | + | |
280 | + /* | |
281 | + if (size_bytes >= 1024 * 1024) { | |
282 | + size_bytes = ut_2pow_round(size_bytes, 1024 * 1024); | |
283 | + } | |
284 | + */ | |
4eec3829 AM |
285 | + |
286 | + if (zip_size) { | |
287 | + fprintf(stderr, "InnoDB: Warning: importing compressed table is still EXPERIMENTAL, currently.\n"); | |
288 | + } | |
289 | + | |
290 | + { | |
8c0fcd57 ER |
291 | + mem_heap_t* heap = NULL; |
292 | + ulint offsets_[REC_OFFS_NORMAL_SIZE]; | |
293 | + ulint* offsets = offsets_; | |
294 | + ib_int64_t offset; | |
295 | + | |
4eec3829 | 296 | + size = (ulint) (size_bytes / (zip_size ? zip_size : UNIV_PAGE_SIZE)); |
8c0fcd57 ER |
297 | + /* over write space id of all pages */ |
298 | + rec_offs_init(offsets_); | |
299 | + | |
300 | + fprintf(stderr, "InnoDB: Progress in %%:"); | |
301 | + | |
4eec3829 AM |
302 | + for (offset = 0; offset < free_limit_bytes; |
303 | + offset += zip_size ? zip_size : UNIV_PAGE_SIZE) { | |
8c0fcd57 ER |
304 | + ibool page_is_corrupt; |
305 | + | |
306 | + success = os_file_read(file, page, | |
307 | + (ulint)(offset & 0xFFFFFFFFUL), | |
4eec3829 AM |
308 | + (ulint)(offset >> 32), |
309 | + zip_size ? zip_size : UNIV_PAGE_SIZE); | |
8c0fcd57 ER |
310 | + |
311 | + page_is_corrupt = FALSE; | |
312 | + | |
313 | + /* check consistency */ | |
4eec3829 | 314 | + if (fil_page_buf_page_is_corrupted_offline(page, zip_size)) { |
8c0fcd57 ER |
315 | + page_is_corrupt = TRUE; |
316 | + } | |
317 | + | |
318 | + if (mach_read_from_4(page + FIL_PAGE_OFFSET) | |
4eec3829 | 319 | + != offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) { |
8c0fcd57 ER |
320 | + |
321 | + page_is_corrupt = TRUE; | |
322 | + } | |
323 | + | |
324 | + /* if it is free page, inconsistency is acceptable */ | |
325 | + if (!offset) { | |
326 | + /* header page*/ | |
327 | + /* it should be overwritten already */ | |
328 | + ut_a(!page_is_corrupt); | |
329 | + | |
4eec3829 AM |
330 | + } else if (!((offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) |
331 | + % (zip_size ? zip_size : UNIV_PAGE_SIZE))) { | |
8c0fcd57 ER |
332 | + /* descr page (not header) */ |
333 | + if (page_is_corrupt) { | |
334 | + file_is_corrupt = TRUE; | |
335 | + descr_is_corrupt = TRUE; | |
336 | + } else { | |
967eb3b7 | 337 | + |
8c0fcd57 ER |
338 | + descr_is_corrupt = FALSE; |
339 | + } | |
340 | + | |
341 | + /* store as descr page */ | |
4eec3829 | 342 | + memcpy(descr_page, page, (zip_size ? zip_size : UNIV_PAGE_SIZE)); |
8c0fcd57 ER |
343 | + |
344 | + } else if (descr_is_corrupt) { | |
345 | + /* unknown state of the page */ | |
346 | + if (page_is_corrupt) { | |
347 | + file_is_corrupt = TRUE; | |
348 | + } | |
349 | + | |
350 | + } else { | |
351 | + /* check free page or not */ | |
352 | + /* These definitions should be same to fsp0fsp.c */ | |
353 | +#define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE) | |
354 | + | |
355 | +#define XDES_BITMAP (FLST_NODE_SIZE + 12) | |
356 | +#define XDES_BITS_PER_PAGE 2 | |
357 | +#define XDES_FREE_BIT 0 | |
358 | +#define XDES_SIZE \ | |
359 | + (XDES_BITMAP + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE)) | |
360 | +#define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE) | |
361 | + | |
362 | + /*descr = descr_page + XDES_ARR_OFFSET + XDES_SIZE * xdes_calc_descriptor_index(zip_size, offset)*/ | |
363 | + /*xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)*/ | |
364 | + byte* descr; | |
365 | + ulint index; | |
366 | + ulint byte_index; | |
367 | + ulint bit_index; | |
368 | + | |
369 | + descr = descr_page + XDES_ARR_OFFSET | |
4eec3829 AM |
370 | + + XDES_SIZE * (ut_2pow_remainder( |
371 | + (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)), | |
372 | + (zip_size ? zip_size : UNIV_PAGE_SIZE)) / FSP_EXTENT_SIZE); | |
8c0fcd57 | 373 | + |
4eec3829 AM |
374 | + index = XDES_FREE_BIT |
375 | + + XDES_BITS_PER_PAGE * ((offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)) % FSP_EXTENT_SIZE); | |
8c0fcd57 ER |
376 | + byte_index = index / 8; |
377 | + bit_index = index % 8; | |
378 | + | |
379 | + if (ut_bit_get_nth(mach_read_from_1(descr + XDES_BITMAP + byte_index), bit_index)) { | |
380 | + /* free page */ | |
381 | + if (page_is_corrupt) { | |
382 | + goto skip_write; | |
383 | + } | |
384 | + } else { | |
385 | + /* not free */ | |
386 | + if (page_is_corrupt) { | |
387 | + file_is_corrupt = TRUE; | |
388 | + } | |
389 | + } | |
390 | + } | |
391 | + | |
392 | + if (page_is_corrupt) { | |
4eec3829 | 393 | + fprintf(stderr, " [errp:%lld]", offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)); |
8c0fcd57 ER |
394 | + |
395 | + /* cannot treat corrupt page */ | |
396 | + goto skip_write; | |
397 | + } | |
398 | + | |
399 | + if (mach_read_from_4(page + FIL_PAGE_OFFSET) || !offset) { | |
400 | + mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id); | |
401 | + | |
402 | + for (i = 0; i < n_index; i++) { | |
4eec3829 AM |
403 | + if (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE) == root_page[i]) { |
404 | + if (fil_page_get_type(page) != FIL_PAGE_INDEX) { | |
405 | + file_is_corrupt = TRUE; | |
406 | + fprintf(stderr, " [etyp:%lld]", | |
407 | + offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)); | |
408 | + goto skip_write; | |
409 | + } | |
8c0fcd57 ER |
410 | + /* this is index root page */ |
411 | + mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF | |
412 | + + FSEG_HDR_SPACE, id); | |
413 | + mach_write_to_4(page + FIL_PAGE_DATA + PAGE_BTR_SEG_TOP | |
414 | + + FSEG_HDR_SPACE, id); | |
415 | + break; | |
416 | + } | |
417 | + } | |
418 | + | |
419 | + if (fil_page_get_type(page) == FIL_PAGE_INDEX) { | |
420 | + dulint tmp = mach_read_from_8(page + (PAGE_HEADER + PAGE_INDEX_ID)); | |
421 | + | |
4eec3829 AM |
422 | + for (i = 0; i < n_index; i++) { |
423 | + if (ut_dulint_cmp(old_id[i], tmp) == 0) { | |
424 | + mach_write_to_8(page + (PAGE_HEADER + PAGE_INDEX_ID), new_id[i]); | |
425 | + break; | |
426 | + } | |
427 | + } | |
428 | + | |
429 | + if (!zip_size && mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0 | |
8c0fcd57 ER |
430 | + && ut_dulint_cmp(old_id[0], tmp) == 0) { |
431 | + /* leaf page of cluster index, reset trx_id of records */ | |
432 | + rec_t* rec; | |
433 | + rec_t* supremum; | |
434 | + ulint n_recs; | |
435 | + | |
436 | + supremum = page_get_supremum_rec(page); | |
437 | + rec = page_rec_get_next(page_get_infimum_rec(page)); | |
438 | + n_recs = page_get_n_recs(page); | |
439 | + | |
440 | + while (rec && rec != supremum && n_recs > 0) { | |
441 | + ulint n_fields; | |
442 | + ulint i; | |
443 | + ulint offset = index->trx_id_offset; | |
444 | + offsets = rec_get_offsets(rec, index, offsets, | |
445 | + ULINT_UNDEFINED, &heap); | |
446 | + n_fields = rec_offs_n_fields(offsets); | |
447 | + if (!offset) { | |
3700c2a6 | 448 | + offset = row_get_trx_id_offset(index, offsets); |
8c0fcd57 ER |
449 | + } |
450 | + trx_write_trx_id(rec + offset, ut_dulint_create(0, 1)); | |
451 | + | |
452 | + for (i = 0; i < n_fields; i++) { | |
453 | + if (rec_offs_nth_extern(offsets, i)) { | |
454 | + ulint local_len; | |
455 | + byte* data; | |
456 | + | |
457 | + data = rec_get_nth_field(rec, offsets, i, &local_len); | |
458 | + | |
459 | + local_len -= BTR_EXTERN_FIELD_REF_SIZE; | |
460 | + | |
461 | + mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id); | |
462 | + } | |
463 | + } | |
464 | + | |
465 | + rec = page_rec_get_next(rec); | |
466 | + n_recs--; | |
467 | + } | |
4eec3829 AM |
468 | + } else if (mach_read_from_2(page + PAGE_HEADER + PAGE_LEVEL) == 0 |
469 | + && ut_dulint_cmp(old_id[0], tmp) != 0) { | |
470 | + mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), ut_dulint_create(0, 1)); | |
8c0fcd57 ER |
471 | + } |
472 | + } | |
473 | + | |
474 | + if (mach_read_ull(page + FIL_PAGE_LSN) > current_lsn) { | |
475 | + mach_write_ull(page + FIL_PAGE_LSN, current_lsn); | |
4eec3829 AM |
476 | + if (!zip_size) { |
477 | + mach_write_ull(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, | |
478 | + current_lsn); | |
479 | + } | |
8c0fcd57 ER |
480 | + } |
481 | + | |
4eec3829 | 482 | + fil_page_buf_page_store_checksum(page, zip_size); |
8c0fcd57 ER |
483 | + |
484 | + success = os_file_write(filepath, file, page, | |
485 | + (ulint)(offset & 0xFFFFFFFFUL), | |
4eec3829 AM |
486 | + (ulint)(offset >> 32), |
487 | + zip_size ? zip_size : UNIV_PAGE_SIZE); | |
8c0fcd57 ER |
488 | + } |
489 | + | |
490 | +skip_write: | |
491 | + if (free_limit_bytes | |
4eec3829 | 492 | + && ((ib_int64_t)((offset + (zip_size ? zip_size : UNIV_PAGE_SIZE)) * 100) / free_limit_bytes) |
8c0fcd57 ER |
493 | + != ((offset * 100) / free_limit_bytes)) { |
494 | + fprintf(stderr, " %lu", | |
4eec3829 | 495 | + (ulong)((ib_int64_t)((offset + (zip_size ? zip_size : UNIV_PAGE_SIZE)) * 100) / free_limit_bytes)); |
8c0fcd57 ER |
496 | + } |
497 | + } | |
498 | + | |
499 | + fprintf(stderr, " done.\n"); | |
500 | + | |
501 | + /* update SYS_INDEXES set root page */ | |
502 | + index = dict_table_get_first_index(table); | |
503 | + while (index) { | |
504 | + for (i = 0; i < n_index; i++) { | |
505 | + if (ut_dulint_cmp(new_id[i], index->id) == 0) { | |
506 | + break; | |
507 | + } | |
508 | + } | |
509 | + | |
510 | + if (i != n_index | |
511 | + && root_page[i] != index->page) { | |
512 | + /* must update */ | |
513 | + ulint error; | |
514 | + trx_t* trx; | |
515 | + pars_info_t* info = NULL; | |
516 | + | |
517 | + trx = trx_allocate_for_mysql(); | |
518 | + trx->op_info = "extended import"; | |
519 | + | |
520 | + info = pars_info_create(); | |
521 | + | |
522 | + pars_info_add_dulint_literal(info, "indexid", new_id[i]); | |
523 | + pars_info_add_int4_literal(info, "new_page", (lint) root_page[i]); | |
524 | + | |
525 | + error = que_eval_sql(info, | |
526 | + "PROCEDURE UPDATE_INDEX_PAGE () IS\n" | |
527 | + "BEGIN\n" | |
528 | + "UPDATE SYS_INDEXES" | |
529 | + " SET PAGE_NO = :new_page" | |
530 | + " WHERE ID = :indexid;\n" | |
531 | + "COMMIT WORK;\n" | |
532 | + "END;\n", | |
533 | + FALSE, trx); | |
534 | + | |
535 | + if (error != DB_SUCCESS) { | |
536 | + fprintf(stderr, "InnoDB: failed to update SYS_INDEXES\n"); | |
537 | + } | |
538 | + | |
539 | + trx_commit_for_mysql(trx); | |
540 | + | |
541 | + trx_free_for_mysql(trx); | |
542 | + | |
543 | + index->page = root_page[i]; | |
544 | + } | |
545 | + | |
546 | + index = dict_table_get_next_index(index); | |
547 | + } | |
548 | + if (UNIV_LIKELY_NULL(heap)) { | |
549 | + mem_heap_free(heap); | |
550 | + } | |
8c0fcd57 ER |
551 | + } |
552 | + /* .exp file should be removed */ | |
553 | + success = os_file_delete(info_file_path); | |
554 | + if (!success) { | |
555 | + success = os_file_delete_if_exists(info_file_path); | |
556 | + } | |
557 | + mem_free(info_file_path); | |
558 | + | |
559 | + system = fil_system; | |
560 | + mutex_enter(&(system->mutex)); | |
561 | + space = fil_space_get_by_id(id); | |
562 | + if (space) | |
563 | + node = UT_LIST_GET_FIRST(space->chain); | |
564 | + if (node && node->size < size) { | |
565 | + space->size += (size - node->size); | |
566 | + node->size = size; | |
567 | + } | |
568 | + mutex_exit(&(system->mutex)); | |
569 | + | |
570 | + ut_free(buf3); | |
571 | + | |
572 | + if (file_is_corrupt) { | |
573 | + ut_print_timestamp(stderr); | |
574 | + fputs(" InnoDB: Error: file ", | |
575 | + stderr); | |
576 | + ut_print_filename(stderr, filepath); | |
577 | + fprintf(stderr, " seems to be corrupt.\n" | |
578 | + "InnoDB: anyway, all not corrupt pages were tried to be converted to salvage.\n" | |
579 | + "InnoDB: ##### CAUTION #####\n" | |
580 | + "InnoDB: ## The .ibd must cause to crash InnoDB, though re-import would seem to be succeeded.\n" | |
581 | + "InnoDB: ## If you don't have knowledge about salvaging data from .ibd, you should not use the file.\n" | |
582 | + "InnoDB: ###################\n"); | |
583 | + success = FALSE; | |
584 | + | |
585 | + ut_free(buf2); | |
586 | + | |
587 | + goto func_exit; | |
588 | + } | |
589 | + } | |
590 | + | |
591 | ut_free(buf2); | |
592 | ||
593 | if (UNIV_UNLIKELY(space_id != id | |
3700c2a6 | 594 | @@ -3117,6 +3642,269 @@ |
4eec3829 AM |
595 | os_file_close(file); |
596 | mem_free(filepath); | |
597 | ||
598 | + if (srv_expand_import && dict_table_flags_to_zip_size(flags)) { | |
599 | + ulint page_no; | |
600 | + ulint zip_size; | |
601 | + ulint height; | |
4eec3829 AM |
602 | + rec_t* node_ptr; |
603 | + dict_table_t* table; | |
604 | + dict_index_t* index; | |
605 | + buf_block_t* block; | |
606 | + page_t* page; | |
607 | + page_zip_des_t* page_zip; | |
608 | + mtr_t mtr; | |
609 | + | |
610 | + mem_heap_t* heap = NULL; | |
611 | + ulint offsets_[REC_OFFS_NORMAL_SIZE]; | |
612 | + ulint* offsets = offsets_; | |
613 | + | |
614 | + rec_offs_init(offsets_); | |
615 | + | |
616 | + zip_size = dict_table_flags_to_zip_size(flags); | |
617 | + | |
618 | + table = dict_table_get_low(name); | |
619 | + index = dict_table_get_first_index(table); | |
620 | + page_no = dict_index_get_page(index); | |
621 | + ut_a(page_no == 3); | |
622 | + | |
623 | + fprintf(stderr, "InnoDB: It is compressed .ibd file. need to convert additionaly on buffer pool.\n"); | |
624 | + | |
625 | + /* down to leaf */ | |
626 | + mtr_start(&mtr); | |
627 | + mtr_set_log_mode(&mtr, MTR_LOG_NONE); | |
628 | + | |
629 | + height = ULINT_UNDEFINED; | |
630 | + | |
631 | + for (;;) { | |
632 | + block = buf_page_get(space_id, zip_size, page_no, | |
633 | + RW_NO_LATCH, &mtr); | |
634 | + page = buf_block_get_frame(block); | |
635 | + | |
636 | + block->check_index_page_at_flush = TRUE; | |
637 | + | |
638 | + if (height == ULINT_UNDEFINED) { | |
639 | + height = btr_page_get_level(page, &mtr); | |
4eec3829 AM |
640 | + } |
641 | + | |
642 | + if (height == 0) { | |
643 | + break; | |
644 | + } | |
645 | + | |
646 | + node_ptr = page_rec_get_next(page_get_infimum_rec(page)); | |
647 | + | |
648 | + height--; | |
649 | + | |
650 | + offsets = rec_get_offsets(node_ptr, index, offsets, ULINT_UNDEFINED, &heap); | |
651 | + page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets); | |
652 | + } | |
653 | + | |
654 | + mtr_commit(&mtr); | |
655 | + | |
656 | + fprintf(stderr, "InnoDB: pages needs split are ..."); | |
657 | + | |
658 | + /* scan reaf pages */ | |
659 | + while (page_no != FIL_NULL) { | |
660 | + rec_t* rec; | |
661 | + rec_t* supremum; | |
662 | + ulint n_recs; | |
663 | + | |
664 | + mtr_start(&mtr); | |
665 | + | |
666 | + block = buf_page_get(space_id, zip_size, page_no, | |
667 | + RW_X_LATCH, &mtr); | |
668 | + page = buf_block_get_frame(block); | |
669 | + page_zip = buf_block_get_page_zip(block); | |
670 | + | |
671 | + if (!page_zip) { | |
672 | + /*something wrong*/ | |
673 | + fprintf(stderr, "InnoDB: Something wrong with reading page %lu.\n", page_no); | |
674 | +convert_err_exit: | |
675 | + mtr_commit(&mtr); | |
676 | + mutex_enter(&fil_system->mutex); | |
677 | + fil_space_free(space_id, FALSE); | |
678 | + mutex_exit(&fil_system->mutex); | |
679 | + success = FALSE; | |
680 | + goto convert_exit; | |
681 | + } | |
682 | + | |
683 | + supremum = page_get_supremum_rec(page); | |
684 | + rec = page_rec_get_next(page_get_infimum_rec(page)); | |
685 | + n_recs = page_get_n_recs(page); | |
686 | + | |
687 | + /* illegal operation as InnoDB online system. so not logged */ | |
688 | + while (rec && rec != supremum && n_recs > 0) { | |
689 | + ulint n_fields; | |
690 | + ulint i; | |
691 | + ulint offset = index->trx_id_offset; | |
692 | + | |
693 | + offsets = rec_get_offsets(rec, index, offsets, | |
694 | + ULINT_UNDEFINED, &heap); | |
695 | + n_fields = rec_offs_n_fields(offsets); | |
696 | + if (!offset) { | |
3700c2a6 | 697 | + offset = row_get_trx_id_offset(index, offsets); |
4eec3829 AM |
698 | + } |
699 | + trx_write_trx_id(rec + offset, ut_dulint_create(0, 1)); | |
700 | + | |
701 | + for (i = 0; i < n_fields; i++) { | |
702 | + if (rec_offs_nth_extern(offsets, i)) { | |
703 | + ulint local_len; | |
704 | + byte* data; | |
705 | + | |
706 | + data = rec_get_nth_field(rec, offsets, i, &local_len); | |
707 | + | |
708 | + local_len -= BTR_EXTERN_FIELD_REF_SIZE; | |
709 | + | |
710 | + mach_write_to_4(data + local_len + BTR_EXTERN_SPACE_ID, id); | |
711 | + } | |
712 | + } | |
713 | + | |
714 | + rec = page_rec_get_next(rec); | |
715 | + n_recs--; | |
716 | + } | |
717 | + | |
718 | + /* dummy logged update for along with modified page path */ | |
719 | + if (ut_dulint_cmp(index->id, btr_page_get_index_id(page)) != 0) { | |
720 | + /* this should be adjusted already */ | |
721 | + fprintf(stderr, "InnoDB: The page %lu seems to be converted wrong.\n", page_no); | |
722 | + goto convert_err_exit; | |
723 | + } | |
724 | + btr_page_set_index_id(page, page_zip, index->id, &mtr); | |
725 | + | |
726 | + /* confirm whether fits to the page size or not */ | |
727 | + if (!page_zip_compress(page_zip, page, index, &mtr) | |
728 | + && !btr_page_reorganize(block, index, &mtr)) { | |
729 | + buf_block_t* new_block; | |
730 | + page_t* new_page; | |
731 | + page_zip_des_t* new_page_zip; | |
732 | + rec_t* split_rec; | |
733 | + ulint n_uniq; | |
734 | + | |
735 | + /* split page is needed */ | |
736 | + fprintf(stderr, " %lu", page_no); | |
737 | + | |
738 | + mtr_x_lock(dict_index_get_lock(index), &mtr); | |
739 | + | |
740 | + n_uniq = dict_index_get_n_unique_in_tree(index); | |
741 | + | |
742 | + if(page_get_n_recs(page) < 2) { | |
743 | + /* no way to make smaller */ | |
744 | + fprintf(stderr, "InnoDB: The page %lu cannot be store to the page size.\n", page_no); | |
745 | + goto convert_err_exit; | |
746 | + } | |
747 | + | |
748 | + if (UNIV_UNLIKELY(page_no == dict_index_get_page(index))) { | |
749 | + ulint new_page_no; | |
750 | + dtuple_t* node_ptr; | |
751 | + ulint level; | |
752 | + rec_t* node_ptr_rec; | |
753 | + page_cur_t page_cursor; | |
754 | + | |
755 | + /* it is root page, need to raise before split */ | |
756 | + | |
757 | + level = btr_page_get_level(page, &mtr); | |
758 | + | |
759 | + new_block = btr_page_alloc(index, 0, FSP_NO_DIR, level, &mtr); | |
760 | + new_page = buf_block_get_frame(new_block); | |
761 | + new_page_zip = buf_block_get_page_zip(new_block); | |
762 | + btr_page_create(new_block, new_page_zip, index, level, &mtr); | |
763 | + | |
764 | + btr_page_set_next(new_page, new_page_zip, FIL_NULL, &mtr); | |
765 | + btr_page_set_prev(new_page, new_page_zip, FIL_NULL, &mtr); | |
766 | + | |
767 | + page_zip_copy_recs(new_page_zip, new_page, | |
768 | + page_zip, page, index, &mtr); | |
769 | + btr_search_move_or_delete_hash_entries(new_block, block, index); | |
770 | + | |
771 | + rec = page_rec_get_next(page_get_infimum_rec(new_page)); | |
772 | + new_page_no = buf_block_get_page_no(new_block); | |
773 | + | |
774 | + node_ptr = dict_index_build_node_ptr(index, rec, new_page_no, heap, | |
775 | + level); | |
776 | + dtuple_set_info_bits(node_ptr, | |
777 | + dtuple_get_info_bits(node_ptr) | |
778 | + | REC_INFO_MIN_REC_FLAG); | |
779 | + btr_page_empty(block, page_zip, index, level + 1, &mtr); | |
780 | + | |
781 | + btr_page_set_next(page, page_zip, FIL_NULL, &mtr); | |
782 | + btr_page_set_prev(page, page_zip, FIL_NULL, &mtr); | |
783 | + | |
784 | + page_cur_set_before_first(block, &page_cursor); | |
785 | + | |
786 | + node_ptr_rec = page_cur_tuple_insert(&page_cursor, node_ptr, | |
787 | + index, 0, &mtr); | |
788 | + ut_a(node_ptr_rec); | |
789 | + | |
790 | + if (!btr_page_reorganize(block, index, &mtr)) { | |
791 | + fprintf(stderr, "InnoDB: failed to store the page %lu.\n", page_no); | |
792 | + goto convert_err_exit; | |
793 | + } | |
794 | + | |
795 | + /* move to the raised page */ | |
796 | + page_no = new_page_no; | |
797 | + block = new_block; | |
798 | + page = new_page; | |
799 | + page_zip = new_page_zip; | |
800 | + | |
801 | + fprintf(stderr, "(raise_to:%lu)", page_no); | |
802 | + } | |
803 | + | |
804 | + split_rec = page_get_middle_rec(page); | |
805 | + | |
806 | + new_block = btr_page_alloc(index, page_no + 1, FSP_UP, | |
807 | + btr_page_get_level(page, &mtr), &mtr); | |
808 | + new_page = buf_block_get_frame(new_block); | |
809 | + new_page_zip = buf_block_get_page_zip(new_block); | |
810 | + btr_page_create(new_block, new_page_zip, index, | |
811 | + btr_page_get_level(page, &mtr), &mtr); | |
812 | + | |
813 | + offsets = rec_get_offsets(split_rec, index, offsets, n_uniq, &heap); | |
814 | + | |
815 | + btr_attach_half_pages(index, block, | |
816 | + split_rec, new_block, FSP_UP, &mtr); | |
817 | + | |
818 | + page_zip_copy_recs(new_page_zip, new_page, | |
819 | + page_zip, page, index, &mtr); | |
820 | + page_delete_rec_list_start(split_rec - page + new_page, | |
821 | + new_block, index, &mtr); | |
822 | + btr_search_move_or_delete_hash_entries(new_block, block, index); | |
823 | + page_delete_rec_list_end(split_rec, block, index, | |
824 | + ULINT_UNDEFINED, ULINT_UNDEFINED, &mtr); | |
825 | + | |
826 | + fprintf(stderr, "(new:%lu)", buf_block_get_page_no(new_block)); | |
827 | + | |
828 | + /* Are they needed? */ | |
829 | + if (!btr_page_reorganize(block, index, &mtr)) { | |
830 | + fprintf(stderr, "InnoDB: failed to store the page %lu.\n", page_no); | |
831 | + goto convert_err_exit; | |
832 | + } | |
833 | + if (!btr_page_reorganize(new_block, index, &mtr)) { | |
834 | + fprintf(stderr, "InnoDB: failed to store the page %lu.\n", buf_block_get_page_no(new_block)); | |
835 | + goto convert_err_exit; | |
836 | + } | |
837 | + } | |
838 | + | |
839 | + page_no = btr_page_get_next(page, &mtr); | |
840 | + | |
841 | + mtr_commit(&mtr); | |
842 | + | |
843 | + if (heap) { | |
844 | + mem_heap_empty(heap); | |
845 | + } | |
846 | + } | |
847 | + | |
848 | + fprintf(stderr, "...done.\nInnoDB: waiting the flush batch of the additional conversion.\n"); | |
849 | + | |
850 | + /* should wait for the not-logged changes are all flushed */ | |
851 | + buf_flush_batch(BUF_FLUSH_LIST, ULINT_MAX, mtr.end_lsn + 1); | |
852 | + buf_flush_wait_batch_end(BUF_FLUSH_LIST); | |
853 | + | |
854 | + fprintf(stderr, "InnoDB: done.\n"); | |
855 | +convert_exit: | |
856 | + if (UNIV_LIKELY_NULL(heap)) { | |
857 | + mem_heap_free(heap); | |
858 | + } | |
859 | + } | |
860 | + | |
861 | return(success); | |
862 | } | |
863 | #endif /* !UNIV_HOTBACKUP */ | |
864 | --- a/storage/innodb_plugin/handler/ha_innodb.cc | |
865 | +++ b/storage/innodb_plugin/handler/ha_innodb.cc | |
3700c2a6 | 866 | @@ -7102,6 +7102,14 @@ |
74952c29 AM |
867 | err = row_discard_tablespace_for_mysql(dict_table->name, trx); |
868 | } else { | |
869 | err = row_import_tablespace_for_mysql(dict_table->name, trx); | |
870 | + | |
871 | + /* in expanded import mode re-initialize auto_increment again */ | |
872 | + if ((err == DB_SUCCESS) && srv_expand_import && | |
873 | + (table->found_next_number_field != NULL)) { | |
874 | + dict_table_autoinc_lock(dict_table); | |
875 | + innobase_initialize_autoinc(); | |
876 | + dict_table_autoinc_unlock(dict_table); | |
877 | + } | |
878 | } | |
879 | ||
880 | err = convert_error_code_to_mysql(err, dict_table->flags, NULL); | |
3700c2a6 | 881 | @@ -11378,6 +11386,11 @@ |
8c0fcd57 ER |
882 | "Enable/Disable unsafe group commit when support_xa=OFF and use with binlog or other XA storage engine.", |
883 | NULL, NULL, 0, 0, 1, 0); | |
884 | ||
885 | +static MYSQL_SYSVAR_ULONG(expand_import, srv_expand_import, | |
886 | + PLUGIN_VAR_RQCMDARG, | |
887 | + "Enable/Disable converting automatically *.ibd files when import tablespace.", | |
888 | + NULL, NULL, 0, 0, 1, 0); | |
889 | + | |
890 | static MYSQL_SYSVAR_ULONG(extra_rsegments, srv_extra_rsegments, | |
891 | PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, | |
892 | "Number of extra user rollback segments when create new database.", | |
3700c2a6 | 893 | @@ -11455,6 +11468,7 @@ |
8c0fcd57 ER |
894 | MYSQL_SYSVAR(adaptive_checkpoint), |
895 | MYSQL_SYSVAR(flush_log_at_trx_commit_session), | |
896 | MYSQL_SYSVAR(enable_unsafe_group_commit), | |
897 | + MYSQL_SYSVAR(expand_import), | |
898 | MYSQL_SYSVAR(extra_rsegments), | |
899 | MYSQL_SYSVAR(dict_size_limit), | |
900 | MYSQL_SYSVAR(use_sys_malloc), | |
4eec3829 AM |
901 | --- a/storage/innodb_plugin/handler/innodb_patch_info.h |
902 | +++ b/storage/innodb_plugin/handler/innodb_patch_info.h | |
8c0fcd57 ER |
903 | @@ -32,6 +32,7 @@ |
904 | {"innodb_extra_rseg","allow to create extra rollback segments","When create new db, the new parameter allows to create more rollback segments","http://www.percona.com/docs/wiki/percona-xtradb"}, | |
905 | {"innodb_overwrite_relay_log_info","overwrite relay-log.info when slave recovery","Building as plugin, it is not used.","http://www.percona.com/docs/wiki/percona-xtradb:innodb_overwrite_relay_log_info"}, | |
906 | {"innodb_thread_concurrency_timer_based","use InnoDB timer based concurrency throttling (backport from MySQL 5.4.0)","",""}, | |
907 | +{"innodb_expand_import","convert .ibd file automatically when import tablespace","the files are generated by xtrabackup export mode.","http://www.percona.com/docs/wiki/percona-xtradb"}, | |
908 | {"innodb_dict_size_limit","Limit dictionary cache size","Variable innodb_dict_size_limit in bytes","http://www.percona.com/docs/wiki/percona-xtradb"}, | |
909 | {"innodb_split_buf_pool_mutex","More fix of buffer_pool mutex","Spliting buf_pool_mutex and optimizing based on innodb_opt_lru_count","http://www.percona.com/docs/wiki/percona-xtradb"}, | |
910 | {NULL, NULL, NULL, NULL} | |
4eec3829 AM |
911 | --- a/storage/innodb_plugin/include/btr0btr.h |
912 | +++ b/storage/innodb_plugin/include/btr0btr.h | |
913 | @@ -208,6 +208,17 @@ | |
914 | @return the uncompressed page frame */ | |
915 | # define btr_page_get(space,zip_size,page_no,mode,mtr) \ | |
916 | buf_block_get_frame(btr_block_get(space,zip_size,page_no,mode,mtr)) | |
917 | +/**************************************************************//** | |
918 | +Sets the index id field of a page. */ | |
919 | +UNIV_INLINE | |
920 | +void | |
921 | +btr_page_set_index_id( | |
922 | +/*==================*/ | |
923 | + page_t* page, /*!< in: page to be created */ | |
924 | + page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed | |
925 | + part will be updated, or NULL */ | |
926 | + dulint id, /*!< in: index id */ | |
927 | + mtr_t* mtr); /*!< in: mtr */ | |
928 | #endif /* !UNIV_HOTBACKUP */ | |
929 | /**************************************************************//** | |
930 | Gets the index id field of a page. | |
931 | @@ -245,6 +256,17 @@ | |
932 | const page_t* page, /*!< in: index page */ | |
933 | mtr_t* mtr); /*!< in: mini-transaction handle */ | |
934 | /********************************************************//** | |
935 | +Sets the next index page field. */ | |
936 | +UNIV_INLINE | |
937 | +void | |
938 | +btr_page_set_next( | |
939 | +/*==============*/ | |
940 | + page_t* page, /*!< in: index page */ | |
941 | + page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed | |
942 | + part will be updated, or NULL */ | |
943 | + ulint next, /*!< in: next page number */ | |
944 | + mtr_t* mtr); /*!< in: mini-transaction handle */ | |
945 | +/********************************************************//** | |
946 | Gets the previous index page number. | |
947 | @return prev page number */ | |
948 | UNIV_INLINE | |
949 | @@ -253,6 +275,17 @@ | |
950 | /*==============*/ | |
951 | const page_t* page, /*!< in: index page */ | |
952 | mtr_t* mtr); /*!< in: mini-transaction handle */ | |
953 | +/********************************************************//** | |
954 | +Sets the previous index page field. */ | |
955 | +UNIV_INLINE | |
956 | +void | |
957 | +btr_page_set_prev( | |
958 | +/*==============*/ | |
959 | + page_t* page, /*!< in: index page */ | |
960 | + page_zip_des_t* page_zip,/*!< in: compressed page whose uncompressed | |
961 | + part will be updated, or NULL */ | |
962 | + ulint prev, /*!< in: previous page number */ | |
963 | + mtr_t* mtr); /*!< in: mini-transaction handle */ | |
964 | /*************************************************************//** | |
965 | Gets pointer to the previous user record in the tree. It is assumed | |
966 | that the caller has appropriate latches on the page and its neighbor. | |
967 | @@ -298,6 +331,18 @@ | |
968 | /*===========================*/ | |
969 | const rec_t* rec, /*!< in: node pointer record */ | |
970 | const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ | |
971 | +/**************************************************************//** | |
972 | +Creates a new index page (not the root, and also not | |
973 | +used in page reorganization). @see btr_page_empty(). */ | |
974 | +UNIV_INTERN | |
975 | +void | |
976 | +btr_page_create( | |
977 | +/*============*/ | |
978 | + buf_block_t* block, /*!< in/out: page to be created */ | |
979 | + page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */ | |
980 | + dict_index_t* index, /*!< in: index */ | |
981 | + ulint level, /*!< in: the B-tree level of the page */ | |
982 | + mtr_t* mtr); /*!< in: mtr */ | |
983 | /************************************************************//** | |
984 | Creates the root node for a new index tree. | |
985 | @return page number of the created root, FIL_NULL if did not succeed */ | |
986 | @@ -368,6 +413,17 @@ | |
987 | dict_index_t* index, /*!< in: record descriptor */ | |
988 | mtr_t* mtr); /*!< in: mtr */ | |
989 | /*************************************************************//** | |
990 | +Empties an index page. @see btr_page_create(). */ | |
991 | +UNIV_INTERN | |
992 | +void | |
993 | +btr_page_empty( | |
994 | +/*===========*/ | |
995 | + buf_block_t* block, /*!< in: page to be emptied */ | |
996 | + page_zip_des_t* page_zip,/*!< out: compressed page, or NULL */ | |
997 | + dict_index_t* index, /*!< in: index of the page */ | |
998 | + ulint level, /*!< in: the B-tree level of the page */ | |
999 | + mtr_t* mtr); /*!< in: mtr */ | |
1000 | +/*************************************************************//** | |
1001 | Decides if the page should be split at the convergence point of | |
1002 | inserts converging to left. | |
1003 | @return TRUE if split recommended */ | |
1004 | @@ -426,6 +482,20 @@ | |
1005 | # define btr_insert_on_non_leaf_level(i,l,t,m) \ | |
1006 | btr_insert_on_non_leaf_level_func(i,l,t,__FILE__,__LINE__,m) | |
1007 | #endif /* !UNIV_HOTBACKUP */ | |
1008 | +/**************************************************************//** | |
1009 | +Attaches the halves of an index page on the appropriate level in an | |
1010 | +index tree. */ | |
1011 | +UNIV_INTERN | |
1012 | +void | |
1013 | +btr_attach_half_pages( | |
1014 | +/*==================*/ | |
1015 | + dict_index_t* index, /*!< in: the index tree */ | |
1016 | + buf_block_t* block, /*!< in/out: page to be split */ | |
3700c2a6 | 1017 | + const rec_t* split_rec, /*!< in: first record on upper |
4eec3829 AM |
1018 | + half page */ |
1019 | + buf_block_t* new_block, /*!< in/out: the new half page */ | |
1020 | + ulint direction, /*!< in: FSP_UP or FSP_DOWN */ | |
1021 | + mtr_t* mtr); /*!< in: mtr */ | |
1022 | /****************************************************************//** | |
1023 | Sets a record as the predefined minimum record. */ | |
1024 | UNIV_INTERN | |
1025 | --- a/storage/innodb_plugin/include/srv0srv.h | |
1026 | +++ b/storage/innodb_plugin/include/srv0srv.h | |
3700c2a6 | 1027 | @@ -219,6 +219,8 @@ |
8c0fcd57 ER |
1028 | extern ulint srv_read_ahead; |
1029 | extern ulint srv_adaptive_checkpoint; | |
1030 | ||
1031 | +extern ulint srv_expand_import; | |
1032 | + | |
1033 | extern ulint srv_extra_rsegments; | |
1034 | extern ulint srv_dict_size_limit; | |
1035 | /*-------------------------------------------*/ | |
4eec3829 AM |
1036 | --- a/storage/innodb_plugin/row/row0mysql.c |
1037 | +++ b/storage/innodb_plugin/row/row0mysql.c | |
1038 | @@ -2520,6 +2520,11 @@ | |
1039 | ||
1040 | current_lsn = log_get_lsn(); | |
1041 | ||
1042 | + /* Enlarge the fatal lock wait timeout during import. */ | |
1043 | + mutex_enter(&kernel_mutex); | |
1044 | + srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */ | |
1045 | + mutex_exit(&kernel_mutex); | |
1046 | + | |
1047 | /* It is possible, though very improbable, that the lsn's in the | |
1048 | tablespace to be imported have risen above the current system lsn, if | |
1049 | a lengthy purge, ibuf merge, or rollback was performed on a backup | |
1050 | @@ -2631,6 +2636,11 @@ | |
1051 | ||
1052 | trx->op_info = ""; | |
1053 | ||
1054 | + /* Restore the fatal semaphore wait timeout */ | |
1055 | + mutex_enter(&kernel_mutex); | |
1056 | + srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */ | |
1057 | + mutex_exit(&kernel_mutex); | |
1058 | + | |
1059 | return((int) err); | |
1060 | } | |
1061 | ||
1062 | --- a/storage/innodb_plugin/srv/srv0srv.c | |
1063 | +++ b/storage/innodb_plugin/srv/srv0srv.c | |
3700c2a6 | 1064 | @@ -392,6 +392,8 @@ |
8c0fcd57 ER |
1065 | UNIV_INTERN ulint srv_read_ahead = 3; /* 1: random 2: linear 3: Both */ |
1066 | UNIV_INTERN ulint srv_adaptive_checkpoint = 0; /* 0: none 1: reflex 2: estimate */ | |
1067 | ||
1068 | +UNIV_INTERN ulint srv_expand_import = 0; /* 0:disable 1:enable */ | |
1069 | + | |
1070 | UNIV_INTERN ulint srv_extra_rsegments = 0; /* extra rseg for users */ | |
1071 | UNIV_INTERN ulint srv_dict_size_limit = 0; | |
1072 | /*-------------------------------------------*/ |