mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Merge desktop.sanja.is.com.ua:/home/bell/mysql/bk/work-maria-bug34695
into desktop.sanja.is.com.ua:/home/bell/mysql/bk/work-maria-loghandlerfixes storage/maria/ma_loghandler.c: Auto merged storage/maria/unittest/ma_test_loghandler_multigroup-t.c: Auto merged
This commit is contained in:
commit
76d9f3c619
8 changed files with 322 additions and 77 deletions
|
@ -62,7 +62,7 @@ TARGET_LINK_LIBRARIES(maria_read_log maria myisam mysys dbug strings zlib wsock3
|
|||
ADD_EXECUTABLE(maria_pack maria_pack.c)
|
||||
TARGET_LINK_LIBRARIES(maria_pack maria myisam mysys dbug strings zlib wsock32)
|
||||
|
||||
ADD_EXECUTABLE(maria_dump_log ma_loghandler.c)
|
||||
ADD_EXECUTABLE(maria_dump_log ma_loghandler.c unittest/ma_loghandler_examples.c)
|
||||
TARGET_LINK_LIBRARIES(maria_dump_log maria myisam mysys dbug strings zlib wsock32)
|
||||
SET_TARGET_PROPERTIES(maria_dump_log PROPERTIES COMPILE_FLAGS "-DMARIA_DUMP_LOG")
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ maria_dump_log_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmaria.a \
|
|||
$(top_builddir)/mysys/libmysys.a \
|
||||
$(top_builddir)/dbug/libdbug.a \
|
||||
$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
|
||||
maria_dump_log_SOURCES= ma_loghandler.c
|
||||
maria_dump_log_SOURCES= ma_loghandler.c unittest/ma_loghandler_examples.c
|
||||
maria_dump_log_CPPFLAGS= -DMARIA_DUMP_LOG
|
||||
noinst_PROGRAMS = ma_test1 ma_test2 ma_test3 ma_rt_test ma_sp_test
|
||||
noinst_HEADERS = maria_def.h ma_rt_index.h ma_rt_key.h ma_rt_mbr.h \
|
||||
|
|
|
@ -322,7 +322,8 @@ enum enum_translog_status translog_status= TRANSLOG_UNINITED;
|
|||
#define TRANSLOG_CHUNK_NOHDR (2 << 6) /* 2 no head chunk (till page end) */
|
||||
#define TRANSLOG_CHUNK_LNGTH (3 << 6) /* 3 chunk with chunk length */
|
||||
#define TRANSLOG_CHUNK_TYPE (3 << 6) /* Mask to get chunk type */
|
||||
#define TRANSLOG_REC_TYPE 0x3F /* Mask to get record type */
|
||||
#define TRANSLOG_REC_TYPE 0x3F /* Mask to get record type */
|
||||
#define TRANSLOG_CHUNK_0_CONT 0x3F /* the type to mark chunk 0 continue */
|
||||
|
||||
/* compressed (relative) LSN constants */
|
||||
#define TRANSLOG_CLSN_LEN_BITS 0xC0 /* Mask to get compressed LSN length */
|
||||
|
@ -343,6 +344,7 @@ static my_bool translog_page_validator(uchar *page,
|
|||
|
||||
static my_bool translog_get_next_chunk(TRANSLOG_SCANNER_DATA *scanner);
|
||||
static uint32 translog_first_file(TRANSLOG_ADDRESS horizon, int is_protected);
|
||||
LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -3267,6 +3269,26 @@ static void translog_fill_overhead_table()
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Checks that chunk is LSN one
|
||||
|
||||
@param type type of the chunk
|
||||
|
||||
@retval 1 the chunk is LNS
|
||||
@retval 0 the chunk is not LSN
|
||||
*/
|
||||
|
||||
static my_bool translog_is_LSN_chunk(uchar type)
|
||||
{
|
||||
DBUG_ENTER("translog_is_LSN_chunk");
|
||||
DBUG_PRINT("info", ("byte: %x chunk type: %u record type: %u",
|
||||
type, type >> 6, type & TRANSLOG_REC_TYPE));
|
||||
DBUG_RETURN(((type & TRANSLOG_CHUNK_TYPE) == TRANSLOG_CHUNK_FIXED) ||
|
||||
(((type & TRANSLOG_CHUNK_TYPE) == TRANSLOG_CHUNK_LSN) &&
|
||||
((type & TRANSLOG_REC_TYPE)) != TRANSLOG_CHUNK_0_CONT));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Initialize transaction log
|
||||
|
||||
|
@ -3765,12 +3787,9 @@ my_bool translog_init_with_table(const char *directory,
|
|||
scanner.page_offset= page_overhead[scanner.page[TRANSLOG_PAGE_FLAGS]];
|
||||
for (;;)
|
||||
{
|
||||
uint chunk_type;
|
||||
chunk_type= scanner.page[scanner.page_offset] & TRANSLOG_CHUNK_TYPE;
|
||||
DBUG_PRINT("info", ("type: %x byte: %x", (uint) chunk_type,
|
||||
(uint) scanner.page[scanner.page_offset]));
|
||||
while (chunk_type != TRANSLOG_CHUNK_LSN &&
|
||||
chunk_type != TRANSLOG_CHUNK_FIXED &&
|
||||
uint chunk_1byte;
|
||||
chunk_1byte= scanner.page[scanner.page_offset];
|
||||
while (!translog_is_LSN_chunk(chunk_1byte) &&
|
||||
scanner.page != END_OF_LOG &&
|
||||
scanner.page[scanner.page_offset] != TRANSLOG_FILLER &&
|
||||
scanner.page_addr == page_addr)
|
||||
|
@ -3781,14 +3800,9 @@ my_bool translog_init_with_table(const char *directory,
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
if (scanner.page != END_OF_LOG)
|
||||
{
|
||||
chunk_type= scanner.page[scanner.page_offset] & TRANSLOG_CHUNK_TYPE;
|
||||
DBUG_PRINT("info", ("type: %x byte: %x", (uint) chunk_type,
|
||||
(uint) scanner.page[scanner.page_offset]));
|
||||
}
|
||||
chunk_1byte= scanner.page[scanner.page_offset];
|
||||
}
|
||||
if (chunk_type == TRANSLOG_CHUNK_LSN ||
|
||||
chunk_type == TRANSLOG_CHUNK_FIXED)
|
||||
if (translog_is_LSN_chunk(chunk_1byte))
|
||||
{
|
||||
last_lsn= scanner.page_addr + scanner.page_offset;
|
||||
if (translog_get_next_chunk(&scanner))
|
||||
|
@ -3798,9 +3812,7 @@ my_bool translog_init_with_table(const char *directory,
|
|||
}
|
||||
if (scanner.page == END_OF_LOG)
|
||||
break; /* it was the last record */
|
||||
chunk_type= scanner.page[scanner.page_offset] & TRANSLOG_CHUNK_TYPE;
|
||||
DBUG_PRINT("info", ("type: %x byte: %x", (uint) chunk_type,
|
||||
(uint) scanner.page[scanner.page_offset]));
|
||||
chunk_1byte= scanner.page[scanner.page_offset];
|
||||
continue; /* try to find other record on this page */
|
||||
}
|
||||
|
||||
|
@ -5506,7 +5518,7 @@ translog_write_variable_record_mgroup(LSN *lsn,
|
|||
LSN_IN_PARTS(log_descriptor.horizon),
|
||||
LSN_IN_PARTS(horizon)));
|
||||
|
||||
*chunk0_header= (uchar) (type |TRANSLOG_CHUNK_LSN);
|
||||
*chunk0_header= (uchar) (type | TRANSLOG_CHUNK_LSN);
|
||||
int2store(chunk0_header + 1, short_trid);
|
||||
translog_write_variable_record_1group_code_len(chunk0_header + 3,
|
||||
parts->record_length,
|
||||
|
@ -5587,7 +5599,8 @@ translog_write_variable_record_mgroup(LSN *lsn,
|
|||
|
||||
chunk0_pages--;
|
||||
curr_group+= limit;
|
||||
|
||||
/* put special type to indicate that it is not LSN chunk */
|
||||
*chunk0_header= (uchar) (TRANSLOG_CHUNK_LSN | TRANSLOG_CHUNK_0_CONT);
|
||||
} while (chunk0_pages != 0);
|
||||
translog_buffer_lock(cursor.buffer);
|
||||
if (cmp_translog_addr(cursor.buffer->last_lsn, *lsn) < 0)
|
||||
|
@ -5906,8 +5919,9 @@ my_bool translog_write_record(LSN *lsn,
|
|||
int rc;
|
||||
uint short_trid= trn->short_id;
|
||||
DBUG_ENTER("translog_write_record");
|
||||
DBUG_PRINT("enter", ("type: %u ShortTrID: %u rec_len: %lu",
|
||||
(uint) type, (uint) short_trid, (ulong) rec_len));
|
||||
DBUG_PRINT("enter", ("type: %u (%s) ShortTrID: %u rec_len: %lu",
|
||||
(uint) type, log_record_type_descriptor[type].name,
|
||||
(uint) short_trid, (ulong) rec_len));
|
||||
DBUG_ASSERT(translog_status == TRANSLOG_OK ||
|
||||
translog_status == TRANSLOG_READONLY);
|
||||
if (unlikely(translog_status != TRANSLOG_OK))
|
||||
|
@ -6674,12 +6688,11 @@ int translog_read_record_header_from_buffer(uchar *page,
|
|||
{
|
||||
translog_size_t res;
|
||||
DBUG_ENTER("translog_read_record_header_from_buffer");
|
||||
DBUG_ASSERT((page[page_offset] & TRANSLOG_CHUNK_TYPE) ==
|
||||
TRANSLOG_CHUNK_LSN ||
|
||||
(page[page_offset] & TRANSLOG_CHUNK_TYPE) ==
|
||||
TRANSLOG_CHUNK_FIXED);
|
||||
DBUG_ASSERT(translog_is_LSN_chunk(page[page_offset]));
|
||||
DBUG_ASSERT(translog_status == TRANSLOG_OK ||
|
||||
translog_status == TRANSLOG_READONLY);
|
||||
DBUG_PRINT("info", ("page byte: 0x%x offset: %u",
|
||||
(uint) page[page_offset], (uint) page_offset));
|
||||
buff->type= (page[page_offset] & TRANSLOG_REC_TYPE);
|
||||
buff->short_trid= uint2korr(page + page_offset + 1);
|
||||
DBUG_PRINT("info", ("Type %u, Short TrID %u, LSN (%lu,0x%lx)",
|
||||
|
@ -6818,7 +6831,6 @@ int translog_read_record_header_scan(TRANSLOG_SCANNER_DATA *scanner,
|
|||
int translog_read_next_record_header(TRANSLOG_SCANNER_DATA *scanner,
|
||||
TRANSLOG_HEADER_BUFFER *buff)
|
||||
{
|
||||
uint8 chunk_type;
|
||||
translog_size_t res;
|
||||
|
||||
DBUG_ENTER("translog_read_next_record_header");
|
||||
|
@ -6845,14 +6857,11 @@ int translog_read_next_record_header(TRANSLOG_SCANNER_DATA *scanner,
|
|||
buff->lsn= LSN_IMPOSSIBLE;
|
||||
DBUG_RETURN(RECHEADER_READ_EOF);
|
||||
}
|
||||
chunk_type= scanner->page[scanner->page_offset] & TRANSLOG_CHUNK_TYPE;
|
||||
DBUG_PRINT("info", ("Page: (%lu,0x%lx) offset: %lu type: %x byte: %x",
|
||||
DBUG_PRINT("info", ("Page: (%lu,0x%lx) offset: %lu byte: %x",
|
||||
LSN_IN_PARTS(scanner->page_addr),
|
||||
(ulong) scanner->page_offset,
|
||||
(uint) chunk_type,
|
||||
(uint) scanner->page[scanner->page_offset]));
|
||||
} while (chunk_type != TRANSLOG_CHUNK_LSN &&
|
||||
chunk_type != TRANSLOG_CHUNK_FIXED &&
|
||||
} while (!translog_is_LSN_chunk(scanner->page[scanner->page_offset]) &&
|
||||
scanner->page[scanner->page_offset] != TRANSLOG_FILLER);
|
||||
|
||||
if (scanner->page[scanner->page_offset] == TRANSLOG_FILLER)
|
||||
|
@ -7695,7 +7704,6 @@ static uint32 translog_first_file(TRANSLOG_ADDRESS horizon, int is_protected)
|
|||
|
||||
LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon)
|
||||
{
|
||||
uint chunk_type;
|
||||
TRANSLOG_SCANNER_DATA scanner;
|
||||
LSN result;
|
||||
DBUG_ENTER("translog_next_LSN");
|
||||
|
@ -7742,11 +7750,7 @@ LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon)
|
|||
}
|
||||
}
|
||||
|
||||
chunk_type= scanner.page[scanner.page_offset] & TRANSLOG_CHUNK_TYPE;
|
||||
DBUG_PRINT("info", ("type: %x byte: %x", (uint) chunk_type,
|
||||
(uint) scanner.page[scanner.page_offset]));
|
||||
while (chunk_type != TRANSLOG_CHUNK_LSN &&
|
||||
chunk_type != TRANSLOG_CHUNK_FIXED &&
|
||||
while (!translog_is_LSN_chunk(scanner.page[scanner.page_offset]) &&
|
||||
scanner.page[scanner.page_offset] != TRANSLOG_FILLER)
|
||||
{
|
||||
if (translog_get_next_chunk(&scanner))
|
||||
|
@ -7759,9 +7763,6 @@ LSN translog_next_LSN(TRANSLOG_ADDRESS addr, TRANSLOG_ADDRESS horizon)
|
|||
result= LSN_IMPOSSIBLE;
|
||||
goto out;
|
||||
}
|
||||
chunk_type= scanner.page[scanner.page_offset] & TRANSLOG_CHUNK_TYPE;
|
||||
DBUG_PRINT("info", ("type: %x byte: %x", (uint) chunk_type,
|
||||
(uint) scanner.page[scanner.page_offset]));
|
||||
}
|
||||
|
||||
if (scanner.page[scanner.page_offset] == TRANSLOG_FILLER)
|
||||
|
@ -8069,6 +8070,7 @@ void translog_set_file_size(uint32 size)
|
|||
|
||||
#ifdef MARIA_DUMP_LOG
|
||||
#include <my_getopt.h>
|
||||
extern void translog_example_table_init();
|
||||
static const char *load_default_groups[]= { "maria_dump_log",0 };
|
||||
static void get_options(int *argc,char * * *argv);
|
||||
#ifndef DBUG_OFF
|
||||
|
@ -8082,6 +8084,7 @@ static ulonglong opt_offset;
|
|||
static ulong opt_pages;
|
||||
static const char *opt_file= NULL;
|
||||
static File handler= -1;
|
||||
static my_bool opt_unit= 0;
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
#ifdef IMPLTMENTED
|
||||
|
@ -8106,6 +8109,10 @@ static struct my_option my_long_options[] =
|
|||
GET_ULONG, REQUIRED_ARG, (long) ~(ulong) 0,
|
||||
(long) 1, (long) ~(ulong) 0, (long) 0,
|
||||
(long) 1, 0},
|
||||
{"unit-test", 'U',
|
||||
"Use unit test record table (for logs created by unittests",
|
||||
(uchar **) &opt_unit, (uchar **) &opt_unit, 0,
|
||||
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"version", 'V', "Print version and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
|
@ -8247,22 +8254,28 @@ static uchar *dump_chunk(uchar *buffer, uchar *ptr)
|
|||
switch (ptr[0] & TRANSLOG_CHUNK_TYPE) {
|
||||
case TRANSLOG_CHUNK_LSN:
|
||||
printf(" LSN chunk type 0 (variable length)\n");
|
||||
printf(" Record type %u: %s record class %s compressed LSNs: %u\n",
|
||||
ptr[0] & TRANSLOG_REC_TYPE,
|
||||
(log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].name ?
|
||||
log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].name :
|
||||
"NULL"),
|
||||
record_class_string[log_record_type_descriptor[ptr[0] &
|
||||
TRANSLOG_REC_TYPE].
|
||||
rclass],
|
||||
log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].
|
||||
compressed_LSN);
|
||||
if (log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].rclass !=
|
||||
LOGRECTYPE_VARIABLE_LENGTH)
|
||||
if (likely((ptr[0] & TRANSLOG_REC_TYPE) != TRANSLOG_CHUNK_0_CONT))
|
||||
{
|
||||
printf(" WARNING: this record class here can't be used "
|
||||
"(stop interpretation)!!!\n");
|
||||
printf(" Record type %u: %s record class %s compressed LSNs: %u\n",
|
||||
ptr[0] & TRANSLOG_REC_TYPE,
|
||||
(log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].name ?
|
||||
log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].name :
|
||||
"NULL"),
|
||||
record_class_string[log_record_type_descriptor[ptr[0] &
|
||||
TRANSLOG_REC_TYPE].
|
||||
rclass],
|
||||
log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].
|
||||
compressed_LSN);
|
||||
if (log_record_type_descriptor[ptr[0] & TRANSLOG_REC_TYPE].rclass !=
|
||||
LOGRECTYPE_VARIABLE_LENGTH)
|
||||
{
|
||||
printf(" WARNING: this record class here can't be used "
|
||||
"(stop interpretation)!!!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
printf(" Continuation of previous chunk 0 header \n");
|
||||
printf(" Short transaction id: %u\n", (uint) uint2korr(ptr + 1));
|
||||
{
|
||||
uchar *hdr_ptr= ptr + 1 + 2; /* chunk type and short trid */
|
||||
|
@ -8433,7 +8446,7 @@ static void dump_datapage(uchar *buffer)
|
|||
|
||||
static void dump_page(uchar *buffer)
|
||||
{
|
||||
printf("Page by offset %lld\n", opt_offset);
|
||||
printf("Page by offset %llu (0x%llx)\n", opt_offset, opt_offset);
|
||||
if (strncmp((char*)maria_trans_file_magic, (char*)buffer,
|
||||
sizeof(maria_trans_file_magic)) == 0)
|
||||
{
|
||||
|
@ -8452,13 +8465,17 @@ int main(int argc, char **argv)
|
|||
char **default_argv;
|
||||
uchar buffer[TRANSLOG_PAGE_SIZE];
|
||||
MY_INIT(argv[0]);
|
||||
translog_table_init();
|
||||
translog_fill_overhead_table();
|
||||
|
||||
load_defaults("my", load_default_groups, &argc, &argv);
|
||||
default_argv= argv;
|
||||
get_options(&argc, &argv);
|
||||
|
||||
if (opt_unit)
|
||||
translog_example_table_init();
|
||||
else
|
||||
translog_table_init();
|
||||
translog_fill_overhead_table();
|
||||
|
||||
maria_data_root= (char *)".";
|
||||
|
||||
if ((handler= my_open(opt_file, O_RDONLY, MYF(MY_WME))) < 0)
|
||||
|
|
|
@ -26,7 +26,7 @@ ADD_EXECUTABLE(lockman2-t lockman2-t.c)
|
|||
ADD_EXECUTABLE(ma_test_loghandler-t
|
||||
ma_test_loghandler-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c)
|
||||
ADD_EXECUTABLE(ma_test_loghandler_multigroup-t
|
||||
ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c)
|
||||
ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c sequence_storage.c)
|
||||
ADD_EXECUTABLE(ma_test_loghandler_multithread-t
|
||||
ma_test_loghandler_multithread-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c)
|
||||
ADD_EXECUTABLE(ma_test_loghandler_pagecache-t
|
||||
|
@ -44,7 +44,7 @@ ADD_EXECUTABLE(ma_test_loghandler_max_lsn-t
|
|||
ADD_EXECUTABLE(ma_test_loghandler_purge-t
|
||||
ma_test_loghandler_purge-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c)
|
||||
ADD_EXECUTABLE(ma_test_loghandler_readonly-t
|
||||
ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c)
|
||||
ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c sequence_storage.c)
|
||||
SET_TARGET_PROPERTIES(ma_test_loghandler_readonly-t PROPERTIES COMPILE_FLAGS "-DREADONLY_TEST")
|
||||
ADD_EXECUTABLE(ma_test_loghandler_nologs-t
|
||||
ma_test_loghandler_nologs-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c)
|
||||
|
|
|
@ -52,7 +52,7 @@ noinst_PROGRAMS = ma_control_file-t trnman-t lockman2-t \
|
|||
ma_test_loghandler_nologs-t
|
||||
|
||||
ma_test_loghandler_t_SOURCES = ma_test_loghandler-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_multigroup_t_SOURCES = ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_multigroup_t_SOURCES = ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c sequence_storage.c
|
||||
ma_test_loghandler_multithread_t_SOURCES = ma_test_loghandler_multithread-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_pagecache_t_SOURCES = ma_test_loghandler_pagecache-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_long_t_SOURCES = ma_test_loghandler-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
|
@ -61,7 +61,7 @@ ma_test_loghandler_noflush_t_SOURCES = ma_test_loghandler_noflush-t.c ma_maria_l
|
|||
ma_test_loghandler_first_lsn_t_SOURCES = ma_test_loghandler_first_lsn-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_max_lsn_t_SOURCES = ma_test_loghandler_max_lsn-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_purge_t_SOURCES = ma_test_loghandler_purge-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_readonly_t_SOURCES = ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
ma_test_loghandler_readonly_t_SOURCES = ma_test_loghandler_multigroup-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c sequence_storage.c
|
||||
ma_test_loghandler_readonly_t_CPPFLAGS = -DREADONLY_TEST
|
||||
ma_test_loghandler_nologs_t_SOURCES = ma_test_loghandler_nologs-t.c ma_maria_log_cleanup.c ma_loghandler_examples.c
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include <errno.h>
|
||||
#include <tap.h>
|
||||
#include "../trnman.h"
|
||||
#include "sequence_storage.h"
|
||||
#include <my_getopt.h>
|
||||
|
||||
extern my_bool maria_log_remove();
|
||||
extern void translog_example_table_init();
|
||||
|
@ -126,13 +128,97 @@ static my_bool read_and_check_content(TRANSLOG_HEADER_BUFFER *rec,
|
|||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
static const char *load_default_groups[]= {"ma_unit_loghandler", 0};
|
||||
#if defined(__WIN__)
|
||||
static const char *default_dbug_option= "d:t:i:O,\\ma_test_loghandler.trace";
|
||||
#else
|
||||
static const char *default_dbug_option= "d:t:i:o,/tmp/ma_test_loghandler.trace";
|
||||
#endif
|
||||
static const char *opt_wfile= NULL;
|
||||
static const char *opt_rfile= NULL;
|
||||
static struct my_option my_long_options[] =
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
{"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.",
|
||||
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
{"write-seq", 'w', "Path to file in which \"random\" sequence used in the test will be written",
|
||||
(uchar**) &opt_wfile, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"read-seq", 'r', "Path to file from which \"random\" sequence used in the test will be read",
|
||||
(uchar**) &opt_rfile, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{"help", '?', "Display this help and exit.",
|
||||
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
static SEQ_STORAGE seq;
|
||||
|
||||
static uint32 get_len()
|
||||
{
|
||||
return (uint32)
|
||||
((ulonglong)rand()*(LONG_BUFFER_SIZE - MIN_REC_LENGTH - 1)/RAND_MAX)+ MIN_REC_LENGTH;
|
||||
uint32 res;
|
||||
DBUG_ENTER("get_len");
|
||||
if (opt_rfile)
|
||||
res= seq_storage_next(&seq);
|
||||
else
|
||||
{
|
||||
res= (uint32)
|
||||
((ulonglong) rand() *
|
||||
(LONG_BUFFER_SIZE - MIN_REC_LENGTH - 1) / RAND_MAX) + MIN_REC_LENGTH;
|
||||
if (opt_wfile &&
|
||||
seq_storage_write(opt_wfile, res))
|
||||
exit(1);
|
||||
}
|
||||
DBUG_PRINT("info", ("length value : %lu", (ulong) res));
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
puts("Copyright (C) 2008 MySQL AB");
|
||||
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
|
||||
puts("and you are welcome to modify and redistribute it under the GPL license\n");
|
||||
|
||||
puts("Unit test of maria engine");
|
||||
VOID(printf("\nUsage: %s [OPTIONS]\n", my_progname_short));
|
||||
my_print_help(my_long_options);
|
||||
print_defaults("my", load_default_groups);
|
||||
my_print_variables(my_long_options);
|
||||
}
|
||||
|
||||
|
||||
static my_bool
|
||||
get_one_option(int optid __attribute__((unused)),
|
||||
const struct my_option *opt __attribute__((unused)),
|
||||
char *argument __attribute__((unused)))
|
||||
{
|
||||
switch (optid) {
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
#ifndef DBUG_OFF
|
||||
case '#':
|
||||
DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void get_options(int *argc,char ***argv)
|
||||
{
|
||||
int ho_error;
|
||||
|
||||
if ((ho_error= handle_options(argc, argv, my_long_options, get_one_option)))
|
||||
exit(ho_error);
|
||||
|
||||
if (opt_rfile && opt_wfile)
|
||||
{
|
||||
usage();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc __attribute__((unused)), char *argv[])
|
||||
{
|
||||
uint32 i;
|
||||
|
@ -146,6 +232,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
|||
0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55
|
||||
};
|
||||
uchar *long_buffer= malloc(LONG_BUFFER_SIZE + LSN_STORE_SIZE * 2 + 2);
|
||||
char **default_argv;
|
||||
PAGECACHE pagecache;
|
||||
LSN lsn, lsn_base, first_lsn;
|
||||
TRANSLOG_HEADER_BUFFER rec;
|
||||
|
@ -157,6 +244,10 @@ int main(int argc __attribute__((unused)), char *argv[])
|
|||
|
||||
bzero(&pagecache, sizeof(pagecache));
|
||||
maria_data_root= (char *)".";
|
||||
load_defaults("my", load_default_groups, &argc, &argv);
|
||||
default_argv= argv;
|
||||
get_options(&argc, &argv);
|
||||
|
||||
if (maria_log_remove())
|
||||
exit(1);
|
||||
|
||||
|
@ -171,18 +262,6 @@ int main(int argc __attribute__((unused)), char *argv[])
|
|||
}
|
||||
|
||||
bzero(long_tr_id, 6);
|
||||
#ifndef DBUG_OFF
|
||||
#if defined(__WIN__)
|
||||
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 (ma_control_file_open(TRUE))
|
||||
{
|
||||
|
@ -206,6 +285,9 @@ int main(int argc __attribute__((unused)), char *argv[])
|
|||
|
||||
plan(((ITERATIONS - 1) * 4 + 1) * 2);
|
||||
|
||||
if (opt_rfile &&
|
||||
seq_storage_reader_init(&seq, opt_rfile))
|
||||
exit(1);
|
||||
srand(122334817L);
|
||||
|
||||
long_tr_id[5]= 0xff;
|
||||
|
@ -366,6 +448,11 @@ int main(int argc __attribute__((unused)), char *argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* If we were writing sequence we need it only once */
|
||||
opt_wfile= NULL;
|
||||
if (opt_rfile)
|
||||
seq_storage_rewind(&seq);
|
||||
srand(122334817L);
|
||||
|
||||
rc= 1;
|
||||
|
@ -477,6 +564,7 @@ int main(int argc __attribute__((unused)), char *argv[])
|
|||
(uint) rec.header[22],
|
||||
LSN_IN_PARTS(rec.lsn));
|
||||
translog_free_record_header(&rec);
|
||||
DBUG_ASSERT(0);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
@ -653,6 +741,8 @@ err:
|
|||
translog_destroy();
|
||||
end_pagecache(&pagecache, 1);
|
||||
ma_control_file_end();
|
||||
free_defaults(default_argv);
|
||||
seq_storage_destroy(&seq);
|
||||
if (maria_log_remove())
|
||||
exit(1);
|
||||
|
||||
|
|
110
storage/maria/unittest/sequence_storage.c
Normal file
110
storage/maria/unittest/sequence_storage.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* Copyright (C) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "../maria_def.h"
|
||||
#include "sequence_storage.h"
|
||||
|
||||
|
||||
/**
|
||||
@brief Initializes the sequence from the sequence file.
|
||||
|
||||
@param seq Reference on the sequence storage.
|
||||
@param file Path to the file where to write the sequence
|
||||
|
||||
@retval 0 OK
|
||||
@retval 1 Error
|
||||
*/
|
||||
|
||||
my_bool seq_storage_reader_init(SEQ_STORAGE *seq, const char *file)
|
||||
{
|
||||
FILE *fd;
|
||||
seq->pos= 0;
|
||||
if ((fd= my_fopen(file, O_RDONLY, MYF(MY_WME))) == NULL)
|
||||
return 1;
|
||||
if (my_init_dynamic_array(&seq->seq, sizeof(ulong), 10, 10))
|
||||
return 1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
ulong num;
|
||||
char line[22];
|
||||
if (fgets(line, sizeof(line), fd) == NULL)
|
||||
break;
|
||||
num= atol(line);
|
||||
if (insert_dynamic(&seq->seq, (uchar*) &num))
|
||||
return 1;
|
||||
}
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Gets next number from the sequence storage
|
||||
|
||||
@param seq Reference on the sequence storage.
|
||||
|
||||
@return Next number from the sequence.
|
||||
*/
|
||||
|
||||
ulong seq_storage_next(SEQ_STORAGE *seq)
|
||||
{
|
||||
DBUG_ASSERT(seq->seq.elements > 0);
|
||||
DBUG_ASSERT(seq->pos < seq->seq.elements);
|
||||
return (*(dynamic_element(&seq->seq, seq->pos++, ulong *)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Frees resources allocated for the storage
|
||||
|
||||
@param seq Reference on the sequence storage.
|
||||
*/
|
||||
|
||||
void seq_storage_destroy(SEQ_STORAGE *seq)
|
||||
{
|
||||
delete_dynamic(&seq->seq);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@brief Starts the sequence from begining
|
||||
|
||||
@param seq Reference on the sequence storage.
|
||||
*/
|
||||
|
||||
void seq_storage_rewind(SEQ_STORAGE *seq)
|
||||
{
|
||||
seq->pos= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief Writes a number to the sequence file.
|
||||
|
||||
@param file Path to the file where to write the sequence
|
||||
@pagem num Number to be written
|
||||
|
||||
@retval 0 OK
|
||||
@retval 1 Error
|
||||
*/
|
||||
|
||||
my_bool seq_storage_write(const char *file, ulong num)
|
||||
{
|
||||
FILE *fd;
|
||||
return ((fd= my_fopen(file, O_CREAT | O_APPEND | O_WRONLY, MYF(MY_WME))) ==
|
||||
NULL ||
|
||||
fprintf(fd, "%lu\n", num) < 0 ||
|
||||
fclose(fd) != 0);
|
||||
}
|
28
storage/maria/unittest/sequence_storage.h
Normal file
28
storage/maria/unittest/sequence_storage.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (C) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
|
||||
typedef struct st_seq_storage
|
||||
{
|
||||
uint pos;
|
||||
DYNAMIC_ARRAY seq;
|
||||
} SEQ_STORAGE;
|
||||
|
||||
extern my_bool seq_storage_reader_init(SEQ_STORAGE *seq, const char *file);
|
||||
extern ulong seq_storage_next(SEQ_STORAGE *seq);
|
||||
extern void seq_storage_destroy(SEQ_STORAGE *seq);
|
||||
extern void seq_storage_rewind(SEQ_STORAGE *seq);
|
||||
extern my_bool seq_storage_write(const char *file, ulong num);
|
||||
|
Loading…
Reference in a new issue