Merge lp:~sergei.glushchenko/percona-xtrabackup/xb21-bug932623 into lp:percona-xtrabackup/2.1
- xb21-bug932623
- Merge into 2.1
Proposed by
Sergei Glushchenko
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Alexey Kopytov | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 416 | ||||
Proposed branch: | lp:~sergei.glushchenko/percona-xtrabackup/xb21-bug932623 | ||||
Merge into: | lp:percona-xtrabackup/2.1 | ||||
Diff against target: |
955 lines (+594/-111) 9 files modified
patches/innodb51_builtin.patch (+67/-4) src/fil_cur.c (+1/-0) src/fil_cur.h (+1/-0) src/innodb_int.c (+76/-0) src/innodb_int.h (+29/-0) src/write_filt.c (+1/-0) src/xtrabackup.c (+333/-107) src/xtrabackup.h (+1/-0) test/t/bug932623.sh (+85/-0) |
||||
To merge this branch: | bzr merge lp:~sergei.glushchenko/percona-xtrabackup/xb21-bug932623 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexey Kopytov (community) | Approve | ||
Review via email: mp+114363@code.launchpad.net |
Commit message
Description of the change
Merge fix for #932623 from 2.0 series
http://
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) : | # |
review:
Approve
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Bug 1031324, one-liner fix MP'ed.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'patches/innodb51_builtin.patch' |
2 | --- patches/innodb51_builtin.patch 2012-02-10 05:04:04 +0000 |
3 | +++ patches/innodb51_builtin.patch 2012-07-11 09:06:21 +0000 |
4 | @@ -613,7 +613,21 @@ |
5 | |
6 | --- a/storage/innobase/include/mem0mem.h |
7 | +++ b/storage/innobase/include/mem0mem.h |
8 | -@@ -401,6 +401,7 @@ |
9 | +@@ -63,6 +63,13 @@ |
10 | + mem_init( |
11 | + /*=====*/ |
12 | + ulint size); /* in: common pool size in bytes */ |
13 | ++ |
14 | ++/******************************************************************//** |
15 | ++Closes the memory system. */ |
16 | ++void |
17 | ++mem_close(void); |
18 | ++/*===========*/ |
19 | ++ |
20 | + /****************************************************************** |
21 | + Use this macro instead of the corresponding function! Macro for memory |
22 | + heap creation. */ |
23 | +@@ -401,6 +409,7 @@ |
24 | allocated buffer frame, which can be appended as a |
25 | free block to the heap, if we need more space; |
26 | otherwise, this is NULL */ |
27 | @@ -654,6 +668,21 @@ |
28 | |
29 | if (heap->free_block) { |
30 | size += UNIV_PAGE_SIZE; |
31 | +--- a/storage/innobase/include/mem0pool.h |
32 | ++++ b/storage/innobase/include/mem0pool.h |
33 | +@@ -42,6 +42,12 @@ |
34 | + /*============*/ |
35 | + /* out: memory pool */ |
36 | + ulint size); /* in: pool size in bytes */ |
37 | ++/********************************************************************//** |
38 | ++Frees a memory pool. */ |
39 | ++void |
40 | ++mem_pool_free( |
41 | ++/*==========*/ |
42 | ++ mem_pool_t* pool); /*!< in, own: memory pool */ |
43 | + /************************************************************************ |
44 | + Allocates memory from a pool. NOTE: This low-level function should only be |
45 | + used in mem0mem.*! */ |
46 | --- a/storage/innobase/include/srv0srv.h |
47 | +++ b/storage/innobase/include/srv0srv.h |
48 | @@ -60,6 +60,8 @@ |
49 | @@ -958,7 +987,7 @@ |
50 | /********************************************************** |
51 | --- a/storage/innobase/mem/mem0dbg.c |
52 | +++ b/storage/innobase/mem/mem0dbg.c |
53 | -@@ -133,6 +133,14 @@ |
54 | +@@ -133,9 +133,30 @@ |
55 | mem_hash_initialized = TRUE; |
56 | #endif |
57 | |
58 | @@ -973,6 +1002,22 @@ |
59 | mem_comm_pool = mem_pool_create(size); |
60 | } |
61 | |
62 | ++/******************************************************************//** |
63 | ++Closes the memory system. */ |
64 | ++void |
65 | ++mem_close(void) |
66 | ++/*===========*/ |
67 | ++{ |
68 | ++ mem_pool_free(mem_comm_pool); |
69 | ++ mem_comm_pool = NULL; |
70 | ++#ifdef UNIV_MEM_DEBUG |
71 | ++ mem_hash_initialized = FALSE; |
72 | ++#endif /* UNIV_MEM_DEBUG */ |
73 | ++} |
74 | ++ |
75 | + #ifdef UNIV_MEM_DEBUG |
76 | + /********************************************************************** |
77 | + Initializes an allocated memory field in the debug version. */ |
78 | --- a/storage/innobase/mem/mem0mem.c |
79 | +++ b/storage/innobase/mem/mem0mem.c |
80 | @@ -472,6 +472,7 @@ |
81 | @@ -1026,7 +1071,25 @@ |
82 | pool = ut_malloc(sizeof(mem_pool_t)); |
83 | |
84 | /* We do not set the memory to zero (FALSE) in the pool, |
85 | -@@ -333,6 +332,10 @@ |
86 | +@@ -244,6 +243,17 @@ |
87 | + return(pool); |
88 | + } |
89 | + |
90 | ++/********************************************************************//** |
91 | ++Frees a memory pool. */ |
92 | ++void |
93 | ++mem_pool_free( |
94 | ++/*==========*/ |
95 | ++ mem_pool_t* pool) /*!< in, own: memory pool */ |
96 | ++{ |
97 | ++ ut_free(pool->buf); |
98 | ++ ut_free(pool); |
99 | ++} |
100 | ++ |
101 | + /************************************************************************ |
102 | + Fills the specified free list. */ |
103 | + static |
104 | +@@ -333,6 +344,10 @@ |
105 | ulint n; |
106 | ibool ret; |
107 | |
108 | @@ -1037,7 +1100,7 @@ |
109 | n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE)); |
110 | |
111 | mutex_enter(&(pool->mutex)); |
112 | -@@ -465,6 +468,11 @@ |
113 | +@@ -465,6 +480,11 @@ |
114 | ulint size; |
115 | ulint n; |
116 | |
117 | |
118 | === modified file 'src/fil_cur.c' |
119 | --- src/fil_cur.c 2012-05-28 16:49:14 +0000 |
120 | +++ src/fil_cur.c 2012-07-11 09:06:21 +0000 |
121 | @@ -54,6 +54,7 @@ |
122 | cursor->orig_buf = NULL; |
123 | cursor->file = XB_FILE_UNDEFINED; |
124 | |
125 | + cursor->space_id = node->space->id; |
126 | cursor->is_system = trx_sys_sys_space(node->space->id); |
127 | |
128 | /* Make the file path relative to the backup root, |
129 | |
130 | === modified file 'src/fil_cur.h' |
131 | --- src/fil_cur.h 2012-05-25 11:38:15 +0000 |
132 | +++ src/fil_cur.h 2012-07-11 09:06:21 +0000 |
133 | @@ -53,6 +53,7 @@ |
134 | ulint buf_page_no; /*!< number of the first page in |
135 | buffer */ |
136 | ulint thread_n; /*!< thread number for diagnostics */ |
137 | + ulint space_id; /*!< ID of tablespace */ |
138 | } xb_fil_cur_t; |
139 | |
140 | typedef enum { |
141 | |
142 | === modified file 'src/innodb_int.c' |
143 | --- src/innodb_int.c 2012-02-16 18:02:07 +0000 |
144 | +++ src/innodb_int.c 2012-07-11 09:06:21 +0000 |
145 | @@ -151,6 +151,82 @@ |
146 | return os_file_flush(file); |
147 | #endif |
148 | } |
149 | +/*******************************************************************//** |
150 | +Returns the table space by a given id, NULL if not found. */ |
151 | +fil_space_t* |
152 | +xb_space_get_by_id( |
153 | +/*================*/ |
154 | + ulint id) /*!< in: space id */ |
155 | +{ |
156 | + fil_space_t* space; |
157 | + |
158 | + ut_ad(mutex_own(&fil_system->mutex)); |
159 | + |
160 | +#ifdef INNODB_VERSION_SHORT |
161 | + HASH_SEARCH(hash, fil_system->spaces, id, |
162 | + fil_space_t*, space, |
163 | + ut_ad(space->magic_n == FIL_SPACE_MAGIC_N), |
164 | + space->id == id); |
165 | +#else |
166 | + HASH_SEARCH(hash, fil_system->spaces, id, space, space->id == id); |
167 | +#endif |
168 | + |
169 | + return(space); |
170 | +} |
171 | + |
172 | +/*******************************************************************//** |
173 | +Returns the table space by a given name, NULL if not found. */ |
174 | +fil_space_t* |
175 | +xb_space_get_by_name( |
176 | +/*==================*/ |
177 | + const char* name) /*!< in: space name */ |
178 | +{ |
179 | + fil_space_t* space; |
180 | + ulint fold; |
181 | + |
182 | + ut_ad(mutex_own(&fil_system->mutex)); |
183 | + |
184 | +#ifdef INNODB_VERSION_SHORT |
185 | + fold = ut_fold_string(name); |
186 | + HASH_SEARCH(name_hash, fil_system->name_hash, fold, |
187 | + fil_space_t*, space, |
188 | + ut_ad(space->magic_n == FIL_SPACE_MAGIC_N), |
189 | + !strcmp(name, space->name)); |
190 | +#else |
191 | + HASH_SEARCH(name_hash, fil_system->name_hash, ut_fold_string(name), |
192 | + space, 0 == strcmp(name, space->name)); |
193 | +#endif |
194 | + |
195 | + return(space); |
196 | +} |
197 | + |
198 | +#ifndef INNODB_VERSION_SHORT |
199 | + |
200 | +/*******************************************************************//** |
201 | +Free all spaces in space_list. */ |
202 | +void |
203 | +fil_free_all_spaces(void) |
204 | +/*=====================*/ |
205 | +{ |
206 | + fil_space_t* space; |
207 | + |
208 | + mutex_enter(&fil_system->mutex); |
209 | + |
210 | + space = UT_LIST_GET_FIRST(fil_system->space_list); |
211 | + |
212 | + while (space != NULL) { |
213 | + fil_node_t* node; |
214 | + fil_space_t* prev_space = space; |
215 | + |
216 | + space = UT_LIST_GET_NEXT(space_list, space); |
217 | + |
218 | + fil_space_free(prev_space->id, FALSE); |
219 | + } |
220 | + |
221 | + mutex_exit(&fil_system->mutex); |
222 | +} |
223 | + |
224 | +#endif |
225 | |
226 | void |
227 | innobase_invalidate_query_cache( |
228 | |
229 | === modified file 'src/innodb_int.h' |
230 | --- src/innodb_int.h 2012-05-25 11:38:15 +0000 |
231 | +++ src/innodb_int.h 2012-07-11 09:06:21 +0000 |
232 | @@ -410,6 +410,9 @@ |
233 | extern char *opt_mysql_tmpdir; |
234 | extern MY_TMPDIR mysql_tmpdir_list; |
235 | |
236 | +/** Value of fil_space_struct::magic_n */ |
237 | +#define FIL_SPACE_MAGIC_N 89472 |
238 | + |
239 | /* ==end=== definition at fil0fil.c === */ |
240 | |
241 | /* prototypes for static functions in original */ |
242 | @@ -581,6 +584,32 @@ |
243 | /*==========*/ |
244 | os_file_t file); /*!< in, own: handle to a file */ |
245 | |
246 | +/*******************************************************************//** |
247 | +Returns the table space by a given id, NULL if not found. */ |
248 | +fil_space_t* |
249 | +xb_space_get_by_id( |
250 | +/*================*/ |
251 | + ulint id); /*!< in: space id */ |
252 | + |
253 | +/*******************************************************************//** |
254 | +Returns the table space by a given name, NULL if not found. */ |
255 | +fil_space_t* |
256 | +xb_space_get_by_name( |
257 | +/*==================*/ |
258 | + const char* name); /*!< in: space name */ |
259 | + |
260 | +#ifndef INNODB_VERSION_SHORT |
261 | + |
262 | +#define SRV_SHUTDOWN_NONE 0 |
263 | + |
264 | +/*******************************************************************//** |
265 | +Free all spaces in space_list. */ |
266 | +void |
267 | +fil_free_all_spaces(void); |
268 | +/*=====================*/ |
269 | + |
270 | +#endif |
271 | + |
272 | void |
273 | innobase_mysql_prepare_print_arbitrary_thd(void); |
274 | |
275 | |
276 | === modified file 'src/write_filt.c' |
277 | --- src/write_filt.c 2012-05-25 11:38:15 +0000 |
278 | +++ src/write_filt.c 2012-07-11 09:06:21 +0000 |
279 | @@ -102,6 +102,7 @@ |
280 | snprintf(meta_name, sizeof(meta_name), "%s%s", dst_name, |
281 | XB_DELTA_INFO_SUFFIX); |
282 | info.page_size = cursor->page_size; |
283 | + info.space_id = cursor->space_id; |
284 | if (!xb_write_delta_metadata(meta_name, &info)) { |
285 | msg("[%02lu] xtrabackup: Error: " |
286 | "failed to write meta info for %s\n", |
287 | |
288 | === modified file 'src/xtrabackup.c' |
289 | --- src/xtrabackup.c 2012-06-20 16:23:58 +0000 |
290 | +++ src/xtrabackup.c 2012-07-11 09:06:21 +0000 |
291 | @@ -1500,7 +1500,8 @@ |
292 | return(TRUE); |
293 | } |
294 | |
295 | - if (fscanf(fp, "page_size = %lu\n", &info->page_size) != 1) |
296 | + if (fscanf(fp, "page_size = %lu\nspace_id = %lu\n", |
297 | + &info->page_size, &info->space_id) != 2) |
298 | r= FALSE; |
299 | |
300 | fclose(fp); |
301 | @@ -1515,14 +1516,16 @@ |
302 | xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info) |
303 | { |
304 | ds_file_t *f; |
305 | - char buf[32]; |
306 | + char buf[64]; |
307 | my_bool ret; |
308 | size_t len; |
309 | MY_STAT mystat; |
310 | |
311 | - snprintf(buf, sizeof(buf), "page_size = %lu\n", info->page_size); |
312 | - |
313 | + snprintf(buf, sizeof(buf), |
314 | + "page_size = %lu\nspace_id = %lu\n", |
315 | + info->page_size, info->space_id); |
316 | len = strlen(buf); |
317 | + |
318 | mystat.st_size = len; |
319 | mystat.st_mtime = my_time(0); |
320 | |
321 | @@ -2108,11 +2111,11 @@ |
322 | void* arg) |
323 | { |
324 | ulint segment; |
325 | - ulint i; |
326 | + |
327 | |
328 | segment = *((ulint*)arg); |
329 | |
330 | - for (i = 0;; i++) { |
331 | + while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) { |
332 | fil_aio_wait(segment); |
333 | } |
334 | |
335 | @@ -2265,6 +2268,141 @@ |
336 | ds_meta = NULL; |
337 | } |
338 | |
339 | +#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD |
340 | +#define SRV_MAX_N_PENDING_SYNC_IOS 100 |
341 | + |
342 | +/************************************************************************ |
343 | +Initialize the tablespace memory cache and populate it by scanning for and |
344 | +opening data files. |
345 | +@returns DB_SUCCESS or error code.*/ |
346 | +ulint |
347 | +xb_data_files_init(void) |
348 | +/*====================*/ |
349 | +{ |
350 | + ulint i; |
351 | + ibool create_new_db; |
352 | +#ifdef XTRADB_BASED |
353 | + ibool create_new_doublewrite_file; |
354 | +#endif |
355 | + ulint err; |
356 | + LSN64 min_flushed_lsn; |
357 | + LSN64 max_flushed_lsn; |
358 | + ulint sum_of_new_sizes; |
359 | + |
360 | +#ifndef INNODB_VERSION_SHORT |
361 | + os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD |
362 | + * srv_n_file_io_threads, |
363 | + srv_n_file_io_threads, |
364 | + SRV_MAX_N_PENDING_SYNC_IOS); |
365 | + |
366 | + fil_init(srv_max_n_open_files); |
367 | +#else |
368 | + srv_n_file_io_threads = 2 + srv_n_read_io_threads + |
369 | + srv_n_write_io_threads; |
370 | + |
371 | + os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD, |
372 | + srv_n_read_io_threads, |
373 | + srv_n_write_io_threads, |
374 | + SRV_MAX_N_PENDING_SYNC_IOS); |
375 | + |
376 | + fil_init(srv_file_per_table ? 50000 : 5000, |
377 | + srv_max_n_open_files); |
378 | +#endif |
379 | + |
380 | + fsp_init(); |
381 | + |
382 | + for (i = 0; i < srv_n_file_io_threads; i++) { |
383 | + thread_nr[i] = i; |
384 | + |
385 | + os_thread_create(io_handler_thread, thread_nr + i, |
386 | + thread_ids + i); |
387 | + } |
388 | + |
389 | + os_thread_sleep(200000); /*0.2 sec*/ |
390 | + |
391 | + err = open_or_create_data_files(&create_new_db, |
392 | +#ifdef XTRADB_BASED |
393 | + &create_new_doublewrite_file, |
394 | +#endif |
395 | + &min_flushed_lsn, &max_flushed_lsn, |
396 | + &sum_of_new_sizes); |
397 | + if (err != DB_SUCCESS) { |
398 | + msg("xtrabackup: Could not open or create data files.\n" |
399 | + "xtrabackup: If you tried to add new data files, and it " |
400 | + "failed here,\n" |
401 | + "xtrabackup: you should now edit innodb_data_file_path in " |
402 | + "my.cnf back\n" |
403 | + "xtrabackup: to what it was, and remove the new ibdata " |
404 | + "files InnoDB created\n" |
405 | + "xtrabackup: in this failed attempt. InnoDB only wrote " |
406 | + "those files full of\n" |
407 | + "xtrabackup: zeros, but did not yet use them in any way. " |
408 | + "But be careful: do not\n" |
409 | + "xtrabackup: remove old data files which contain your " |
410 | + "precious data!\n"); |
411 | + return(err); |
412 | + } |
413 | + |
414 | + /* create_new_db must not be TRUE.. */ |
415 | + if (create_new_db) { |
416 | + msg("xtrabackup: could not find data files at the " |
417 | + "specified datadir\n"); |
418 | + return(DB_ERROR); |
419 | + } |
420 | + |
421 | + return(fil_load_single_table_tablespaces()); |
422 | +} |
423 | + |
424 | +/************************************************************************ |
425 | +Destroy the tablespace memory cache. */ |
426 | +void |
427 | +xb_data_files_close(void) |
428 | +/*====================*/ |
429 | +{ |
430 | + ulint i; |
431 | + |
432 | + /* Shutdown the aio threads. This has been copied from |
433 | + innobase_shutdown_for_mysql(). */ |
434 | + |
435 | + srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS; |
436 | + |
437 | + for (i = 0; i < 1000; i++) { |
438 | + os_aio_wake_all_threads_at_shutdown(); |
439 | + |
440 | + os_mutex_enter(os_sync_mutex); |
441 | + |
442 | + if (os_thread_count == 0) { |
443 | + |
444 | + os_mutex_exit(os_sync_mutex); |
445 | + |
446 | + os_thread_sleep(10000); |
447 | + |
448 | + break; |
449 | + } |
450 | + |
451 | + os_mutex_exit(os_sync_mutex); |
452 | + |
453 | + os_thread_sleep(10000); |
454 | + } |
455 | + |
456 | + if (i == 1000) { |
457 | + msg("xtrabackup: Warning: %lu threads created by InnoDB" |
458 | + " had not exited at shutdown!\n", |
459 | + (ulong) os_thread_count); |
460 | + } |
461 | + |
462 | +#ifdef INNODB_VERSION_SHORT |
463 | + os_aio_free(); |
464 | +#endif |
465 | + fil_close_all_files(); |
466 | +#ifndef INNODB_VERSION_SHORT |
467 | + fil_free_all_spaces(); |
468 | +#endif |
469 | + fil_system = NULL; |
470 | + |
471 | + srv_shutdown_state = SRV_SHUTDOWN_NONE; |
472 | +} |
473 | + |
474 | static void |
475 | xtrabackup_backup_func(void) |
476 | { |
477 | @@ -2418,85 +2556,25 @@ |
478 | srv_general_init(); |
479 | |
480 | { |
481 | - ibool create_new_db; |
482 | -#ifdef XTRADB_BASED |
483 | - ibool create_new_doublewrite_file; |
484 | -#endif |
485 | ibool log_file_created; |
486 | ibool log_created = FALSE; |
487 | ibool log_opened = FALSE; |
488 | - LSN64 min_flushed_lsn; |
489 | - LSN64 max_flushed_lsn; |
490 | - ulint sum_of_new_sizes; |
491 | ulint err; |
492 | ulint i; |
493 | |
494 | - |
495 | - |
496 | - |
497 | -#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD |
498 | -#define SRV_MAX_N_PENDING_SYNC_IOS 100 |
499 | - |
500 | -#ifndef INNODB_VERSION_SHORT |
501 | - os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD |
502 | - * srv_n_file_io_threads, |
503 | - srv_n_file_io_threads, |
504 | - SRV_MAX_N_PENDING_SYNC_IOS); |
505 | - |
506 | - fil_init(srv_max_n_open_files); |
507 | -#else |
508 | - srv_n_file_io_threads = 2 + srv_n_read_io_threads + srv_n_write_io_threads; |
509 | - |
510 | - os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD, |
511 | - srv_n_read_io_threads, |
512 | - srv_n_write_io_threads, |
513 | - SRV_MAX_N_PENDING_SYNC_IOS); |
514 | - |
515 | - fil_init(srv_file_per_table ? 50000 : 5000, |
516 | - srv_max_n_open_files); |
517 | -#endif |
518 | - |
519 | - fsp_init(); |
520 | + err = xb_data_files_init(); |
521 | + if (err != DB_SUCCESS) { |
522 | + msg("xtrabackup: error: xb_data_files_init() failed with" |
523 | + "error code %lu\n", err); |
524 | + exit(EXIT_FAILURE); |
525 | + } |
526 | + |
527 | log_init(); |
528 | |
529 | lock_sys_create(srv_lock_table_size); |
530 | |
531 | - for (i = 0; i < srv_n_file_io_threads; i++) { |
532 | - thread_nr[i] = i; |
533 | - |
534 | - os_thread_create(io_handler_thread, thread_nr + i, thread_ids + i); |
535 | - } |
536 | - |
537 | - os_thread_sleep(200000); /*0.2 sec*/ |
538 | - |
539 | - err = open_or_create_data_files(&create_new_db, |
540 | -#ifdef XTRADB_BASED |
541 | - &create_new_doublewrite_file, |
542 | -#endif |
543 | - &min_flushed_lsn, &max_flushed_lsn, |
544 | - &sum_of_new_sizes); |
545 | - if (err != DB_SUCCESS) { |
546 | - msg( |
547 | -"xtrabackup: Could not open or create data files.\n" |
548 | -"xtrabackup: If you tried to add new data files, and it failed here,\n" |
549 | -"xtrabackup: you should now edit innodb_data_file_path in my.cnf back\n" |
550 | -"xtrabackup: to what it was, and remove the new ibdata files InnoDB created\n" |
551 | -"xtrabackup: in this failed attempt. InnoDB only wrote those files full of\n" |
552 | -"xtrabackup: zeros, but did not yet use them in any way. But be careful: do not\n" |
553 | -"xtrabackup: remove old data files which contain your precious data!\n"); |
554 | - |
555 | - //return((int) err); |
556 | - exit(EXIT_FAILURE); |
557 | - } |
558 | - |
559 | - /* create_new_db must not be TRUE.. */ |
560 | - if (create_new_db) { |
561 | - msg("xtrabackup: Something wrong with source files...\n"); |
562 | - exit(EXIT_FAILURE); |
563 | - } |
564 | - |
565 | for (i = 0; i < srv_n_log_files; i++) { |
566 | - err = open_or_create_log_file(create_new_db, &log_file_created, |
567 | + err = open_or_create_log_file(FALSE, &log_file_created, |
568 | log_opened, 0, i); |
569 | if (err != DB_SUCCESS) { |
570 | |
571 | @@ -2509,8 +2587,7 @@ |
572 | } else { |
573 | log_opened = TRUE; |
574 | } |
575 | - if ((log_opened && create_new_db) |
576 | - || (log_opened && log_created)) { |
577 | + if ((log_opened && log_created)) { |
578 | msg( |
579 | "xtrabackup: Error: all log files must be created at the same time.\n" |
580 | "xtrabackup: All log files must be created also in database creation.\n" |
581 | @@ -2830,6 +2907,8 @@ |
582 | msg("xtrabackup: Transaction log of lsn (%llu) to (%llu) was copied.\n", |
583 | checkpoint_lsn_start, log_copy_scanned_lsn); |
584 | #endif |
585 | + |
586 | + xb_data_files_close(); |
587 | } |
588 | |
589 | /* ================= stats ================= */ |
590 | @@ -3717,6 +3796,155 @@ |
591 | return TRUE; |
592 | } |
593 | |
594 | + |
595 | +/*********************************************************************** |
596 | +Searches for matching tablespace file for given .delta file and space_id |
597 | +in given directory. When matching tablespace found, renames it to match the |
598 | +name of .delta file. If there was a tablespace with matching name and |
599 | +mismatching ID, renames it to xtrabackup_tmp_#ID.ibd. If there was no |
600 | +matching file, creates the new one. |
601 | +@return file handle of matched or created file */ |
602 | +static |
603 | +os_file_t |
604 | +xb_delta_open_matching_space( |
605 | + const char* dbname, /* in: path to destination database dir */ |
606 | + const char* name, /* in: name of delta file (without .delta) */ |
607 | + ulint space_id, /* in: space id of delta file */ |
608 | + ulint zip_size, /* in: zip_size of tablespace */ |
609 | + char* real_name, /* out: full path of destination file */ |
610 | + size_t real_name_len, /* out: buffer size for real_name */ |
611 | + ibool* success) /* out: indicates error. TRUE = success */ |
612 | +{ |
613 | + char dest_dir[FN_REFLEN]; |
614 | + char dest_space_name[FN_REFLEN]; |
615 | + ibool ok; |
616 | + fil_space_t* fil_space; |
617 | + os_file_t file = 0; |
618 | + |
619 | + ut_a(dbname || space_id == 0); |
620 | + |
621 | + *success = FALSE; |
622 | + |
623 | + if (dbname) { |
624 | + snprintf(dest_dir, FN_REFLEN, "%s/%s", |
625 | + xtrabackup_target_dir, dbname); |
626 | + srv_normalize_path_for_win(dest_dir); |
627 | + |
628 | + snprintf(dest_space_name, FN_REFLEN, "./%s/%s", |
629 | + dbname, name); |
630 | + } else { |
631 | + snprintf(dest_dir, FN_REFLEN, "%s", xtrabackup_target_dir); |
632 | + srv_normalize_path_for_win(dest_dir); |
633 | + |
634 | + snprintf(dest_space_name, FN_REFLEN, "./%s", name); |
635 | + } |
636 | + |
637 | + snprintf(real_name, real_name_len, |
638 | + "%s/%s", |
639 | + xtrabackup_target_dir, dest_space_name); |
640 | + srv_normalize_path_for_win(real_name); |
641 | + |
642 | + /* Create the database directory if it doesn't exist yet */ |
643 | + if (!os_file_create_directory(dest_dir, FALSE)) { |
644 | + msg("xtrabackup: error: cannot create dir %s\n", dest_dir); |
645 | + return file; |
646 | + } |
647 | + |
648 | + mutex_enter(&fil_system->mutex); |
649 | + fil_space = xb_space_get_by_name(dest_space_name); |
650 | + mutex_exit(&fil_system->mutex); |
651 | + |
652 | + if (fil_space != NULL) { |
653 | + if (fil_space->id == space_id) { |
654 | + /* we found matching space */ |
655 | + goto found; |
656 | + } else { |
657 | + |
658 | + char tmpname[FN_REFLEN]; |
659 | + |
660 | + snprintf(tmpname, FN_REFLEN, "./%s/xtrabackup_tmp_#%lu", |
661 | + dbname, fil_space->id); |
662 | + |
663 | + msg("xtrabackup: Renaming %s to %s.ibd\n", |
664 | + fil_space->name, tmpname); |
665 | + |
666 | + if (!fil_rename_tablespace(NULL, |
667 | + fil_space->id, tmpname)) |
668 | + { |
669 | + msg("xtrabackup: Cannot rename %s to %s\n", |
670 | + fil_space->name, tmpname); |
671 | + goto exit; |
672 | + } |
673 | + } |
674 | + } |
675 | + |
676 | + mutex_enter(&fil_system->mutex); |
677 | + fil_space = xb_space_get_by_id(space_id); |
678 | + mutex_exit(&fil_system->mutex); |
679 | + if (fil_space != NULL) { |
680 | + char tmpname[FN_REFLEN]; |
681 | + |
682 | + strncpy(tmpname, dest_space_name, FN_REFLEN); |
683 | + tmpname[strlen(tmpname) - 4] = 0; |
684 | + |
685 | + msg("xtrabackup: Renaming %s to %s\n", |
686 | + fil_space->name, dest_space_name); |
687 | + |
688 | + if (!fil_rename_tablespace(NULL, |
689 | + fil_space->id, tmpname)) |
690 | + { |
691 | + msg("xtrabackup: Cannot rename %s to %s\n", |
692 | + fil_space->name, dest_space_name); |
693 | + goto exit; |
694 | + } |
695 | + |
696 | + goto found; |
697 | + } |
698 | + |
699 | + /* no matching space found. create the new one */ |
700 | + |
701 | +#ifdef INNODB_VERSION_SHORT |
702 | + if (!fil_space_create(dest_space_name, space_id, |
703 | + zip_size, FIL_TABLESPACE)) { |
704 | +#else |
705 | + if (!fil_space_create(dest_space_name, space_id, |
706 | + FIL_TABLESPACE)) { |
707 | +#endif |
708 | + msg("xtrabackup: Cannot create tablespace %s\n", |
709 | + dest_space_name); |
710 | + goto exit; |
711 | + } |
712 | + |
713 | + file = xb_file_create_no_error_handling(real_name, OS_FILE_CREATE, |
714 | + OS_FILE_READ_WRITE, |
715 | + &ok); |
716 | + |
717 | + if (ok) { |
718 | + *success = TRUE; |
719 | + } else { |
720 | + msg("xtrabackup: Cannot open file %s\n", real_name); |
721 | + } |
722 | + |
723 | + goto exit; |
724 | + |
725 | +found: |
726 | + /* open the file and return it's handle */ |
727 | + |
728 | + file = xb_file_create_no_error_handling(real_name, OS_FILE_OPEN, |
729 | + OS_FILE_READ_WRITE, |
730 | + &ok); |
731 | + |
732 | + if (ok) { |
733 | + *success = TRUE; |
734 | + } else { |
735 | + msg("xtrabackup: Cannot open file %s\n", real_name); |
736 | + } |
737 | + |
738 | +exit: |
739 | + |
740 | + return file; |
741 | +} |
742 | + |
743 | /************************************************************************ |
744 | Applies a given .delta file to the corresponding data file. |
745 | @return TRUE on success */ |
746 | @@ -3734,6 +3962,7 @@ |
747 | char src_path[FN_REFLEN]; |
748 | char dst_path[FN_REFLEN]; |
749 | char meta_path[FN_REFLEN]; |
750 | + char space_name[FN_REFLEN]; |
751 | ibool success; |
752 | |
753 | ibool last_buffer = FALSE; |
754 | @@ -3761,6 +3990,9 @@ |
755 | } |
756 | dst_path[strlen(dst_path) - 6] = '\0'; |
757 | |
758 | + strncpy(space_name, filename, FN_REFLEN); |
759 | + space_name[strlen(space_name) - 6] = 0; |
760 | + |
761 | if (!get_meta_path(src_path, meta_path)) { |
762 | goto error; |
763 | } |
764 | @@ -3798,36 +4030,11 @@ |
765 | |
766 | xb_file_set_nocache(src_file, src_path, "OPEN"); |
767 | |
768 | - dst_file = xb_file_create_no_error_handling(dst_path, OS_FILE_OPEN, |
769 | - OS_FILE_READ_WRITE, |
770 | - &success); |
771 | -again: |
772 | + dst_file = xb_delta_open_matching_space( |
773 | + dbname, space_name, info.space_id, |
774 | + info.page_size == UNIV_PAGE_SIZE ? 0 : info.page_size, |
775 | + dst_path, sizeof(dst_path), &success); |
776 | if (!success) { |
777 | - ulint errcode = os_file_get_last_error(TRUE); |
778 | - |
779 | - if (errcode == OS_FILE_NOT_FOUND) { |
780 | - msg("xtrabackup: target data file %s " |
781 | - "is not found, creating a new one\n", dst_path); |
782 | - /* Create the database directory if it doesn't exist yet |
783 | - */ |
784 | - if (dbname) { |
785 | - char dst_dir[FN_REFLEN]; |
786 | - |
787 | - snprintf(dst_dir, sizeof(dst_dir), "%s/%s", |
788 | - xtrabackup_real_target_dir, dbname); |
789 | - srv_normalize_path_for_win(dst_dir); |
790 | - |
791 | - if (!os_file_create_directory(dst_dir, FALSE)) |
792 | - goto error; |
793 | - } |
794 | - dst_file = |
795 | - xb_file_create_no_error_handling(dst_path, |
796 | - OS_FILE_CREATE, |
797 | - OS_FILE_READ_WRITE, |
798 | - &success); |
799 | - goto again; |
800 | - } |
801 | - |
802 | msg("xtrabackup: error: cannot open %s\n", dst_path); |
803 | goto error; |
804 | } |
805 | @@ -3842,7 +4049,7 @@ |
806 | incremental_buffer = ut_align(incremental_buffer_base, |
807 | UNIV_PAGE_SIZE_MAX); |
808 | |
809 | - msg("Applying %s ...\n", src_path); |
810 | + msg("Applying %s to %s...\n", src_path, dst_path); |
811 | |
812 | while (!last_buffer) { |
813 | ulint cluster_header; |
814 | @@ -4150,6 +4357,8 @@ |
815 | static void |
816 | xtrabackup_prepare_func(void) |
817 | { |
818 | + ulint err; |
819 | + |
820 | /* cd to target-dir */ |
821 | |
822 | if (my_setwd(xtrabackup_real_target_dir,MYF(MY_WME))) |
823 | @@ -4220,12 +4429,29 @@ |
824 | if(xtrabackup_init_temp_log()) |
825 | goto error; |
826 | |
827 | - if(xtrabackup_incremental && !xtrabackup_apply_deltas(TRUE)) |
828 | + if(innodb_init_param()) |
829 | goto error; |
830 | |
831 | + mem_init(srv_mem_pool_size); |
832 | + if (xtrabackup_incremental) { |
833 | + err = xb_data_files_init(); |
834 | + if (err != DB_SUCCESS) { |
835 | + msg("xtrabackup: error: xb_data_files_init() failed with" |
836 | + "error code %lu\n", err); |
837 | + goto error; |
838 | + } |
839 | + |
840 | + if(!xtrabackup_apply_deltas(TRUE)) { |
841 | + xb_data_files_close(); |
842 | + goto error; |
843 | + } |
844 | + |
845 | + xb_data_files_close(); |
846 | + } |
847 | sync_close(); |
848 | sync_initialized = FALSE; |
849 | os_sync_free(); |
850 | + mem_close(); |
851 | os_sync_mutex = NULL; |
852 | ut_free_all_mem(); |
853 | |
854 | |
855 | === modified file 'src/xtrabackup.h' |
856 | --- src/xtrabackup.h 2012-05-28 16:49:14 +0000 |
857 | +++ src/xtrabackup.h 2012-07-11 09:06:21 +0000 |
858 | @@ -23,6 +23,7 @@ |
859 | |
860 | typedef struct { |
861 | ulint page_size; |
862 | + ulint space_id; |
863 | } xb_delta_info_t; |
864 | |
865 | typedef enum { |
866 | |
867 | === added file 'test/t/bug932623.sh' |
868 | --- test/t/bug932623.sh 1970-01-01 00:00:00 +0000 |
869 | +++ test/t/bug932623.sh 2012-07-11 09:06:21 +0000 |
870 | @@ -0,0 +1,85 @@ |
871 | +######################################################################## |
872 | +# Bug #932623: RENAME TABLE causes incremental prepare to fail |
873 | +######################################################################## |
874 | + |
875 | +. inc/common.sh |
876 | + |
877 | +start_server --innodb_file_per_table |
878 | + |
879 | +run_cmd $MYSQL $MYSQL_ARGS test <<EOF |
880 | +CREATE TABLE t1_old(a INT) ENGINE=InnoDB; |
881 | +INSERT INTO t1_old VALUES (1), (2), (3); |
882 | + |
883 | +CREATE TABLE t1(a INT) ENGINE=InnoDB; |
884 | +INSERT INTO t1 VALUES (4), (5), (6); |
885 | +EOF |
886 | + |
887 | +# Full backup |
888 | +# backup root directory |
889 | +vlog "Starting backup" |
890 | +innobackupex --no-timestamp $topdir/full |
891 | + |
892 | +vlog "Rotating the table" |
893 | + |
894 | +run_cmd $MYSQL $MYSQL_ARGS test <<EOF |
895 | +CREATE TABLE t1_new(a int) ENGINE=InnoDB; |
896 | +INSERT INTO t1_new VALUES (7), (8), (9); |
897 | + |
898 | +CREATE DATABASE db2; |
899 | +RENAME TABLE t1_old TO db2.t1; |
900 | + |
901 | +RENAME TABLE t1 TO t1_old; |
902 | +RENAME TABLE t1_new TO t1; |
903 | + |
904 | +INSERT INTO t1_old VALUES (10), (11), (12); |
905 | +INSERT INTO t1 VALUES (13), (14), (15); |
906 | + |
907 | +EOF |
908 | + |
909 | +vlog "Creating incremental backup" |
910 | + |
911 | +innobackupex --incremental --no-timestamp \ |
912 | + --incremental-basedir=$topdir/full $topdir/inc |
913 | + |
914 | +vlog "Preparing backup" |
915 | + |
916 | +innobackupex --apply-log --redo-only $topdir/full |
917 | +vlog "Log applied to full backup" |
918 | + |
919 | +innobackupex --apply-log --redo-only --incremental-dir=$topdir/inc \ |
920 | + $topdir/full |
921 | +vlog "Delta applied to full backup" |
922 | + |
923 | +innobackupex --apply-log $topdir/full |
924 | +vlog "Data prepared for restore" |
925 | + |
926 | +checksum_t1_a=`checksum_table test t1` |
927 | +checksum_t1_old_a=`checksum_table test t1_old` |
928 | +checksum_t1_db2_a=`checksum_table db2 t1` |
929 | + |
930 | +# Destroying mysql data |
931 | +stop_server |
932 | +rm -rf $mysql_datadir/* |
933 | +vlog "Data destroyed" |
934 | + |
935 | +# Restore backup |
936 | +vlog "Copying files" |
937 | + |
938 | +innobackupex --copy-back $topdir/full |
939 | +vlog "Data restored" |
940 | + |
941 | +start_server --innodb_file_per_table |
942 | + |
943 | +vlog "Checking checksums" |
944 | +checksum_t1_b=`checksum_table test t1` |
945 | +checksum_t1_old_b=`checksum_table test t1_old` |
946 | +checksum_t1_db2_b=`checksum_table db2 t1` |
947 | + |
948 | +if [ "$checksum_t1_a" != "$checksum_t1_b" -o "$checksum_t1_old_a" != "$checksum_t1_old_b" \ |
949 | + -o "$checksum_t1_db2_a" != "$checksum_t1_db2_b" ] |
950 | +then |
951 | + vlog "Checksums do not match" |
952 | + exit -1 |
953 | +fi |
954 | + |
955 | +vlog "Checksums are OK" |
This branch introduces many messages like this one:
2012-07-31 13:58:32: xb_incremental.sh: ===> /home/laurynas/ percona/ src/xb21-bug932623/test/. ./src/xtrabacku p --no-defaults --datadir= /home/laurynas/ percona/ src/xb21-bug932623/test/var1/data --backup --target- dir=/home/ laurynas/ percona/ src/xb21-bug932623/test/var1/ data/full percona/ src/xb21-bug932623/test/. ./src/xtrabacku p version 2.0.0 for Percona Server 5.1.59 unknown-linux-gnu (x86_64) (revision id: undefined) percona/ src/xb21-bug932623/test/var1/data data_home_ dir = ./ data_file_ path = ibdata1: 10M:autoextend log_group_ home_dir = ./ log_files_ in_group = 2 log_file_ size = 5242880 sample/ test.ibd' ,
/home/laurynas/
xtrabackup: uses posix_fadvise().
xtrabackup: cd to /home/laurynas/
xtrabackup: Target instance is assumed as followings.
xtrabackup: innodb_
xtrabackup: innodb_
xtrabackup: innodb_
xtrabackup: innodb_
xtrabackup: innodb_
120731 13:58:32 InnoDB: Warning: allocated tablespace 10, old maximum was 9
120731 13:58:32 InnoDB: Warning: trying to init to the tablespace memory cache
InnoDB: a tablespace 10 of name './incremental_
InnoDB: but a tablespace 10 of the same name
InnoDB: already exists in the tablespace memory cache!
InnoDB: We assume that InnoDB did a crash recovery, and you had
InnoDB: an .ibd file for which the table did not exist in the
InnoDB: InnoDB internal data dictionary in the ibdata files.
InnoDB: We assume that you later removed the .ibd and .frm files,
InnoDB: and are now trying to recreate the table. We now remove the
InnoDB: conflicting tablespace object from the memory cache and try
InnoDB: the init again.
Since Sergei is on vacation and I depend on this code, let's keep this "Approved" and merge and I will fix as a follow-up.