1 | /* Copyright (C) 2006-2008 MySQL AB |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ |
15 | |
16 | #include "../maria_def.h" |
17 | #include <stdio.h> |
18 | #include <errno.h> |
19 | #include <tap.h> |
20 | #include "../trnman.h" |
21 | #include "sequence_storage.h" |
22 | #include <my_getopt.h> |
23 | |
24 | extern my_bool maria_log_remove(const char *testdir); |
25 | extern char *create_tmpdir(const char *progname); |
26 | extern void translog_example_table_init(); |
27 | |
28 | #ifndef DBUG_OFF |
29 | static const char *default_dbug_option; |
30 | #endif |
31 | static TRN *trn= &dummy_transaction_object; |
32 | |
33 | |
34 | #ifndef READONLY_TEST |
35 | |
36 | #define PCACHE_SIZE (1024*1024*10) |
37 | #define LONG_BUFFER_SIZE ((1024L*1024L*1024L) + (1024L*1024L*512)) |
38 | #define MIN_REC_LENGTH (1024L*1024L + 1024L*512L + 1) |
39 | #define LOG_FILE_SIZE (1024L*1024L*1024L + 1024L*1024L*512) |
40 | #define ITERATIONS 2 |
41 | #define READONLY 0 |
42 | #define BIG 1 |
43 | |
44 | #else |
45 | |
46 | #define PCACHE_SIZE (1024*1024*10) |
47 | #define LONG_BUFFER_SIZE (1024L*1024L) |
48 | #define MIN_REC_LENGTH (1024L) |
49 | #define LOG_FILE_SIZE (1024L*1024L*1024L + 1024L*1024L*512) |
50 | #define ITERATIONS 2 |
51 | #define READONLY 1 |
52 | #undef BIG |
53 | |
54 | #endif /*READONLY_TEST*/ |
55 | |
56 | |
57 | /* |
58 | #define LOG_FILE_SIZE 1024L*1024L*3L |
59 | #define ITERATIONS 1600 |
60 | */ |
61 | /* |
62 | #define LOG_FILE_SIZE 1024L*1024L*100L |
63 | #define ITERATIONS 65000 |
64 | */ |
65 | |
66 | |
67 | /* |
68 | Check that the buffer filled correctly |
69 | |
70 | SYNOPSIS |
71 | check_content() |
72 | ptr Pointer to the buffer |
73 | length length of the buffer |
74 | |
75 | RETURN |
76 | 0 - OK |
77 | 1 - Error |
78 | */ |
79 | |
80 | static my_bool check_content(uchar *ptr, ulong length) |
81 | { |
82 | ulong i; |
83 | uchar buff[4]; |
84 | DBUG_ENTER("check_content" ); |
85 | for (i= 0; i < length; i++) |
86 | { |
87 | if (i % 4 == 0) |
88 | int4store(buff, (i >> 2)); |
89 | if (ptr[i] != buff[i % 4]) |
90 | { |
91 | fprintf(stderr, "Byte # %lu is %x instead of %x" , |
92 | i, (uint) ptr[i], (uint) buff[i % 4]); |
93 | DBUG_DUMP("mem" , ptr +(ulong) (i > 16 ? i - 16 : 0), |
94 | (i > 16 ? 16 : i) + (i + 16 < length ? 16 : length - i)); |
95 | DBUG_RETURN(1); |
96 | } |
97 | } |
98 | DBUG_RETURN(0); |
99 | } |
100 | |
101 | |
102 | /* |
103 | Read whole record content, and check content (put with offset) |
104 | |
105 | SYNOPSIS |
106 | read_and_check_content() |
107 | rec The record header buffer |
108 | buffer The buffer to read the record in |
109 | skip Skip this number of bytes ot the record content |
110 | |
111 | RETURN |
112 | 0 - OK |
113 | 1 - Error |
114 | */ |
115 | |
116 | static my_bool read_and_check_content(TRANSLOG_HEADER_BUFFER *rec, |
117 | uchar *buffer, uint skip) |
118 | { |
119 | int res= 0; |
120 | translog_size_t len; |
121 | DBUG_ENTER("read_and_check_content" ); |
122 | DBUG_ASSERT(rec->record_length < LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); |
123 | if ((len= translog_read_record(rec->lsn, 0, rec->record_length, |
124 | buffer, NULL)) != rec->record_length) |
125 | { |
126 | fprintf(stderr, "Requested %lu byte, read %lu\n" , |
127 | (ulong) rec->record_length, (ulong) len); |
128 | res= 1; |
129 | } |
130 | res|= check_content(buffer + skip, rec->record_length - skip); |
131 | DBUG_RETURN(res); |
132 | } |
133 | |
134 | static const char *load_default_groups[]= {"ma_unit_loghandler" , 0}; |
135 | #ifndef DBUG_OFF |
136 | static const char *default_dbug_option= |
137 | IF_WIN("d:t:i:O,\\ma_test_loghandler.trace" , |
138 | "d:t:i:o,/tmp/ma_test_loghandler.trace" ); |
139 | #endif |
140 | static const char *opt_wfile= NULL; |
141 | static const char *opt_rfile= NULL; |
142 | static struct my_option my_long_options[] = |
143 | { |
144 | #ifndef DBUG_OFF |
145 | {"debug" , '#', "Output debug log. Often the argument is 'd:t:o,filename'." , |
146 | 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, |
147 | #endif |
148 | {"write-seq" , 'w', "Path to file in which \"random\" sequence used in the test will be written" , |
149 | (uchar**) &opt_wfile, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
150 | {"read-seq" , 'r', "Path to file from which \"random\" sequence used in the test will be read" , |
151 | (uchar**) &opt_rfile, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, |
152 | {"help" , '?', "Display this help and exit." , |
153 | 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, |
154 | { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} |
155 | }; |
156 | static SEQ_STORAGE seq; |
157 | |
158 | static uint32 get_len() |
159 | { |
160 | uint32 res; |
161 | DBUG_ENTER("get_len" ); |
162 | if (opt_rfile) |
163 | res= seq_storage_next(&seq); |
164 | else |
165 | { |
166 | res= (uint32) |
167 | ((ulonglong) rand() * |
168 | (LONG_BUFFER_SIZE - MIN_REC_LENGTH - 1) / RAND_MAX) + MIN_REC_LENGTH; |
169 | if (opt_wfile && |
170 | seq_storage_write(opt_wfile, res)) |
171 | exit(1); |
172 | } |
173 | DBUG_PRINT("info" , ("length value : %lu" , (ulong) res)); |
174 | DBUG_RETURN(res); |
175 | } |
176 | |
177 | static void usage(void) |
178 | { |
179 | puts("Copyright (C) 2008 MySQL AB" ); |
180 | puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software," ); |
181 | puts("and you are welcome to modify and redistribute it under the GPL license\n" ); |
182 | |
183 | puts("Unit test of maria engine" ); |
184 | printf("\nUsage: %s [OPTIONS]\n" , my_progname_short); |
185 | my_print_help(my_long_options); |
186 | print_defaults("my" , load_default_groups); |
187 | my_print_variables(my_long_options); |
188 | } |
189 | |
190 | |
191 | static my_bool |
192 | get_one_option(int optid __attribute__((unused)), |
193 | const struct my_option *opt __attribute__((unused)), |
194 | char *argument __attribute__((unused))) |
195 | { |
196 | switch (optid) { |
197 | case '?': |
198 | usage(); |
199 | exit(0); |
200 | #ifndef DBUG_OFF |
201 | case '#': |
202 | DBUG_SET_INITIAL(argument ? argument : default_dbug_option); |
203 | break; |
204 | #endif |
205 | } |
206 | return 0; |
207 | } |
208 | |
209 | |
210 | static void get_options(int *argc,char ***argv) |
211 | { |
212 | int ho_error; |
213 | |
214 | if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option))) |
215 | exit(ho_error); |
216 | |
217 | if (opt_rfile && opt_wfile) |
218 | { |
219 | usage(); |
220 | exit(1); |
221 | } |
222 | } |
223 | |
224 | |
225 | int main(int argc __attribute__((unused)), char *argv[]) |
226 | { |
227 | uint32 i; |
228 | uint32 rec_len; |
229 | uchar long_tr_id[6]; |
230 | uchar lsn_buff[23]= |
231 | { |
232 | 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, |
233 | 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, |
234 | 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 |
235 | }; |
236 | uchar *long_buffer; |
237 | char **default_argv; |
238 | PAGECACHE pagecache; |
239 | LSN lsn, lsn_base, first_lsn; |
240 | TRANSLOG_HEADER_BUFFER rec; |
241 | LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 2]; |
242 | struct st_translog_scanner_data scanner; |
243 | const char *progname=argv[0]; |
244 | int rc; |
245 | MY_INIT(argv[0]); |
246 | |
247 | plan(0); // read configuration (MYTAP_CONFIG) |
248 | #ifdef BIG |
249 | if (skip_big_tests) |
250 | { |
251 | plan(1); |
252 | ok(1, "skipped as big test" ); |
253 | my_end(0); |
254 | return 0; |
255 | } |
256 | #endif |
257 | |
258 | long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); |
259 | load_defaults_or_exit("my" , load_default_groups, &argc, &argv); |
260 | default_argv= argv; |
261 | get_options(&argc, &argv); |
262 | |
263 | bzero(&pagecache, sizeof(pagecache)); |
264 | maria_data_root= create_tmpdir(progname); |
265 | if (maria_log_remove(0)) |
266 | exit(1); |
267 | |
268 | /* We don't need to do physical syncs in this test */ |
269 | my_disable_sync= 1; |
270 | |
271 | { |
272 | uchar buff[4]; |
273 | for (i= 0; i < (LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2); i++) |
274 | { |
275 | if (i % 4 == 0) |
276 | int4store(buff, (i >> 2)); |
277 | long_buffer[i]= buff[i % 4]; |
278 | } |
279 | } |
280 | |
281 | bzero(long_tr_id, 6); |
282 | |
283 | if (ma_control_file_open(TRUE, TRUE)) |
284 | { |
285 | fprintf(stderr, "Can't init control file (%d)\n" , errno); |
286 | exit(1); |
287 | } |
288 | if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, |
289 | TRANSLOG_PAGE_SIZE, 0, 0) == 0) |
290 | { |
291 | fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n" , errno); |
292 | exit(1); |
293 | } |
294 | if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, |
295 | 0, 0, &translog_example_table_init, 0)) |
296 | { |
297 | fprintf(stderr, "Can't init loghandler (%d)\n" , errno); |
298 | exit(1); |
299 | } |
300 | /* Suppressing of automatic record writing */ |
301 | trn->first_undo_lsn|= TRANSACTION_LOGGED_LONG_ID; |
302 | |
303 | plan(((ITERATIONS - 1) * 4 + 1) * 2); |
304 | |
305 | if (opt_rfile && |
306 | seq_storage_reader_init(&seq, opt_rfile)) |
307 | exit(1); |
308 | srand(122334817L); |
309 | |
310 | long_tr_id[5]= 0xff; |
311 | |
312 | int4store(long_tr_id, 0); |
313 | parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id; |
314 | parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6; |
315 | trn->short_id= 0; |
316 | trn->first_undo_lsn= TRANSACTION_LOGGED_LONG_ID; |
317 | if (translog_write_record(&lsn, LOGREC_FIXED_RECORD_0LSN_EXAMPLE, |
318 | trn, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1, parts, |
319 | NULL, NULL)) |
320 | { |
321 | fprintf(stderr, "Can't write record #%u\n" , 0); |
322 | translog_destroy(); |
323 | ok(0, "write LOGREC_FIXED_RECORD_0LSN_EXAMPLE" ); |
324 | exit(1); |
325 | } |
326 | ok(1, "write LOGREC_FIXED_RECORD_0LSN_EXAMPLE" ); |
327 | lsn_base= first_lsn= lsn; |
328 | |
329 | for (i= 1; i < ITERATIONS; i++) |
330 | { |
331 | if (i % 2) |
332 | { |
333 | lsn_store(lsn_buff, lsn_base); |
334 | parts[TRANSLOG_INTERNAL_PARTS + 0].str= lsn_buff; |
335 | parts[TRANSLOG_INTERNAL_PARTS + 0].length= LSN_STORE_SIZE; |
336 | trn->short_id= i % 0xFFFF; |
337 | if (translog_write_record(&lsn, |
338 | LOGREC_FIXED_RECORD_1LSN_EXAMPLE, trn, NULL, |
339 | LSN_STORE_SIZE, TRANSLOG_INTERNAL_PARTS + 1, |
340 | parts, NULL, NULL)) |
341 | { |
342 | fprintf(stderr, "1 Can't write reference before record #%u\n" , i); |
343 | translog_destroy(); |
344 | ok(0, "write LOGREC_FIXED_RECORD_1LSN_EXAMPLE" ); |
345 | exit(1); |
346 | } |
347 | ok(1, "write LOGREC_FIXED_RECORD_1LSN_EXAMPLE" ); |
348 | lsn_store(lsn_buff, lsn_base); |
349 | rec_len= get_len(); |
350 | parts[TRANSLOG_INTERNAL_PARTS + 0].str= lsn_buff; |
351 | parts[TRANSLOG_INTERNAL_PARTS + 0].length= LSN_STORE_SIZE; |
352 | parts[TRANSLOG_INTERNAL_PARTS + 1].str= long_buffer; |
353 | parts[TRANSLOG_INTERNAL_PARTS + 1].length= rec_len; |
354 | trn->short_id= i % 0xFFFF; |
355 | if (translog_write_record(&lsn, |
356 | LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE, |
357 | trn, NULL, LSN_STORE_SIZE + rec_len, |
358 | TRANSLOG_INTERNAL_PARTS + 2, |
359 | parts, NULL, NULL)) |
360 | { |
361 | fprintf(stderr, "1 Can't write var reference before record #%u\n" , i); |
362 | translog_destroy(); |
363 | ok(0, "write LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE" ); |
364 | exit(1); |
365 | } |
366 | ok(1, "write LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE" ); |
367 | } |
368 | else |
369 | { |
370 | lsn_store(lsn_buff, lsn_base); |
371 | lsn_store(lsn_buff + LSN_STORE_SIZE, first_lsn); |
372 | parts[TRANSLOG_INTERNAL_PARTS + 1].str= lsn_buff; |
373 | parts[TRANSLOG_INTERNAL_PARTS + 1].length= 23; |
374 | trn->short_id= i % 0xFFFF; |
375 | if (translog_write_record(&lsn, |
376 | LOGREC_FIXED_RECORD_2LSN_EXAMPLE, |
377 | trn, NULL, 23, TRANSLOG_INTERNAL_PARTS + 1, |
378 | parts, NULL, NULL)) |
379 | { |
380 | fprintf(stderr, "0 Can't write reference before record #%u\n" , i); |
381 | translog_destroy(); |
382 | ok(0, "write LOGREC_FIXED_RECORD_2LSN_EXAMPLE" ); |
383 | exit(1); |
384 | } |
385 | ok(1, "write LOGREC_FIXED_RECORD_2LSN_EXAMPLE" ); |
386 | lsn_store(lsn_buff, lsn_base); |
387 | lsn_store(lsn_buff + LSN_STORE_SIZE, first_lsn); |
388 | rec_len= get_len(); |
389 | parts[TRANSLOG_INTERNAL_PARTS + 0].str= lsn_buff; |
390 | parts[TRANSLOG_INTERNAL_PARTS + 0].length= LSN_STORE_SIZE * 2; |
391 | parts[TRANSLOG_INTERNAL_PARTS + 1].str= long_buffer; |
392 | parts[TRANSLOG_INTERNAL_PARTS + 1].length= rec_len; |
393 | trn->short_id= i % 0xFFFF; |
394 | if (translog_write_record(&lsn, |
395 | LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE, |
396 | trn, NULL, LSN_STORE_SIZE * 2 + rec_len, |
397 | TRANSLOG_INTERNAL_PARTS + 2, |
398 | parts, NULL, NULL)) |
399 | { |
400 | fprintf(stderr, "0 Can't write var reference before record #%u\n" , i); |
401 | translog_destroy(); |
402 | ok(0, "write LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE" ); |
403 | exit(1); |
404 | } |
405 | ok(1, "write LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE" ); |
406 | } |
407 | int4store(long_tr_id, i); |
408 | parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id; |
409 | parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6; |
410 | trn->short_id= i % 0xFFFF; |
411 | if (translog_write_record(&lsn, |
412 | LOGREC_FIXED_RECORD_0LSN_EXAMPLE, |
413 | trn, NULL, 6, |
414 | TRANSLOG_INTERNAL_PARTS + 1, parts, NULL, NULL)) |
415 | { |
416 | fprintf(stderr, "Can't write record #%u\n" , i); |
417 | translog_destroy(); |
418 | ok(0, "write LOGREC_FIXED_RECORD_0LSN_EXAMPLE" ); |
419 | exit(1); |
420 | } |
421 | ok(1, "write LOGREC_FIXED_RECORD_0LSN_EXAMPLE" ); |
422 | |
423 | lsn_base= lsn; |
424 | |
425 | rec_len= get_len(); |
426 | parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_buffer; |
427 | parts[TRANSLOG_INTERNAL_PARTS + 0].length= rec_len; |
428 | trn->short_id= i % 0xFFFF; |
429 | if (translog_write_record(&lsn, |
430 | LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE, |
431 | trn, NULL, rec_len, |
432 | TRANSLOG_INTERNAL_PARTS + 1, parts, NULL, NULL)) |
433 | { |
434 | fprintf(stderr, "Can't write variable record #%u\n" , i); |
435 | translog_destroy(); |
436 | ok(0, "write LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE" ); |
437 | exit(1); |
438 | } |
439 | ok(1, "write LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE" ); |
440 | } |
441 | |
442 | translog_destroy(); |
443 | end_pagecache(&pagecache, 1); |
444 | ma_control_file_end(); |
445 | |
446 | if (ma_control_file_open(TRUE,TRUE)) |
447 | { |
448 | fprintf(stderr, "pass2: Can't init control file (%d)\n" , errno); |
449 | exit(1); |
450 | } |
451 | if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0, |
452 | TRANSLOG_PAGE_SIZE, 0, 0) == 0) |
453 | { |
454 | fprintf(stderr, "pass2: Got error: init_pagecache() (errno: %d)\n" , errno); |
455 | exit(1); |
456 | } |
457 | if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache, |
458 | 0, READONLY, &translog_example_table_init, 0)) |
459 | { |
460 | fprintf(stderr, "pass2: Can't init loghandler (%d)\n" , errno); |
461 | exit(1); |
462 | } |
463 | |
464 | |
465 | /* If we were writing sequence we need it only once */ |
466 | opt_wfile= NULL; |
467 | if (opt_rfile) |
468 | seq_storage_rewind(&seq); |
469 | srand(122334817L); |
470 | |
471 | rc= 1; |
472 | |
473 | { |
474 | int len= translog_read_record_header(first_lsn, &rec); |
475 | if (len == RECHEADER_READ_ERROR) |
476 | { |
477 | fprintf(stderr, "translog_read_record_header failed (%d)\n" , errno); |
478 | translog_free_record_header(&rec); |
479 | goto err; |
480 | } |
481 | if (rec.type !=LOGREC_FIXED_RECORD_0LSN_EXAMPLE || rec.short_trid != 0 || |
482 | rec.record_length != 6 || uint4korr(rec.header) != 0 || |
483 | ((uchar)rec.header[4]) != 0 || ((uchar)rec.header[5]) != 0xFF || |
484 | first_lsn != rec.lsn) |
485 | { |
486 | fprintf(stderr, "Incorrect LOGREC_FIXED_RECORD_0LSN_EXAMPLE " |
487 | "data read(0)\n" |
488 | "type %u, strid %u, len %u, i: %u, 4: %u 5: %u, " |
489 | LSN_FMT "\n" , |
490 | (uint) rec.type, (uint) rec.short_trid, (uint) rec.record_length, |
491 | (uint)uint4korr(rec.header), (uint) rec.header[4], |
492 | (uint) rec.header[5], |
493 | LSN_IN_PARTS(rec.lsn)); |
494 | translog_free_record_header(&rec); |
495 | goto err; |
496 | } |
497 | ok(1, "read record" ); |
498 | translog_free_record_header(&rec); |
499 | lsn= first_lsn; |
500 | if (translog_scanner_init(first_lsn, 1, &scanner, 0)) |
501 | { |
502 | fprintf(stderr, "scanner init failed\n" ); |
503 | goto err; |
504 | } |
505 | for (i= 1;; i++) |
506 | { |
507 | len= translog_read_next_record_header(&scanner, &rec); |
508 | if (len == RECHEADER_READ_ERROR) |
509 | { |
510 | fprintf(stderr, "1-%d translog_read_next_record_header failed (%d)\n" , |
511 | i, errno); |
512 | translog_free_record_header(&rec); |
513 | goto err; |
514 | } |
515 | if (len == RECHEADER_READ_EOF) |
516 | { |
517 | if (i != ITERATIONS) |
518 | { |
519 | fprintf(stderr, "EOL met at iteration %u instead of %u\n" , |
520 | i, ITERATIONS); |
521 | translog_free_record_header(&rec); |
522 | goto err; |
523 | } |
524 | break; |
525 | } |
526 | |
527 | if (i % 2) |
528 | { |
529 | LSN ref; |
530 | ref= lsn_korr(rec.header); |
531 | if (rec.type != LOGREC_FIXED_RECORD_1LSN_EXAMPLE || |
532 | rec.short_trid != (i % 0xFFFF) || |
533 | rec.record_length != LSN_STORE_SIZE || ref != lsn) |
534 | { |
535 | fprintf(stderr, "Incorrect LOGREC_FIXED_RECORD_1LSN_EXAMPLE " |
536 | "data read(%d)" |
537 | "type %u, strid %u, len %u, ref" LSN_FMT ", lsn" LSN_FMT "\n" , |
538 | i, (uint) rec.type, (uint) rec.short_trid, |
539 | (uint) rec.record_length, |
540 | LSN_IN_PARTS(ref), LSN_IN_PARTS(rec.lsn)); |
541 | translog_free_record_header(&rec); |
542 | goto err; |
543 | } |
544 | } |
545 | else |
546 | { |
547 | LSN ref1, ref2; |
548 | ref1= lsn_korr(rec.header); |
549 | ref2= lsn_korr(rec.header + LSN_STORE_SIZE); |
550 | if (rec.type != LOGREC_FIXED_RECORD_2LSN_EXAMPLE || |
551 | rec.short_trid != (i % 0xFFFF) || |
552 | rec.record_length != 23 || |
553 | ref1 != lsn || |
554 | ref2 != first_lsn || |
555 | ((uchar)rec.header[22]) != 0x55 || |
556 | ((uchar)rec.header[21]) != 0xAA || |
557 | ((uchar)rec.header[20]) != 0x55 || |
558 | ((uchar)rec.header[19]) != 0xAA || |
559 | ((uchar)rec.header[18]) != 0x55 || |
560 | ((uchar)rec.header[17]) != 0xAA || |
561 | ((uchar)rec.header[16]) != 0x55 || |
562 | ((uchar)rec.header[15]) != 0xAA || |
563 | ((uchar)rec.header[14]) != 0x55) |
564 | { |
565 | fprintf(stderr, "Incorrect LOGREC_FIXED_RECORD_2LSN_EXAMPLE " |
566 | "data read(%d) " |
567 | "type %u, strid %u, len %u, ref1" LSN_FMT ", " |
568 | "ref2" LSN_FMT " %x%x%x%x%x%x%x%x%x " |
569 | "lsn" LSN_FMT "\n" , |
570 | i, (uint) rec.type, (uint) rec.short_trid, |
571 | (uint) rec.record_length, |
572 | LSN_IN_PARTS(ref1), LSN_IN_PARTS(ref2), |
573 | (uint) rec.header[14], (uint) rec.header[15], |
574 | (uint) rec.header[16], (uint) rec.header[17], |
575 | (uint) rec.header[18], (uint) rec.header[19], |
576 | (uint) rec.header[20], (uint) rec.header[21], |
577 | (uint) rec.header[22], |
578 | LSN_IN_PARTS(rec.lsn)); |
579 | translog_free_record_header(&rec); |
580 | DBUG_ASSERT(0); |
581 | goto err; |
582 | } |
583 | } |
584 | ok(1, "read record" ); |
585 | translog_free_record_header(&rec); |
586 | |
587 | len= translog_read_next_record_header(&scanner, &rec); |
588 | if (len == RECHEADER_READ_ERROR) |
589 | { |
590 | fprintf(stderr, "1-%d translog_read_next_record_header (var) " |
591 | "failed (%d)\n" , i, errno); |
592 | goto err; |
593 | } |
594 | if (len == RECHEADER_READ_EOF) |
595 | { |
596 | fprintf(stderr, "EOL met at the middle of iteration (first var) %u " |
597 | "instead of beginning of %u\n" , i, ITERATIONS); |
598 | goto err; |
599 | } |
600 | if (i % 2) |
601 | { |
602 | LSN ref; |
603 | ref= lsn_korr(rec.header); |
604 | rec_len= get_len(); |
605 | if (rec.type !=LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE || |
606 | rec.short_trid != (i % 0xFFFF) || |
607 | rec.record_length != rec_len + LSN_STORE_SIZE || |
608 | len != 12 || ref != lsn || |
609 | check_content(rec.header + LSN_STORE_SIZE, len - LSN_STORE_SIZE)) |
610 | { |
611 | fprintf(stderr, "Incorrect LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE " |
612 | "data read(%d)" |
613 | "type %u (%d), strid %u (%d), len %lu, %lu + 7 (%d), " |
614 | "hdr len: %d (%d), " |
615 | "ref" LSN_FMT ", lsn" LSN_FMT " (%d), content: %d\n" , |
616 | i, (uint) rec.type, |
617 | rec.type !=LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE, |
618 | (uint) rec.short_trid, |
619 | rec.short_trid != (i % 0xFFFF), |
620 | (ulong) rec.record_length, (ulong) rec_len, |
621 | rec.record_length != rec_len + LSN_STORE_SIZE, |
622 | len, |
623 | len != 12, |
624 | LSN_IN_PARTS(ref), LSN_IN_PARTS(rec.lsn), |
625 | (ref != lsn), |
626 | check_content(rec.header + LSN_STORE_SIZE, |
627 | len - LSN_STORE_SIZE)); |
628 | translog_free_record_header(&rec); |
629 | goto err; |
630 | } |
631 | if (read_and_check_content(&rec, long_buffer, LSN_STORE_SIZE)) |
632 | { |
633 | fprintf(stderr, |
634 | "Incorrect LOGREC_VARIABLE_RECORD_1LSN_EXAMPLE " |
635 | "in whole rec read lsn" LSN_FMT "\n" , |
636 | LSN_IN_PARTS(rec.lsn)); |
637 | translog_free_record_header(&rec); |
638 | goto err; |
639 | } |
640 | } |
641 | else |
642 | { |
643 | LSN ref1, ref2; |
644 | ref1= lsn_korr(rec.header); |
645 | ref2= lsn_korr(rec.header + LSN_STORE_SIZE); |
646 | rec_len= get_len(); |
647 | if (rec.type != LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE || |
648 | rec.short_trid != (i % 0xFFFF) || |
649 | rec.record_length != rec_len + LSN_STORE_SIZE * 2 || |
650 | len != 19 || |
651 | ref1 != lsn || |
652 | ref2 != first_lsn || |
653 | check_content(rec.header + LSN_STORE_SIZE * 2, |
654 | len - LSN_STORE_SIZE * 2)) |
655 | { |
656 | fprintf(stderr, "Incorrect LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE " |
657 | " data read(%d) " |
658 | "type %u, strid %u, len %lu != %lu + 14, hdr len: %d, " |
659 | "ref1" LSN_FMT ", ref2" LSN_FMT ", " |
660 | "lsn" LSN_FMT "\n" , |
661 | i, (uint) rec.type, (uint) rec.short_trid, |
662 | (ulong) rec.record_length, (ulong) rec_len, |
663 | len, |
664 | LSN_IN_PARTS(ref1), LSN_IN_PARTS(ref2), |
665 | LSN_IN_PARTS(rec.lsn)); |
666 | translog_free_record_header(&rec); |
667 | goto err; |
668 | } |
669 | if (read_and_check_content(&rec, long_buffer, LSN_STORE_SIZE * 2)) |
670 | { |
671 | fprintf(stderr, |
672 | "Incorrect LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE " |
673 | "in whole rec read lsn" LSN_FMT "\n" , |
674 | LSN_IN_PARTS(rec.lsn)); |
675 | translog_free_record_header(&rec); |
676 | goto err; |
677 | } |
678 | } |
679 | ok(1, "read record" ); |
680 | translog_free_record_header(&rec); |
681 | |
682 | len= translog_read_next_record_header(&scanner, &rec); |
683 | if (len == RECHEADER_READ_ERROR) |
684 | { |
685 | fprintf(stderr, "1-%d translog_read_next_record_header failed (%d)\n" , |
686 | i, errno); |
687 | translog_free_record_header(&rec); |
688 | goto err; |
689 | } |
690 | if (len == RECHEADER_READ_EOF) |
691 | { |
692 | fprintf(stderr, "EOL met at the middle of iteration %u " |
693 | "instead of beginning of %u\n" , i, ITERATIONS); |
694 | translog_free_record_header(&rec); |
695 | goto err; |
696 | } |
697 | if (rec.type != LOGREC_FIXED_RECORD_0LSN_EXAMPLE || |
698 | rec.short_trid != (i % 0xFFFF) || |
699 | rec.record_length != 6 || uint4korr(rec.header) != i || |
700 | ((uchar)rec.header[4]) != 0 || ((uchar)rec.header[5]) != 0xFF) |
701 | { |
702 | fprintf(stderr, "Incorrect LOGREC_FIXED_RECORD_0LSN_EXAMPLE " |
703 | "data read(%d)\n" |
704 | "type %u, strid %u, len %u, i: %u, 4: %u 5: %u " |
705 | "lsn" LSN_FMT "\n" , |
706 | i, (uint) rec.type, (uint) rec.short_trid, |
707 | (uint) rec.record_length, |
708 | (uint)uint4korr(rec.header), (uint) rec.header[4], |
709 | (uint) rec.header[5], |
710 | LSN_IN_PARTS(rec.lsn)); |
711 | translog_free_record_header(&rec); |
712 | goto err; |
713 | } |
714 | ok(1, "read record" ); |
715 | translog_free_record_header(&rec); |
716 | |
717 | lsn= rec.lsn; |
718 | |
719 | len= translog_read_next_record_header(&scanner, &rec); |
720 | rec_len= get_len(); |
721 | if (rec.type != LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE || |
722 | rec.short_trid != (i % 0xFFFF) || |
723 | rec.record_length != rec_len || |
724 | len != 9 || check_content(rec.header, len)) |
725 | { |
726 | fprintf(stderr, "Incorrect LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE " |
727 | "data read(%d) " |
728 | "type %u, strid %u, len %lu != %lu, hdr len: %d, " |
729 | "lsn" LSN_FMT "\n" , |
730 | i, (uint) rec.type, (uint) rec.short_trid, |
731 | (ulong) rec.record_length, (ulong) rec_len, |
732 | len, LSN_IN_PARTS(rec.lsn)); |
733 | translog_free_record_header(&rec); |
734 | goto err; |
735 | } |
736 | if (read_and_check_content(&rec, long_buffer, 0)) |
737 | { |
738 | fprintf(stderr, |
739 | "Incorrect LOGREC_VARIABLE_RECORD_2LSN_EXAMPLE " |
740 | "in whole rec read lsn" LSN_FMT "\n" , |
741 | LSN_IN_PARTS(rec.lsn)); |
742 | translog_free_record_header(&rec); |
743 | goto err; |
744 | } |
745 | ok(1, "read record" ); |
746 | translog_free_record_header(&rec); |
747 | } |
748 | } |
749 | |
750 | rc= 0; |
751 | err: |
752 | if (rc) |
753 | ok(0, "read record" ); |
754 | translog_destroy(); |
755 | end_pagecache(&pagecache, 1); |
756 | ma_control_file_end(); |
757 | free_defaults(default_argv); |
758 | seq_storage_destroy(&seq); |
759 | if (maria_log_remove(maria_data_root)) |
760 | exit(1); |
761 | |
762 | free(long_buffer); |
763 | |
764 | my_uuid_end(); |
765 | my_free_open_file_info(); |
766 | my_end(0); |
767 | |
768 | return (MY_TEST(exit_status())); |
769 | } |
770 | |
771 | #include "../ma_check_standalone.h" |
772 | |