Merge lp:~akopytov/percona-xtrabackup/bug1079700-2.1 into lp:percona-xtrabackup/2.1

Proposed by Alexey Kopytov
Status: Merged
Approved by: Laurynas Biveinis
Approved revision: no longer in the source branch.
Merged at revision: 602
Proposed branch: lp:~akopytov/percona-xtrabackup/bug1079700-2.1
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 1977 lines (+750/-183)
9 files modified
patches/innodb51.patch (+116/-22)
patches/innodb55.patch (+105/-22)
patches/innodb56.patch (+102/-26)
patches/xtradb51.patch (+118/-25)
patches/xtradb55.patch (+106/-23)
src/fil_cur.cc (+104/-27)
src/fil_cur.h (+1/-0)
src/xtrabackup.cc (+61/-7)
test/t/ddl.sh (+37/-31)
To merge this branch: bzr merge lp:~akopytov/percona-xtrabackup/bug1079700-2.1
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+162928@code.launchpad.net

Description of the change

Bug #1079700: Issues with renaming/rotating tables during the backup
              stage

The problem was in the way XtraBackup handled DDL on individual
tablespaces on the backup stage. It first created a list of tablespaces
to copy which is represented by fil_system, but when starting the actual
tablespace copy operation later, it opened tablespace files by name. If
a tablespace file could not be opened, XtraBackup assumed the tablespace
got removed after the fil_system list was created and ignored the
tablespaces. This naturally only worked for cases when the tablespace
got dropped. A renamed tablespace would be missing in the resulting
backup, and tablespace rotations resulted in a missing tablespace and a
duplicate copy of another tablespace participating in rotation.

The idea of the fix is to make sure that once a tablespace is added to
fil_system, the underlying file is copied to backup with the same name
and space ID, regardless of what operations have been performed on the
tablespace/file during the backup procedure.

The only way to achieve that is to reuse file handles created when
opening tablespaces and adding them to fil_system, i.e. never attempt to
access tablespaces by name and rely on the fact the an open file handle
will always point to the same inode, even if the file is unlink()ed or
rename()d along the way. In other words, exclude the case when we are
going to copy a tablespace, but the file does not exist already.

This requires changes to fil_load_single_table_tablespace() to not close
the file handle after adding a space/node to fil_system, but keep the
node open and assign the handle to node->handle. We could use
fil_node_open_file() for that, but that function creates another handle
and open the tablespace file by name, which would still leave some room
for a race condition during the time when fil_system is populated. This
also requires XtraBackup to close the node correctly basically to comply
with various invariants enforced by fil_validate() in debug builds. This
part is implemented in XtraBackup in xb_fil_node_close_file().

We also want to reuse file handles in fil_load_single_table_tablespace()
only at the backup stage. Historically, XtraBackup patches used
recv_recovery_on to detect whether we are currently in the 'backup' or
'recovery' mode. That doesn't always work reliably. For example, we may
initialize fil_system before we start recovery to apply an incremental
backup. So recovery is still not started, but we are not in the backup
mode either. To circumvent that, the patch introduces another global
variable srv_backup_mode which is set by XtraBackup only in
xtrabackup_backup_func(). This patch also changes remote tablespaces
support in innodb56.patch to use srv_backup_mode instead of
recv_recovery_on.

Another change necessitated by the patch is ignoring deleted tablespaces
on recovery, which has been implemented in XB patches to
recv_apply_hashed_log_recs(). After MLOG_FILE_DELETE is replayed on
recovery and the underlying file is deleted, possible updates to the
same tablespace done before deleting the tablespace are left in the redo
log. They will be ignored by the recovery code. This can never cause any
problems for server, because file creation/removal is done immediately,
so on recovery InnoDB detects missing tablespace files and does not the
corresponding log records to the hash table (see the first lines in
recv_add_to_hash_table). The situation is different with XtraBackup: the
underlying file will be present when recovery starts, but then get
deleted when MLOG_FILE_DELETE is replayed, i.e. after all log records
from the current batch have been added to the hash table. As a result,
log records corresponding to the deleted tablespace are ignore, but are
still left in the hash table, so recv_apply_hashed_log_recs() hangs
forever waiting for recv_sys->n_addrs to become zero. This was also
possible with XtraBackup before this fix, i.e. when a tablespace is
removed after it has been copied by XtraBackup. This fix just makes this
condition more likely to occur, as we always copy all tablespaces rather
than ignore those removed before the copy operation is tarted.

To fix the above case, we also check for deleted tablespaces in
recv_apply_hashed_log_recs(). Those corresponding to previously deleted
tablespaces are marked as processed and recv_sys->n_addrs is decremented
accordingly to not leave spurious unprocessed log records in the hash
table.

Finally, now that we reuse fil_system file handles again, bug #870119
needs another fix. I.e. the number of open file handles grows to the
number of tablespaces we want to copy, so we want to prevent InnoDB LRU
policies from kicking in and closing/reusing file handles. There are
multiple ways to achieve that. Patching InnoDB code to disable
fil_system LRU and file closing policies in InnoDB appeared to be too
risky. The easiest one is to set the allowed number of open InnoDB files
to some vary large value unconditionally (i.e. override
innodb_open_files with the maximum possible value, LONG_MAX). InnoDB
does not allocate any resource for each srv_max_n_open_files
increment. It's just the maximum possible LRU list length, so this
change does not incur any additional resource consumption.

This revision also extends bug722638.sh (since there's 95% overlap
between that one and the test case for this bug), and renames
bug722638.sh to ddl.sh to better reflect the contents. It also backports
record_db_state() / verify_db_state() from the 2.1 test suite, because
messing with individual table checksums and checksum_table looks rather
cumbersome with a higher number of tables in the test.

http://jenkins.percona.com/view/XtraBackup/job/percona-xtrabackup-2.1-param/299/

To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

Same comments as for the 2.0 MP.

