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
24extern my_bool maria_log_remove(const char *testdir);
25extern char *create_tmpdir(const char *progname);
26extern void translog_example_table_init();
27
28#ifndef DBUG_OFF
29static const char *default_dbug_option;
30#endif
31static 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
80static 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
116static 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
134static const char *load_default_groups[]= {"ma_unit_loghandler", 0};
135#ifndef DBUG_OFF
136static 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
140static const char *opt_wfile= NULL;
141static const char *opt_rfile= NULL;
142static 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};
156static SEQ_STORAGE seq;
157
158static 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
177static 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
191static my_bool
192get_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
210static 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
225int 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;
751err:
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