Merge lp:~akopytov/percona-xtrabackup/bugs_665210_and_810269 into lp:percona-xtrabackup/1.6
- bugs_665210_and_810269
- Merge into release-1.6
Proposed by
Alexey Kopytov
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Stewart Smith | ||||||||
Approved revision: | no longer in the source branch. | ||||||||
Merged at revision: | 275 | ||||||||
Proposed branch: | lp:~akopytov/percona-xtrabackup/bugs_665210_and_810269 | ||||||||
Merge into: | lp:percona-xtrabackup/1.6 | ||||||||
Diff against target: |
649 lines (+318/-66) 2 files modified
patches/tar4ibd_libtar-1.2.11.patch (+236/-66) test/t/bug810269.sh (+82/-0) |
||||||||
To merge this branch: | bzr merge lp:~akopytov/percona-xtrabackup/bugs_665210_and_810269 | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Stewart Smith | Pending | ||
Review via email: mp+68000@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'patches/tar4ibd_libtar-1.2.11.patch' | |||
2 | --- patches/tar4ibd_libtar-1.2.11.patch 2011-05-26 03:56:57 +0000 | |||
3 | +++ patches/tar4ibd_libtar-1.2.11.patch 2011-07-18 09:36:44 +0000 | |||
4 | @@ -1,7 +1,40 @@ | |||
9 | 1 | diff -ruN a/lib/Makefile.in b/lib/Makefile.in | 1 | # (c) 2009 - 2011 Percona Inc. |
10 | 2 | --- a/lib/Makefile.in 2011-05-25 16:46:41.000000000 +0400 | 2 | # |
11 | 3 | +++ b/lib/Makefile.in 2011-05-25 16:47:54.000000000 +0400 | 3 | # This program is free software; you can redistribute it and/or modify |
12 | 4 | @@ -29,7 +29,7 @@ | 4 | # it under the terms of the GNU General Public License as published by |
13 | 5 | # the Free Software Foundation; version 2 of the License. | ||
14 | 6 | # | ||
15 | 7 | # This program is distributed in the hope that it will be useful, | ||
16 | 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | 10 | # GNU General Public License for more details. | ||
19 | 11 | # | ||
20 | 12 | # You should have received a copy of the GNU General Public License | ||
21 | 13 | # along with this program; if not, write to the Free Software | ||
22 | 14 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | 15 | # | ||
24 | 16 | # This patch incorporates code covered by the following copyright and | ||
25 | 17 | # permission notice: | ||
26 | 18 | # | ||
27 | 19 | # Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved. | ||
28 | 20 | # | ||
29 | 21 | # This program is free software; you can redistribute it and/or modify it under | ||
30 | 22 | # the terms of the GNU General Public License as published by the Free Software | ||
31 | 23 | # Foundation; version 2 of the License. | ||
32 | 24 | # | ||
33 | 25 | # This program is distributed in the hope that it will be useful, but WITHOUT | ||
34 | 26 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
35 | 27 | # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
36 | 28 | # | ||
37 | 29 | # You should have received a copy of the GNU General Public License along with | ||
38 | 30 | # this program; if not, write to the Free Software Foundation, Inc., 59 Temple | ||
39 | 31 | # Place, Suite 330, Boston, MA 02111-1307 USA | ||
40 | 32 | # | ||
41 | 33 | # | ||
42 | 34 | diff -ruN libtar-1.2.11.orig/lib/Makefile.in libtar-1.2.11/lib/Makefile.in | ||
43 | 35 | --- libtar-1.2.11.orig/lib/Makefile.in 2011-07-14 13:27:10.000000000 +0400 | ||
44 | 36 | +++ libtar-1.2.11/lib/Makefile.in 2011-07-14 13:27:37.000000000 +0400 | ||
45 | 37 | @@ -29,7 +29,7 @@ CPPFLAGS = -I. \ | ||
46 | 5 | -I${top_srcdir}/compat \ | 38 | -I${top_srcdir}/compat \ |
47 | 6 | -I../listhash \ | 39 | -I../listhash \ |
48 | 7 | @CPPFLAGS@ | 40 | @CPPFLAGS@ |
49 | @@ -10,13 +43,19 @@ | |||
50 | 10 | LDFLAGS = @LDFLAGS@ | 43 | LDFLAGS = @LDFLAGS@ |
51 | 11 | LIBS = @LIBS@ | 44 | LIBS = @LIBS@ |
52 | 12 | LIBOBJS = @LIBOBJS@ | 45 | LIBOBJS = @LIBOBJS@ |
57 | 13 | diff -ruN a/lib/append.c b/lib/append.c | 46 | diff -ruN libtar-1.2.11.orig/lib/append.c libtar-1.2.11/lib/append.c |
58 | 14 | --- a/lib/append.c 2011-05-25 16:46:41.000000000 +0400 | 47 | --- libtar-1.2.11.orig/lib/append.c 2011-07-14 13:27:10.000000000 +0400 |
59 | 15 | +++ b/lib/append.c 2011-05-25 17:42:25.000000000 +0400 | 48 | +++ libtar-1.2.11/lib/append.c 2011-07-14 18:37:57.000000000 +0400 |
60 | 16 | @@ -27,6 +27,218 @@ | 49 | @@ -27,6 +27,327 @@ |
61 | 17 | # include <unistd.h> | 50 | # include <unistd.h> |
62 | 18 | #endif | 51 | #endif |
63 | 19 | 52 | ||
64 | 53 | +#ifdef HAVE_LIBZ | ||
65 | 54 | +#include <zlib.h> | ||
66 | 55 | +#else | ||
67 | 56 | +#error "zlib not found" | ||
68 | 57 | +#endif | ||
69 | 58 | + | ||
70 | 20 | +#ifdef POSIX_FADV_NORMAL | 59 | +#ifdef POSIX_FADV_NORMAL |
71 | 21 | +#define USE_POSIX_FADVISE | 60 | +#define USE_POSIX_FADVISE |
72 | 22 | +#endif | 61 | +#endif |
73 | @@ -24,15 +63,26 @@ | |||
74 | 24 | +/* all of these ripped from InnoDB code from MySQL 4.0.22 */ | 63 | +/* all of these ripped from InnoDB code from MySQL 4.0.22 */ |
75 | 25 | +#define UT_HASH_RANDOM_MASK 1463735687 | 64 | +#define UT_HASH_RANDOM_MASK 1463735687 |
76 | 26 | +#define UT_HASH_RANDOM_MASK2 1653893711 | 65 | +#define UT_HASH_RANDOM_MASK2 1653893711 |
78 | 27 | +#define FIL_PAGE_LSN 16 | 66 | +#define FIL_PAGE_LSN 16 |
79 | 28 | +#define FIL_PAGE_FILE_FLUSH_LSN 26 | 67 | +#define FIL_PAGE_FILE_FLUSH_LSN 26 |
80 | 29 | +#define FIL_PAGE_OFFSET 4 | 68 | +#define FIL_PAGE_OFFSET 4 |
81 | 30 | +#define FIL_PAGE_DATA 38 | 69 | +#define FIL_PAGE_DATA 38 |
82 | 31 | +#define FIL_PAGE_DATA_ALIGN_32 40 | 70 | +#define FIL_PAGE_DATA_ALIGN_32 40 |
83 | 32 | +#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 | 71 | +#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 |
84 | 33 | +#define FIL_PAGE_SPACE_OR_CHKSUM 0 | 72 | +#define FIL_PAGE_SPACE_OR_CHKSUM 0 |
85 | 34 | +//#define UNIV_PAGE_SIZE (2 * 8192) | ||
86 | 35 | +#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL | 73 | +#define BUF_NO_CHECKSUM_MAGIC 0xDEADBEEFUL |
87 | 74 | +#define FSP_EXTENT_SIZE 64 | ||
88 | 75 | +#define FSP_HEADER_OFFSET FIL_PAGE_DATA | ||
89 | 76 | +#define FSP_SPACE_FLAGS 16 /* table->flags & ~DICT_TF_COMPACT */ | ||
90 | 77 | +#define DICT_TF_ZSSIZE_SHIFT 1 | ||
91 | 78 | +#define DICT_TF_ZSSIZE_MASK (15 << DICT_TF_ZSSIZE_SHIFT) | ||
92 | 79 | +#define PAGE_ZIP_MIN_SIZE_SHIFT 10 | ||
93 | 80 | +#define PAGE_ZIP_MIN_SIZE (1 << PAGE_ZIP_MIN_SIZE_SHIFT) | ||
94 | 81 | +#define UNIV_PAGE_SIZE (2 * 8192) | ||
95 | 82 | +#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /* starting from 4.1.x this | ||
96 | 83 | + contains the space id of the page */ | ||
97 | 84 | +#define FIL_PAGE_TYPE 24 /* file page type: FIL_PAGE_INDEX,..., | ||
98 | 85 | + 2 bytes. | ||
99 | 36 | + | 86 | + |
100 | 37 | +/* defined in libtar.c. if 1, O_DIRECT will be used for input files */ | 87 | +/* defined in libtar.c. if 1, O_DIRECT will be used for input files */ |
101 | 38 | +extern int use_direct; | 88 | +extern int use_direct; |
102 | @@ -136,6 +186,87 @@ | |||
103 | 136 | +} | 186 | +} |
104 | 137 | + | 187 | + |
105 | 138 | +ulint | 188 | +ulint |
106 | 189 | +fsp_header_get_flags( | ||
107 | 190 | +/*=================*/ | ||
108 | 191 | + byte* page) /*!< in: first page of a tablespace */ | ||
109 | 192 | +{ | ||
110 | 193 | + return(mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page)); | ||
111 | 194 | +} | ||
112 | 195 | + | ||
113 | 196 | +ulint | ||
114 | 197 | +dict_table_flags_to_zip_size( | ||
115 | 198 | +/*=========================*/ | ||
116 | 199 | + ulint flags) /*!< in: flags */ | ||
117 | 200 | +{ | ||
118 | 201 | + ulint zip_size = flags & DICT_TF_ZSSIZE_MASK; | ||
119 | 202 | + | ||
120 | 203 | + if (zip_size) { | ||
121 | 204 | + zip_size = ((PAGE_ZIP_MIN_SIZE >> 1) | ||
122 | 205 | + << (zip_size >> DICT_TF_ZSSIZE_SHIFT)); | ||
123 | 206 | + } | ||
124 | 207 | + | ||
125 | 208 | + return(zip_size); | ||
126 | 209 | +} | ||
127 | 210 | + | ||
128 | 211 | +int | ||
129 | 212 | +fil_fd_get_zip_size( | ||
130 | 213 | +/*===================*/ | ||
131 | 214 | + int fd) | ||
132 | 215 | +{ | ||
133 | 216 | + ulint flags; | ||
134 | 217 | + byte buf[UNIV_PAGE_SIZE * 2]; | ||
135 | 218 | + byte *page = (byte *) (((unsigned long) buf + UNIV_PAGE_SIZE - 1) & | ||
136 | 219 | + ~(UNIV_PAGE_SIZE - 1)); | ||
137 | 220 | + | ||
138 | 221 | + if(pread(fd, page, UNIV_PAGE_SIZE, 0) != UNIV_PAGE_SIZE) | ||
139 | 222 | + return -1; | ||
140 | 223 | + | ||
141 | 224 | + flags = fsp_header_get_flags(page); | ||
142 | 225 | + | ||
143 | 226 | + if (flags && flags != (ulint)-1) { | ||
144 | 227 | + return(dict_table_flags_to_zip_size(flags)); | ||
145 | 228 | + } | ||
146 | 229 | + | ||
147 | 230 | + return(flags); | ||
148 | 231 | +} | ||
149 | 232 | + | ||
150 | 233 | +ulint | ||
151 | 234 | +fil_fd_get_space_id( | ||
152 | 235 | +/*===================*/ | ||
153 | 236 | + int fd) | ||
154 | 237 | +{ | ||
155 | 238 | + byte buf[UNIV_PAGE_SIZE * 2]; | ||
156 | 239 | + byte *page = (byte *) (((unsigned long) buf + UNIV_PAGE_SIZE - 1) & | ||
157 | 240 | + ~(UNIV_PAGE_SIZE - 1)); | ||
158 | 241 | + | ||
159 | 242 | + if(pread(fd, page, UNIV_PAGE_SIZE, 0) != UNIV_PAGE_SIZE) | ||
160 | 243 | + return -1; | ||
161 | 244 | + | ||
162 | 245 | + return(mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID)); | ||
163 | 246 | +} | ||
164 | 247 | + | ||
165 | 248 | +ulint | ||
166 | 249 | +page_zip_calc_checksum( | ||
167 | 250 | +/*===================*/ | ||
168 | 251 | + const void* data, /*!< in: compressed page */ | ||
169 | 252 | + ulint size) /*!< in: size of compressed page */ | ||
170 | 253 | +{ | ||
171 | 254 | + /* Exclude FIL_PAGE_SPACE_OR_CHKSUM, FIL_PAGE_LSN, | ||
172 | 255 | + and FIL_PAGE_FILE_FLUSH_LSN from the checksum. */ | ||
173 | 256 | + | ||
174 | 257 | + const Bytef* s = data; | ||
175 | 258 | + uLong adler; | ||
176 | 259 | + | ||
177 | 260 | + adler = adler32(0L, s + FIL_PAGE_OFFSET, | ||
178 | 261 | + FIL_PAGE_LSN - FIL_PAGE_OFFSET); | ||
179 | 262 | + adler = adler32(adler, s + FIL_PAGE_TYPE, 2); | ||
180 | 263 | + adler = adler32(adler, s + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, | ||
181 | 264 | + size - FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); | ||
182 | 265 | + | ||
183 | 266 | + return((ulint) adler); | ||
184 | 267 | +} | ||
185 | 268 | + | ||
186 | 269 | +ulint | ||
187 | 139 | +buf_calc_page_new_checksum_32( | 270 | +buf_calc_page_new_checksum_32( |
188 | 140 | +/*==========================*/ | 271 | +/*==========================*/ |
189 | 141 | + byte* page, | 272 | + byte* page, |
190 | @@ -175,15 +306,17 @@ | |||
191 | 175 | +/*==================*/ | 306 | +/*==================*/ |
192 | 176 | + /* out: TRUE if corrupted */ | 307 | + /* out: TRUE if corrupted */ |
193 | 177 | + byte* read_buf, /* in: a database page */ | 308 | + byte* read_buf, /* in: a database page */ |
195 | 178 | + ulint page_size) | 309 | + ulint page_size, |
196 | 310 | + ulint zip_size) | ||
197 | 179 | +{ | 311 | +{ |
198 | 180 | + ulint checksum; | 312 | + ulint checksum; |
199 | 181 | + ulint old_checksum; | 313 | + ulint old_checksum; |
200 | 182 | + ulint checksum_field; | 314 | + ulint checksum_field; |
201 | 183 | + ulint old_checksum_field; | 315 | + ulint old_checksum_field; |
202 | 184 | + | 316 | + |
205 | 185 | + if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4) | 317 | + if (!zip_size && |
206 | 186 | + != mach_read_from_4(read_buf + page_size | 318 | + mach_read_from_4(read_buf + FIL_PAGE_LSN + 4) |
207 | 319 | + != mach_read_from_4(read_buf + page_size | ||
208 | 187 | + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { | 320 | + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { |
209 | 188 | + | 321 | + |
210 | 189 | + /* Stored log sequence numbers at the start and the end | 322 | + /* Stored log sequence numbers at the start and the end |
211 | @@ -195,18 +328,27 @@ | |||
212 | 195 | + /* If we use checksums validation, make additional check before returning | 328 | + /* If we use checksums validation, make additional check before returning |
213 | 196 | + TRUE to ensure that the checksum is not equal to BUF_NO_CHECKSUM_MAGIC which | 329 | + TRUE to ensure that the checksum is not equal to BUF_NO_CHECKSUM_MAGIC which |
214 | 197 | + might be stored by InnoDB with checksums disabled. | 330 | + might be stored by InnoDB with checksums disabled. |
221 | 198 | + Otherwise, skip checksum calculation and return FALSE */ | 331 | + Otherwise, skip checksum calculation and return FALSE */ |
222 | 199 | + | 332 | + |
223 | 200 | + old_checksum = buf_calc_page_old_checksum(read_buf); | 333 | + checksum_field = mach_read_from_4(read_buf + |
224 | 201 | + | 334 | + FIL_PAGE_SPACE_OR_CHKSUM); |
225 | 202 | + old_checksum_field = mach_read_from_4(read_buf + page_size | 335 | + |
226 | 203 | + - FIL_PAGE_END_LSN_OLD_CHKSUM); | 336 | + if (zip_size) { |
227 | 337 | + return(checksum_field != BUF_NO_CHECKSUM_MAGIC | ||
228 | 338 | + && checksum_field | ||
229 | 339 | + != page_zip_calc_checksum(read_buf, zip_size)); | ||
230 | 340 | + } | ||
231 | 341 | + | ||
232 | 342 | + old_checksum = buf_calc_page_old_checksum(read_buf); | ||
233 | 343 | + | ||
234 | 344 | + old_checksum_field = mach_read_from_4(read_buf + page_size | ||
235 | 345 | + - FIL_PAGE_END_LSN_OLD_CHKSUM); | ||
236 | 204 | + | 346 | + |
237 | 205 | + /* There are 2 valid formulas for old_checksum_field: | 347 | + /* There are 2 valid formulas for old_checksum_field: |
238 | 206 | + 1. Very old versions of InnoDB only stored 8 byte lsn to the start | 348 | + 1. Very old versions of InnoDB only stored 8 byte lsn to the start |
239 | 207 | + and the end of the page. | 349 | + and the end of the page. |
240 | 208 | + 2. Newer InnoDB versions store the old formula checksum there. */ | 350 | + 2. Newer InnoDB versions store the old formula checksum there. */ |
242 | 209 | + | 351 | + |
243 | 210 | + if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN) | 352 | + if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN) |
244 | 211 | + && old_checksum_field != old_checksum | 353 | + && old_checksum_field != old_checksum |
245 | 212 | + && old_checksum_field != BUF_NO_CHECKSUM_MAGIC) { | 354 | + && old_checksum_field != BUF_NO_CHECKSUM_MAGIC) { |
246 | @@ -226,13 +368,13 @@ | |||
247 | 226 | + | 368 | + |
248 | 227 | + return(1); | 369 | + return(1); |
249 | 228 | + } | 370 | + } |
251 | 229 | + | 371 | + |
252 | 230 | + return(0); | 372 | + return(0); |
253 | 231 | +} | 373 | +} |
254 | 232 | 374 | ||
255 | 233 | struct tar_dev | 375 | struct tar_dev |
256 | 234 | { | 376 | { |
258 | 235 | @@ -69,7 +281,7 @@ | 377 | @@ -69,7 +390,7 @@ tar_append_file(TAR *t, char *realname, |
259 | 236 | (savename ? savename : "[NULL]")); | 378 | (savename ? savename : "[NULL]")); |
260 | 237 | #endif | 379 | #endif |
261 | 238 | 380 | ||
262 | @@ -241,7 +383,7 @@ | |||
263 | 241 | { | 383 | { |
264 | 242 | #ifdef DEBUG | 384 | #ifdef DEBUG |
265 | 243 | perror("lstat()"); | 385 | perror("lstat()"); |
267 | 244 | @@ -210,11 +422,14 @@ | 386 | @@ -210,11 +531,17 @@ tar_append_eof(TAR *t) |
268 | 245 | int | 387 | int |
269 | 246 | tar_append_regfile(TAR *t, char *realname) | 388 | tar_append_regfile(TAR *t, char *realname) |
270 | 247 | { | 389 | { |
271 | @@ -252,14 +394,17 @@ | |||
272 | 252 | - int i, j; | 394 | - int i, j; |
273 | 253 | - size_t size; | 395 | - size_t size; |
274 | 254 | + int j, k, n_retry; | 396 | + int j, k, n_retry; |
277 | 255 | + size_t i, size; | 397 | + long long i, size, offset; |
278 | 256 | + int page_size = 4 * 1024; /* check 4K, 8K and 16K */ | 398 | + int page_size = 1 * 1024; /* check 1K, 2K, 4K, 8K and 16K */ |
279 | 399 | + int page_size_shift = 10; | ||
280 | 400 | + int zip_size; | ||
281 | 401 | + int is_sys_space; | ||
282 | 257 | 402 | ||
283 | 258 | + block = (unsigned char *)(((unsigned long) buf + 16384 - 1) & ~(16384 - 1)); | 403 | + block = (unsigned char *)(((unsigned long) buf + 16384 - 1) & ~(16384 - 1)); |
284 | 259 | filefd = open(realname, O_RDONLY); | 404 | filefd = open(realname, O_RDONLY); |
285 | 260 | if (filefd == -1) | 405 | if (filefd == -1) |
286 | 261 | { | 406 | { |
288 | 262 | @@ -224,28 +439,66 @@ | 407 | @@ -224,27 +551,93 @@ tar_append_regfile(TAR *t, char *realnam |
289 | 263 | return -1; | 408 | return -1; |
290 | 264 | } | 409 | } |
291 | 265 | 410 | ||
292 | @@ -273,10 +418,23 @@ | |||
293 | 273 | + fcntl(filefd, F_SETFL, O_DIRECT); | 418 | + fcntl(filefd, F_SETFL, O_DIRECT); |
294 | 274 | +#endif | 419 | +#endif |
295 | 275 | + | 420 | + |
296 | 421 | + zip_size = fil_fd_get_zip_size(filefd); | ||
297 | 422 | + if (zip_size == -1) { | ||
298 | 423 | + fprintf(stderr, | ||
299 | 424 | + "tar4ibd: file '%s' has invalid zip_size value.\n", | ||
300 | 425 | + realname); | ||
301 | 426 | + return(-1); | ||
302 | 427 | + } else if (zip_size != 0) { | ||
303 | 428 | + page_size = zip_size; | ||
304 | 429 | + } | ||
305 | 430 | + | ||
306 | 431 | + is_sys_space = (fil_fd_get_space_id(filefd) == 0); | ||
307 | 432 | + | ||
308 | 276 | + n_retry = 0; | 433 | + n_retry = 0; |
309 | 277 | size = th_get_size(t); | 434 | size = th_get_size(t); |
310 | 278 | - for (i = size; i > T_BLOCKSIZE; i -= T_BLOCKSIZE) | 435 | - for (i = size; i > T_BLOCKSIZE; i -= T_BLOCKSIZE) |
312 | 279 | + for (i = size; i >= page_size; i -= page_size) | 436 | + for (i = size, offset = 0; i >= page_size; |
313 | 437 | + i -= page_size, offset += page_size) | ||
314 | 280 | { | 438 | { |
315 | 281 | - j = read(filefd, &block, T_BLOCKSIZE); | 439 | - j = read(filefd, &block, T_BLOCKSIZE); |
316 | 282 | - if (j != T_BLOCKSIZE) | 440 | - if (j != T_BLOCKSIZE) |
317 | @@ -288,8 +446,19 @@ | |||
318 | 288 | return -1; | 446 | return -1; |
319 | 289 | } | 447 | } |
320 | 290 | - if (tar_block_write(t, &block) == -1) | 448 | - if (tar_block_write(t, &block) == -1) |
323 | 291 | - return -1; | 449 | + if (buf_page_is_corrupted(block, (ulint)page_size, |
324 | 292 | + if (buf_page_is_corrupted(block, (ulint)page_size)) { | 450 | + (ulint)zip_size)) { |
325 | 451 | + ulint page_no = (unsigned long) | ||
326 | 452 | + (offset >> page_size_shift); | ||
327 | 453 | + if (is_sys_space && | ||
328 | 454 | + page_no >= FSP_EXTENT_SIZE && | ||
329 | 455 | + page_no < FSP_EXTENT_SIZE * 3) { | ||
330 | 456 | + fprintf(stderr, "tar4ibd: page %lu seems to " | ||
331 | 457 | + "be from the doublewrite buffer. " | ||
332 | 458 | + "skipping checksum validation.\n", | ||
333 | 459 | + page_no); | ||
334 | 460 | + goto write_page; | ||
335 | 461 | + } | ||
336 | 293 | + if (n_retry > 9) { | 462 | + if (n_retry > 9) { |
337 | 294 | + fprintf(stderr, | 463 | + fprintf(stderr, |
338 | 295 | +"The file '%s' may not be InnoDB datafile or may be corrupted.\n", | 464 | +"The file '%s' may not be InnoDB datafile or may be corrupted.\n", |
339 | @@ -302,20 +471,23 @@ | |||
340 | 302 | + if (lseek(filefd, - page_size, SEEK_CUR) == -1) | 471 | + if (lseek(filefd, - page_size, SEEK_CUR) == -1) |
341 | 303 | + return -1; | 472 | + return -1; |
342 | 304 | + | 473 | + |
344 | 305 | + if (i == size | 474 | + if (i == size && !zip_size |
345 | 306 | + && page_size < 16 * 1024) { | 475 | + && page_size < 16 * 1024) { |
346 | 307 | + page_size *= 2; | 476 | + page_size *= 2; |
347 | 477 | + page_size_shift++; | ||
348 | 308 | + } else { | 478 | + } else { |
349 | 309 | + n_retry++; | 479 | + n_retry++; |
350 | 310 | + } | 480 | + } |
351 | 311 | + | 481 | + |
352 | 312 | + i += page_size; | 482 | + i += page_size; |
353 | 483 | + offset -= page_size; | ||
354 | 313 | + | 484 | + |
355 | 314 | + continue; | 485 | + continue; |
356 | 315 | + } | 486 | + } |
357 | 487 | +write_page: | ||
358 | 316 | + for (k = 0; k < page_size / T_BLOCKSIZE; k++) | 488 | + for (k = 0; k < page_size / T_BLOCKSIZE; k++) |
359 | 317 | + if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1) | 489 | + if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1) |
361 | 318 | + return -1; | 490 | return -1; |
362 | 319 | + n_retry = 0; | 491 | + n_retry = 0; |
363 | 320 | } | 492 | } |
364 | 321 | 493 | ||
365 | @@ -327,18 +499,16 @@ | |||
366 | 327 | return -1; | 499 | return -1; |
367 | 328 | - memset(&(block[i]), 0, T_BLOCKSIZE - i); | 500 | - memset(&(block[i]), 0, T_BLOCKSIZE - i); |
368 | 329 | - if (tar_block_write(t, &block) == -1) | 501 | - if (tar_block_write(t, &block) == -1) |
369 | 330 | - return -1; | ||
370 | 331 | + memset(&(block[i]), 0, T_BLOCKSIZE * 32 - i); | 502 | + memset(&(block[i]), 0, T_BLOCKSIZE * 32 - i); |
371 | 332 | + for (k = 0; k < ((j - 1) / T_BLOCKSIZE + 1); k++) | 503 | + for (k = 0; k < ((j - 1) / T_BLOCKSIZE + 1); k++) |
372 | 333 | + if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1) | 504 | + if (tar_block_write(t, &block[T_BLOCKSIZE * k]) == -1) |
374 | 334 | + return -1; | 505 | return -1; |
375 | 335 | } | 506 | } |
376 | 336 | 507 | ||
382 | 337 | close(filefd); | 508 | diff -ruN libtar-1.2.11.orig/lib/extract.c libtar-1.2.11/lib/extract.c |
383 | 338 | diff -ruN a/lib/extract.c b/lib/extract.c | 509 | --- libtar-1.2.11.orig/lib/extract.c 2011-07-14 13:27:10.000000000 +0400 |
384 | 339 | --- a/lib/extract.c 2011-05-25 16:46:41.000000000 +0400 | 510 | +++ libtar-1.2.11/lib/extract.c 2011-07-14 13:27:37.000000000 +0400 |
385 | 340 | +++ b/lib/extract.c 2011-05-25 16:47:54.000000000 +0400 | 511 | @@ -158,11 +158,11 @@ int |
381 | 341 | @@ -158,11 +158,11 @@ | ||
386 | 342 | tar_extract_regfile(TAR *t, char *realname) | 512 | tar_extract_regfile(TAR *t, char *realname) |
387 | 343 | { | 513 | { |
388 | 344 | mode_t mode; | 514 | mode_t mode; |
389 | @@ -352,10 +522,10 @@ | |||
390 | 352 | char buf[T_BLOCKSIZE]; | 522 | char buf[T_BLOCKSIZE]; |
391 | 353 | char *filename; | 523 | char *filename; |
392 | 354 | 524 | ||
397 | 355 | diff -ruN a/lib/libtar.h b/lib/libtar.h | 525 | diff -ruN libtar-1.2.11.orig/lib/libtar.h libtar-1.2.11/lib/libtar.h |
398 | 356 | --- a/lib/libtar.h 2011-05-25 16:46:41.000000000 +0400 | 526 | --- libtar-1.2.11.orig/lib/libtar.h 2011-07-14 13:27:10.000000000 +0400 |
399 | 357 | +++ b/lib/libtar.h 2011-05-25 16:47:54.000000000 +0400 | 527 | +++ libtar-1.2.11/lib/libtar.h 2011-07-14 13:27:37.000000000 +0400 |
400 | 358 | @@ -180,7 +180,7 @@ | 528 | @@ -180,7 +180,7 @@ int th_write(TAR *t); |
401 | 359 | 529 | ||
402 | 360 | /* decode tar header info */ | 530 | /* decode tar header info */ |
403 | 361 | #define th_get_crc(t) oct_to_int((t)->th_buf.chksum) | 531 | #define th_get_crc(t) oct_to_int((t)->th_buf.chksum) |
404 | @@ -364,7 +534,7 @@ | |||
405 | 364 | #define th_get_mtime(t) oct_to_int((t)->th_buf.mtime) | 534 | #define th_get_mtime(t) oct_to_int((t)->th_buf.mtime) |
406 | 365 | #define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor) | 535 | #define th_get_devmajor(t) oct_to_int((t)->th_buf.devmajor) |
407 | 366 | #define th_get_devminor(t) oct_to_int((t)->th_buf.devminor) | 536 | #define th_get_devminor(t) oct_to_int((t)->th_buf.devminor) |
409 | 367 | @@ -204,9 +204,9 @@ | 537 | @@ -204,9 +204,9 @@ void th_set_user(TAR *t, uid_t uid); |
410 | 368 | void th_set_group(TAR *t, gid_t gid); | 538 | void th_set_group(TAR *t, gid_t gid); |
411 | 369 | void th_set_mode(TAR *t, mode_t fmode); | 539 | void th_set_mode(TAR *t, mode_t fmode); |
412 | 370 | #define th_set_mtime(t, fmtime) \ | 540 | #define th_set_mtime(t, fmtime) \ |
413 | @@ -376,7 +546,7 @@ | |||
414 | 376 | 546 | ||
415 | 377 | /* encode everything at once (except the pathname and linkname) */ | 547 | /* encode everything at once (except the pathname and linkname) */ |
416 | 378 | void th_set_from_stat(TAR *t, struct stat *s); | 548 | void th_set_from_stat(TAR *t, struct stat *s); |
418 | 379 | @@ -268,13 +268,16 @@ | 549 | @@ -268,13 +268,16 @@ int th_crc_calc(TAR *t); |
419 | 380 | 550 | ||
420 | 381 | /* string-octal to integer conversion */ | 551 | /* string-octal to integer conversion */ |
421 | 382 | int oct_to_int(char *oct); | 552 | int oct_to_int(char *oct); |
422 | @@ -394,10 +564,10 @@ | |||
423 | 394 | 564 | ||
424 | 395 | 565 | ||
425 | 396 | /***** wrapper.c **********************************************************/ | 566 | /***** wrapper.c **********************************************************/ |
430 | 397 | diff -ruN a/lib/util.c b/lib/util.c | 567 | diff -ruN libtar-1.2.11.orig/lib/util.c libtar-1.2.11/lib/util.c |
431 | 398 | --- a/lib/util.c 2011-05-25 16:46:41.000000000 +0400 | 568 | --- libtar-1.2.11.orig/lib/util.c 2011-07-14 13:27:10.000000000 +0400 |
432 | 399 | +++ b/lib/util.c 2011-05-25 16:47:54.000000000 +0400 | 569 | +++ libtar-1.2.11/lib/util.c 2011-07-14 13:27:37.000000000 +0400 |
433 | 400 | @@ -138,6 +138,14 @@ | 570 | @@ -138,6 +138,14 @@ oct_to_int(char *oct) |
434 | 401 | return i; | 571 | return i; |
435 | 402 | } | 572 | } |
436 | 403 | 573 | ||
437 | @@ -412,7 +582,7 @@ | |||
438 | 412 | 582 | ||
439 | 413 | /* integer to string-octal conversion, no NULL */ | 583 | /* integer to string-octal conversion, no NULL */ |
440 | 414 | void | 584 | void |
442 | 415 | @@ -147,4 +155,46 @@ | 585 | @@ -147,4 +155,46 @@ int_to_oct_nonull(int num, char *oct, si |
443 | 416 | oct[octlen - 1] = ' '; | 586 | oct[octlen - 1] = ' '; |
444 | 417 | } | 587 | } |
445 | 418 | 588 | ||
446 | @@ -459,10 +629,10 @@ | |||
447 | 459 | + } | 629 | + } |
448 | 460 | + return i; | 630 | + return i; |
449 | 461 | +} | 631 | +} |
454 | 462 | diff -ruN a/libtar/Makefile.in b/libtar/Makefile.in | 632 | diff -ruN libtar-1.2.11.orig/libtar/Makefile.in libtar-1.2.11/libtar/Makefile.in |
455 | 463 | --- a/libtar/Makefile.in 2011-05-25 16:46:41.000000000 +0400 | 633 | --- libtar-1.2.11.orig/libtar/Makefile.in 2011-07-14 13:27:10.000000000 +0400 |
456 | 464 | +++ b/libtar/Makefile.in 2011-05-25 16:47:54.000000000 +0400 | 634 | +++ libtar-1.2.11/libtar/Makefile.in 2011-07-14 13:27:37.000000000 +0400 |
457 | 465 | @@ -29,7 +29,7 @@ | 635 | @@ -29,7 +29,7 @@ CPPFLAGS = -I.. \ |
458 | 466 | -I${top_srcdir}/lib \ | 636 | -I${top_srcdir}/lib \ |
459 | 467 | -I${top_srcdir}/compat \ | 637 | -I${top_srcdir}/compat \ |
460 | 468 | @CPPFLAGS@ | 638 | @CPPFLAGS@ |
461 | @@ -471,7 +641,7 @@ | |||
462 | 471 | LDFLAGS = @LDFLAGS@ | 641 | LDFLAGS = @LDFLAGS@ |
463 | 472 | LIBS = @LIBS@ | 642 | LIBS = @LIBS@ |
464 | 473 | LIBOBJS = @LIBOBJS@ | 643 | LIBOBJS = @LIBOBJS@ |
466 | 474 | @@ -46,15 +46,15 @@ | 644 | @@ -46,15 +46,15 @@ LIBTAR_HDRS = ../config.h \ |
467 | 475 | ${top_srcdir}/lib/libtar.h \ | 645 | ${top_srcdir}/lib/libtar.h \ |
468 | 476 | ../listhash/libtar_listhash.h | 646 | ../listhash/libtar_listhash.h |
469 | 477 | LIBTAR_LIBS = ../lib/libtar.a | 647 | LIBTAR_LIBS = ../lib/libtar.a |
470 | @@ -490,16 +660,16 @@ | |||
471 | 490 | 660 | ||
472 | 491 | ${LIBTAR_OBJS}: ${LIBTAR_HDRS} | 661 | ${LIBTAR_OBJS}: ${LIBTAR_HDRS} |
473 | 492 | 662 | ||
475 | 493 | @@ -69,5 +69,5 @@ | 663 | @@ -69,5 +69,5 @@ distclean: clean |
476 | 494 | 664 | ||
477 | 495 | install: ${ALL} | 665 | install: ${ALL} |
478 | 496 | ${MKDIR} ${DESTDIR}${bindir} | 666 | ${MKDIR} ${DESTDIR}${bindir} |
479 | 497 | - ${INSTALL_PROGRAM} libtar ${DESTDIR}${bindir} | 667 | - ${INSTALL_PROGRAM} libtar ${DESTDIR}${bindir} |
480 | 498 | + ${INSTALL_PROGRAM} tar4ibd ${DESTDIR}${bindir} | 668 | + ${INSTALL_PROGRAM} tar4ibd ${DESTDIR}${bindir} |
481 | 499 | 669 | ||
485 | 500 | diff -ruN a/libtar/libtar.c b/libtar/libtar.c | 670 | diff -ruN libtar-1.2.11.orig/libtar/libtar.c libtar-1.2.11/libtar/libtar.c |
486 | 501 | --- a/libtar/libtar.c 2011-05-25 16:46:41.000000000 +0400 | 671 | --- libtar-1.2.11.orig/libtar/libtar.c 2011-07-14 13:27:10.000000000 +0400 |
487 | 502 | +++ b/libtar/libtar.c 2011-05-25 16:47:54.000000000 +0400 | 672 | +++ libtar-1.2.11/libtar/libtar.c 2011-07-14 17:22:13.000000000 +0400 |
488 | 503 | @@ -14,6 +14,7 @@ | 673 | @@ -14,6 +14,7 @@ |
489 | 504 | #include <libtar.h> | 674 | #include <libtar.h> |
490 | 505 | 675 | ||
491 | @@ -516,7 +686,7 @@ | |||
492 | 516 | 686 | ||
493 | 517 | #ifdef DEBUG | 687 | #ifdef DEBUG |
494 | 518 | void | 688 | void |
496 | 519 | @@ -109,7 +111,7 @@ | 689 | @@ -109,7 +111,7 @@ create(char *tarfile, char *rootdir, lib |
497 | 520 | char buf[MAXPATHLEN]; | 690 | char buf[MAXPATHLEN]; |
498 | 521 | libtar_listptr_t lp; | 691 | libtar_listptr_t lp; |
499 | 522 | 692 | ||
500 | @@ -525,7 +695,7 @@ | |||
501 | 525 | #ifdef HAVE_LIBZ | 695 | #ifdef HAVE_LIBZ |
502 | 526 | (use_zlib ? &gztype : NULL), | 696 | (use_zlib ? &gztype : NULL), |
503 | 527 | #else | 697 | #else |
505 | 528 | @@ -164,7 +166,7 @@ | 698 | @@ -164,7 +166,7 @@ list(char *tarfile) |
506 | 529 | TAR *t; | 699 | TAR *t; |
507 | 530 | int i; | 700 | int i; |
508 | 531 | 701 | ||
509 | @@ -534,7 +704,7 @@ | |||
510 | 534 | #ifdef HAVE_LIBZ | 704 | #ifdef HAVE_LIBZ |
511 | 535 | (use_zlib ? &gztype : NULL), | 705 | (use_zlib ? &gztype : NULL), |
512 | 536 | #else | 706 | #else |
514 | 537 | @@ -225,7 +227,7 @@ | 707 | @@ -225,7 +227,7 @@ extract(char *tarfile, char *rootdir) |
515 | 538 | #ifdef DEBUG | 708 | #ifdef DEBUG |
516 | 539 | puts("opening tarfile..."); | 709 | puts("opening tarfile..."); |
517 | 540 | #endif | 710 | #endif |
518 | @@ -543,7 +713,7 @@ | |||
519 | 543 | #ifdef HAVE_LIBZ | 713 | #ifdef HAVE_LIBZ |
520 | 544 | (use_zlib ? &gztype : NULL), | 714 | (use_zlib ? &gztype : NULL), |
521 | 545 | #else | 715 | #else |
523 | 546 | @@ -264,9 +266,9 @@ | 716 | @@ -264,9 +266,9 @@ extract(char *tarfile, char *rootdir) |
524 | 547 | void | 717 | void |
525 | 548 | usage() | 718 | usage() |
526 | 549 | { | 719 | { |
527 | @@ -555,7 +725,7 @@ | |||
528 | 555 | progname); | 725 | progname); |
529 | 556 | exit(-1); | 726 | exit(-1); |
530 | 557 | } | 727 | } |
532 | 558 | @@ -287,7 +289,7 @@ | 728 | @@ -287,7 +289,7 @@ main(int argc, char *argv[]) |
533 | 559 | 729 | ||
534 | 560 | progname = basename(argv[0]); | 730 | progname = basename(argv[0]); |
535 | 561 | 731 | ||
536 | @@ -564,7 +734,7 @@ | |||
537 | 564 | switch (c) | 734 | switch (c) |
538 | 565 | { | 735 | { |
539 | 566 | case 'V': | 736 | case 'V': |
541 | 567 | @@ -323,11 +325,21 @@ | 737 | @@ -323,11 +325,21 @@ main(int argc, char *argv[]) |
542 | 568 | use_zlib = 1; | 738 | use_zlib = 1; |
543 | 569 | break; | 739 | break; |
544 | 570 | #endif /* HAVE_LIBZ */ | 740 | #endif /* HAVE_LIBZ */ |
545 | @@ -577,7 +747,7 @@ | |||
546 | 577 | + use_direct = 1; | 747 | + use_direct = 1; |
547 | 578 | + break; | 748 | + break; |
548 | 579 | +#endif | 749 | +#endif |
550 | 580 | + | 750 | + |
551 | 581 | default: | 751 | default: |
552 | 582 | usage(); | 752 | usage(); |
553 | 583 | } | 753 | } |
554 | @@ -587,7 +757,7 @@ | |||
555 | 587 | { | 757 | { |
556 | 588 | #ifdef DEBUG | 758 | #ifdef DEBUG |
557 | 589 | printf("argc - optind == %d\tmode == %d\n", argc - optind, | 759 | printf("argc - optind == %d\tmode == %d\n", argc - optind, |
559 | 590 | @@ -343,15 +355,14 @@ | 760 | @@ -343,15 +355,14 @@ main(int argc, char *argv[]) |
560 | 591 | switch (mode) | 761 | switch (mode) |
561 | 592 | { | 762 | { |
562 | 593 | case MODE_EXTRACT: | 763 | case MODE_EXTRACT: |
563 | 594 | 764 | ||
564 | === added file 'test/t/bug810269.sh' | |||
565 | --- test/t/bug810269.sh 1970-01-01 00:00:00 +0000 | |||
566 | +++ test/t/bug810269.sh 2011-07-18 09:36:44 +0000 | |||
567 | @@ -0,0 +1,82 @@ | |||
568 | 1 | ######################################################################## | ||
569 | 2 | # Bug #665210: tar4ibd does not support innodb row_format=compressed | ||
570 | 3 | # Bug #810269: tar4ibd does not check for doublewrite buffer pages | ||
571 | 4 | ######################################################################## | ||
572 | 5 | |||
573 | 6 | . inc/common.sh | ||
574 | 7 | |||
575 | 8 | init | ||
576 | 9 | |||
577 | 10 | if [ -z "$INNODB_VERSION" ]; then | ||
578 | 11 | echo "Requires InnoDB plugin or XtraDB" >$SKIPPED_REASON | ||
579 | 12 | exit $SKIPPED_EXIT_CODE | ||
580 | 13 | fi | ||
581 | 14 | |||
582 | 15 | run_mysqld "--innodb_strict_mode --innodb_file_per_table \ | ||
583 | 16 | --innodb_file_format=Barracuda" | ||
584 | 17 | |||
585 | 18 | load_dbase_schema incremental_sample | ||
586 | 19 | |||
587 | 20 | vlog "Compressing the table" | ||
588 | 21 | |||
589 | 22 | run_cmd $MYSQL $MYSQL_ARGS -e \ | ||
590 | 23 | "ALTER TABLE test ENGINE=InnoDB ROW_FORMAT=compressed \ | ||
591 | 24 | KEY_BLOCK_SIZE=4" incremental_sample | ||
592 | 25 | |||
593 | 26 | vlog "Adding initial rows to table" | ||
594 | 27 | |||
595 | 28 | numrow=10000 | ||
596 | 29 | count=0 | ||
597 | 30 | while [ "$numrow" -gt "$count" ]; do | ||
598 | 31 | sql="INSERT INTO test VALUES ($count, $numrow)" | ||
599 | 32 | let "count=count+1" | ||
600 | 33 | for ((i=0; $i<99; i++)); do | ||
601 | 34 | sql="$sql,($count, $numrow)" | ||
602 | 35 | let "count=count+1" | ||
603 | 36 | done | ||
604 | 37 | ${MYSQL} ${MYSQL_ARGS} -e "$sql" incremental_sample | ||
605 | 38 | done | ||
606 | 39 | |||
607 | 40 | rows=`${MYSQL} ${MYSQL_ARGS} -Ns -e "SELECT COUNT(*) FROM test" \ | ||
608 | 41 | incremental_sample` | ||
609 | 42 | if [ "$rows" != "10000" ]; then | ||
610 | 43 | vlog "Failed to add initial rows" | ||
611 | 44 | exit -1 | ||
612 | 45 | fi | ||
613 | 46 | |||
614 | 47 | vlog "Initial rows added" | ||
615 | 48 | |||
616 | 49 | checksum_a=`${MYSQL} ${MYSQL_ARGS} -Ns -e "checksum table test;" \ | ||
617 | 50 | incremental_sample | awk '{print $2}'` | ||
618 | 51 | |||
619 | 52 | vlog "Starting streaming backup" | ||
620 | 53 | |||
621 | 54 | mkdir -p $topdir/backup | ||
622 | 55 | |||
623 | 56 | innobackupex --stream=tar $topdir/backup > $topdir/backup/out.tar | ||
624 | 57 | |||
625 | 58 | stop_mysqld | ||
626 | 59 | rm -rf $mysql_datadir | ||
627 | 60 | |||
628 | 61 | vlog "Applying log" | ||
629 | 62 | |||
630 | 63 | cd $topdir/backup | ||
631 | 64 | $TAR -ixvf out.tar | ||
632 | 65 | cd - | ||
633 | 66 | innobackupex --apply-log $topdir/backup | ||
634 | 67 | |||
635 | 68 | vlog "Restoring MySQL datadir" | ||
636 | 69 | mkdir -p $mysql_datadir | ||
637 | 70 | innobackupex --copy-back $topdir/backup | ||
638 | 71 | |||
639 | 72 | run_mysqld | ||
640 | 73 | |||
641 | 74 | checksum_b=`${MYSQL} ${MYSQL_ARGS} -Ns -e "checksum table test;" \ | ||
642 | 75 | incremental_sample | awk '{print $2}'` | ||
643 | 76 | |||
644 | 77 | if [ "$checksum_a" != "$checksum_b" ]; then | ||
645 | 78 | vlog "Checksums do not match" | ||
646 | 79 | exit -1 | ||
647 | 80 | fi | ||
648 | 81 | |||
649 | 82 | vlog "Checksums are OK" |
Added copyright notice to tar4ibd_ libtar- 1.2.11. patch.