review: Needs Information
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'patches/innodb51.patch'
2--- patches/innodb51.patch 2013-04-16 14:34:55 +0000
3+++ patches/innodb51.patch 2013-05-08 05:18:19 +0000
4@@ -474,7 +474,60 @@
5 if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
6 fprintf(stderr,
7 "InnoDB: Error: the size of single-table tablespace"
8-@@ -3425,7 +3530,7 @@
9+@@ -3414,7 +3519,51 @@
10+
11+ fil_node_create(filepath, 0, space_id, FALSE);
12+ func_exit:
13+- os_file_close(file);
14++ /* We reuse file handles on the backup stage in XtraBackup to avoid
15++ inconsistencies between the file name and the actual tablespace contents
16++ if a DDL occurs between a fil_load_single_table_tablespaces() call and
17++ the actual copy operation. */
18++ if (srv_backup_mode) {
19++
20++ fil_node_t* node;
21++ fil_space_t* space;
22++
23++ mutex_enter(&fil_system->mutex);
24++
25++ space = fil_space_get_by_id(space_id);
26++
27++ if (space) {
28++ node = UT_LIST_GET_LAST(space->chain);
29++
30++ /* The handle will be closed by xtrabackup in
31++ xtrabackup_copy_datafile(). We set node->open to TRUE to
32++ make sure no one calls fil_node_open_file()
33++ (i.e. attempts to reopen the tablespace by name) during
34++ the backup stage. */
35++
36++ node->open = TRUE;
37++ node->handle = file;
38++
39++ /* The following is copied from fil_node_open_file() to
40++ pass fil_system validity checks. We cannot use
41++ fil_node_open_file() directly, as that would re-open the
42++ file by name and create another file handle. */
43++
44++ fil_system->n_open++;
45++
46++ if (space->purpose == FIL_TABLESPACE &&
47++ space->id != 0) {
48++
49++ /* Put the node to the LRU list */
50++ UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
51++ }
52++ }
53++
54++ mutex_exit(&fil_system->mutex);
55++ } else {
56++
57++ os_file_close(file);
58++ }
59+ ut_free(buf2);
60+ mem_free(filepath);
61+ }
62+@@ -3425,7 +3574,7 @@
63 idea is to read as much good data as we can and jump over bad data.
64 @return 0 if ok, -1 if error even after the retries, 1 if at the end
65 of the directory */
66@@ -483,7 +536,7 @@
67 int
68 fil_file_readdir_next_file(
69 /*=======================*/
70-@@ -3469,7 +3574,7 @@
71+@@ -3469,7 +3618,7 @@
72 @return DB_SUCCESS or error number */
73 UNIV_INTERN
74 ulint
75@@ -492,7 +545,7 @@
76 /*===================================*/
77 {
78 int ret;
79-@@ -3525,7 +3630,9 @@
80+@@ -3525,7 +3674,9 @@
81 dbinfo.name);
82 srv_normalize_path_for_win(dbpath);
83
84@@ -503,7 +556,7 @@
85
86 if (dbdir != NULL) {
87 /* printf("Opened dir %s\n", dbinfo.name); */
88-@@ -3551,8 +3658,11 @@
89+@@ -3551,8 +3702,11 @@
90 ".ibd")) {
91 /* The name ends in .ibd; try opening
92 the file */
93@@ -516,7 +569,7 @@
94 }
95 next_file_item:
96 ret = fil_file_readdir_next_file(&err,
97-@@ -3724,15 +3834,97 @@
98+@@ -3724,15 +3878,97 @@
99 "InnoDB: in InnoDB data dictionary"
100 " has tablespace id %lu,\n"
101 "InnoDB: but tablespace with that id"
102@@ -622,7 +675,7 @@
103 } else {
104 ut_print_timestamp(stderr);
105 fputs(" InnoDB: Error: table ", stderr);
106-@@ -4121,7 +4313,7 @@
107+@@ -4121,7 +4357,7 @@
108 off the LRU list if it is in the LRU list. The caller must hold the fil_sys
109 mutex. */
110 static
111@@ -631,7 +684,7 @@
112 fil_node_prepare_for_io(
113 /*====================*/
114 fil_node_t* node, /*!< in: file node */
115-@@ -4141,10 +4333,13 @@
116+@@ -4141,10 +4377,13 @@
117 }
118
119 if (node->open == FALSE) {
120@@ -646,7 +699,7 @@
121 }
122
123 if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
124-@@ -4157,6 +4352,8 @@
125+@@ -4157,6 +4396,8 @@
126 }
127
128 node->n_pending++;
129@@ -655,7 +708,7 @@
130 }
131
132 /********************************************************************//**
133-@@ -4292,7 +4489,9 @@
134+@@ -4292,7 +4533,9 @@
135 ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
136 || !ibuf_bitmap_page(zip_size, block_offset)
137 || sync || is_log);
138@@ -666,7 +719,7 @@
139 || ibuf_page(space_id, zip_size, block_offset, NULL));
140 # endif /* UNIV_LOG_DEBUG */
141 if (sync) {
142-@@ -4341,6 +4540,16 @@
143+@@ -4341,6 +4584,16 @@
144
145 ut_ad((mode != OS_AIO_IBUF) || (space->purpose == FIL_TABLESPACE));
146
147@@ -740,7 +793,7 @@
148
149 --- a/storage/innodb_plugin/include/srv0srv.h
150 +++ b/storage/innodb_plugin/include/srv0srv.h
151-@@ -202,6 +202,10 @@
152+@@ -202,6 +202,11 @@
153 extern ulong srv_max_purge_lag;
154
155 extern ulong srv_replication_delay;
156@@ -748,6 +801,7 @@
157 +extern ibool srv_read_only;
158 +extern ibool srv_fake_write;
159 +extern ibool srv_apply_log_only;
160++extern ibool srv_backup_mode;
161 /*-------------------------------------------*/
162
163 extern ulint srv_n_rows_inserted;
164@@ -961,7 +1015,35 @@
165
166 ib_uint64_t end_lsn;
167
168-@@ -2297,7 +2306,7 @@
169+@@ -1762,6 +1771,18 @@
170+ ulint zip_size = fil_space_get_zip_size(space);
171+ ulint page_no = recv_addr->page_no;
172+
173++ /* By now we have replayed all DDL log records from the
174++ current batch. Check if the space ID is still valid in
175++ the entry being processed, and ignore it if it is not.*/
176++ if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) {
177++
178++ ut_a(recv_sys->n_addrs);
179++
180++ recv_addr->state = RECV_PROCESSED;
181++ recv_sys->n_addrs--;
182++
183++ goto next;
184++ }
185+ if (recv_addr->state == RECV_NOT_PROCESSED) {
186+ if (!has_printed) {
187+ ut_print_timestamp(stderr);
188+@@ -1795,7 +1816,7 @@
189+
190+ mutex_enter(&(recv_sys->mutex));
191+ }
192+-
193++next:
194+ recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
195+ }
196+
197+@@ -2297,7 +2318,7 @@
198 || type == MLOG_FILE_RENAME
199 || type == MLOG_FILE_DELETE) {
200 ut_a(space);
201@@ -970,7 +1052,7 @@
202 if (recv_replay_file_ops) {
203
204 /* In ibbackup --apply-log, replay an .ibd file
205-@@ -2320,7 +2329,7 @@
206+@@ -2320,7 +2341,7 @@
207 ut_error;
208 }
209 }
210@@ -979,7 +1061,7 @@
211 /* In normal mysqld crash recovery we do not try to
212 replay file operations */
213 #ifdef UNIV_LOG_LSN_DEBUG
214-@@ -2737,8 +2746,11 @@
215+@@ -2737,8 +2758,11 @@
216
217 fprintf(stderr,
218 "InnoDB: Doing recovery: scanned up to"
219@@ -993,7 +1075,7 @@
220 }
221 }
222
223-@@ -2841,7 +2845,7 @@
224+@@ -2841,7 +2865,7 @@
225 "InnoDB: Reading tablespace information"
226 " from the .ibd files...\n");
227
228@@ -1002,7 +1084,7 @@
229
230 /* If we are using the doublewrite method, we will
231 check if there are half-written pages in data files,
232-@@ -2850,12 +2862,14 @@
233+@@ -2850,12 +2874,14 @@
234
235 if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
236
237@@ -1018,7 +1100,7 @@
238 }
239 }
240
241-@@ -3005,6 +3019,7 @@
242+@@ -3005,6 +3031,7 @@
243 recv_sys->recovered_lsn = checkpoint_lsn;
244
245 srv_start_lsn = checkpoint_lsn;
246@@ -1026,7 +1108,7 @@
247 }
248
249 contiguous_lsn = ut_uint64_align_down(recv_sys->scanned_lsn,
250-@@ -3286,6 +3301,7 @@
251+@@ -3286,6 +3313,7 @@
252 that the data dictionary tables will be free of any locks.
253 The data dictionary latch should guarantee that there is at
254 most one data dictionary transaction active at a time. */
255@@ -1111,17 +1193,18 @@
256
257 --- a/storage/innodb_plugin/srv/srv0srv.c
258 +++ b/storage/innodb_plugin/srv/srv0srv.c
259-@@ -374,6 +374,9 @@
260+@@ -374,6 +374,10 @@
261
262 UNIV_INTERN ulong srv_replication_delay = 0;
263
264 +UNIV_INTERN ibool srv_read_only = FALSE;
265 +UNIV_INTERN ibool srv_fake_write = FALSE;
266 +UNIV_INTERN ibool srv_apply_log_only = FALSE;
267++UNIV_INTERN ibool srv_backup_mode = FALSE;
268 /*-------------------------------------------*/
269 UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
270 UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
271-@@ -1002,7 +1005,7 @@
272+@@ -1002,7 +1006,7 @@
273 }
274
275 /* Initialize some INFORMATION SCHEMA internal structures */
276@@ -1130,7 +1213,7 @@
277 }
278
279 /*********************************************************************//**
280-@@ -1013,6 +1016,7 @@
281+@@ -1013,6 +1017,7 @@
282 /*==========*/
283 {
284 os_fast_mutex_free(&srv_conc_mutex);
285@@ -1138,7 +1221,7 @@
286 mem_free(srv_conc_slots);
287 srv_conc_slots = NULL;
288
289-@@ -1026,6 +1030,7 @@
290+@@ -1026,6 +1031,7 @@
291 srv_mysql_table = NULL;
292
293 trx_i_s_cache_free(trx_i_s_cache);
294@@ -1410,3 +1493,14 @@
295
296 UNIV_MEM_FREE(buf, n);
297 }
298+--- a/configure.in
299++++ b/configure.in
300+@@ -22,7 +22,7 @@
301+ AM_INIT_AUTOMAKE([1.9 tar-ustar])
302+ AC_PROG_LIBTOOL
303+
304+-AM_CONFIG_HEADER([include/config.h])
305++AC_CONFIG_HEADERS([include/config.h])
306+
307+ # Request support for automake silent-rules if available.
308+ # Default to verbose output. One can use the configure-time
309
310=== modified file 'patches/innodb55.patch'
311--- patches/innodb55.patch 2013-04-16 14:34:55 +0000
312+++ patches/innodb55.patch 2013-05-08 05:18:19 +0000
313@@ -464,7 +464,60 @@
314 if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
315 fprintf(stderr,
316 "InnoDB: Error: the size of single-table tablespace"
317-@@ -3476,7 +3581,7 @@
318+@@ -3465,7 +3570,51 @@
319+
320+ fil_node_create(filepath, 0, space_id, FALSE);
321+ func_exit:
322+- os_file_close(file);
323++ /* We reuse file handles on the backup stage in XtraBackup to avoid
324++ inconsistencies between the file name and the actual tablespace contents
325++ if a DDL occurs between a fil_load_single_table_tablespaces() call and
326++ the actual copy operation. */
327++ if (srv_backup_mode) {
328++
329++ fil_node_t* node;
330++ fil_space_t* space;
331++
332++ mutex_enter(&fil_system->mutex);
333++
334++ space = fil_space_get_by_id(space_id);
335++
336++ if (space) {
337++ node = UT_LIST_GET_LAST(space->chain);
338++
339++ /* The handle will be closed by xtrabackup in
340++ xtrabackup_copy_datafile(). We set node->open to TRUE to
341++ make sure no one calls fil_node_open_file()
342++ (i.e. attempts to reopen the tablespace by name) during
343++ the backup stage. */
344++
345++ node->open = TRUE;
346++ node->handle = file;
347++
348++ /* The following is copied from fil_node_open_file() to
349++ pass fil_system validity checks. We cannot use
350++ fil_node_open_file() directly, as that would re-open the
351++ file by name and create another file handle. */
352++
353++ fil_system->n_open++;
354++
355++ if (space->purpose == FIL_TABLESPACE &&
356++ space->id != 0) {
357++
358++ /* Put the node to the LRU list */
359++ UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
360++ }
361++ }
362++
363++ mutex_exit(&fil_system->mutex);
364++ } else {
365++
366++ os_file_close(file);
367++ }
368+ ut_free(buf2);
369+ mem_free(filepath);
370+ }
371+@@ -3476,7 +3625,7 @@
372 idea is to read as much good data as we can and jump over bad data.
373 @return 0 if ok, -1 if error even after the retries, 1 if at the end
374 of the directory */
375@@ -473,7 +526,7 @@
376 int
377 fil_file_readdir_next_file(
378 /*=======================*/
379-@@ -3520,7 +3625,7 @@
380+@@ -3520,7 +3669,7 @@
381 @return DB_SUCCESS or error number */
382 UNIV_INTERN
383 ulint
384@@ -482,7 +535,7 @@
385 /*===================================*/
386 {
387 int ret;
388-@@ -3576,7 +3681,9 @@
389+@@ -3576,7 +3725,9 @@
390 dbinfo.name);
391 srv_normalize_path_for_win(dbpath);
392
393@@ -493,7 +546,7 @@
394
395 if (dbdir != NULL) {
396 /* printf("Opened dir %s\n", dbinfo.name); */
397-@@ -3602,8 +3709,11 @@
398+@@ -3602,8 +3753,11 @@
399 ".ibd")) {
400 /* The name ends in .ibd; try opening
401 the file */
402@@ -506,7 +559,7 @@
403 }
404 next_file_item:
405 ret = fil_file_readdir_next_file(&err,
406-@@ -3775,15 +3885,97 @@
407+@@ -3775,15 +3929,97 @@
408 "InnoDB: in InnoDB data dictionary"
409 " has tablespace id %lu,\n"
410 "InnoDB: but tablespace with that id"
411@@ -612,7 +665,7 @@
412 } else {
413 ut_print_timestamp(stderr);
414 fputs(" InnoDB: Error: table ", stderr);
415-@@ -4172,7 +4364,7 @@
416+@@ -4172,7 +4408,7 @@
417 off the LRU list if it is in the LRU list. The caller must hold the fil_sys
418 mutex. */
419 static
420@@ -621,7 +674,7 @@
421 fil_node_prepare_for_io(
422 /*====================*/
423 fil_node_t* node, /*!< in: file node */
424-@@ -4192,10 +4384,13 @@
425+@@ -4192,10 +4428,13 @@
426 }
427
428 if (node->open == FALSE) {
429@@ -636,7 +689,7 @@
430 }
431
432 if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
433-@@ -4208,6 +4403,8 @@
434+@@ -4208,6 +4447,8 @@
435 }
436
437 node->n_pending++;
438@@ -645,7 +698,7 @@
439 }
440
441 /********************************************************************//**
442-@@ -4390,6 +4587,16 @@
443+@@ -4390,6 +4631,16 @@
444
445 ut_ad((mode != OS_AIO_IBUF) || (space->purpose == FIL_TABLESPACE));
446
447@@ -697,7 +750,7 @@
448 Returns TRUE if a single-table tablespace does not exist in the memory cache,
449 --- a/storage/innobase/include/srv0srv.h
450 +++ b/storage/innobase/include/srv0srv.h
451-@@ -218,6 +218,10 @@
452+@@ -218,6 +218,11 @@
453 extern ulong srv_max_purge_lag;
454
455 extern ulong srv_replication_delay;
456@@ -705,6 +758,7 @@
457 +extern ibool srv_read_only;
458 +extern ibool srv_fake_write;
459 +extern ibool srv_apply_log_only;
460++extern ibool srv_backup_mode;
461 /*-------------------------------------------*/
462
463 extern ulint srv_n_rows_inserted;
464@@ -874,7 +928,35 @@
465
466 ib_uint64_t end_lsn;
467
468-@@ -2308,7 +2317,7 @@
469+@@ -1774,6 +1783,18 @@
470+ ulint zip_size = fil_space_get_zip_size(space);
471+ ulint page_no = recv_addr->page_no;
472+
473++ /* By now we have replayed all DDL log records from the
474++ current batch. Check if the space ID is still valid in
475++ the entry being processed, and ignore it if it is not.*/
476++ if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) {
477++
478++ ut_a(recv_sys->n_addrs);
479++
480++ recv_addr->state = RECV_PROCESSED;
481++ recv_sys->n_addrs--;
482++
483++ goto next;
484++ }
485+ if (recv_addr->state == RECV_NOT_PROCESSED) {
486+ if (!has_printed) {
487+ ut_print_timestamp(stderr);
488+@@ -1807,7 +1828,7 @@
489+
490+ mutex_enter(&(recv_sys->mutex));
491+ }
492+-
493++next:
494+ recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
495+ }
496+
497+@@ -2308,7 +2329,7 @@
498 || type == MLOG_FILE_RENAME
499 || type == MLOG_FILE_DELETE) {
500 ut_a(space);
501@@ -883,7 +965,7 @@
502 if (recv_replay_file_ops) {
503
504 /* In ibbackup --apply-log, replay an .ibd file
505-@@ -2331,7 +2340,7 @@
506+@@ -2331,7 +2352,7 @@
507 ut_error;
508 }
509 }
510@@ -892,7 +974,7 @@
511 /* In normal mysqld crash recovery we do not try to
512 replay file operations */
513 #ifdef UNIV_LOG_LSN_DEBUG
514-@@ -2748,8 +2757,11 @@
515+@@ -2748,8 +2769,11 @@
516
517 fprintf(stderr,
518 "InnoDB: Doing recovery: scanned up to"
519@@ -906,7 +988,7 @@
520 }
521 }
522
523-@@ -2854,7 +2858,7 @@
524+@@ -2854,7 +2878,7 @@
525 "InnoDB: Reading tablespace information"
526 " from the .ibd files...\n");
527
528@@ -915,7 +997,7 @@
529
530 /* If we are using the doublewrite method, we will
531 check if there are half-written pages in data files,
532-@@ -2863,12 +2875,14 @@
533+@@ -2863,12 +2887,14 @@
534
535 if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
536
537@@ -931,7 +1013,7 @@
538 }
539 }
540
541-@@ -3018,6 +3032,7 @@
542+@@ -3018,6 +3044,7 @@
543 recv_sys->recovered_lsn = checkpoint_lsn;
544
545 srv_start_lsn = checkpoint_lsn;
546@@ -939,7 +1021,7 @@
547 }
548
549 contiguous_lsn = ut_uint64_align_down(recv_sys->scanned_lsn,
550-@@ -3299,6 +3314,7 @@
551+@@ -3299,6 +3326,7 @@
552 that the data dictionary tables will be free of any locks.
553 The data dictionary latch should guarantee that there is at
554 most one data dictionary transaction active at a time. */
555@@ -1023,17 +1105,18 @@
556 }
557 --- a/storage/innobase/srv/srv0srv.c
558 +++ b/storage/innobase/srv/srv0srv.c
559-@@ -399,6 +399,9 @@
560+@@ -399,6 +399,10 @@
561
562 UNIV_INTERN ulong srv_replication_delay = 0;
563
564 +UNIV_INTERN ibool srv_read_only = FALSE;
565 +UNIV_INTERN ibool srv_fake_write = FALSE;
566 +UNIV_INTERN ibool srv_apply_log_only = FALSE;
567++UNIV_INTERN ibool srv_backup_mode = FALSE;
568 /*-------------------------------------------*/
569 UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
570 UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
571-@@ -1078,7 +1081,7 @@
572+@@ -1078,7 +1082,7 @@
573 }
574
575 /* Initialize some INFORMATION SCHEMA internal structures */
576@@ -1042,7 +1125,7 @@
577 }
578
579 /*********************************************************************//**
580-@@ -1089,6 +1092,7 @@
581+@@ -1089,6 +1093,7 @@
582 /*==========*/
583 {
584 os_fast_mutex_free(&srv_conc_mutex);
585@@ -1050,7 +1133,7 @@
586 mem_free(srv_conc_slots);
587 srv_conc_slots = NULL;
588
589-@@ -1102,6 +1106,7 @@
590+@@ -1102,6 +1107,7 @@
591 srv_mysql_table = NULL;
592
593 trx_i_s_cache_free(trx_i_s_cache);
594@@ -1058,7 +1141,7 @@
595 }
596
597 /*********************************************************************//**
598-@@ -1717,7 +1722,7 @@
599+@@ -1717,7 +1723,7 @@
600 }
601
602 /* Record the lock wait time for this thread */
603
604=== modified file 'patches/innodb56.patch'
605--- patches/innodb56.patch 2013-05-04 05:26:19 +0000
606+++ patches/innodb56.patch 2013-05-08 05:18:19 +0000
607@@ -375,7 +375,7 @@
608
609 + /* Ignore .isl files on XtraBackup recovery. All tablespaces must be
610 + local. */
611-+ if (!recv_recovery_on) {
612++ if (srv_backup_mode) {
613 /* Check for a link file which locates a remote tablespace. */
614 remote.success = fil_open_linked_file(
615 tablename, &remote.filepath, &remote.file);
616@@ -396,7 +396,60 @@
617 ib_logf(IB_LOG_LEVEL_ERROR,
618 "The size of single-table tablespace file %s "
619 "is only " UINT64PF ", should be at least %lu!",
620-@@ -4263,7 +4390,7 @@
621+@@ -4243,7 +4370,51 @@
622+ }
623+
624+ func_exit:
625+- os_file_close(fsp->file);
626++ /* We reuse file handles on the backup stage in XtraBackup to avoid
627++ inconsistencies between the file name and the actual tablespace contents
628++ if a DDL occurs between a fil_load_single_table_tablespaces() call and
629++ the actual copy operation. */
630++ if (srv_backup_mode) {
631++
632++ fil_node_t* node;
633++ fil_space_t* space;
634++
635++ mutex_enter(&fil_system->mutex);
636++
637++ space = fil_space_get_by_id(fsp->id);
638++
639++ if (space) {
640++ node = UT_LIST_GET_LAST(space->chain);
641++
642++ /* The handle will be closed by xtrabackup in
643++ xtrabackup_copy_datafile(). We set node->open to TRUE to
644++ make sure no one calls fil_node_open_file()
645++ (i.e. attempts to reopen the tablespace by name) during
646++ the backup stage. */
647++
648++ node->open = TRUE;
649++ node->handle = fsp->file;
650++
651++ /* The following is copied from fil_node_open_file() to
652++ pass fil_system validaty checks. We cannot use
653++ fil_node_open_file() directly, as that would re-open the
654++ file by name and create another file handle. */
655++
656++ fil_system->n_open++;
657++ fil_n_file_opened++;
658++
659++ if (fil_space_belongs_in_lru(space)) {
660++
661++ /* Put the node to the LRU list */
662++ UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
663++ }
664++ }
665++
666++ mutex_exit(&fil_system->mutex);
667++ } else {
668++
669++ os_file_close(fsp->file);
670++ }
671+
672+ #ifdef UNIV_HOTBACKUP
673+ func_exit_after_close:
674+@@ -4263,7 +4434,7 @@
675 idea is to read as much good data as we can and jump over bad data.
676 @return 0 if ok, -1 if error even after the retries, 1 if at the end
677 of the directory */
678@@ -405,7 +458,7 @@
679 int
680 fil_file_readdir_next_file(
681 /*=======================*/
682-@@ -4303,7 +4430,7 @@
683+@@ -4303,7 +4474,7 @@
684 @return DB_SUCCESS or error number */
685 UNIV_INTERN
686 dberr_t
687@@ -414,7 +467,7 @@
688 /*===================================*/
689 {
690 int ret;
691-@@ -4359,7 +4486,9 @@
692+@@ -4359,7 +4530,9 @@
693 "%s/%s", fil_path_to_mysql_datadir, dbinfo.name);
694 srv_normalize_path_for_win(dbpath);
695
696@@ -425,7 +478,7 @@
697
698 if (dbdir != NULL) {
699
700-@@ -4380,9 +4509,15 @@
701+@@ -4380,9 +4553,15 @@
702 && (0 == strcmp(fileinfo.name
703 + strlen(fileinfo.name) - 4,
704 ".ibd")
705@@ -433,7 +486,7 @@
706 + /* Ignore .isl files on XtraBackup
707 + recovery, all tablespaces must be
708 + local. */
709-+ || (!recv_recovery_on &&
710++ || (srv_backup_mode &&
711 + 0 == strcmp(fileinfo.name
712 + strlen(fileinfo.name) - 4,
713 - ".isl"))) {
714@@ -443,7 +496,7 @@
715 /* The name ends in .ibd or .isl;
716 try opening the file */
717 fil_load_single_table_tablespace(
718-@@ -4538,6 +4673,7 @@
719+@@ -4538,6 +4717,7 @@
720 {
721 fil_space_t* fnamespace;
722 fil_space_t* space;
723@@ -451,7 +504,7 @@
724
725 ut_ad(fil_system);
726
727-@@ -4615,6 +4751,10 @@
728+@@ -4615,6 +4795,10 @@
729 if (fnamespace == NULL) {
730 if (print_error_if_does_not_exist) {
731 fil_report_missing_tablespace(name, id);
732@@ -462,7 +515,7 @@
733 }
734 } else {
735 ut_print_timestamp(stderr);
736-@@ -4638,6 +4778,10 @@
737+@@ -4638,6 +4822,10 @@
738
739 mutex_exit(&fil_system->mutex);
740
741@@ -473,7 +526,7 @@
742 return(FALSE);
743 }
744
745-@@ -4728,6 +4872,7 @@
746+@@ -4728,6 +4916,7 @@
747 ulint page_size;
748 ulint pages_added;
749 ibool success;
750@@ -481,7 +534,7 @@
751
752 ut_ad(!srv_read_only_mode);
753
754-@@ -4772,13 +4917,17 @@
755+@@ -4772,13 +4961,17 @@
756 goto retry;
757 }
758
759@@ -500,7 +553,7 @@
760 start_page_no = space->size;
761 file_start_page_no = space->size - node->size;
762
763-@@ -5024,7 +5173,7 @@
764+@@ -5024,7 +5217,7 @@
765 off the LRU list if it is in the LRU list. The caller must hold the fil_sys
766 mutex. */
767 static
768@@ -509,7 +562,7 @@
769 fil_node_prepare_for_io(
770 /*====================*/
771 fil_node_t* node, /*!< in: file node */
772-@@ -5044,9 +5193,12 @@
773+@@ -5044,9 +5237,12 @@
774 }
775
776 if (node->open == FALSE) {
777@@ -523,7 +576,7 @@
778 }
779
780 if (node->n_pending == 0 && fil_space_belongs_in_lru(space)) {
781-@@ -5058,6 +5210,8 @@
782+@@ -5058,6 +5254,8 @@
783 }
784
785 node->n_pending++;
786@@ -532,7 +585,7 @@
787 }
788
789 /********************************************************************//**
790-@@ -5259,6 +5413,16 @@
791+@@ -5259,6 +5457,16 @@
792
793 ut_ad(mode != OS_AIO_IBUF || space->purpose == FIL_TABLESPACE);
794
795@@ -549,7 +602,7 @@
796 node = UT_LIST_GET_FIRST(space->chain);
797
798 for (;;) {
799-@@ -5290,7 +5454,11 @@
800+@@ -5290,7 +5498,11 @@
801 }
802
803 /* Open file if closed */
804@@ -562,7 +615,7 @@
805
806 /* Check that at least the start offset is within the bounds of a
807 single-table tablespace, including rollback tablespaces. */
808-@@ -6164,6 +6332,7 @@
809+@@ -6164,6 +6376,7 @@
810 return(err);
811 }
812
813@@ -570,7 +623,7 @@
814 /****************************************************************//**
815 Generate redo logs for swapping two .ibd files */
816 UNIV_INTERN
817-@@ -6187,4 +6356,4 @@
818+@@ -6187,4 +6400,4 @@
819 0, 0, new_name, old_name, &mtr);
820 mtr_commit(&mtr);
821 }
822@@ -713,13 +766,15 @@
823 Returns TRUE if a single-table tablespace does not exist in the memory cache,
824 --- a/storage/innobase/include/srv0srv.h
825 +++ b/storage/innobase/include/srv0srv.h
826-@@ -353,6 +353,9 @@
827+@@ -353,6 +353,11 @@
828 extern ulong srv_max_purge_lag_delay;
829
830 extern ulong srv_replication_delay;
831 +
832 +extern ibool srv_apply_log_only;
833 +
834++extern ibool srv_backup_mode;
835++
836 /*-------------------------------------------*/
837
838 extern ibool srv_print_innodb_monitor;
839@@ -814,7 +869,26 @@
840
841 lsn_t end_lsn;
842
843-@@ -2413,7 +2424,7 @@
844+@@ -1868,6 +1879,18 @@
845+ ulint zip_size = fil_space_get_zip_size(space);
846+ ulint page_no = recv_addr->page_no;
847+
848++ /* By now we have replayed all DDL log records from the
849++ current batch. Check if the space ID is still valid in
850++ the entry being processed, and ignore it if it is not.*/
851++ if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) {
852++
853++ ut_a(recv_sys->n_addrs);
854++
855++ recv_addr->state = RECV_PROCESSED;
856++ recv_sys->n_addrs--;
857++
858++ continue;
859++ }
860+ if (recv_addr->state == RECV_NOT_PROCESSED) {
861+ if (!has_printed) {
862+ ib_logf(IB_LOG_LEVEL_INFO,
863+@@ -2413,7 +2436,7 @@
864 || type == MLOG_FILE_RENAME
865 || type == MLOG_FILE_DELETE) {
866 ut_a(space);
867@@ -823,7 +897,7 @@
868 if (recv_replay_file_ops) {
869
870 /* In ibbackup --apply-log, replay an .ibd file
871-@@ -2436,7 +2447,7 @@
872+@@ -2436,7 +2459,7 @@
873 ut_error;
874 }
875 }
876@@ -832,7 +906,7 @@
877 /* In normal mysqld crash recovery we do not try to
878 replay file operations */
879 #ifdef UNIV_LOG_LSN_DEBUG
880-@@ -2863,8 +2874,14 @@
881+@@ -2863,8 +2886,14 @@
882
883 fprintf(stderr,
884 "InnoDB: Doing recovery: scanned up to"
885@@ -849,7 +923,7 @@
886 }
887 }
888
889-@@ -2964,7 +2981,7 @@
890+@@ -2964,7 +2993,7 @@
891 ib_logf(IB_LOG_LEVEL_INFO,
892 "Reading tablespace information from the .ibd files...");
893
894@@ -858,7 +932,7 @@
895
896 /* If we are using the doublewrite method, we will
897 check if there are half-written pages in data files,
898-@@ -3456,7 +3473,8 @@
899+@@ -3456,7 +3485,8 @@
900 that the data dictionary tables will be free of any locks.
901 The data dictionary latch should guarantee that there is at
902 most one data dictionary transaction active at a time. */
903@@ -895,16 +969,18 @@
904 tested with following crash point */
905 --- a/storage/innobase/srv/srv0srv.cc
906 +++ b/storage/innobase/srv/srv0srv.cc
907-@@ -349,6 +349,8 @@
908+@@ -349,6 +349,10 @@
909
910 UNIV_INTERN ulong srv_replication_delay = 0;
911
912 +UNIV_INTERN ibool srv_apply_log_only = FALSE;
913 +
914++UNIV_INTERN ibool srv_backup_mode = FALSE;
915++
916 /*-------------------------------------------*/
917 UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
918 UNIV_INTERN ulong srv_spin_wait_delay = 6;
919-@@ -1808,7 +1810,8 @@
920+@@ -1808,7 +1812,8 @@
921 if (ret == SRV_NONE
922 && srv_shutdown_state != SRV_SHUTDOWN_NONE
923 && trx_purge_state() != PURGE_STATE_DISABLED
924
925=== modified file 'patches/xtradb51.patch'
926--- patches/xtradb51.patch 2013-04-16 14:34:55 +0000
927+++ patches/xtradb51.patch 2013-05-08 05:18:19 +0000
928@@ -357,7 +357,60 @@
929 if (size < FIL_IBD_FILE_INITIAL_SIZE * (lint)UNIV_PAGE_SIZE) {
930 fprintf(stderr,
931 "InnoDB: Error: the size of single-table tablespace"
932-@@ -4247,7 +4349,7 @@
933+@@ -4236,7 +4338,51 @@
934+
935+ fil_node_create(filepath, 0, space_id, FALSE);
936+ func_exit:
937+- os_file_close(file);
938++ /* We reuse file handles on the backup stage in XtraBackup to avoid
939++ inconsistencies between the file name and the actual tablespace contents
940++ if a DDL occurs between a fil_load_single_table_tablespaces() call and
941++ the actual copy operation. */
942++ if (srv_backup_mode) {
943++
944++ fil_node_t* node;
945++ fil_space_t* space;
946++
947++ mutex_enter(&fil_system->mutex);
948++
949++ space = fil_space_get_by_id(space_id);
950++
951++ if (space) {
952++ node = UT_LIST_GET_LAST(space->chain);
953++
954++ /* The handle will be closed by xtrabackup in
955++ xtrabackup_copy_datafile(). We set node->open to TRUE to
956++ make sure no one calls fil_node_open_file()
957++ (i.e. attempts to reopen the tablespace by name) during
958++ the backup stage. */
959++
960++ node->open = TRUE;
961++ node->handle = file;
962++
963++ /* The following is copied from fil_node_open_file() to
964++ pass fil_system validity checks. We cannot use
965++ fil_node_open_file() directly, as that would re-open the
966++ file by name and create another file handle. */
967++
968++ fil_system->n_open++;
969++
970++ if (space->purpose == FIL_TABLESPACE &&
971++ space->id != 0) {
972++
973++ /* Put the node to the LRU list */
974++ UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
975++ }
976++ }
977++
978++ mutex_exit(&fil_system->mutex);
979++ } else {
980++
981++ os_file_close(file);
982++ }
983+ ut_free(buf2);
984+ mem_free(filepath);
985+ }
986+@@ -4247,7 +4393,7 @@
987 idea is to read as much good data as we can and jump over bad data.
988 @return 0 if ok, -1 if error even after the retries, 1 if at the end
989 of the directory */
990@@ -366,7 +419,7 @@
991 int
992 fil_file_readdir_next_file(
993 /*=======================*/
994-@@ -4291,7 +4393,7 @@
995+@@ -4291,7 +4437,7 @@
996 @return DB_SUCCESS or error number */
997 UNIV_INTERN
998 ulint
999@@ -375,7 +428,7 @@
1000 /*===================================*/
1001 {
1002 int ret;
1003-@@ -4347,7 +4449,9 @@
1004+@@ -4347,7 +4493,9 @@
1005 dbinfo.name);
1006 srv_normalize_path_for_win(dbpath);
1007
1008@@ -386,7 +439,7 @@
1009
1010 if (dbdir != NULL) {
1011 /* printf("Opened dir %s\n", dbinfo.name); */
1012-@@ -4373,8 +4477,11 @@
1013+@@ -4373,8 +4521,11 @@
1014 ".ibd")) {
1015 /* The name ends in .ibd; try opening
1016 the file */
1017@@ -399,7 +452,7 @@
1018 }
1019 next_file_item:
1020 ret = fil_file_readdir_next_file(&err,
1021-@@ -4546,15 +4653,97 @@
1022+@@ -4546,15 +4697,97 @@
1023 "InnoDB: in InnoDB data dictionary"
1024 " has tablespace id %lu,\n"
1025 "InnoDB: but tablespace with that id"
1026@@ -505,7 +558,7 @@
1027 } else {
1028 ut_print_timestamp(stderr);
1029 fputs(" InnoDB: Error: table ", stderr);
1030-@@ -4953,7 +5142,7 @@
1031+@@ -4953,7 +5186,7 @@
1032 off the LRU list if it is in the LRU list. The caller must hold the fil_sys
1033 mutex. */
1034 static
1035@@ -514,7 +567,7 @@
1036 fil_node_prepare_for_io(
1037 /*====================*/
1038 fil_node_t* node, /*!< in: file node */
1039-@@ -4973,10 +5162,13 @@
1040+@@ -4973,10 +5206,13 @@
1041 }
1042
1043 if (node->open == FALSE) {
1044@@ -529,7 +582,7 @@
1045 }
1046
1047 if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
1048-@@ -4989,6 +5181,8 @@
1049+@@ -4989,6 +5225,8 @@
1050 }
1051
1052 node->n_pending++;
1053@@ -538,7 +591,7 @@
1054 }
1055
1056 /********************************************************************//**
1057-@@ -5125,7 +5319,9 @@
1058+@@ -5125,7 +5363,9 @@
1059 ut_ad(recv_no_ibuf_operations || (type == OS_FILE_WRITE)
1060 || !ibuf_bitmap_page(zip_size, block_offset)
1061 || sync || is_log);
1062@@ -549,7 +602,7 @@
1063 || ibuf_page(space_id, zip_size, block_offset, NULL));
1064 # endif /* UNIV_LOG_DEBUG */
1065 if (sync) {
1066-@@ -5190,6 +5386,16 @@
1067+@@ -5190,6 +5430,16 @@
1068
1069 ut_ad((mode != OS_AIO_IBUF) || (space->purpose == FIL_TABLESPACE));
1070
1071@@ -681,13 +734,14 @@
1072 return(buf);
1073 --- a/storage/innodb_plugin/include/srv0srv.h
1074 +++ b/storage/innodb_plugin/include/srv0srv.h
1075-@@ -226,6 +226,10 @@
1076+@@ -226,6 +226,11 @@
1077
1078 extern ulong srv_replication_delay;
1079
1080 +extern ibool srv_read_only;
1081 +extern ibool srv_fake_write;
1082 +extern ibool srv_apply_log_only;
1083++extern ibool srv_backup_mode;
1084 +
1085 extern long long srv_ibuf_max_size;
1086 extern ulint srv_ibuf_active_contract;
1087@@ -876,7 +930,35 @@
1088
1089 ib_uint64_t end_lsn;
1090
1091-@@ -2369,7 +2377,7 @@
1092+@@ -1830,6 +1838,18 @@
1093+ ulint zip_size = fil_space_get_zip_size(space);
1094+ ulint page_no = recv_addr->page_no;
1095+
1096++ /* By now we have replayed all DDL log records from the
1097++ current batch. Check if the space ID is still valid in
1098++ the entry being processed, and ignore it if it is not.*/
1099++ if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) {
1100++
1101++ ut_a(recv_sys->n_addrs);
1102++
1103++ recv_addr->state = RECV_PROCESSED;
1104++ recv_sys->n_addrs--;
1105++
1106++ goto next;
1107++ }
1108+ if (recv_addr->state == RECV_NOT_PROCESSED) {
1109+ if (!has_printed) {
1110+ ut_print_timestamp(stderr);
1111+@@ -1863,7 +1883,7 @@
1112+
1113+ mutex_enter(&(recv_sys->mutex));
1114+ }
1115+-
1116++next:
1117+ recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
1118+ }
1119+
1120+@@ -2369,7 +2389,7 @@
1121 || type == MLOG_FILE_RENAME
1122 || type == MLOG_FILE_DELETE) {
1123 ut_a(space);
1124@@ -885,7 +967,7 @@
1125 if (recv_replay_file_ops) {
1126
1127 /* In ibbackup --apply-log, replay an .ibd file
1128-@@ -2392,7 +2400,7 @@
1129+@@ -2392,7 +2412,7 @@
1130 ut_error;
1131 }
1132 }
1133@@ -894,7 +976,7 @@
1134 /* In normal mysqld crash recovery we do not try to
1135 replay file operations */
1136 #ifdef UNIV_LOG_LSN_DEBUG
1137-@@ -2809,8 +2817,11 @@
1138+@@ -2809,8 +2829,11 @@
1139
1140 fprintf(stderr,
1141 "InnoDB: Doing recovery: scanned up to"
1142@@ -908,7 +990,7 @@
1143 }
1144 }
1145
1146-@@ -2913,7 +2916,7 @@
1147+@@ -2913,7 +2936,7 @@
1148 "InnoDB: Reading tablespace information"
1149 " from the .ibd files...\n");
1150
1151@@ -917,7 +999,7 @@
1152
1153 /* If we are using the doublewrite method, we will
1154 check if there are half-written pages in data files,
1155-@@ -2922,12 +2933,14 @@
1156+@@ -2922,12 +2945,14 @@
1157
1158 if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
1159
1160@@ -933,7 +1015,7 @@
1161 }
1162 }
1163
1164-@@ -3095,6 +3108,7 @@
1165+@@ -3095,6 +3120,7 @@
1166 recv_sys->recovered_lsn = checkpoint_lsn;
1167
1168 srv_start_lsn = checkpoint_lsn;
1169@@ -941,7 +1023,7 @@
1170 }
1171
1172 contiguous_lsn = ut_uint64_align_down(recv_sys->scanned_lsn,
1173-@@ -3453,6 +3467,7 @@
1174+@@ -3453,6 +3479,7 @@
1175 that the data dictionary tables will be free of any locks.
1176 The data dictionary latch should guarantee that there is at
1177 most one data dictionary transaction active at a time. */
1178@@ -1038,18 +1120,19 @@
1179 /* prototypes for new functions added to ha_innodb.cc */
1180 ibool innobase_get_slow_log();
1181
1182-@@ -415,6 +410,10 @@
1183+@@ -415,6 +410,11 @@
1184
1185 UNIV_INTERN ulong srv_replication_delay = 0;
1186
1187 +UNIV_INTERN ibool srv_read_only = FALSE;
1188 +UNIV_INTERN ibool srv_fake_write = FALSE;
1189 +UNIV_INTERN ibool srv_apply_log_only = FALSE;
1190++UNIV_INTERN ibool srv_backup_mode = FALSE;
1191 +
1192 UNIV_INTERN long long srv_ibuf_max_size = 0;
1193 UNIV_INTERN ulint srv_ibuf_active_contract = 0; /* 0:disable 1:enable */
1194 UNIV_INTERN ulint srv_ibuf_accel_rate = 100;
1195-@@ -1065,7 +1064,7 @@
1196+@@ -1065,7 +1065,7 @@
1197 }
1198
1199 /* Initialize some INFORMATION SCHEMA internal structures */
1200@@ -1058,7 +1141,7 @@
1201 }
1202
1203 /*********************************************************************//**
1204-@@ -1076,6 +1075,7 @@
1205+@@ -1076,6 +1076,7 @@
1206 /*==========*/
1207 {
1208 os_fast_mutex_free(&srv_conc_mutex);
1209@@ -1066,7 +1149,7 @@
1210 mem_free(srv_conc_slots);
1211 srv_conc_slots = NULL;
1212
1213-@@ -1089,6 +1089,7 @@
1214+@@ -1089,6 +1090,7 @@
1215 srv_mysql_table = NULL;
1216
1217 trx_i_s_cache_free(trx_i_s_cache);
1218@@ -1074,7 +1157,7 @@
1219 }
1220
1221 /*********************************************************************//**
1222-@@ -2570,36 +2571,6 @@
1223+@@ -2570,36 +2572,6 @@
1224 old_sema = sema;
1225 }
1226
1227@@ -1163,7 +1246,6 @@
1228
1229 if (srv_auto_extend_last_data_file
1230 && sum_of_data_file_sizes < tablespace_size_in_header) {
1231--
1232 + /* extend table space size aligning with header */
1233 + ulint actual_size;
1234 + fil_extend_space_to_desired_size(&actual_size, 0, tablespace_size_in_header);
1235@@ -1174,7 +1256,7 @@
1236 + (ulong) actual_size,
1237 + (ulong) tablespace_size_in_header);
1238 + }
1239-+
1240+
1241 +#ifdef UNDEFINED
1242 fprintf(stderr,
1243 "InnoDB: Error: tablespace size stored in header"
1244@@ -1497,3 +1579,14 @@
1245
1246 UNIV_MEM_FREE(buf, n);
1247 }
1248+--- a/configure.in
1249++++ b/configure.in
1250+@@ -22,7 +22,7 @@
1251+ AM_INIT_AUTOMAKE([1.9 tar-ustar])
1252+ AC_PROG_LIBTOOL
1253+
1254+-AM_CONFIG_HEADER([include/config.h])
1255++AC_CONFIG_HEADERS([include/config.h])
1256+
1257+ # Request support for automake silent-rules if available.
1258+ # Default to verbose output. One can use the configure-time
1259
1260=== modified file 'patches/xtradb55.patch'
1261--- patches/xtradb55.patch 2013-04-16 14:34:55 +0000
1262+++ patches/xtradb55.patch 2013-05-08 05:18:19 +0000
1263@@ -356,7 +356,60 @@
1264 if (size < FIL_IBD_FILE_INITIAL_SIZE * (lint)UNIV_PAGE_SIZE) {
1265 fprintf(stderr,
1266 "InnoDB: Error: the size of single-table tablespace"
1267-@@ -4299,7 +4402,7 @@
1268+@@ -4288,7 +4391,51 @@
1269+
1270+ fil_node_create(filepath, 0, space_id, FALSE);
1271+ func_exit:
1272+- os_file_close(file);
1273++ /* We reuse file handles on the backup stage in XtraBackup to avoid
1274++ inconsistencies between the file name and the actual tablespace contents
1275++ if a DDL occurs between a fil_load_single_table_tablespaces() call and
1276++ the actual copy operation. */
1277++ if (srv_backup_mode) {
1278++
1279++ fil_node_t* node;
1280++ fil_space_t* space;
1281++
1282++ mutex_enter(&fil_system->mutex);
1283++
1284++ space = fil_space_get_by_id(space_id);
1285++
1286++ if (space) {
1287++ node = UT_LIST_GET_LAST(space->chain);
1288++
1289++ /* The handle will be closed by xtrabackup in
1290++ xtrabackup_copy_datafile(). We set node->open to TRUE to
1291++ make sure no one calls fil_node_open_file()
1292++ (i.e. attempts to reopen the tablespace by name) during
1293++ the backup stage. */
1294++
1295++ node->open = TRUE;
1296++ node->handle = file;
1297++
1298++ /* The following is copied from fil_node_open_file() to
1299++ pass fil_system validity checks. We cannot use
1300++ fil_node_open_file() directly, as that would re-open the
1301++ file by name and create another file handle. */
1302++
1303++ fil_system->n_open++;
1304++
1305++ if (space->purpose == FIL_TABLESPACE &&
1306++ space->id != 0) {
1307++
1308++ /* Put the node to the LRU list */
1309++ UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
1310++ }
1311++ }
1312++
1313++ mutex_exit(&fil_system->mutex);
1314++ } else {
1315++
1316++ os_file_close(file);
1317++ }
1318+ ut_free(buf2);
1319+ mem_free(filepath);
1320+ }
1321+@@ -4299,7 +4446,7 @@
1322 idea is to read as much good data as we can and jump over bad data.
1323 @return 0 if ok, -1 if error even after the retries, 1 if at the end
1324 of the directory */
1325@@ -365,7 +418,7 @@
1326 int
1327 fil_file_readdir_next_file(
1328 /*=======================*/
1329-@@ -4343,7 +4446,7 @@
1330+@@ -4343,7 +4490,7 @@
1331 @return DB_SUCCESS or error number */
1332 UNIV_INTERN
1333 ulint
1334@@ -374,7 +427,7 @@
1335 /*===================================*/
1336 {
1337 int ret;
1338-@@ -4399,7 +4502,9 @@
1339+@@ -4399,7 +4546,9 @@
1340 dbinfo.name);
1341 srv_normalize_path_for_win(dbpath);
1342
1343@@ -385,7 +438,7 @@
1344
1345 if (dbdir != NULL) {
1346 /* printf("Opened dir %s\n", dbinfo.name); */
1347-@@ -4425,8 +4530,11 @@
1348+@@ -4425,8 +4574,11 @@
1349 ".ibd")) {
1350 /* The name ends in .ibd; try opening
1351 the file */
1352@@ -398,7 +451,7 @@
1353 }
1354 next_file_item:
1355 ret = fil_file_readdir_next_file(&err,
1356-@@ -4598,15 +4706,97 @@
1357+@@ -4598,15 +4750,97 @@
1358 "InnoDB: in InnoDB data dictionary"
1359 " has tablespace id %lu,\n"
1360 "InnoDB: but tablespace with that id"
1361@@ -504,7 +557,7 @@
1362 } else {
1363 ut_print_timestamp(stderr);
1364 fputs(" InnoDB: Error: table ", stderr);
1365-@@ -5005,7 +5195,7 @@
1366+@@ -5005,7 +5239,7 @@
1367 off the LRU list if it is in the LRU list. The caller must hold the fil_sys
1368 mutex. */
1369 static
1370@@ -513,7 +566,7 @@
1371 fil_node_prepare_for_io(
1372 /*====================*/
1373 fil_node_t* node, /*!< in: file node */
1374-@@ -5025,10 +5215,13 @@
1375+@@ -5025,10 +5259,13 @@
1376 }
1377
1378 if (node->open == FALSE) {
1379@@ -528,7 +581,7 @@
1380 }
1381
1382 if (node->n_pending == 0 && space->purpose == FIL_TABLESPACE
1383-@@ -5041,6 +5234,8 @@
1384+@@ -5041,6 +5278,8 @@
1385 }
1386
1387 node->n_pending++;
1388@@ -537,7 +590,7 @@
1389 }
1390
1391 /********************************************************************//**
1392-@@ -5240,6 +5435,16 @@
1393+@@ -5240,6 +5479,16 @@
1394
1395 ut_ad((mode != OS_AIO_IBUF) || (space->purpose == FIL_TABLESPACE));
1396
1397@@ -691,7 +744,7 @@
1398 extern char srv_adaptive_flushing;
1399
1400
1401-@@ -247,6 +246,10 @@
1402+@@ -247,6 +246,11 @@
1403 extern ulint srv_dict_size_limit;
1404
1405 extern ulint srv_lazy_drop_table;
1406@@ -699,6 +752,7 @@
1407 +extern ibool srv_read_only;
1408 +extern ibool srv_fake_write;
1409 +extern ibool srv_apply_log_only;
1410++extern ibool srv_backup_mode;
1411 /*-------------------------------------------*/
1412
1413 extern ulint srv_n_rows_inserted;
1414@@ -840,7 +894,35 @@
1415
1416 ib_uint64_t end_lsn;
1417
1418-@@ -2380,7 +2388,7 @@
1419+@@ -1842,6 +1850,18 @@
1420+ ulint zip_size = fil_space_get_zip_size(space);
1421+ ulint page_no = recv_addr->page_no;
1422+
1423++ /* By now we have replayed all DDL log records from the
1424++ current batch. Check if the space ID is still valid in
1425++ the entry being processed, and ignore it if it is not.*/
1426++ if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) {
1427++
1428++ ut_a(recv_sys->n_addrs);
1429++
1430++ recv_addr->state = RECV_PROCESSED;
1431++ recv_sys->n_addrs--;
1432++
1433++ goto next;
1434++ }
1435+ if (recv_addr->state == RECV_NOT_PROCESSED) {
1436+ if (!has_printed) {
1437+ ut_print_timestamp(stderr);
1438+@@ -1875,7 +1895,7 @@
1439+
1440+ mutex_enter(&(recv_sys->mutex));
1441+ }
1442+-
1443++next:
1444+ recv_addr = HASH_GET_NEXT(addr_hash, recv_addr);
1445+ }
1446+
1447+@@ -2380,7 +2400,7 @@
1448 || type == MLOG_FILE_RENAME
1449 || type == MLOG_FILE_DELETE) {
1450 ut_a(space);
1451@@ -849,7 +931,7 @@
1452 if (recv_replay_file_ops) {
1453
1454 /* In ibbackup --apply-log, replay an .ibd file
1455-@@ -2403,7 +2411,7 @@
1456+@@ -2403,7 +2423,7 @@
1457 ut_error;
1458 }
1459 }
1460@@ -858,7 +940,7 @@
1461 /* In normal mysqld crash recovery we do not try to
1462 replay file operations */
1463 #ifdef UNIV_LOG_LSN_DEBUG
1464-@@ -2820,8 +2828,11 @@
1465+@@ -2820,8 +2840,11 @@
1466
1467 fprintf(stderr,
1468 "InnoDB: Doing recovery: scanned up to"
1469@@ -872,7 +954,7 @@
1470 }
1471 }
1472
1473-@@ -2926,7 +2929,7 @@
1474+@@ -2926,7 +2949,7 @@
1475 "InnoDB: Reading tablespace information"
1476 " from the .ibd files...\n");
1477
1478@@ -881,7 +963,7 @@
1479
1480 /* If we are using the doublewrite method, we will
1481 check if there are half-written pages in data files,
1482-@@ -2935,12 +2946,14 @@
1483+@@ -2935,12 +2958,14 @@
1484
1485 if (srv_force_recovery < SRV_FORCE_NO_LOG_REDO) {
1486
1487@@ -897,7 +979,7 @@
1488 }
1489 }
1490
1491-@@ -3109,6 +3122,7 @@
1492+@@ -3109,6 +3134,7 @@
1493 recv_sys->recovered_lsn = checkpoint_lsn;
1494
1495 srv_start_lsn = checkpoint_lsn;
1496@@ -905,7 +987,7 @@
1497 }
1498
1499 contiguous_lsn = ut_uint64_align_down(recv_sys->scanned_lsn,
1500-@@ -3474,6 +3488,7 @@
1501+@@ -3474,6 +3500,7 @@
1502 that the data dictionary tables will be free of any locks.
1503 The data dictionary latch should guarantee that there is at
1504 most one data dictionary transaction active at a time. */
1505@@ -1029,7 +1111,7 @@
1506
1507 /* Try to flush dirty pages so as to avoid IO bursts at
1508 the checkpoints. */
1509-@@ -457,6 +451,10 @@
1510+@@ -457,6 +451,11 @@
1511 UNIV_INTERN ulint srv_dict_size_limit = 0;
1512
1513 UNIV_INTERN ulint srv_lazy_drop_table = 0;
1514@@ -1037,10 +1119,11 @@
1515 +UNIV_INTERN ibool srv_read_only = FALSE;
1516 +UNIV_INTERN ibool srv_fake_write = FALSE;
1517 +UNIV_INTERN ibool srv_apply_log_only = FALSE;
1518++UNIV_INTERN ibool srv_backup_mode = FALSE;
1519 /*-------------------------------------------*/
1520 UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
1521 UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
1522-@@ -1137,7 +1135,7 @@
1523+@@ -1137,7 +1136,7 @@
1524 }
1525
1526 /* Initialize some INFORMATION SCHEMA internal structures */
1527@@ -1049,7 +1132,7 @@
1528 }
1529
1530 /*********************************************************************//**
1531-@@ -1148,6 +1146,7 @@
1532+@@ -1148,6 +1147,7 @@
1533 /*==========*/
1534 {
1535 os_fast_mutex_free(&srv_conc_mutex);
1536@@ -1057,7 +1140,7 @@
1537 mem_free(srv_conc_slots);
1538 srv_conc_slots = NULL;
1539
1540-@@ -1161,6 +1160,7 @@
1541+@@ -1161,6 +1161,7 @@
1542 srv_mysql_table = NULL;
1543
1544 trx_i_s_cache_free(trx_i_s_cache);
1545@@ -1065,7 +1148,7 @@
1546 }
1547
1548 /*********************************************************************//**
1549-@@ -1886,7 +1886,7 @@
1550+@@ -1886,7 +1887,7 @@
1551 }
1552
1553 /* Record the lock wait time for this thread */
1554@@ -1074,7 +1157,7 @@
1555 }
1556
1557 if (trx->was_chosen_as_deadlock_victim) {
1558-@@ -2842,36 +2842,6 @@
1559+@@ -2842,36 +2843,6 @@
1560 old_sema = sema;
1561 }
1562
1563
1564=== modified file 'src/fil_cur.cc'
1565--- src/fil_cur.cc 2013-04-29 06:43:29 +0000
1566+++ src/fil_cur.cc 2013-05-08 05:18:19 +0000
1567@@ -74,6 +74,55 @@
1568
1569 }
1570
1571+/**********************************************************************//**
1572+Closes a file. */
1573+static
1574+void
1575+xb_fil_node_close_file(
1576+/*===================*/
1577+ fil_node_t* node) /*!< in: file node */
1578+{
1579+ ibool ret;
1580+
1581+ mutex_enter(&fil_system->mutex);
1582+
1583+ ut_ad(node);
1584+ ut_a(node->n_pending == 0);
1585+ ut_a(node->n_pending_flushes == 0);
1586+#if MYSQL_VERSION_ID >= 50600
1587+ ut_a(!node->being_extended);
1588+#endif
1589+
1590+ if (!node->open) {
1591+
1592+ mutex_exit(&fil_system->mutex);
1593+
1594+ return;
1595+ }
1596+
1597+ ret = os_file_close(node->handle);
1598+ ut_a(ret);
1599+
1600+ node->open = FALSE;
1601+
1602+ ut_a(fil_system->n_open > 0);
1603+ fil_system->n_open--;
1604+#if MYSQL_VERSION_ID >= 50600
1605+ fil_n_file_opened--;
1606+#endif
1607+
1608+ if (node->space->purpose == FIL_TABLESPACE &&
1609+ !trx_sys_sys_space(node->space->id)) {
1610+
1611+ ut_a(UT_LIST_GET_LEN(fil_system->LRU) > 0);
1612+
1613+ /* The node is in the LRU list, remove it */
1614+ UT_LIST_REMOVE(LRU, fil_system->LRU, node);
1615+ }
1616+
1617+ mutex_exit(&fil_system->mutex);
1618+}
1619+
1620 /************************************************************************
1621 Open a source file cursor and initialize the associated read filter.
1622
1623@@ -90,11 +139,12 @@
1624 ulint page_size;
1625 ulint page_size_shift;
1626 ulint zip_size;
1627+ ibool success;
1628
1629 /* Initialize these first so xb_fil_cur_close() handles them correctly
1630 in case of error */
1631 cursor->orig_buf = NULL;
1632- cursor->file = XB_FILE_UNDEFINED;
1633+ cursor->node = NULL;
1634
1635 cursor->space_id = node->space->id;
1636 cursor->is_system = trx_sys_sys_space(node->space->id);
1637@@ -109,31 +159,56 @@
1638 xb_get_relative_path(cursor->abs_path, cursor->is_system),
1639 sizeof(cursor->rel_path));
1640
1641- /* Open the file */
1642-
1643- if (my_stat(node->name, &cursor->statinfo, MYF(MY_WME)) == NULL) {
1644- msg("[%02u] xtrabackup: Warning: cannot stat %s\n",
1645- thread_n, node->name);
1646- return(XB_FIL_CUR_SKIP);
1647- }
1648-
1649- ibool success;
1650-
1651- cursor->file =
1652- xb_file_create_no_error_handling(node->name,
1653+ /* In the backup mode we should already have a tablespace handle created
1654+ by fil_load_single_table_tablespace() unless it is a system
1655+ tablespace. Otherwise we open the file here. */
1656+ if (cursor->is_system || !srv_backup_mode) {
1657+ node->handle =
1658+ xb_file_create_no_error_handling(node->name,
1659 OS_FILE_OPEN,
1660 OS_FILE_READ_ONLY,
1661 &success);
1662- if (!success) {
1663- /* The following call prints an error message */
1664- os_file_get_last_error(TRUE);
1665-
1666- msg("[%02u] xtrabackup: Warning: cannot open %s\n"
1667- "[%02u] xtrabackup: Warning: We assume the "
1668- "table was dropped or renamed during "
1669- "xtrabackup execution and ignore the file.\n",
1670- thread_n, node->name, thread_n);
1671- return(XB_FIL_CUR_SKIP);
1672+ if (!success) {
1673+ /* The following call prints an error message */
1674+ os_file_get_last_error(TRUE);
1675+
1676+ msg("[%02u] xtrabackup: error: cannot open "
1677+ "tablespace %s\n",
1678+ thread_n, cursor->abs_path);
1679+
1680+ return(XB_FIL_CUR_ERROR);
1681+ }
1682+ mutex_enter(&fil_system->mutex);
1683+
1684+ node->open = TRUE;
1685+
1686+ fil_system->n_open++;
1687+#if MYSQL_VERSION_ID >= 50600
1688+ fil_n_file_opened++;
1689+#endif
1690+
1691+ if (node->space->purpose == FIL_TABLESPACE &&
1692+ !trx_sys_sys_space(node->space->id)) {
1693+
1694+ /* Put the node to the LRU list */
1695+ UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
1696+ }
1697+
1698+ mutex_exit(&fil_system->mutex);
1699+ }
1700+
1701+ ut_ad(node->open);
1702+
1703+ cursor->node = node;
1704+ cursor->file = node->handle;
1705+
1706+ if (my_fstat(cursor->file, &cursor->statinfo, MYF(MY_WME))) {
1707+ msg("[%02u] xtrabackup: error: cannot stat %s\n",
1708+ thread_n, cursor->abs_path);
1709+
1710+ xb_fil_cur_close(cursor);
1711+
1712+ return(XB_FIL_CUR_ERROR);
1713 }
1714
1715 xb_file_set_nocache(cursor->file, node->name, "OPEN");
1716@@ -142,7 +217,7 @@
1717 /* Determine the page size */
1718 zip_size = xb_get_zip_size(cursor->file);
1719 if (zip_size == ULINT_UNDEFINED) {
1720- os_file_close(cursor->file);
1721+ xb_fil_cur_close(cursor);
1722 return(XB_FIL_CUR_SKIP);
1723 } else if (zip_size) {
1724 page_size = zip_size;
1725@@ -230,7 +305,8 @@
1726 cursor->buf_offset = offset;
1727 cursor->buf_page_no = (ulint) (offset >> cursor->page_size_shift);
1728
1729- success = xb_os_file_read(cursor->file, cursor->buf, offset, to_read);
1730+ success = xb_os_file_read(cursor->file, cursor->buf, offset,
1731+ to_read);
1732 if (!success) {
1733 return(XB_FIL_CUR_ERROR);
1734 }
1735@@ -294,7 +370,8 @@
1736 if (cursor->orig_buf != NULL) {
1737 ut_free(cursor->orig_buf);
1738 }
1739- if (cursor->file != XB_FILE_UNDEFINED) {
1740- os_file_close(cursor->file);
1741+ if (cursor->node != NULL) {
1742+ xb_fil_node_close_file(cursor->node);
1743+ cursor->file = XB_FILE_UNDEFINED;
1744 }
1745 }
1746
1747=== modified file 'src/fil_cur.h'
1748--- src/fil_cur.h 2013-04-23 07:44:24 +0000
1749+++ src/fil_cur.h 2013-05-08 05:18:19 +0000
1750@@ -31,6 +31,7 @@
1751
1752 struct xb_fil_cur_t {
1753 os_file_t file; /*!< source file handle */
1754+ fil_node_t* node; /*!< source tablespace node */
1755 char rel_path[FN_REFLEN];
1756 /*!< normalized file path */
1757 char abs_path[FN_REFLEN];
1758
1759=== modified file 'src/xtrabackup.cc'
1760--- src/xtrabackup.cc 2013-05-07 13:28:22 +0000
1761+++ src/xtrabackup.cc 2013-05-08 05:18:19 +0000
1762@@ -1813,6 +1813,55 @@
1763 return(zip_size);
1764 }
1765
1766+/**********************************************************************//**
1767+Closes a file. */
1768+static
1769+void
1770+xb_fil_node_close_file(
1771+/*===================*/
1772+ fil_node_t* node) /*!< in: file node */
1773+{
1774+ ibool ret;
1775+
1776+ mutex_enter(&fil_system->mutex);
1777+
1778+ ut_ad(node);
1779+ ut_a(node->n_pending == 0);
1780+ ut_a(node->n_pending_flushes == 0);
1781+#if MYSQL_VERSION_ID >= 50600
1782+ ut_a(!node->being_extended);
1783+#endif
1784+
1785+ if (!node->open) {
1786+
1787+ mutex_exit(&fil_system->mutex);
1788+
1789+ return;
1790+ }
1791+
1792+ ret = os_file_close(node->handle);
1793+ ut_a(ret);
1794+
1795+ node->open = FALSE;
1796+
1797+ ut_a(fil_system->n_open > 0);
1798+ fil_system->n_open--;
1799+#if MYSQL_VERSION_ID >= 50600
1800+ fil_n_file_opened--;
1801+#endif
1802+
1803+ if (node->space->purpose == FIL_TABLESPACE &&
1804+ !trx_sys_sys_space(node->space->id)) {
1805+
1806+ ut_a(UT_LIST_GET_LEN(fil_system->LRU) > 0);
1807+
1808+ /* The node is in the LRU list, remove it */
1809+ UT_LIST_REMOVE(LRU, fil_system->LRU, node);
1810+ }
1811+
1812+ mutex_exit(&fil_system->mutex);
1813+}
1814+
1815 /* TODO: We may tune the behavior (e.g. by fil_aio)*/
1816
1817 static
1818@@ -2497,8 +2546,7 @@
1819 srv_n_write_io_threads,
1820 SRV_MAX_N_PENDING_SYNC_IOS);
1821
1822- fil_init(srv_file_per_table ? 50000 : 5000,
1823- srv_max_n_open_files);
1824+ fil_init(srv_file_per_table ? 50000 : 5000, LONG_MAX);
1825
1826 fsp_init();
1827
1828@@ -2541,11 +2589,6 @@
1829 return(DB_ERROR);
1830 }
1831
1832- err = fil_load_single_table_tablespaces(xb_check_if_open_tablespace);
1833- if (err != DB_SUCCESS) {
1834- return(err);
1835- }
1836-
1837 #if MYSQL_VERSION_ID >= 50600
1838 /* Add separate undo tablespaces to fil_system */
1839
1840@@ -2558,6 +2601,15 @@
1841 }
1842 #endif
1843
1844+ /* It is important to call fil_load_single_table_tablespace() after
1845+ srv_undo_tablespaces_init(), because fil_is_user_tablespace_id() *
1846+ relies on srv_undo_tablespaces_open to be properly initialized */
1847+
1848+ err = fil_load_single_table_tablespaces(xb_check_if_open_tablespace);
1849+ if (err != DB_SUCCESS) {
1850+ return(err);
1851+ }
1852+
1853 return(DB_SUCCESS);
1854 }
1855
1856@@ -2851,6 +2903,8 @@
1857
1858 xb_set_innodb_read_only();
1859
1860+ srv_backup_mode = TRUE;
1861+
1862 /* initialize components */
1863 if(innodb_init_param())
1864 exit(EXIT_FAILURE);
1865
1866=== renamed file 'test/t/bug722638.sh' => 'test/t/ddl.sh'
1867--- test/t/bug722638.sh 2012-06-04 18:29:48 +0000
1868+++ test/t/ddl.sh 2013-05-08 05:18:19 +0000
1869@@ -1,7 +1,9 @@
1870-########################################################################
1871-# Bug #722638: xtrabackup: taking backup while tables are droped and
1872+############################################################################
1873+# Bug #722638: xtrabackup: taking backup while tables are droped and
1874 # created breaks backup
1875-########################################################################
1876+#
1877+# Bug #1079700: Issues with renaming/rotating tables during the backup stage
1878+############################################################################
1879
1880 . inc/common.sh
1881
1882@@ -10,7 +12,11 @@
1883 exit $SKIPPED_EXIT_CODE
1884 fi
1885
1886-start_server --innodb_file_per_table
1887+MYSQLD_EXTRA_MY_CNF_OPTS="
1888+innodb_file_per_table
1889+"
1890+
1891+start_server
1892
1893 run_cmd $MYSQL $MYSQL_ARGS test <<EOF
1894
1895@@ -26,8 +32,19 @@
1896 CREATE TABLE t4_old(a INT) ENGINE=InnoDB;
1897 INSERT INTO t4_old VALUES (1), (2), (3);
1898
1899+CREATE TABLE t5(a INT) ENGINE=InnoDB;
1900+INSERT INTO t5 VALUES (1), (2), (3);
1901+
1902+CREATE TABLE t6(c CHAR(1)) ENGINE=InnoDB;
1903+INSERT INTO t6 VALUES ('a'), ('b'), ('c');
1904+
1905 EOF
1906
1907+# Make a checkpoint so that original tablespace creation events are not in the
1908+# xtrabackup log
1909+shutdown_server
1910+start_server
1911+
1912 mkdir -p $topdir/backup
1913
1914 # Backup
1915@@ -70,13 +87,18 @@
1916 ALTER TABLE t4_old RENAME t4;
1917 INSERT INTO t4 VALUES (7), (8), (9);
1918
1919+INSERT INTO t5 VALUES (4), (5), (6);
1920+INSERT INTO t6 VALUES ('d'), ('e'), ('f');
1921+
1922+# Rotate tables t5 and t6
1923+RENAME TABLE t5 TO temp, t6 TO t5, temp TO t6;
1924+
1925+INSERT INTO t5 VALUES ('g'), ('h'), ('i');
1926+INSERT INTO t6 VALUES (7), (8), (9);
1927+
1928 EOF
1929
1930-# Calculate checksums
1931-checksum_t1=`checksum_table test t1`
1932-checksum_t2=`checksum_table test t2`
1933-checksum_t3=`checksum_table test t3`
1934-checksum_t4=`checksum_table test t4`
1935+record_db_state test
1936
1937 # Resume xtrabackup
1938 vlog "Resuming xtrabackup"
1939@@ -84,6 +106,8 @@
1940
1941 run_cmd wait $job_pid
1942
1943+# exit 1
1944+
1945 # Prepare
1946 xtrabackup --datadir=$mysql_datadir --prepare --target-dir=$topdir/backup
1947
1948@@ -94,25 +118,7 @@
1949 $mysql_datadir/test/*.ibd
1950 cp -r $topdir/backup/* $mysql_datadir
1951
1952-start_server --innodb_file_per_table
1953-
1954-# Verify checksums
1955-checksum_t1_new=`checksum_table test t1`
1956-checksum_t2_new=`checksum_table test t2`
1957-checksum_t3_new=`checksum_table test t3`
1958-checksum_t4_new=`checksum_table test t4`
1959-vlog "Checksums (old/new):"
1960-vlog "t1: $checksum_t1/$checksum_t1_new"
1961-vlog "t2: $checksum_t2/$checksum_t2_new"
1962-vlog "t3: $checksum_t3/$checksum_t3_new"
1963-vlog "t4: $checksum_t4/$checksum_t4_new"
1964-
1965-if [ "$checksum_t1" = "$checksum_t1_new" -a \
1966- "$checksum_t2" = "$checksum_t2_new" -a \
1967- "$checksum_t3" = "$checksum_t3_new" -a \
1968- "$checksum_t4" = "$checksum_t4_new" ]; then
1969- exit 0
1970-fi
1971-
1972-vlog "Checksums do not match"
1973-exit -1
1974+start_server
1975+
1976+# Verify backup
1977+verify_db_state test

Subscribers

People subscribed via source and target branches

to all changes: