Merge lp:~akopytov/percona-xtrabackup/bugs-1177206-and-1187071-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: 620
Proposed branch: lp:~akopytov/percona-xtrabackup/bugs-1177206-and-1187071-2.1
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 365 lines (+137/-44)
2 files modified
patches/innodb56.patch (+91/-22)
src/xtrabackup.cc (+46/-22)
To merge this branch: bzr merge lp:~akopytov/percona-xtrabackup/bugs-1177206-and-1187071-2.1
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+170241@code.launchpad.net

Description of the change

    Bug #1177206: InnoDB: Assertion failure in thread <nr> in file
                  log0recv.c line 1105 InnoDB: Failing assertion: !page
                  || (ibool)!!page_is_comp(page) ==
                  dict_table_is_comp(index->table)

    Bug #1187071: xb 2.1 against ps 5.6 gives Error: Tablespace is not
                  sensible during backup"

    The problems are related, so fixing in a single revision.

    The problem in bug #1187071 was a difference in behavior between InnoDB
    5.5- and 5.6 codebases in cases when a newly created tablespace has
    uninitialized first page at the time when XtraBackup opens it while
    creating a list of tablespaces to backup. 5.1/5.5 InnoDB code would just
    complain about tablespace ID being non-sensible and omit it from the
    backup. But in 5.6 it fails with an error in such a case.

    A related problem in bug #1177206 was that
    xb_data_files_init() (i.e. loading tablespaces into fil_system) was
    called before log copying was started. This could lead to a race between
    the datafiles state in the resulting backup and xtrabackup_logfile: a
    tablespace created at a sensitive time would be missing in both the
    backup itself and as the corresponding MLOG_FILE_CREATE* log record in
    xtrabackup_logfile, so it would not be created on --apply-log
    either. This problem has existed since the very first XtraBackup
    version.

    Fixed by:

    1. Ignoring tablespaces with uninitialized pages on xtrabackup startup
    for InnoDB 5.6 codebase to match the behavior of InnoDB 5.5-.
    2. Moving the call to xb_data_files_init() in xtrabackup_backup_func()
    to a later stage so that it is only called after the log copying is
    started. This involved a minor code refactoring, since
    xb_data_files_init() previously did 2 things: initializing the 'fil'
    subsystem (which is also required by the log copying code) and actually
    populating fil_system. We now have 2 separate functions:
    xb_fil_io_init() (called before log copying is started) and
    xb_load_tablespaces() (called after log copying is started).

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

To post a comment you must log in.
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/innodb56.patch'
2--- patches/innodb56.patch 2013-05-17 15:59:05 +0000
3+++ patches/innodb56.patch 2013-06-19 05:52:36 +0000
4@@ -369,7 +369,17 @@
5
6 err = DB_CORRUPTION;
7
8-@@ -4018,6 +4141,9 @@
9+@@ -3974,6 +4097,9 @@
10+ #ifdef UNIV_HOTBACKUP
11+ fil_space_t* space;
12+ #endif
13++ fsp_open_info* fsp;
14++ ulong minimum_size;
15++ ibool file_space_create_success;
16+
17+ memset(&def, 0, sizeof(def));
18+ memset(&remote, 0, sizeof(remote));
19+@@ -4018,6 +4144,9 @@
20 # endif /* !UNIV_HOTBACKUP */
21 #endif
22
23@@ -379,24 +389,76 @@
24 /* Check for a link file which locates a remote tablespace. */
25 remote.success = fil_open_linked_file(
26 tablename, &remote.filepath, &remote.file);
27-@@ -4030,6 +4156,7 @@
28+@@ -4028,8 +4157,20 @@
29+ if (!remote.success) {
30+ os_file_close(remote.file);
31 mem_free(remote.filepath);
32++
33++ if (srv_backup_mode) {
34++
35++ /* Ignore files that have uninitialized space
36++ IDs on the backup stage. This means that a
37++ tablespace has just been created and we will
38++ replay the corresponding log records on
39++ prepare. */
40++
41++ goto func_exit_after_close;
42++ }
43 }
44 }
45 + }
46
47
48 /* Try to open the tablespace in the datadir. */
49-@@ -4135,7 +4262,7 @@
50+@@ -4042,6 +4183,17 @@
51+ fil_validate_single_table_tablespace(tablename, &def);
52+ if (!def.success) {
53+ os_file_close(def.file);
54++
55++ if (srv_backup_mode) {
56++
57++ /* Ignore files that have uninitialized space
58++ IDs on the backup stage. This means that a
59++ tablespace has just been created and we will
60++ replay the corresponding log records on
61++ prepare. */
62++
63++ goto func_exit_after_close;
64++ }
65+ }
66+ }
67+
68+@@ -4114,7 +4266,7 @@
69+ /* At this point, only one tablespace is open */
70+ ut_a(def.success == !remote.success);
71+
72+- fsp_open_info* fsp = def.success ? &def : &remote;
73++ fsp = def.success ? &def : &remote;
74+
75+ /* Get and test the file size. */
76+ size = os_file_get_size(fsp->file);
77+@@ -4133,9 +4285,9 @@
78+
79+ /* Every .ibd file is created >= 4 pages in size. Smaller files
80 cannot be ok. */
81- ulong minimum_size = FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE;
82+- ulong minimum_size = FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE;
83++ minimum_size = FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE;
84 if (size < minimum_size) {
85 -#ifndef UNIV_HOTBACKUP
86 +#if 0
87 ib_logf(IB_LOG_LEVEL_ERROR,
88 "The size of single-table tablespace file %s "
89 "is only " UINT64PF ", should be at least %lu!",
90-@@ -4243,7 +4370,51 @@
91+@@ -4216,7 +4368,7 @@
92+ }
93+ mutex_exit(&fil_system->mutex);
94+ #endif /* UNIV_HOTBACKUP */
95+- ibool file_space_create_success = fil_space_create(
96++ file_space_create_success = fil_space_create(
97+ tablename, fsp->id, fsp->flags, FIL_TABLESPACE);
98+
99+ if (!file_space_create_success) {
100+@@ -4243,13 +4395,55 @@
101 }
102
103 func_exit:
104@@ -447,9 +509,16 @@
105 + os_file_close(fsp->file);
106 + }
107
108- #ifdef UNIV_HOTBACKUP
109+-#ifdef UNIV_HOTBACKUP
110 func_exit_after_close:
111-@@ -4263,7 +4434,7 @@
112+-#else
113+ ut_ad(!mutex_own(&fil_system->mutex));
114+-#endif
115++
116+ mem_free(tablename);
117+ if (remote.success) {
118+ mem_free(remote.filepath);
119+@@ -4263,7 +4457,7 @@
120 idea is to read as much good data as we can and jump over bad data.
121 @return 0 if ok, -1 if error even after the retries, 1 if at the end
122 of the directory */
123@@ -458,7 +527,7 @@
124 int
125 fil_file_readdir_next_file(
126 /*=======================*/
127-@@ -4303,7 +4474,7 @@
128+@@ -4303,7 +4497,7 @@
129 @return DB_SUCCESS or error number */
130 UNIV_INTERN
131 dberr_t
132@@ -467,7 +536,7 @@
133 /*===================================*/
134 {
135 int ret;
136-@@ -4359,7 +4530,9 @@
137+@@ -4359,7 +4553,9 @@
138 "%s/%s", fil_path_to_mysql_datadir, dbinfo.name);
139 srv_normalize_path_for_win(dbpath);
140
141@@ -478,7 +547,7 @@
142
143 if (dbdir != NULL) {
144
145-@@ -4380,9 +4553,15 @@
146+@@ -4380,9 +4576,15 @@
147 && (0 == strcmp(fileinfo.name
148 + strlen(fileinfo.name) - 4,
149 ".ibd")
150@@ -496,7 +565,7 @@
151 /* The name ends in .ibd or .isl;
152 try opening the file */
153 fil_load_single_table_tablespace(
154-@@ -4538,6 +4717,7 @@
155+@@ -4538,6 +4740,7 @@
156 {
157 fil_space_t* fnamespace;
158 fil_space_t* space;
159@@ -504,7 +573,7 @@
160
161 ut_ad(fil_system);
162
163-@@ -4615,6 +4795,10 @@
164+@@ -4615,6 +4818,10 @@
165 if (fnamespace == NULL) {
166 if (print_error_if_does_not_exist) {
167 fil_report_missing_tablespace(name, id);
168@@ -515,7 +584,7 @@
169 }
170 } else {
171 ut_print_timestamp(stderr);
172-@@ -4638,6 +4822,10 @@
173+@@ -4638,6 +4845,10 @@
174
175 mutex_exit(&fil_system->mutex);
176
177@@ -526,7 +595,7 @@
178 return(FALSE);
179 }
180
181-@@ -4728,6 +4916,7 @@
182+@@ -4728,6 +4939,7 @@
183 ulint page_size;
184 ulint pages_added;
185 ibool success;
186@@ -534,7 +603,7 @@
187
188 ut_ad(!srv_read_only_mode);
189
190-@@ -4772,13 +4961,17 @@
191+@@ -4772,13 +4984,17 @@
192 goto retry;
193 }
194
195@@ -553,7 +622,7 @@
196 start_page_no = space->size;
197 file_start_page_no = space->size - node->size;
198
199-@@ -5024,7 +5217,7 @@
200+@@ -5024,7 +5240,7 @@
201 off the LRU list if it is in the LRU list. The caller must hold the fil_sys
202 mutex. */
203 static
204@@ -562,7 +631,7 @@
205 fil_node_prepare_for_io(
206 /*====================*/
207 fil_node_t* node, /*!< in: file node */
208-@@ -5044,9 +5237,12 @@
209+@@ -5044,9 +5260,12 @@
210 }
211
212 if (node->open == FALSE) {
213@@ -576,7 +645,7 @@
214 }
215
216 if (node->n_pending == 0 && fil_space_belongs_in_lru(space)) {
217-@@ -5058,6 +5254,8 @@
218+@@ -5058,6 +5277,8 @@
219 }
220
221 node->n_pending++;
222@@ -585,7 +654,7 @@
223 }
224
225 /********************************************************************//**
226-@@ -5259,6 +5457,16 @@
227+@@ -5259,6 +5480,16 @@
228
229 ut_ad(mode != OS_AIO_IBUF || space->purpose == FIL_TABLESPACE);
230
231@@ -602,7 +671,7 @@
232 node = UT_LIST_GET_FIRST(space->chain);
233
234 for (;;) {
235-@@ -5290,7 +5498,11 @@
236+@@ -5290,7 +5521,11 @@
237 }
238
239 /* Open file if closed */
240@@ -615,7 +684,7 @@
241
242 /* Check that at least the start offset is within the bounds of a
243 single-table tablespace, including rollback tablespaces. */
244-@@ -6164,6 +6376,7 @@
245+@@ -6164,6 +6399,7 @@
246 return(err);
247 }
248
249@@ -623,7 +692,7 @@
250 /****************************************************************//**
251 Generate redo logs for swapping two .ibd files */
252 UNIV_INTERN
253-@@ -6187,4 +6400,4 @@
254+@@ -6187,4 +6423,4 @@
255 0, 0, new_name, old_name, &mtr);
256 mtr_commit(&mtr);
257 }
258
259=== modified file 'src/xtrabackup.cc'
260--- src/xtrabackup.cc 2013-05-17 15:59:05 +0000
261+++ src/xtrabackup.cc 2013-06-19 05:52:36 +0000
262@@ -2517,23 +2517,12 @@
263 }
264
265 /************************************************************************
266-Initialize the tablespace memory cache and populate it by scanning for and
267-opening data files.
268-@returns DB_SUCCESS or error code.*/
269-ulint
270-xb_data_files_init(void)
271-/*====================*/
272+Initializes the I/O and tablespace cache subsystems. */
273+static
274+void
275+xb_fil_io_init(void)
276+/*================*/
277 {
278- ulint i;
279- ibool create_new_db;
280-#ifdef XTRADB_BASED
281- ibool create_new_doublewrite_file;
282-#endif
283- ulint err;
284- lsn_t min_flushed_lsn;
285- lsn_t max_flushed_lsn;
286- ulint sum_of_new_sizes;
287-
288 #if MYSQL_VERSION_ID >= 50600
289 srv_n_file_io_threads = srv_n_read_io_threads;
290 #else
291@@ -2549,6 +2538,25 @@
292 fil_init(srv_file_per_table ? 50000 : 5000, LONG_MAX);
293
294 fsp_init();
295+}
296+
297+/****************************************************************************
298+Populates the tablespace memory cache by scanning for and opening data files.
299+@returns DB_SUCCESS or error code.*/
300+static
301+ulint
302+xb_load_tablespaces(void)
303+/*=====================*/
304+{
305+ ulint i;
306+ ibool create_new_db;
307+#ifdef XTRADB_BASED
308+ ibool create_new_doublewrite_file;
309+#endif
310+ ulint err;
311+ lsn_t min_flushed_lsn;
312+ lsn_t max_flushed_lsn;
313+ ulint sum_of_new_sizes;
314
315 for (i = 0; i < srv_n_file_io_threads; i++) {
316 thread_nr[i] = i;
317@@ -2614,6 +2622,19 @@
318 }
319
320 /************************************************************************
321+Initialize the tablespace memory cache and populate it by scanning for and
322+opening data files.
323+@returns DB_SUCCESS or error code.*/
324+ulint
325+xb_data_files_init(void)
326+/*====================*/
327+{
328+ xb_fil_io_init();
329+
330+ return(xb_load_tablespaces());
331+}
332+
333+/************************************************************************
334 Destroy the tablespace memory cache. */
335 void
336 xb_data_files_close(void)
337@@ -2989,12 +3010,7 @@
338 ulint err;
339 ulint i;
340
341- err = xb_data_files_init();
342- if (err != DB_SUCCESS) {
343- msg("xtrabackup: error: xb_data_files_init() failed with"
344- "error code %lu\n", err);
345- exit(EXIT_FAILURE);
346- }
347+ xb_fil_io_init();
348
349 log_init();
350
351@@ -3173,6 +3189,14 @@
352 log_copying_stop = xb_os_event_create(NULL);
353 os_thread_create(log_copying_thread, NULL, &log_copying_thread_id);
354
355+ /* Populate fil_system with tablespaces to copy */
356+ err = xb_load_tablespaces();
357+ if (err != DB_SUCCESS) {
358+ msg("xtrabackup: error: xb_load_tablespaces() failed with"
359+ "error code %lu\n", err);
360+ exit(EXIT_FAILURE);
361+ }
362+
363 /* Suspend at start, for the FLUSH CHANGED_PAGE_BITMAPS call */
364 if (xtrabackup_suspend_at_start) {
365 xtrabackup_suspend(XB_FN_SUSPENDED_AT_START);

Subscribers

People subscribed via source and target branches

to all changes: