Commit 4e0964cb authored by unknown's avatar unknown

Fixed repair_by_sort to work with BLOCK_RECORD

Fixed bugs in undo logging
Fixed bug where head block was split before min_row_length (caused Maria to believe row was crashed on read)
Reserved place for reference-transid on key pages (for packing of transids)
ALTER TABLE and INSERT ... SELECT now uses fast creation of index
    
Known bugs:
ma_test_recovery fails because of a bug in redo handling when log is cut directly after a redo (Guilhem knows how to fix)
ma_test_recovery.excepted is not totally correct, because of the above bug
mysqld sometimes fails to restart; Fails with error "end_of_redo_phase: Assertion `long_trid != 0' failed"; Guilhem to investigate


include/maria.h:
  Prototype changes
  Added current_filepos to st_maria_sort_info
mysql-test/r/maria.result:
  Updated results that changes as alter table and insert ... select now uses fast creation of index
mysys/mf_iocache.c:
  Reset variable to gurard against double invocation
storage/maria/ma_bitmap.c:
  Added _ma_bitmap_reset_cache() (needed for repair)
storage/maria/ma_blockrec.c:
  Simplify code
  More initial allocations
  Fixed bug where head block was split before min_row_length (caused Maria to believe row was crashed on read)
storage/maria/ma_blockrec.h:
  Moved TRANSID_SIZE to maria_def.h
  Added prototype for new functions
storage/maria/ma_check.c:
  Simplicy code
  Fixed repair_by_sort to work with BLOCK_RECORD
  - When using BLOCK_RECORD or UNPACK create new Maria handle
  - Use common initializer function
  - Align code with maria_repair()
  
  Made some changes to maria_repair_parallel() to use common initializer function
  Removed ASK_MONTY section by fixing noted problem
storage/maria/ma_close.c:
  Moved check for readonly to _ma_state_info_write()
storage/maria/ma_key_recover.c:
  Use different log entries if key root changes or not.
  This fixed some bugs when tree grows
storage/maria/ma_key_recover.h:
  Added keynr to st_msg_to_write_hook_for_undo_key
storage/maria/ma_loghandler.c:
  Added INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT
storage/maria/ma_loghandler.h:
  Added INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT
storage/maria/ma_open.c:
  Added TRANSID to all key pages (for future compressing of trans id's)
  For compressed records, alloc a bit bigger buffer to avoid valgrind warnings
  If table is opened readonly, don't update state
storage/maria/ma_packrec.c:
  Allocate bigger array for bit unpacking to avoid valgrind errors
storage/maria/ma_recovery.c:
  Added UNDO_KEY_INSERT_WITH_ROOT & UNDO_KEY_DELETE_WITH_ROOT
storage/maria/ma_sort.c:
  More logging
storage/maria/ma_test_all.sh:
  More tests
storage/maria/ma_test_recovery.expected:
  Update results
  Note that this is not complete becasue of a bug in recovery
storage/maria/ma_test_recovery:
  Removed recreation of index (not needed when we have redo for index pages)
storage/maria/maria_chk.c:
  When using flag --read-only, don't update status for files
  When using --unpack, don't use REPAIR_BY_SORT if other repair option is given
  Enable repair_by_sort for BLOCK records
  Removed not needed newline at start of --describe
storage/maria/maria_def.h:
  Support for TRANSID_SIZE to key pages
storage/maria/maria_read_log.c:
  renamed --only-display to --display-only
parent 63cd7bdc
...@@ -370,7 +370,7 @@ typedef struct st_maria_sort_param ...@@ -370,7 +370,7 @@ typedef struct st_maria_sort_param
ulonglong unique[HA_MAX_KEY_SEG+1]; ulonglong unique[HA_MAX_KEY_SEG+1];
ulonglong notnull[HA_MAX_KEY_SEG+1]; ulonglong notnull[HA_MAX_KEY_SEG+1];
MARIA_RECORD_POS pos,max_pos,filepos,start_recpos; MARIA_RECORD_POS pos,max_pos,filepos,start_recpos, current_filepos;
uint key, key_length,real_key_length,sortbuff_size; uint key, key_length,real_key_length,sortbuff_size;
uint maxbuffers, keys, find_length, sort_keys_length; uint maxbuffers, keys, find_length, sort_keys_length;
my_bool fix_datafile, master; my_bool fix_datafile, master;
...@@ -392,18 +392,16 @@ typedef struct st_maria_sort_param ...@@ -392,18 +392,16 @@ typedef struct st_maria_sort_param
/* functions in maria_check */ /* functions in maria_check */
void maria_chk_init(HA_CHECK *param); void maria_chk_init(HA_CHECK *param);
int maria_chk_status(HA_CHECK *param, MARIA_HA *info); int maria_chk_status(HA_CHECK *param, MARIA_HA *info);
int maria_chk_del(HA_CHECK *param, register MARIA_HA *info, uint test_flag); int maria_chk_del(HA_CHECK *param, MARIA_HA *info, uint test_flag);
int maria_chk_size(HA_CHECK *param, MARIA_HA *info); int maria_chk_size(HA_CHECK *param, MARIA_HA *info);
int maria_chk_key(HA_CHECK *param, MARIA_HA *info); int maria_chk_key(HA_CHECK *param, MARIA_HA *info);
int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, int extend); int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, int extend);
int maria_repair(HA_CHECK *param, register MARIA_HA *info, int maria_repair(HA_CHECK *param, MARIA_HA *info, char * name, uint rep_quick);
char * name, int rep_quick); int maria_sort_index(HA_CHECK *param, MARIA_HA *info, char * name);
int maria_sort_index(HA_CHECK *param, register MARIA_HA *info, int maria_repair_by_sort(HA_CHECK *param, MARIA_HA *info,
char * name); const char *name, uint rep_quick);
int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
const char *name, int rep_quick);
int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
const char *name, int rep_quick); const char *name, uint rep_quick);
int maria_change_to_newfile(const char *filename, const char *old_ext, int maria_change_to_newfile(const char *filename, const char *old_ext,
const char *new_ext, myf myflags); const char *new_ext, myf myflags);
void maria_lock_memory(HA_CHECK *param); void maria_lock_memory(HA_CHECK *param);
......
...@@ -625,7 +625,7 @@ t1 1 a 1 a A NULL NULL NULL YES BTREE disabled ...@@ -625,7 +625,7 @@ t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
alter table t1 enable keys; alter table t1 enable keys;
show keys from t1; show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 1 a 1 a A NULL NULL NULL YES BTREE t1 1 a 1 a A 1000 NULL NULL YES BTREE
alter table t1 engine=heap; alter table t1 engine=heap;
alter table t1 disable keys; alter table t1 disable keys;
Warnings: Warnings:
...@@ -1957,12 +1957,12 @@ create table t2 like t1; ...@@ -1957,12 +1957,12 @@ create table t2 like t1;
insert into t2 select * from t1; insert into t2 select * from t1;
analyze table t2; analyze table t2;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t2 analyze status OK test.t2 analyze status Table is already up to date
delete from t2; delete from t2;
insert into t2 select * from t1; insert into t2 select * from t1;
analyze table t2; analyze table t2;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t2 analyze status OK test.t2 analyze status Table is already up to date
drop table t1,t2; drop table t1,t2;
create table t1 (a bigint auto_increment, primary key(a), b char(255), c varchar(20000)); create table t1 (a bigint auto_increment, primary key(a), b char(255), c varchar(20000));
update t1 set b=repeat('a',100) where a between 1 and 100; update t1 set b=repeat('a',100) where a between 1 and 100;
......
...@@ -1834,6 +1834,7 @@ int end_io_cache(IO_CACHE *info) ...@@ -1834,6 +1834,7 @@ int end_io_cache(IO_CACHE *info)
pthread_mutex_destroy(&info->append_buffer_lock); pthread_mutex_destroy(&info->append_buffer_lock);
#endif #endif
} }
info->share= 0;
DBUG_RETURN(error); DBUG_RETURN(error);
} /* end_io_cache */ } /* end_io_cache */
......
...@@ -124,9 +124,6 @@ ...@@ -124,9 +124,6 @@
#include "maria_def.h" #include "maria_def.h"
#include "ma_blockrec.h" #include "ma_blockrec.h"
/* Number of pages to store blob parts */
#define BLOB_SEGMENT_MIN_SIZE 128
#define FULL_HEAD_PAGE 4 #define FULL_HEAD_PAGE 4
#define FULL_TAIL_PAGE 7 #define FULL_TAIL_PAGE 7
...@@ -187,7 +184,6 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file) ...@@ -187,7 +184,6 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
return 1; return 1;
bitmap->file.file= file; bitmap->file.file= file;
bitmap->changed= 0;
bitmap->block_size= share->block_size; bitmap->block_size= share->block_size;
/* Size needs to be alligned on 6 */ /* Size needs to be alligned on 6 */
aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6; aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6;
...@@ -212,18 +208,8 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file) ...@@ -212,18 +208,8 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
pthread_mutex_init(&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW); pthread_mutex_init(&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW);
/* _ma_bitmap_reset_cache(share);
We can't read a page yet, as in some case we don't have an active
page cache yet.
Pretend we have a dummy, full and not changed bitmap page in memory.
*/
bitmap->page= ~(ulonglong) 0;
bitmap->used_size= bitmap->total_size;
bfill(bitmap->map, share->block_size, 255);
#ifndef DBUG_OFF
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
#endif
if (share->state.first_bitmap_with_space == ~(ulonglong) 0) if (share->state.first_bitmap_with_space == ~(ulonglong) 0)
{ {
/* Start scanning for free space from start of file */ /* Start scanning for free space from start of file */
...@@ -313,6 +299,41 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share) ...@@ -313,6 +299,41 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share)
} }
/**
@brief Reset bitmap caches
@fn _ma_bitmap_reset_cache()
@param share Maria share
@notes
This is called after we have swapped file descriptors and we want
bitmap to forget all cached information
*/
void _ma_bitmap_reset_cache(MARIA_SHARE *share)
{
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
if (bitmap->map) /* If using bitmap */
{
/* Forget changes in current bitmap page */
bitmap->changed= 0;
/*
We can't read a page yet, as in some case we don't have an active
page cache yet.
Pretend we have a dummy, full and not changed bitmap page in memory.
*/
bitmap->page= ~(ulonglong) 0;
bitmap->used_size= bitmap->total_size;
bfill(bitmap->map, share->block_size, 255);
#ifndef DBUG_OFF
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
#endif
}
}
/* /*
Return bitmap pattern for the smallest head block that can hold 'size' Return bitmap pattern for the smallest head block that can hold 'size'
...@@ -1630,7 +1651,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row, ...@@ -1630,7 +1651,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
{ {
MARIA_SHARE *share= info->s; MARIA_SHARE *share= info->s;
my_bool res= 1; my_bool res= 1;
uint full_page_size, position; uint position;
uint head_length, row_length, rest_length, extents_length; uint head_length, row_length, rest_length, extents_length;
ulonglong bitmap_page; ulonglong bitmap_page;
DBUG_ENTER("_ma_bitmap_find_new_place"); DBUG_ENTER("_ma_bitmap_find_new_place");
...@@ -1670,9 +1691,8 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row, ...@@ -1670,9 +1691,8 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
/* The first segment size is stored in 'row_length' */ /* The first segment size is stored in 'row_length' */
row_length= find_where_to_split_row(share, row, extents_length, free_size); row_length= find_where_to_split_row(share, row, extents_length, free_size);
full_page_size= FULL_PAGE_SIZE(share->block_size);
position= 0; position= 0;
if (head_length - row_length <= full_page_size) if (head_length - row_length < MAX_TAIL_SIZE(share->block_size))
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */ position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
use_head(info, page, row_length, position); use_head(info, page, row_length, position);
rest_length= head_length - row_length; rest_length= head_length - row_length;
......
...@@ -456,6 +456,7 @@ my_bool _ma_once_end_block_record(MARIA_SHARE *share) ...@@ -456,6 +456,7 @@ my_bool _ma_once_end_block_record(MARIA_SHARE *share)
my_bool _ma_init_block_record(MARIA_HA *info) my_bool _ma_init_block_record(MARIA_HA *info)
{ {
MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row; MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row;
uint default_extents;
DBUG_ENTER("_ma_init_block_record"); DBUG_ENTER("_ma_init_block_record");
if (!my_multi_malloc(MY_WME, if (!my_multi_malloc(MY_WME,
...@@ -490,17 +491,27 @@ my_bool _ma_init_block_record(MARIA_HA *info) ...@@ -490,17 +491,27 @@ my_bool _ma_init_block_record(MARIA_HA *info)
/* Skip over bytes used to store length of field length for logging */ /* Skip over bytes used to store length of field length for logging */
row->field_lengths+= 2; row->field_lengths+= 2;
new_row->field_lengths+= 2; new_row->field_lengths+= 2;
/* Reserve some initial space to avoid mallocs during execution */
default_extents= (ELEMENTS_RESERVED_FOR_MAIN_PART + 1 +
(AVERAGE_BLOB_SIZE /
FULL_PAGE_SIZE(info->s->block_size) /
BLOB_SEGMENT_MIN_SIZE));
if (my_init_dynamic_array(&info->bitmap_blocks, if (my_init_dynamic_array(&info->bitmap_blocks,
sizeof(MARIA_BITMAP_BLOCK), sizeof(MARIA_BITMAP_BLOCK), default_extents,
ELEMENTS_RESERVED_FOR_MAIN_PART, 16)) 64))
goto err; goto err;
if (!(info->cur_row.extents= my_malloc(default_extents * ROW_EXTENT_SIZE,
MYF(MY_WME))))
goto err;
row->base_length= new_row->base_length= info->s->base_length; row->base_length= new_row->base_length= info->s->base_length;
/* /*
We need to reserve 'EXTRA_LENGTH_FIELDS' number of parts in We need to reserve 'EXTRA_LENGTH_FIELDS' number of parts in
null_field_lengths to allow splitting of rows in 'find_where_to_split_row' null_field_lengths to allow splitting of rows in 'find_where_to_split_row'
*/ */
row->null_field_lengths+= EXTRA_LENGTH_FIELDS; row->null_field_lengths+= EXTRA_LENGTH_FIELDS;
new_row->null_field_lengths+= EXTRA_LENGTH_FIELDS; new_row->null_field_lengths+= EXTRA_LENGTH_FIELDS;
...@@ -3697,7 +3708,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, ...@@ -3697,7 +3708,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
column < end_column; column++) column < end_column; column++)
{ {
uint column_length= column->length; uint column_length= column->length;
if (data >= end_of_data && if (data + column_length > end_of_data &&
!(data= read_next_extent(info, &extent, &end_of_data))) !(data= read_next_extent(info, &extent, &end_of_data)))
goto err; goto err;
memcpy(record + column->offset, data, column_length); memcpy(record + column->offset, data, column_length);
...@@ -3731,7 +3742,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record, ...@@ -3731,7 +3742,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
case FIELD_NORMAL: /* Fixed length field */ case FIELD_NORMAL: /* Fixed length field */
case FIELD_SKIP_PRESPACE: case FIELD_SKIP_PRESPACE:
case FIELD_SKIP_ZERO: /* Fixed length field */ case FIELD_SKIP_ZERO: /* Fixed length field */
if (data >= end_of_data && if (data + column->length > end_of_data &&
!(data= read_next_extent(info, &extent, &end_of_data))) !(data= read_next_extent(info, &extent, &end_of_data)))
goto err; goto err;
memcpy(field_pos, data, column->length); memcpy(field_pos, data, column->length);
...@@ -4991,6 +5002,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, ...@@ -4991,6 +5002,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
MARIA_PINNED_PAGE page_link; MARIA_PINNED_PAGE page_link;
enum pagecache_page_lock unlock_method; enum pagecache_page_lock unlock_method;
enum pagecache_page_pin unpin_method; enum pagecache_page_pin unpin_method;
my_off_t end_of_page;
DBUG_ENTER("_ma_apply_redo_insert_row_head_or_tail"); DBUG_ENTER("_ma_apply_redo_insert_row_head_or_tail");
page= page_korr(header); page= page_korr(header);
...@@ -5000,8 +5012,12 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, ...@@ -5000,8 +5012,12 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
(ulong) ma_recordpos(page, rownr), (ulong) ma_recordpos(page, rownr),
(ulong) page, rownr, (uint) data_length)); (ulong) page, rownr, (uint) data_length));
if (((page + 1) * info->s->block_size) > info->state->data_file_length) end_of_page= (page + 1) * info->s->block_size;
if (end_of_page > info->state->data_file_length)
{ {
DBUG_PRINT("info", ("Enlarging data file from %lu to %lu",
(ulong) info->state->data_file_length,
(ulong) end_of_page));
/* /*
New page at end of file. Note that the test above is also positive if New page at end of file. Note that the test above is also positive if
data_file_length is not a multiple of block_size (system crashed while data_file_length is not a multiple of block_size (system crashed while
...@@ -5153,11 +5169,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, ...@@ -5153,11 +5169,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
case we extended the file. We could not do it earlier: bitmap code tests case we extended the file. We could not do it earlier: bitmap code tests
data_file_length to know if it has to create a new page or not. data_file_length to know if it has to create a new page or not.
*/ */
{ set_if_bigger(info->state->data_file_length, end_of_page);
my_off_t end_of_page= (page + 1) * info->s->block_size;
set_if_bigger(info->state->data_file_length, end_of_page);
}
DBUG_RETURN(result); DBUG_RETURN(result);
err: err:
......
...@@ -29,8 +29,8 @@ ...@@ -29,8 +29,8 @@
PAGE_SUFFIX_SIZE) PAGE_SUFFIX_SIZE)
#define BLOCK_RECORD_POINTER_SIZE 6 #define BLOCK_RECORD_POINTER_SIZE 6
#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - PAGE_TYPE_SIZE - \ #define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - \
PAGE_SUFFIX_SIZE) PAGE_TYPE_SIZE - PAGE_SUFFIX_SIZE)
#define ROW_EXTENT_PAGE_SIZE 5 #define ROW_EXTENT_PAGE_SIZE 5
#define ROW_EXTENT_COUNT_SIZE 2 #define ROW_EXTENT_COUNT_SIZE 2
...@@ -40,12 +40,16 @@ ...@@ -40,12 +40,16 @@
#define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */ #define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */
/* Number of extents reserved MARIA_BITMAP_BLOCKS to store head part */ /* Number of extents reserved MARIA_BITMAP_BLOCKS to store head part */
#define ELEMENTS_RESERVED_FOR_MAIN_PART 4 #define ELEMENTS_RESERVED_FOR_MAIN_PART 4
/* This is just used to prealloc a dynamic array */
#define AVERAGE_BLOB_SIZE 1024L*1024L
/* Number of pages to store continuous blob parts */
#define BLOB_SEGMENT_MIN_SIZE 128
/* Fields before 'row->null_field_lengths' used by find_where_to_split_row */ /* Fields before 'row->null_field_lengths' used by find_where_to_split_row */
#define EXTRA_LENGTH_FIELDS 3 #define EXTRA_LENGTH_FIELDS 3
/* Size for the different parts in the row header (and head page) */ /* Size for the different parts in the row header (and head page) */
#define FLAG_SIZE 1 #define FLAG_SIZE 1
#define TRANSID_SIZE 6
#define VERPTR_SIZE 7 #define VERPTR_SIZE 7
#define DIR_ENTRY_SIZE 4 #define DIR_ENTRY_SIZE 4
#define FIELD_OFFSET_SIZE 2 /* size of pointers to field starts */ #define FIELD_OFFSET_SIZE 2 /* size of pointers to field starts */
...@@ -167,6 +171,7 @@ my_bool _ma_compare_block_record(register MARIA_HA *info, ...@@ -167,6 +171,7 @@ my_bool _ma_compare_block_record(register MARIA_HA *info,
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file); my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
my_bool _ma_bitmap_end(MARIA_SHARE *share); my_bool _ma_bitmap_end(MARIA_SHARE *share);
my_bool _ma_flush_bitmap(MARIA_SHARE *share); my_bool _ma_flush_bitmap(MARIA_SHARE *share);
void _ma_bitmap_reset_cache(MARIA_SHARE *share);
my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row, my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
MARIA_BITMAP_BLOCKS *result_blocks); MARIA_BITMAP_BLOCKS *result_blocks);
my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks); my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks);
......
This diff is collapsed.
...@@ -86,8 +86,7 @@ int maria_close(register MARIA_HA *info) ...@@ -86,8 +86,7 @@ int maria_close(register MARIA_HA *info)
may be using the file at this point may be using the file at this point
IF using --external-locking, which does not apply to Maria. IF using --external-locking, which does not apply to Maria.
*/ */
if (share->mode != O_RDONLY && if (((share->changed && share->base.born_transactional) ||
((share->changed && share->base.born_transactional) ||
maria_is_crashed(info))) maria_is_crashed(info)))
{ {
/* /*
......
...@@ -73,7 +73,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn, ...@@ -73,7 +73,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
LSN *res_lsn, void *extra_msg) LSN *res_lsn, void *extra_msg)
{ {
uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + CLR_TYPE_STORE_SIZE + uchar log_data[LSN_STORE_SIZE + FILEID_STORE_SIZE + CLR_TYPE_STORE_SIZE +
HA_CHECKSUM_STORE_SIZE]; HA_CHECKSUM_STORE_SIZE+ KEY_NR_STORE_SIZE + PAGE_STORE_SIZE];
uchar *log_pos;
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1]; LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
struct st_msg_to_write_hook_for_clr_end msg; struct st_msg_to_write_hook_for_clr_end msg;
my_bool res; my_bool res;
...@@ -81,10 +82,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn, ...@@ -81,10 +82,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
/* undo_lsn must be first for compression to work */ /* undo_lsn must be first for compression to work */
lsn_store(log_data, undo_lsn); lsn_store(log_data, undo_lsn);
clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE, clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE, undo_type);
undo_type); log_pos= log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + CLR_TYPE_STORE_SIZE;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
/* Extra_msg is handled in write_hook_for_clr_end() */ /* Extra_msg is handled in write_hook_for_clr_end() */
msg.undone_record_type= undo_type; msg.undone_record_type= undo_type;
...@@ -95,11 +94,24 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn, ...@@ -95,11 +94,24 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
if (store_checksum) if (store_checksum)
{ {
msg.checksum_delta= checksum; msg.checksum_delta= checksum;
ha_checksum_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + ha_checksum_store(log_pos, checksum);
CLR_TYPE_STORE_SIZE, checksum); log_pos+= HA_CHECKSUM_STORE_SIZE;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
} }
else if (undo_type == LOGREC_UNDO_KEY_INSERT_WITH_ROOT ||
undo_type == LOGREC_UNDO_KEY_DELETE_WITH_ROOT)
{
/* Key root changed. Store new key root */
struct st_msg_to_write_hook_for_undo_key *undo_msg= extra_msg;
ulonglong page;
key_nr_store(log_pos, undo_msg->keynr);
page= (undo_msg->value == HA_OFFSET_ERROR ? IMPOSSIBLE_PAGE_NO :
undo_msg->value / info->s->block_size);
page_store(log_pos + KEY_NR_STORE_SIZE, page);
log_pos+= KEY_NR_STORE_SIZE + PAGE_STORE_SIZE;
}
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data; log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= (uint) (log_pos - log_data);
res= translog_write_record(res_lsn, LOGREC_CLR_END, res= translog_write_record(res_lsn, LOGREC_CLR_END,
info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS
...@@ -141,8 +153,8 @@ my_bool write_hook_for_clr_end(enum translog_record_type type ...@@ -141,8 +153,8 @@ my_bool write_hook_for_clr_end(enum translog_record_type type
case LOGREC_UNDO_ROW_UPDATE: case LOGREC_UNDO_ROW_UPDATE:
share->state.state.checksum+= msg->checksum_delta; share->state.state.checksum+= msg->checksum_delta;
break; break;
case LOGREC_UNDO_KEY_INSERT: case LOGREC_UNDO_KEY_INSERT_WITH_ROOT:
case LOGREC_UNDO_KEY_DELETE: case LOGREC_UNDO_KEY_DELETE_WITH_ROOT:
{ {
/* Update key root */ /* Update key root */
struct st_msg_to_write_hook_for_undo_key *extra_msg= struct st_msg_to_write_hook_for_undo_key *extra_msg=
...@@ -150,6 +162,9 @@ my_bool write_hook_for_clr_end(enum translog_record_type type ...@@ -150,6 +162,9 @@ my_bool write_hook_for_clr_end(enum translog_record_type type
*extra_msg->root= extra_msg->value; *extra_msg->root= extra_msg->value;
break; break;
} }
case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE:
break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
...@@ -812,9 +827,11 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn, ...@@ -812,9 +827,11 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn,
msg.root= &share->state.key_root[keynr]; msg.root= &share->state.key_root[keynr];
msg.value= new_root; msg.value= new_root;
msg.keynr= keynr;
if (_ma_write_clr(info, undo_lsn, LOGREC_UNDO_KEY_INSERT, 1, 0, &lsn, if (_ma_write_clr(info, undo_lsn, *msg.root == msg.value ?
(void*) &msg)) LOGREC_UNDO_KEY_INSERT : LOGREC_UNDO_KEY_INSERT_WITH_ROOT,
0, 0, &lsn, (void*) &msg))
res= 1; res= 1;
_ma_unpin_all_pages_and_finalize_row(info, lsn); _ma_unpin_all_pages_and_finalize_row(info, lsn);
...@@ -855,7 +872,11 @@ my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn, ...@@ -855,7 +872,11 @@ my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
msg.root= &share->state.key_root[keynr]; msg.root= &share->state.key_root[keynr];
msg.value= new_root; msg.value= new_root;
if (_ma_write_clr(info, undo_lsn, LOGREC_UNDO_KEY_DELETE, 1, 0, &lsn, msg.keynr= keynr;
if (_ma_write_clr(info, undo_lsn,
*msg.root == msg.value ?
LOGREC_UNDO_KEY_DELETE : LOGREC_UNDO_KEY_DELETE_WITH_ROOT,
0, 0, &lsn,
(void*) &msg)) (void*) &msg))
res= 1; res= 1;
......
...@@ -35,6 +35,7 @@ struct st_msg_to_write_hook_for_undo_key ...@@ -35,6 +35,7 @@ struct st_msg_to_write_hook_for_undo_key
{ {
my_off_t *root; my_off_t *root;
my_off_t value; my_off_t value;
uint keynr;
}; };
......
...@@ -490,6 +490,13 @@ static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT= ...@@ -490,6 +490,13 @@ static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT=
NULL, write_hook_for_undo_key, NULL, 1, NULL, write_hook_for_undo_key, NULL, 1,
"undo_key_insert", LOGREC_LAST_IN_GROUP, NULL, NULL}; "undo_key_insert", LOGREC_LAST_IN_GROUP, NULL, NULL};
/* This will never be in the log, only in the clr */
static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE + PAGE_STORE_SIZE,
NULL, write_hook_for_undo_key, NULL, 1,
"undo_key_insert_with_root", LOGREC_LAST_IN_GROUP, NULL, NULL};
static LOG_DESC INIT_LOGREC_UNDO_KEY_DELETE= static LOG_DESC INIT_LOGREC_UNDO_KEY_DELETE=
{LOGRECTYPE_VARIABLE_LENGTH, 0, {LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE, LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE,
...@@ -605,6 +612,8 @@ static void loghandler_init() ...@@ -605,6 +612,8 @@ static void loghandler_init()
INIT_LOGREC_UNDO_ROW_UPDATE; INIT_LOGREC_UNDO_ROW_UPDATE;
log_record_type_descriptor[LOGREC_UNDO_KEY_INSERT]= log_record_type_descriptor[LOGREC_UNDO_KEY_INSERT]=
INIT_LOGREC_UNDO_KEY_INSERT; INIT_LOGREC_UNDO_KEY_INSERT;
log_record_type_descriptor[LOGREC_UNDO_KEY_INSERT_WITH_ROOT]=
INIT_LOGREC_UNDO_KEY_INSERT_WITH_ROOT;
log_record_type_descriptor[LOGREC_UNDO_KEY_DELETE]= log_record_type_descriptor[LOGREC_UNDO_KEY_DELETE]=
INIT_LOGREC_UNDO_KEY_DELETE; INIT_LOGREC_UNDO_KEY_DELETE;
log_record_type_descriptor[LOGREC_UNDO_KEY_DELETE_WITH_ROOT]= log_record_type_descriptor[LOGREC_UNDO_KEY_DELETE_WITH_ROOT]=
......
...@@ -123,6 +123,7 @@ enum translog_record_type ...@@ -123,6 +123,7 @@ enum translog_record_type
LOGREC_UNDO_ROW_DELETE, LOGREC_UNDO_ROW_DELETE,
LOGREC_UNDO_ROW_UPDATE, LOGREC_UNDO_ROW_UPDATE,
LOGREC_UNDO_KEY_INSERT, LOGREC_UNDO_KEY_INSERT,
LOGREC_UNDO_KEY_INSERT_WITH_ROOT,
LOGREC_UNDO_KEY_DELETE, LOGREC_UNDO_KEY_DELETE,
LOGREC_UNDO_KEY_DELETE_WITH_ROOT, LOGREC_UNDO_KEY_DELETE_WITH_ROOT,
LOGREC_PREPARE, LOGREC_PREPARE,
......
...@@ -613,7 +613,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -613,7 +613,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->base.null_bytes + share->base.null_bytes +
share->base.pack_bytes + share->base.pack_bytes +
test(share->options & HA_OPTION_CHECKSUM)); test(share->options & HA_OPTION_CHECKSUM));
share->keypage_header= ((share->base.born_transactional ? LSN_STORE_SIZE : share->keypage_header= ((share->base.born_transactional ?
LSN_STORE_SIZE + TRANSID_SIZE :
0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + 0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE +
KEYPAGE_USED_SIZE); KEYPAGE_USED_SIZE);
...@@ -672,6 +673,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -672,6 +673,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
MARIA_REC_BUFF_OFFSET); MARIA_REC_BUFF_OFFSET);
share->base.default_rec_buff_size+= share->base.extra_rec_buff_size; share->base.default_rec_buff_size+= share->base.extra_rec_buff_size;
} }
if (share->data_file_type == COMPRESSED_RECORD)
{
/* Need some extra bytes for decode_bytes */
share->base.extra_rec_buff_size= 7;
}
disk_pos_assert(disk_pos + share->base.fields *MARIA_COLUMNDEF_SIZE, disk_pos_assert(disk_pos + share->base.fields *MARIA_COLUMNDEF_SIZE,
end_pos); end_pos);
for (i= j= 0 ; i < share->base.fields ; i++) for (i= j= 0 ; i < share->base.fields ; i++)
...@@ -1042,6 +1048,9 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo) ...@@ -1042,6 +1048,9 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite) uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
{ {
uint res; uint res;
if (share->options & HA_OPTION_READ_ONLY_DATA)
return 0;
if (pWrite & 4) if (pWrite & 4)
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);
else if (maria_multi_threaded) else if (maria_multi_threaded)
...@@ -1091,7 +1100,7 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite) ...@@ -1091,7 +1100,7 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite)
uchar *ptr=buff; uchar *ptr=buff;
uint i, keys= (uint) state->header.keys; uint i, keys= (uint) state->header.keys;
size_t res; size_t res;
DBUG_ENTER("_ma_state_info_write"); DBUG_ENTER("_ma_state_info_write_sub");
memcpy_fixed(ptr,&state->header,sizeof(state->header)); memcpy_fixed(ptr,&state->header,sizeof(state->header));
ptr+=sizeof(state->header); ptr+=sizeof(state->header);
......
...@@ -44,7 +44,9 @@ ...@@ -44,7 +44,9 @@
{ bits-=(bit+1); break; } \ { bits-=(bit+1); break; } \
pos+= *pos pos+= *pos
/* Size in uint16 of a Huffman tree for uchar compression of 256 uchar values. */ /*
Size in uint16 of a Huffman tree for uchar compression of 256 uchar values
*/
#define OFFSET_TABLE_SIZE 512 #define OFFSET_TABLE_SIZE 512
static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file, static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
...@@ -245,7 +247,8 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file, ...@@ -245,7 +247,8 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
length=(uint) (elements*2+trees*(1 << maria_quick_table_bits)); length=(uint) (elements*2+trees*(1 << maria_quick_table_bits));
if (!(share->decode_tables=(uint16*) if (!(share->decode_tables=(uint16*)
my_malloc((length+OFFSET_TABLE_SIZE)*sizeof(uint16)+ my_malloc((length+OFFSET_TABLE_SIZE)*sizeof(uint16)+
(uint) (share->pack.header_length - sizeof(header)), (uint) (share->pack.header_length - sizeof(header)) +
share->base.extra_rec_buff_size,
MYF(MY_WME | MY_ZEROFILL)))) MYF(MY_WME | MY_ZEROFILL))))
goto err1; goto err1;
tmp_buff=share->decode_tables+length; tmp_buff=share->decode_tables+length;
...@@ -255,6 +258,11 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file, ...@@ -255,6 +258,11 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
(uint) (share->pack.header_length-sizeof(header)), (uint) (share->pack.header_length-sizeof(header)),
MYF(MY_NABP))) MYF(MY_NABP)))
goto err2; goto err2;
#ifdef HAVE_purify
/* Zero bytes accessed by fill_buffer */
bzero(disk_cache + (share->pack.header_length-sizeof(header)),
share->base.extra_rec_buff_size);
#endif
huff_tree_bits=max_bit(trees ? trees-1 : 0); huff_tree_bits=max_bit(trees ? trees-1 : 0);
init_bit_buffer(&bit_buff, disk_cache, init_bit_buffer(&bit_buff, disk_cache,
......
...@@ -1147,7 +1147,7 @@ static int new_table(uint16 sid, const char *name, ...@@ -1147,7 +1147,7 @@ static int new_table(uint16 sid, const char *name,
tprint(tracef, ", has wrong state.key_file_length (fixing it)"); tprint(tracef, ", has wrong state.key_file_length (fixing it)");
share->state.state.key_file_length= kfile_len; share->state.state.key_file_length= kfile_len;
} }
if ((dfile_len % share->block_size) > 0) if ((dfile_len % share->block_size) || (kfile_len % share->block_size))
{ {
tprint(tracef, ", has too short last page\n"); tprint(tracef, ", has too short last page\n");
/* Recovery will fix this, no error */ /* Recovery will fix this, no error */
...@@ -1669,9 +1669,10 @@ prototype_redo_exec_hook(CLR_END) ...@@ -1669,9 +1669,10 @@ prototype_redo_exec_hook(CLR_END)
enum translog_record_type undone_record_type; enum translog_record_type undone_record_type;
const LOG_DESC *log_desc; const LOG_DESC *log_desc;
my_bool row_entry= 0; my_bool row_entry= 0;
DBUG_ENTER("exec_REDO_LOGREC_CLR_END");
if (info == NULL) if (info == NULL)
return 0; DBUG_RETURN(0);
share= info->s; share= info->s;
previous_undo_lsn= lsn_korr(rec->header); previous_undo_lsn= lsn_korr(rec->header);
undone_record_type= undone_record_type=
...@@ -1699,6 +1700,28 @@ prototype_redo_exec_hook(CLR_END) ...@@ -1699,6 +1700,28 @@ prototype_redo_exec_hook(CLR_END)
case LOGREC_UNDO_KEY_INSERT: case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE: case LOGREC_UNDO_KEY_DELETE:
break; break;
case LOGREC_UNDO_KEY_INSERT_WITH_ROOT:
case LOGREC_UNDO_KEY_DELETE_WITH_ROOT:
{
uint key_nr;
my_off_t page;
uchar buff[KEY_NR_STORE_SIZE + PAGE_STORE_SIZE];
if (translog_read_record(rec->lsn, LSN_STORE_SIZE + FILEID_STORE_SIZE +
CLR_TYPE_STORE_SIZE,
KEY_NR_STORE_SIZE + PAGE_STORE_SIZE,
buff, NULL) !=
KEY_NR_STORE_SIZE + PAGE_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
DBUG_RETURN(1);
}
key_nr= key_nr_korr(buff);
page= page_korr(buff + KEY_NR_STORE_SIZE);
share->state.key_root[key_nr]= (page == IMPOSSIBLE_PAGE_NO ?
HA_OFFSET_ERROR :
page * share->block_size);
break;
}
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
...@@ -1710,7 +1733,7 @@ prototype_redo_exec_hook(CLR_END) ...@@ -1710,7 +1733,7 @@ prototype_redo_exec_hook(CLR_END)
buff, NULL) != HA_CHECKSUM_STORE_SIZE) buff, NULL) != HA_CHECKSUM_STORE_SIZE)
{ {
tprint(tracef, "Failed to read record\n"); tprint(tracef, "Failed to read record\n");
return 1; DBUG_RETURN(1);
} }
share->state.state.checksum+= ha_checksum_korr(buff); share->state.state.checksum+= ha_checksum_korr(buff);
} }
...@@ -1719,7 +1742,7 @@ prototype_redo_exec_hook(CLR_END) ...@@ -1719,7 +1742,7 @@ prototype_redo_exec_hook(CLR_END)
if (row_entry) if (row_entry)
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records); tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
_ma_unpin_all_pages(info, rec->lsn); _ma_unpin_all_pages(info, rec->lsn);
return 0; DBUG_RETURN(0);
} }
......
...@@ -110,7 +110,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages, ...@@ -110,7 +110,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
uchar **sort_keys; uchar **sort_keys;
IO_CACHE tempfile, tempfile_for_exceptions; IO_CACHE tempfile, tempfile_for_exceptions;
DBUG_ENTER("_ma_create_index_by_sort"); DBUG_ENTER("_ma_create_index_by_sort");
DBUG_PRINT("enter",("sort_length: %d", info->key_length)); DBUG_PRINT("enter",("sort_buff_size: %lu sort_length: %d max_records: %lu",
(ulong) sortbuff_size, info->key_length,
(ulong) info->sort_info->max_records));
if (info->keyinfo->flag & HA_VAR_LENGTH_KEY) if (info->keyinfo->flag & HA_VAR_LENGTH_KEY)
{ {
......
...@@ -169,6 +169,11 @@ run_pack_tests() ...@@ -169,6 +169,11 @@ run_pack_tests()
$maria_path/maria_chk$suffix -rus test1 $maria_path/maria_chk$suffix -rus test1
$maria_path/maria_chk$suffix -es test1 $maria_path/maria_chk$suffix -es test1
$maria_path/ma_test1$suffix $silent --checksum $row_type
$maria_path/maria_pack$suffix --force -s test1
$maria_path/maria_chk$suffix -rus --safe-recover test1
$maria_path/maria_chk$suffix -es test1
$maria_path/ma_test1$suffix $silent --checksum -S $row_type $maria_path/ma_test1$suffix $silent --checksum -S $row_type
$maria_path/maria_chk$suffix -se test1 $maria_path/maria_chk$suffix -se test1
$maria_path/maria_chk$suffix -ros test1 $maria_path/maria_chk$suffix -ros test1
...@@ -184,10 +189,10 @@ run_pack_tests() ...@@ -184,10 +189,10 @@ run_pack_tests()
$maria_path/ma_test2$suffix $silent -c -d1 $row_type $maria_path/ma_test2$suffix $silent -c -d1 $row_type
$maria_path/maria_chk$suffix -s --parallel-recover test2 $maria_path/maria_chk$suffix -s --parallel-recover test2
$maria_path/maria_chk$suffix -se test2 $maria_path/maria_chk$suffix -se test2
$maria_path/maria_chk$suffix -s --parallel-recover --unpack test2 $maria_path/maria_chk$suffix -s --unpack --parallel-recover test2
$maria_path/maria_chk$suffix -se test2 $maria_path/maria_chk$suffix -se test2
$maria_path/maria_pack$suffix --force -s test1 $maria_path/maria_pack$suffix --force -s test1
$maria_path/maria_chk$suffix -s --parallel-recover --unpack test2 $maria_path/maria_chk$suffix -s --unpack --parallel-recover test2
$maria_path/maria_chk$suffix -se test2 $maria_path/maria_chk$suffix -se test2
} }
...@@ -233,6 +238,30 @@ $maria_path/maria_chk$suffix -ssm test2 ...@@ -233,6 +238,30 @@ $maria_path/maria_chk$suffix -ssm test2
# #
/bin/sh $maria_path/ma_test_recovery /bin/sh $maria_path/ma_test_recovery
#
# Extra tests that has caused failures in the past
#
# Problem with re-executing CLR's
rm -f maria_log.* maria_log_control
ma_test2 -s -L -K -W -P -M -T -c -b -t2 -u1
cp maria_log_control tmp
maria_read_log -a -s
maria_chk -s -e test2
cp tmp/maria_log_control .
rm test2.MA?
maria_read_log -a -s
maria_chk -s -e test2
# Problem with re-executing CLR's
rm -f maria_log.* maria_log_control
ma_test2 -s -L -K -W -P -M -T -c -b -t2 -u1
maria_read_log -a -s
maria_chk -s -e test2
rm test2.MA?
maria_read_log -a -s
maria_chk -e -s test2
# #
# Some timing tests # Some timing tests
# #
......
...@@ -24,14 +24,7 @@ check_table_is_same() ...@@ -24,14 +24,7 @@ check_table_is_same()
$maria_path/maria_chk -dvv $table | grep -v "Creation time:" > $tmp/maria_chk_message.txt 2>&1 $maria_path/maria_chk -dvv $table | grep -v "Creation time:" > $tmp/maria_chk_message.txt 2>&1
# save the index file (because we want to test idempotency afterwards) $maria_path/maria_chk -s -e --read-only $table
cp $table.MAI tmp/
# In the repair below it's good to use -q because it will die on any
# incorrectness of the data file if UNDO was badly applied.
# QQ: Remove the following line when we also can recover the index file
$maria_path/maria_chk -s -rq $table
$maria_path/maria_chk -s -e $table
checksum2=`$maria_path/maria_chk -dss $table` checksum2=`$maria_path/maria_chk -dss $table`
if test "$checksum" != "$checksum2" if test "$checksum" != "$checksum2"
then then
...@@ -47,7 +40,6 @@ check_table_is_same() ...@@ -47,7 +40,6 @@ check_table_is_same()
cat $tmp/maria_chk_diff.txt cat $tmp/maria_chk_diff.txt
echo "========DIFF END=======" echo "========DIFF END======="
fi fi
mv tmp/$table.MAI .
} }
apply_log() apply_log()
......
This diff is collapsed.
...@@ -135,7 +135,7 @@ int main(int argc, char **argv) ...@@ -135,7 +135,7 @@ int main(int argc, char **argv)
{ /* Only if descript */ { /* Only if descript */
char buff[22],buff2[22]; char buff[22],buff2[22];
if (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO) if (!(check_param.testflag & T_SILENT) || check_param.testflag & T_INFO)
puts("\n---------\n"); puts("\n---------");
printf("\nTotal of all %d MARIA-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff), printf("\nTotal of all %d MARIA-files:\nData records: %9s Deleted blocks: %9s\n",check_param.total_files,llstr(check_param.total_records,buff),
llstr(check_param.total_deleted,buff2)); llstr(check_param.total_deleted,buff2));
} }
...@@ -624,9 +624,13 @@ get_one_option(int optid, ...@@ -624,9 +624,13 @@ get_one_option(int optid,
break; break;
case 'u': case 'u':
if (argument == disabled_my_option) if (argument == disabled_my_option)
check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT); check_param.testflag&= ~T_UNPACK;
else else
check_param.testflag|= T_UNPACK | T_REP_BY_SORT; {
check_param.testflag|= T_UNPACK;
if (!(check_param.testflag & T_REP_ANY))
check_param.testflag|= T_REP_BY_SORT;
}
break; break;
case 'v': /* Verbose */ case 'v': /* Verbose */
if (argument == disabled_my_option) if (argument == disabled_my_option)
...@@ -802,13 +806,13 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -802,13 +806,13 @@ static int maria_chk(HA_CHECK *param, char *filename)
datafile=0; datafile=0;
param->isam_file_name=filename; /* For error messages */ param->isam_file_name=filename; /* For error messages */
if (!(info=maria_open(filename, if (!(info=maria_open(filename,
(param->testflag & (T_DESCRIPT | T_READONLY)) ? (param->testflag & (T_DESCRIPT | T_READONLY)) ?
O_RDONLY : O_RDWR, O_RDONLY : O_RDWR,
HA_OPEN_FOR_REPAIR | HA_OPEN_FOR_REPAIR |
((param->testflag & T_WAIT_FOREVER) ? ((param->testflag & T_WAIT_FOREVER) ?
HA_OPEN_WAIT_IF_LOCKED : HA_OPEN_WAIT_IF_LOCKED :
(param->testflag & T_DESCRIPT) ? (param->testflag & T_DESCRIPT) ?
HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED)))) HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED))))
{ {
/* Avoid twice printing of isam file name */ /* Avoid twice printing of isam file name */
param->error_printed=1; param->error_printed=1;
...@@ -852,7 +856,6 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -852,7 +856,6 @@ static int maria_chk(HA_CHECK *param, char *filename)
DBUG_RETURN(1); DBUG_RETURN(1);
} }
share=info->s; share=info->s;
share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */
share->tot_locks-= share->r_locks; share->tot_locks-= share->r_locks;
share->r_locks=0; share->r_locks=0;
maria_block_size= share->base.block_size; maria_block_size= share->base.block_size;
...@@ -871,10 +874,10 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -871,10 +874,10 @@ static int maria_chk(HA_CHECK *param, char *filename)
goto end2; goto end2;
} }
/* We can't do parallell repair with BLOCK_RECORD yet */ /* We can't do parallell repair with BLOCK_RECORD yet */
if (param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL)) if (param->testflag & T_REP_PARALLEL)
{ {
param->testflag&= ~(T_REP_BY_SORT | T_REP_PARALLEL); param->testflag&= ~T_REP_PARALLEL;
param->testflag|= T_REP; param->testflag|= T_REP_BY_SORT;
} }
} }
...@@ -1255,7 +1258,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) ...@@ -1255,7 +1258,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
printf("\nMARIA file: %s\n",name); printf("MARIA file: %s\n",name);
printf("Record format: %s\n", record_formats[share->data_file_type]); printf("Record format: %s\n", record_formats[share->data_file_type]);
printf("Crashsafe: %s\n", printf("Crashsafe: %s\n",
share->base.born_transactional ? "yes" : "no"); share->base.born_transactional ? "yes" : "no");
......
...@@ -118,7 +118,7 @@ typedef struct st_maria_state_info ...@@ -118,7 +118,7 @@ typedef struct st_maria_state_info
#define MARIA_STATE_KEYBLOCK_SIZE 8 #define MARIA_STATE_KEYBLOCK_SIZE 8
#define MARIA_STATE_KEYSEG_SIZE 12 #define MARIA_STATE_KEYSEG_SIZE 12
#define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE) #define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
#define MARIA_KEYDEF_SIZE (2+ 5*2) #define MARIA_KEYDEF_SIZE (2+ 5*2)
#define MARIA_UNIQUEDEF_SIZE (2+1+1) #define MARIA_UNIQUEDEF_SIZE (2+1+1)
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2) #define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1) #define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
...@@ -507,6 +507,7 @@ struct st_maria_handler ...@@ -507,6 +507,7 @@ struct st_maria_handler
#define USE_WHOLE_KEY 65535 /* Use whole key in _search() */ #define USE_WHOLE_KEY 65535 /* Use whole key in _search() */
#define F_EXTRA_LCK -1 #define F_EXTRA_LCK -1
#define TRANSID_SIZE 6
/* bits in opt_flag */ /* bits in opt_flag */
#define MEMMAP_USED 32 #define MEMMAP_USED 32
...@@ -540,7 +541,8 @@ struct st_maria_handler ...@@ -540,7 +541,8 @@ struct st_maria_handler
#define KEYPAGE_FLAG_SIZE 1 #define KEYPAGE_FLAG_SIZE 1
#define KEYPAGE_CHECKSUM_SIZE 4 #define KEYPAGE_CHECKSUM_SIZE 4
#define MAX_KEYPAGE_HEADER_SIZE (LSN_STORE_SIZE + KEYPAGE_USED_SIZE + \ #define MAX_KEYPAGE_HEADER_SIZE (LSN_STORE_SIZE + KEYPAGE_USED_SIZE + \
KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE) KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + \
TRANSID_SIZE)
#define _ma_get_page_used(info,x) \ #define _ma_get_page_used(info,x) \
(((uint) mi_uint2korr(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) & \ (((uint) mi_uint2korr(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) & \
...@@ -560,6 +562,11 @@ struct st_maria_handler ...@@ -560,6 +562,11 @@ struct st_maria_handler
} }
#define _ma_store_keynr(info, x, nr) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= nr #define _ma_store_keynr(info, x, nr) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= nr
#define _ma_get_keynr(info, x) ((uchar) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]) #define _ma_get_keynr(info, x) ((uchar) x[(info)->s->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE])
#define _ma_store_transid(buff, transid) \
int6store((buff) + LSN_STORE_SIZE, (transid))
#define _ma_korr_transid(buff) \
uint6korr((buff) + LSN_STORE_SIZE)
#define maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \ #define maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
DBUG_PRINT("error", ("Marked table crashed")); \ DBUG_PRINT("error", ("Marked table crashed")); \
}while(0) }while(0)
......
...@@ -29,7 +29,7 @@ const char *default_dbug_option= "d:t:i:O,\\maria_read_log.trace"; ...@@ -29,7 +29,7 @@ const char *default_dbug_option= "d:t:i:O,\\maria_read_log.trace";
const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace"; const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace";
#endif #endif
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
static my_bool opt_only_display, opt_apply, opt_apply_undo, opt_silent, static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent,
opt_check; opt_check;
static ulong opt_page_buffer_size; static ulong opt_page_buffer_size;
...@@ -84,8 +84,8 @@ int main(int argc, char **argv) ...@@ -84,8 +84,8 @@ int main(int argc, char **argv)
goto err; goto err;
} }
if (opt_only_display) if (opt_display_only)
printf("You are using --only-display, NOTHING will be written to disk\n"); printf("You are using --display-only, NOTHING will be written to disk\n");
/* LSN could be also --start-from-lsn=# */ /* LSN could be also --start-from-lsn=# */
lsn= translog_first_lsn_in_log(); lsn= translog_first_lsn_in_log();
...@@ -138,7 +138,7 @@ static struct my_option my_long_options[] = ...@@ -138,7 +138,7 @@ static struct my_option my_long_options[] =
(uchar **) &opt_apply, (uchar **) &opt_apply, 0, (uchar **) &opt_apply, (uchar **) &opt_apply, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"check", 'c', {"check", 'c',
"if --only-display, check if record is fully readable (for debugging)", "if --display-only, check if record is fully readable (for debugging)",
(uchar **) &opt_check, (uchar **) &opt_check, 0, (uchar **) &opt_check, (uchar **) &opt_check, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF #ifndef DBUG_OFF
...@@ -147,8 +147,8 @@ static struct my_option my_long_options[] = ...@@ -147,8 +147,8 @@ static struct my_option my_long_options[] =
#endif #endif
{"help", '?', "Display this help and exit.", {"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"only-display", 'o', "display brief info read from records' header", {"display-only", 'o', "display brief info read from records' header",
(uchar **) &opt_only_display, (uchar **) &opt_only_display, 0, GET_BOOL, (uchar **) &opt_display_only, (uchar **) &opt_display_only, 0, GET_BOOL,
NO_ARG,0, 0, 0, 0, 0, 0}, NO_ARG,0, 0, 0, 0, 0, 0},
{ "page_buffer_size", 'P', "", { "page_buffer_size", 'P', "",
(uchar**) &opt_page_buffer_size, (uchar**) &opt_page_buffer_size, 0, (uchar**) &opt_page_buffer_size, (uchar**) &opt_page_buffer_size, 0,
...@@ -225,7 +225,7 @@ static void get_options(int *argc,char ***argv) ...@@ -225,7 +225,7 @@ static void get_options(int *argc,char ***argv)
if (!opt_apply) if (!opt_apply)
opt_apply_undo= FALSE; opt_apply_undo= FALSE;
if ((opt_only_display + opt_apply) != 1) if ((opt_display_only + opt_apply) != 1)
{ {
usage(); usage();
exit(1); exit(1);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment