mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 10:56:12 +01:00 
			
		
		
		
	 d7c943b363
			
		
	
	
	d7c943b363
	
	
	
		
			
			- Updated prototype for is_binary_frm_header(). - Added extra argument to ma_control_file_open(). - Added ma_control_file_open_or_create() for usage by tests. (to make test a bit simpler).
		
			
				
	
	
		
			553 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			553 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* Copyright (C) 2006-2008 MySQL AB
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; version 2 of the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
 | |
| 
 | |
| #include "../maria_def.h"
 | |
| #include <stdio.h>
 | |
| #include <errno.h>
 | |
| #include <tap.h>
 | |
| #include "../trnman.h"
 | |
| 
 | |
| extern my_bool maria_log_remove(const char *testdir);
 | |
| extern char *create_tmpdir(const char *progname);
 | |
| 
 | |
| #ifndef DBUG_OFF
 | |
| static const char *default_dbug_option;
 | |
| #endif
 | |
| 
 | |
| #define PCACHE_SIZE (1024*1024*10)
 | |
| 
 | |
| #define LOG_FILE_SIZE (1024L*1024L*1024L + 1024L*1024L*512)
 | |
| /*#define LOG_FLAGS TRANSLOG_SECTOR_PROTECTION | TRANSLOG_PAGE_CRC */
 | |
| #define LOG_FLAGS 0
 | |
| /*#define LONG_BUFFER_SIZE (1024L*1024L*1024L + 1024L*1024L*512)*/
 | |
| 
 | |
| #ifdef MULTIFLUSH_TEST
 | |
| 
 | |
| #define LONG_BUFFER_SZ (16384L)
 | |
| #define MIN_REC_LENGTH 10
 | |
| #define SHOW_DIVIDER 20
 | |
| #define ITERATIONS 10000
 | |
| #define FLUSH_ITERATIONS 1000
 | |
| #define WRITERS 2
 | |
| #define FLUSHERS 10
 | |
| 
 | |
| #else
 | |
| 
 | |
| #define LONG_BUFFER_SZ (512L*1024L*1024L)
 | |
| #define MIN_REC_LENGTH 30
 | |
| #define SHOW_DIVIDER 10
 | |
| #define ITERATIONS 3
 | |
| #define FLUSH_ITERATIONS 0
 | |
| #define WRITERS 3
 | |
| #define FLUSHERS 0
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #define LONG_BUFFER_SIZE (LONG_BUFFER_SZ >> (skip_big_tests ? 4 : 0))
 | |
| 
 | |
| static uint number_of_writers= WRITERS;
 | |
| static uint number_of_flushers= FLUSHERS;
 | |
| 
 | |
| static pthread_cond_t COND_thread_count;
 | |
| static pthread_mutex_t LOCK_thread_count;
 | |
| static uint thread_count;
 | |
| 
 | |
| static ulong lens[WRITERS][ITERATIONS];
 | |
| static LSN lsns1[WRITERS][ITERATIONS];
 | |
| static LSN lsns2[WRITERS][ITERATIONS];
 | |
| static uchar *long_buffer;
 | |
| 
 | |
| 
 | |
| static LSN last_lsn; /* For test purposes the variable allow dirty read/write */
 | |
| 
 | |
| /*
 | |
|   Get pseudo-random length of the field in
 | |
|     limits [MIN_REC_LENGTH..LONG_BUFFER_SIZE]
 | |
| 
 | |
|   SYNOPSIS
 | |
|     get_len()
 | |
| 
 | |
|   RETURN
 | |
|     length - length >= 0 length <= LONG_BUFFER_SIZE
 | |
| */
 | |
| 
 | |
| static uint32 get_len()
 | |
| {
 | |
|   return MIN_REC_LENGTH +
 | |
|     (uint32)(((ulonglong)rand())*
 | |
|        (LONG_BUFFER_SIZE - MIN_REC_LENGTH - 1)/RAND_MAX);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Check that the buffer filled correctly
 | |
| 
 | |
|   SYNOPSIS
 | |
|     check_content()
 | |
|     ptr                  Pointer to the buffer
 | |
|     length               length of the buffer
 | |
| 
 | |
|   RETURN
 | |
|     0 - OK
 | |
|     1 - Error
 | |
| */
 | |
| 
 | |
| static my_bool check_content(uchar *ptr, ulong length)
 | |
| {
 | |
|   ulong i;
 | |
|   for (i= 0; i < length; i++)
 | |
|   {
 | |
|     if (((uchar)ptr[i]) != (i & 0xFF))
 | |
|     {
 | |
|       fprintf(stderr, "Byte # %lu is %x instead of %x",
 | |
|               i, (uint) ptr[i], (uint) (i & 0xFF));
 | |
|       return 1;
 | |
|     }
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Read whole record content, and check content (put with offset)
 | |
| 
 | |
|   SYNOPSIS
 | |
|     read_and_check_content()
 | |
|     rec                  The record header buffer
 | |
|     buffer               The buffer to read the record in
 | |
|     skip                 Skip this number of bytes ot the record content
 | |
| 
 | |
|   RETURN
 | |
|     0 - OK
 | |
|     1 - Error
 | |
| */
 | |
| 
 | |
| 
 | |
| static my_bool read_and_check_content(TRANSLOG_HEADER_BUFFER *rec,
 | |
|                                       uchar *buffer, uint skip)
 | |
| {
 | |
|   int res= 0;
 | |
|   translog_size_t len;
 | |
| 
 | |
|   if ((len= translog_read_record(rec->lsn, 0, rec->record_length,
 | |
|                                  buffer, NULL)) != rec->record_length)
 | |
|   {
 | |
|     fprintf(stderr, "Requested %lu byte, read %lu\n",
 | |
|             (ulong) rec->record_length, (ulong) len);
 | |
|     res= 1;
 | |
|   }
 | |
|   res|= check_content(buffer + skip, rec->record_length - skip);
 | |
|   return(res);
 | |
| }
 | |
| 
 | |
| void writer(int num)
 | |
| {
 | |
|   LSN lsn;
 | |
|   TRN trn;
 | |
|   uchar long_tr_id[6];
 | |
|   uint i;
 | |
| 
 | |
|   trn.short_id= num;
 | |
|   trn.first_undo_lsn= TRANSACTION_LOGGED_LONG_ID;
 | |
|   for (i= 0; i < ITERATIONS; i++)
 | |
|   {
 | |
|     uint len= get_len();
 | |
|     LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1];
 | |
|     lens[num][i]= len;
 | |
| 
 | |
|     int2store(long_tr_id, num);
 | |
|     int4store(long_tr_id + 2, i);
 | |
|     parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
 | |
|     parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
 | |
|     if (translog_write_record(&lsn,
 | |
|                               LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
 | |
|                               &trn, NULL, 6, TRANSLOG_INTERNAL_PARTS + 1,
 | |
|                               parts, NULL, NULL))
 | |
|     {
 | |
|       fprintf(stderr, "Can't write LOGREC_FIXED_RECORD_0LSN_EXAMPLE record #%lu "
 | |
|               "thread %i\n", (ulong) i, num);
 | |
|       translog_destroy();
 | |
|       pthread_mutex_lock(&LOCK_thread_count);
 | |
|       ok(0, "write records");
 | |
|       pthread_mutex_unlock(&LOCK_thread_count);
 | |
|       return;
 | |
|     }
 | |
|     lsns1[num][i]= lsn;
 | |
|     parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_buffer;
 | |
|     parts[TRANSLOG_INTERNAL_PARTS + 0].length= len;
 | |
|     if (translog_write_record(&lsn,
 | |
|                               LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE,
 | |
|                               &trn, NULL,
 | |
|                               len, TRANSLOG_INTERNAL_PARTS + 1,
 | |
|                               parts, NULL, NULL))
 | |
|     {
 | |
|       fprintf(stderr, "Can't write variable record #%lu\n", (ulong) i);
 | |
|       translog_destroy();
 | |
|       pthread_mutex_lock(&LOCK_thread_count);
 | |
|       ok(0, "write records");
 | |
|       pthread_mutex_unlock(&LOCK_thread_count);
 | |
|       return;
 | |
|     }
 | |
|     lsns2[num][i]= lsn;
 | |
|     last_lsn= lsn;
 | |
|     pthread_mutex_lock(&LOCK_thread_count);
 | |
|     ok(1, "write records");
 | |
|     pthread_mutex_unlock(&LOCK_thread_count);
 | |
|   }
 | |
|   return;
 | |
| }
 | |
| 
 | |
| 
 | |
| static void *test_thread_writer(void *arg)
 | |
| {
 | |
|   int param= *((int*) arg);
 | |
| 
 | |
|   my_thread_init();
 | |
| 
 | |
|   writer(param);
 | |
| 
 | |
|   pthread_mutex_lock(&LOCK_thread_count);
 | |
|   thread_count--;
 | |
|   ok(1, "writer finished"); /* just to show progress */
 | |
|   pthread_cond_signal(&COND_thread_count);        /* Tell main we are
 | |
|                                                            ready */
 | |
|   pthread_mutex_unlock(&LOCK_thread_count);
 | |
|   free((uchar*) arg);
 | |
|   my_thread_end();
 | |
|   return(0);
 | |
| }
 | |
| 
 | |
| 
 | |
| static void *test_thread_flusher(void *arg)
 | |
| {
 | |
|   int param= *((int*) arg);
 | |
|   int i;
 | |
| 
 | |
|   my_thread_init();
 | |
| 
 | |
|   for(i= 0; i < FLUSH_ITERATIONS; i++)
 | |
|   {
 | |
|     translog_flush(last_lsn);
 | |
|     pthread_mutex_lock(&LOCK_thread_count);
 | |
|     ok(1, "-- flush %d", param);
 | |
|     pthread_mutex_unlock(&LOCK_thread_count);
 | |
|   }
 | |
| 
 | |
|   pthread_mutex_lock(&LOCK_thread_count);
 | |
|   thread_count--;
 | |
|   ok(1, "flusher finished"); /* just to show progress */
 | |
|   pthread_cond_signal(&COND_thread_count);        /* Tell main we are
 | |
|                                                            ready */
 | |
|   pthread_mutex_unlock(&LOCK_thread_count);
 | |
|   free((uchar*) arg);
 | |
|   my_thread_end();
 | |
|   return(0);
 | |
| }
 | |
| 
 | |
| 
 | |
| int main(int argc __attribute__((unused)),
 | |
|          char **argv __attribute__ ((unused)))
 | |
| {
 | |
|   uint32 i;
 | |
|   PAGECACHE pagecache;
 | |
|   LSN first_lsn;
 | |
|   TRANSLOG_HEADER_BUFFER rec;
 | |
|   struct st_translog_scanner_data scanner;
 | |
|   pthread_t tid;
 | |
|   pthread_attr_t thr_attr;
 | |
|   int *param, error;
 | |
|   int rc;
 | |
|   MY_INIT(argv[0]);
 | |
| 
 | |
|   // plan read MYTAP_CONFIG so skip_big_tests will be set before using
 | |
|   plan(WRITERS + FLUSHERS +
 | |
|        ITERATIONS * WRITERS * 3 + FLUSH_ITERATIONS * FLUSHERS );
 | |
|   /* We don't need to do physical syncs in this test */
 | |
|   my_disable_sync= 1;
 | |
| 
 | |
|   bzero(&pagecache, sizeof(pagecache));
 | |
|   maria_data_root= create_tmpdir(argv[0]);
 | |
|   if (maria_log_remove(0))
 | |
|     exit(1);
 | |
| 
 | |
|   long_buffer= malloc(LONG_BUFFER_SIZE + 7 * 2 + 2);
 | |
|   if (long_buffer == 0)
 | |
|   {
 | |
|     fprintf(stderr, "End of memory\n");
 | |
|     exit(1);
 | |
|   }
 | |
|   for (i= 0; i < (uint32)(LONG_BUFFER_SIZE + 7 * 2 + 2); i++)
 | |
|     long_buffer[i]= (i & 0xFF);
 | |
| 
 | |
| #ifndef DBUG_OFF
 | |
| #if defined(_WIN32)
 | |
|   default_dbug_option= "d:t:i:O,\\ma_test_loghandler.trace";
 | |
| #else
 | |
|   default_dbug_option= "d:t:i:o,/tmp/ma_test_loghandler.trace";
 | |
| #endif
 | |
|   if (argc > 1)
 | |
|   {
 | |
|     DBUG_SET(default_dbug_option);
 | |
|     DBUG_SET_INITIAL(default_dbug_option);
 | |
|   }
 | |
| #endif
 | |
| 
 | |
| 
 | |
|   if ((error= pthread_cond_init(&COND_thread_count, NULL)))
 | |
|   {
 | |
|     fprintf(stderr, "COND_thread_count: %d from pthread_cond_init "
 | |
|             "(errno: %d)\n", error, errno);
 | |
|     exit(1);
 | |
|   }
 | |
|   if ((error= pthread_mutex_init(&LOCK_thread_count, MY_MUTEX_INIT_FAST)))
 | |
|   {
 | |
|     fprintf(stderr, "LOCK_thread_count: %d from pthread_cond_init "
 | |
|             "(errno: %d)\n", error, errno);
 | |
|     exit(1);
 | |
|   }
 | |
|   if ((error= pthread_attr_init(&thr_attr)))
 | |
|   {
 | |
|     fprintf(stderr, "Got error: %d from pthread_attr_init "
 | |
|             "(errno: %d)\n", error, errno);
 | |
|     exit(1);
 | |
|   }
 | |
|   if ((error= pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED)))
 | |
|   {
 | |
|     fprintf(stderr,
 | |
|             "Got error: %d from pthread_attr_setdetachstate (errno: %d)\n",
 | |
|             error, errno);
 | |
|     exit(1);
 | |
|   }
 | |
| 
 | |
|   if (ma_control_file_open(TRUE, TRUE, TRUE, control_file_open_flags))
 | |
|   {
 | |
|     fprintf(stderr, "Can't init control file (%d)\n", errno);
 | |
|     exit(1);
 | |
|   }
 | |
|   if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
 | |
|                      TRANSLOG_PAGE_SIZE, 0, 0) == 0)
 | |
|   {
 | |
|     fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
 | |
|     exit(1);
 | |
|   }
 | |
|   if (translog_init_with_table(maria_data_root, LOG_FILE_SIZE, 50112, 0, &pagecache,
 | |
|                                LOG_FLAGS, 0, &translog_example_table_init,
 | |
|                                0))
 | |
|   {
 | |
|     fprintf(stderr, "Can't init loghandler (%d)\n", errno);
 | |
|     exit(1);
 | |
|   }
 | |
|   /* Suppressing of automatic record writing */
 | |
|   dummy_transaction_object.first_undo_lsn|= TRANSACTION_LOGGED_LONG_ID;
 | |
| 
 | |
|   srand(122334817L);
 | |
|   {
 | |
|     LEX_CUSTRING parts[TRANSLOG_INTERNAL_PARTS + 1];
 | |
|     uchar long_tr_id[6]=
 | |
|     {
 | |
|       0x11, 0x22, 0x33, 0x44, 0x55, 0x66
 | |
|     };
 | |
| 
 | |
|     parts[TRANSLOG_INTERNAL_PARTS + 0].str= long_tr_id;
 | |
|     parts[TRANSLOG_INTERNAL_PARTS + 0].length= 6;
 | |
|     dummy_transaction_object.first_undo_lsn= TRANSACTION_LOGGED_LONG_ID;
 | |
|     if (translog_write_record(&first_lsn,
 | |
|                               LOGREC_FIXED_RECORD_0LSN_EXAMPLE,
 | |
|                               &dummy_transaction_object, NULL, 6,
 | |
|                               TRANSLOG_INTERNAL_PARTS + 1,
 | |
|                               parts, NULL, NULL))
 | |
|     {
 | |
|       fprintf(stderr, "Can't write the first record\n");
 | |
|       translog_destroy();
 | |
|       exit(1);
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
|   pthread_mutex_lock(&LOCK_thread_count);
 | |
|   while (number_of_writers != 0 || number_of_flushers != 0)
 | |
|   {
 | |
|     if (number_of_writers)
 | |
|     {
 | |
|       param= (int*) malloc(sizeof(int));
 | |
|       *param= number_of_writers - 1;
 | |
|       if ((error= pthread_create(&tid, &thr_attr, test_thread_writer,
 | |
|                                  (void*) param)))
 | |
|       {
 | |
|         fprintf(stderr, "Got error: %d from pthread_create (errno: %d)\n",
 | |
|                 error, errno);
 | |
|         exit(1);
 | |
|       }
 | |
|       thread_count++;
 | |
|       number_of_writers--;
 | |
|     }
 | |
|     if (number_of_flushers)
 | |
|     {
 | |
|       param= (int*) malloc(sizeof(int));
 | |
|       *param= number_of_flushers - 1;
 | |
|       if ((error= pthread_create(&tid, &thr_attr, test_thread_flusher,
 | |
|                                  (void*) param)))
 | |
|       {
 | |
|         fprintf(stderr, "Got error: %d from pthread_create (errno: %d)\n",
 | |
|                 error, errno);
 | |
|         exit(1);
 | |
|       }
 | |
|       thread_count++;
 | |
|       number_of_flushers--;
 | |
|     }
 | |
|   }
 | |
|   pthread_mutex_unlock(&LOCK_thread_count);
 | |
| 
 | |
|   pthread_attr_destroy(&thr_attr);
 | |
| 
 | |
|   /* wait finishing */
 | |
|   pthread_mutex_lock(&LOCK_thread_count);
 | |
|   while (thread_count)
 | |
|   {
 | |
|     if ((error= pthread_cond_wait(&COND_thread_count, &LOCK_thread_count)))
 | |
|       fprintf(stderr, "COND_thread_count: %d from pthread_cond_wait\n", error);
 | |
|   }
 | |
|   pthread_mutex_unlock(&LOCK_thread_count);
 | |
| 
 | |
|   /* Find last LSN and flush up to it (all our log) */
 | |
|   {
 | |
|     LSN max= 0;
 | |
|     for (i= 0; i < WRITERS; i++)
 | |
|     {
 | |
|       if (cmp_translog_addr(lsns2[i][ITERATIONS - 1], max) > 0)
 | |
|         max= lsns2[i][ITERATIONS - 1];
 | |
|     }
 | |
|     translog_flush(max);
 | |
|   }
 | |
| 
 | |
|   rc= 1;
 | |
| 
 | |
|   {
 | |
|     uint indeces[WRITERS];
 | |
|     uint index, stage;
 | |
|     int len;
 | |
|     bzero(indeces, sizeof(uint) * WRITERS);
 | |
| 
 | |
|     bzero(indeces, sizeof(indeces));
 | |
| 
 | |
|     if (translog_scanner_init(first_lsn, 1, &scanner, 0))
 | |
|     {
 | |
|       fprintf(stderr, "scanner init failed\n");
 | |
|       goto err;
 | |
|     }
 | |
|     for (i= 0;; i++)
 | |
|     {
 | |
|       len= translog_read_next_record_header(&scanner, &rec);
 | |
| 
 | |
|       if (len == RECHEADER_READ_ERROR)
 | |
|       {
 | |
|         fprintf(stderr, "1-%d translog_read_next_record_header failed (%d)\n",
 | |
|                 i, errno);
 | |
|         translog_free_record_header(&rec);
 | |
|         goto err;
 | |
|       }
 | |
|       if (len == RECHEADER_READ_EOF)
 | |
|       {
 | |
|         if (i != WRITERS * ITERATIONS * 2)
 | |
|         {
 | |
|           fprintf(stderr, "EOL met at iteration %u instead of %u\n",
 | |
|                   i, ITERATIONS * WRITERS * 2);
 | |
|           translog_free_record_header(&rec);
 | |
|           goto err;
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|       index= indeces[rec.short_trid] / 2;
 | |
|       stage= indeces[rec.short_trid] % 2;
 | |
|       if (stage == 0)
 | |
|       {
 | |
|         if (rec.type !=LOGREC_FIXED_RECORD_0LSN_EXAMPLE ||
 | |
|             rec.record_length != 6 ||
 | |
|             uint2korr(rec.header) != rec.short_trid ||
 | |
|             index != uint4korr(rec.header + 2) ||
 | |
|             cmp_translog_addr(lsns1[rec.short_trid][index], rec.lsn) != 0)
 | |
|         {
 | |
|           fprintf(stderr, "Incorrect LOGREC_FIXED_RECORD_0LSN_EXAMPLE "
 | |
|                   "data read(%d)\n"
 | |
|                   "type %u, strid %u %u, len %u, i: %u %u, "
 | |
|                   "lsn" LSN_FMT " " LSN_FMT "\n",
 | |
|                   i, (uint) rec.type,
 | |
|                   (uint) rec.short_trid, (uint) uint2korr(rec.header),
 | |
|                   (uint) rec.record_length,
 | |
|                   (uint) index, (uint) uint4korr(rec.header + 2),
 | |
|                   LSN_IN_PARTS(rec.lsn),
 | |
|                   LSN_IN_PARTS(lsns1[rec.short_trid][index]));
 | |
|           translog_free_record_header(&rec);
 | |
|           goto err;
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         if (rec.type != LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE ||
 | |
|             len != 9 ||
 | |
|             rec.record_length != lens[rec.short_trid][index] ||
 | |
|             cmp_translog_addr(lsns2[rec.short_trid][index], rec.lsn) != 0 ||
 | |
|             check_content(rec.header, (uint)len))
 | |
|         {
 | |
|           fprintf(stderr,
 | |
|                   "Incorrect LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE "
 | |
|                   "data read(%d) "
 | |
|                   "thread: %d, iteration %d, stage %d\n"
 | |
|                   "type %u (%d), len %d, length %lu %lu (%d) "
 | |
|                   "lsn" LSN_FMT " " LSN_FMT "\n",
 | |
|                   i, (uint) rec.short_trid, index, stage,
 | |
|                   (uint) rec.type, (rec.type !=
 | |
|                                     LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE),
 | |
|                   len,
 | |
|                   (ulong) rec.record_length, lens[rec.short_trid][index],
 | |
|                   (rec.record_length != lens[rec.short_trid][index]),
 | |
|                   LSN_IN_PARTS(rec.lsn),
 | |
|                   LSN_IN_PARTS(lsns2[rec.short_trid][index]));
 | |
|           translog_free_record_header(&rec);
 | |
|           goto err;
 | |
|         }
 | |
|         if (read_and_check_content(&rec, long_buffer, 0))
 | |
|         {
 | |
|           fprintf(stderr,
 | |
|                   "Incorrect LOGREC_VARIABLE_RECORD_0LSN_EXAMPLE "
 | |
|                   "in whole rec read lsn" LSN_FMT "\n",
 | |
|                   LSN_IN_PARTS(rec.lsn));
 | |
|           translog_free_record_header(&rec);
 | |
|           goto err;
 | |
|         }
 | |
|       }
 | |
|       ok(1, "record read");
 | |
|       translog_free_record_header(&rec);
 | |
|       indeces[rec.short_trid]++;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   rc= 0;
 | |
| err:
 | |
|   if (rc)
 | |
|     ok(0, "record read");
 | |
|   translog_destroy();
 | |
|   end_pagecache(&pagecache, 1);
 | |
|   ma_control_file_end();
 | |
|   if (maria_log_remove(maria_data_root))
 | |
|     exit(1);
 | |
| 
 | |
|   my_uuid_end();
 | |
|   my_free_open_file_info();
 | |
|   my_end(0);
 | |
|   return(exit_status());
 | |
| }
 | |
| 
 | |
| #include "../ma_check_standalone.h"
 |