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.
*/ */
{
my_off_t end_of_page= (page + 1) * info->s->block_size;
set_if_bigger(info->state->data_file_length, end_of_page); 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);
......
...@@ -87,12 +87,15 @@ static ha_checksum maria_byte_checksum(const uchar *buf, uint length); ...@@ -87,12 +87,15 @@ static ha_checksum maria_byte_checksum(const uchar *buf, uint length);
static void set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share); static void set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share);
static void restore_data_file_type(MARIA_SHARE *share); static void restore_data_file_type(MARIA_SHARE *share);
static void change_data_file_descriptor(MARIA_HA *info, File new_file); static void change_data_file_descriptor(MARIA_HA *info, File new_file);
static void unuse_data_file_descriptor(MARIA_HA *info);
static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info, static int _ma_safe_scan_block_record(MARIA_SORT_INFO *sort_info,
MARIA_HA *info, uchar *record); MARIA_HA *info, uchar *record);
static void copy_data_file_state(MARIA_STATE_INFO *to, static void copy_data_file_state(MARIA_STATE_INFO *to,
MARIA_STATE_INFO *from); MARIA_STATE_INFO *from);
static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info); static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info);
static void report_keypage_fault(HA_CHECK *param, my_off_t position); static void report_keypage_fault(HA_CHECK *param, my_off_t position);
my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file);
void maria_chk_init(HA_CHECK *param) void maria_chk_init(HA_CHECK *param)
{ {
...@@ -2031,6 +2034,38 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend) ...@@ -2031,6 +2034,38 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
} /* maria_chk_data_link */ } /* maria_chk_data_link */
/**
@brief Initialize variables for repair
*/
static void initialize_variables_for_repair(HA_CHECK *param,
MARIA_SORT_INFO *sort_info,
MARIA_SORT_PARAM *sort_param,
MARIA_HA *info,
uint rep_quick)
{
bzero((char *) sort_info, sizeof(*sort_info));
bzero((char *) sort_param, sizeof(*sort_param));
param->testflag|= T_REP; /* for easy checking */
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|= T_CALC_CHECKSUM;
param->glob_crc= 0;
sort_param->sort_info= sort_info;
sort_param->fix_datafile= (my_bool) (! rep_quick);
sort_param->calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
sort_info->info= sort_info->new_info= info;
sort_info->param= param;
set_data_file_type(sort_info, info->s);
sort_info->org_data_file_type= info->s->data_file_type;
bzero(&info->rec_cache, sizeof(info->rec_cache));
info->rec_cache.file= info->dfile.file;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
}
/* /*
Recover old table by reading each record and writing all keys Recover old table by reading each record and writing all keys
...@@ -2054,7 +2089,7 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend) ...@@ -2054,7 +2089,7 @@ 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, register MARIA_HA *info,
char *name, int rep_quick) char *name, uint rep_quick)
{ {
int error, got_error= 1; int error, got_error= 1;
uint i; uint i;
...@@ -2071,26 +2106,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2071,26 +2106,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
MY_SYNC_DIR : 0); MY_SYNC_DIR : 0);
DBUG_ENTER("maria_repair"); DBUG_ENTER("maria_repair");
bzero((char *)&sort_info, sizeof(sort_info)); initialize_variables_for_repair(param, &sort_info, &sort_param, info,
bzero((char *)&sort_param, sizeof(sort_param)); rep_quick);
start_records=info->state->records; start_records=info->state->records;
new_header_length=(param->testflag & T_UNPACK) ? 0L : new_header_length= ((param->testflag & T_UNPACK) ? 0L :
share->pack.header_length; share->pack.header_length);
new_file= -1; new_file= -1;
sort_param.sort_info=&sort_info;
block_record= org_data_file_type == BLOCK_RECORD;
sort_info.info= sort_info.new_info= info;
bzero(&info->rec_cache,sizeof(info->rec_cache));
if (!(param->testflag & T_SILENT)) if (!(param->testflag & T_SILENT))
{ {
printf("- recovering (with keycache) MARIA-table '%s'\n",name); printf("- recovering (with keycache) MARIA-table '%s'\n",name);
printf("Data records: %s\n", llstr(info->state->records,llbuff)); printf("Data records: %s\n", llstr(info->state->records,llbuff));
} }
param->testflag|=T_REP; /* for easy checking */
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
/* /*
The physical size of the data file is sometimes used during repair (see The physical size of the data file is sometimes used during repair (see
...@@ -2121,43 +2148,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2121,43 +2148,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
new_header_length, "datafile-header")) new_header_length, "datafile-header"))
goto err; goto err;
info->s->state.dellink= HA_OFFSET_ERROR; info->s->state.dellink= HA_OFFSET_ERROR;
info->rec_cache.file= new_file; info->rec_cache.file= new_file; /* For sort_delete_record */
if (share->data_file_type == BLOCK_RECORD || if (share->data_file_type == BLOCK_RECORD ||
(param->testflag & T_UNPACK)) (param->testflag & T_UNPACK))
{ {
MARIA_HA *new_info; if (create_new_data_handle(&sort_param, new_file))
/*
It's ok for Recovery to have two MARIA_SHARE on the same index file
because the one below is not transactional
*/
if (!(sort_info.new_info= maria_open(info->s->open_file_name, O_RDWR,
HA_OPEN_COPY | HA_OPEN_FOR_REPAIR)))
goto err;
new_info= sort_info.new_info;
change_data_file_descriptor(new_info, new_file);
maria_lock_database(new_info, F_EXTRA_LCK);
if ((param->testflag & T_UNPACK) &&
share->data_file_type == COMPRESSED_RECORD)
{
(*new_info->s->once_end)(new_info->s);
(*new_info->s->end)(new_info);
restore_data_file_type(new_info->s);
_ma_setup_functions(new_info->s);
if ((*new_info->s->once_init)(new_info->s, new_file) ||
(*new_info->s->init)(new_info))
goto err; goto err;
} sort_info.new_info->rec_cache.file= new_file;
_ma_reset_status(sort_info.new_info);
if (_ma_initialize_data_file(sort_info.new_info->s, new_file))
goto err;
block_record= 1;
/* Use new virtual functions for key generation */
info->s->keypos_to_recpos= new_info->s->keypos_to_recpos;
info->s->recpos_to_keypos= new_info->s->recpos_to_keypos;
} }
} }
block_record= sort_info.new_info->s->data_file_type == BLOCK_RECORD;
if (org_data_file_type != BLOCK_RECORD) if (org_data_file_type != BLOCK_RECORD)
{ {
/* We need a read buffer to read rows in big blocks */ /* We need a read buffer to read rows in big blocks */
...@@ -2170,14 +2172,16 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2170,14 +2172,16 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
{ {
/* When writing to not block records, we need a write buffer */ /* When writing to not block records, we need a write buffer */
if (!rep_quick) if (!rep_quick)
if (init_io_cache(&info->rec_cache, new_file, {
if (init_io_cache(&sort_info.new_info->rec_cache, new_file,
(uint) param->write_buffer_length, (uint) param->write_buffer_length,
WRITE_CACHE, new_header_length, 1, WRITE_CACHE, new_header_length, 1,
MYF(MY_WME | MY_WAIT_IF_FULL))) MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw))
goto err; goto err;
info->opt_flag|=WRITE_CACHE_USED; sort_info.new_info->opt_flag|=WRITE_CACHE_USED;
} }
else }
else if (block_record)
{ {
scan_inited= 1; scan_inited= 1;
if (maria_scan_init(sort_info.info)) if (maria_scan_init(sort_info.info))
...@@ -2193,26 +2197,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2193,26 +2197,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
goto err; goto err;
} }
sort_info.param = param;
sort_param.read_cache=param->read_cache; sort_param.read_cache=param->read_cache;
sort_param.pos=sort_param.max_pos=share->pack.header_length; sort_param.pos=sort_param.max_pos=share->pack.header_length;
sort_param.filepos=new_header_length; sort_param.filepos=new_header_length;
param->read_cache.end_of_file=sort_info.filelength= param->read_cache.end_of_file= sort_info.filelength=
my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0)); my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
sort_info.dupp=0;
sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master=1; sort_param.master=1;
sort_info.max_records= ~(ha_rows) 0; sort_info.max_records= ~(ha_rows) 0;
set_data_file_type(&sort_info, share);
del=info->state->del; del=info->state->del;
info->state->records=info->state->del=share->state.split=0; info->state->records=info->state->del=share->state.split=0;
info->state->empty=0; info->state->empty=0;
param->glob_crc=0;
if (param->testflag & T_CALC_CHECKSUM)
sort_param.calc_checksum= 1;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
/* /*
Clear all keys. Note that all key blocks allocated until now remain Clear all keys. Note that all key blocks allocated until now remain
...@@ -2235,8 +2230,6 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2235,8 +2230,6 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
maria_lock_memory(param); /* Everything is alloced */ maria_lock_memory(param); /* Everything is alloced */
sort_info.org_data_file_type= info->s->data_file_type;
/* Re-create all keys, which are set in key_map. */ /* Re-create all keys, which are set in key_map. */
while (!(error=sort_get_next_record(&sort_param))) while (!(error=sort_get_next_record(&sort_param)))
{ {
...@@ -2248,7 +2241,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2248,7 +2241,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (my_errno != HA_ERR_FOUND_DUPP_KEY) if (my_errno != HA_ERR_FOUND_DUPP_KEY)
goto err; goto err;
DBUG_DUMP("record",(uchar*) sort_param.record,share->base.pack_reclength); DBUG_DUMP("record",(uchar*) sort_param.record,share->base.pack_reclength);
_ma_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s", _ma_check_print_info(param,
"Duplicate key %2d for record at %10s against new record at %10s",
info->errkey+1, info->errkey+1,
llstr(sort_param.start_recpos,llbuff), llstr(sort_param.start_recpos,llbuff),
llstr(info->dup_key_pos,llbuff2)); llstr(info->dup_key_pos,llbuff2));
...@@ -2279,11 +2273,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2279,11 +2273,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
} }
/* purecov: end */ /* purecov: end */
} }
if (!block_record && _ma_sort_write_record(&sort_param)) if (!block_record)
{
if (_ma_sort_write_record(&sort_param))
goto err; goto err;
/* Filepos is pointer to where next row will be stored */
sort_param.current_filepos= sort_param.filepos;
}
} }
if (error > 0 || maria_write_data_suffix(&sort_info, (my_bool)!rep_quick) || if (error > 0 || maria_write_data_suffix(&sort_info, (my_bool)!rep_quick) ||
flush_io_cache(&info->rec_cache) || param->read_cache.error < 0) flush_io_cache(&sort_info.new_info->rec_cache) ||
param->read_cache.error < 0)
goto err; goto err;
if (param->testflag & T_WRITE_LOOP) if (param->testflag & T_WRITE_LOOP)
...@@ -2317,8 +2317,14 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2317,8 +2317,14 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
} }
} }
VOID(end_io_cache(&sort_info.new_info->rec_cache));
info->opt_flag&= ~WRITE_CACHE_USED;
if (_ma_flush_table_files_after_repair(param, info))
goto err;
if (!rep_quick) if (!rep_quick)
{ {
sort_info.new_info->state->data_file_length= sort_param.filepos;
if (sort_info.new_info != sort_info.info) if (sort_info.new_info != sort_info.info)
{ {
MARIA_STATE_INFO save_state= sort_info.new_info->s->state; MARIA_STATE_INFO save_state= sort_info.new_info->s->state;
...@@ -2329,9 +2335,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info, ...@@ -2329,9 +2335,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
} }
copy_data_file_state(&info->s->state, &save_state); copy_data_file_state(&info->s->state, &save_state);
new_file= -1; new_file= -1;
sort_info.new_info= info;
} }
else
info->state->data_file_length= sort_param.filepos;
share->state.version=(ulong) time((time_t*) 0); /* Force reopen */ share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
/* Replace the actual file with the temporary file */ /* Replace the actual file with the temporary file */
...@@ -2376,38 +2381,25 @@ err: ...@@ -2376,38 +2381,25 @@ err:
maria_scan_end(sort_info.info); maria_scan_end(sort_info.info);
VOID(end_io_cache(&param->read_cache)); VOID(end_io_cache(&param->read_cache));
VOID(end_io_cache(&sort_info.new_info->rec_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
/* this below could fail, shouldn't we detect error? */ /* this below could fail, shouldn't we detect error? */
VOID(end_io_cache(&info->rec_cache));
got_error|= _ma_flush_table_files_after_repair(param, info);
if (got_error) if (got_error)
{ {
if (! param->error_printed) if (! param->error_printed)
_ma_check_print_error(param,"%d for record at pos %s",my_errno, _ma_check_print_error(param,"%d for record at pos %s",my_errno,
llstr(sort_param.start_recpos,llbuff)); llstr(sort_param.start_recpos,llbuff));
(void) _ma_flush_table_files_after_repair(param, info);
if (sort_info.new_info && sort_info.new_info != sort_info.info) if (sort_info.new_info && sort_info.new_info != sort_info.info)
{ {
/** unuse_data_file_descriptor(sort_info.new_info);
@todo ASK_MONTY
grepping for "dfile.file="
shows several places (ma_check.c, ma_panic.c, ma_extra.c) where we
modify dfile.file without modifying share->bitmap.file.file; those
sound like bugs because the two variables are normally copies of each
other in BLOCK_RECORD (and in other record formats it does not hurt
to change the unused share->bitmap.file.file).
It does matter, because if we close dfile.file, set dfile.file to -1,
but leave bitmap.file.file to its positive value, maria_close() will
close a file which it is not allowed to (maybe even a file in another
engine or mysqld!).
*/
sort_info.new_info->dfile.file= -1;
maria_close(sort_info.new_info); maria_close(sort_info.new_info);
} }
if (new_file >= 0) if (new_file >= 0)
{ {
VOID(my_close(new_file,MYF(0))); VOID(my_close(new_file,MYF(0)));
VOID(my_delete(param->temp_filename, MYF(MY_WME))); VOID(my_delete(param->temp_filename, MYF(MY_WME)));
info->rec_cache.file=-1; /* don't flush data to new_file, it's closed */
} }
maria_mark_crashed_on_repair(info); maria_mark_crashed_on_repair(info);
} }
...@@ -2439,7 +2431,7 @@ static int writekeys(MARIA_SORT_PARAM *sort_param) ...@@ -2439,7 +2431,7 @@ static int writekeys(MARIA_SORT_PARAM *sort_param)
uchar *key; uchar *key;
MARIA_HA *info= sort_param->sort_info->info; MARIA_HA *info= sort_param->sort_info->info;
uchar *buff= sort_param->record; uchar *buff= sort_param->record;
my_off_t filepos= sort_param->filepos; my_off_t filepos= sort_param->current_filepos;
DBUG_ENTER("writekeys"); DBUG_ENTER("writekeys");
key= info->lastkey+info->s->base.max_key_length; key= info->lastkey+info->s->base.max_key_length;
...@@ -2866,7 +2858,7 @@ err: ...@@ -2866,7 +2858,7 @@ err:
*/ */
int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
const char * name, int rep_quick) const char * name, uint rep_quick)
{ {
int got_error; int got_error;
uint i; uint i;
...@@ -2883,57 +2875,32 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -2883,57 +2875,32 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
ulonglong key_map=share->state.key_map; ulonglong key_map=share->state.key_map;
myf sync_dir= ((share->now_transactional && !share->temporary) ? myf sync_dir= ((share->now_transactional && !share->temporary) ?
MY_SYNC_DIR : 0); MY_SYNC_DIR : 0);
my_bool scan_inited= 0;
DBUG_ENTER("maria_repair_by_sort"); DBUG_ENTER("maria_repair_by_sort");
bzero((char*)&sort_info,sizeof(sort_info)); start_records= info->state->records;
bzero((char *)&sort_param, sizeof(sort_param)); initialize_variables_for_repair(param, &sort_info, &sort_param, info,
rep_quick);
start_records=info->state->records;
got_error=1; got_error=1;
new_file= -1; new_file= -1;
org_header_length= share->pack.header_length; org_header_length= share->pack.header_length;
new_header_length= (param->testflag & T_UNPACK) ? 0 : org_header_length; new_header_length= (param->testflag & T_UNPACK) ? 0 : org_header_length;
sort_param.filepos= new_header_length;
if (!(param->testflag & T_SILENT)) if (!(param->testflag & T_SILENT))
{ {
printf("- recovering (with sort) MARIA-table '%s'\n",name); printf("- recovering (with sort) MARIA-table '%s'\n",name);
printf("Data records: %s\n", llstr(start_records,llbuff)); printf("Data records: %s\n", llstr(start_records,llbuff));
} }
param->testflag|=T_REP; /* for easy checking */
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
/* Flushing of keys is done later */
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX, if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_FORCE_WRITE, FLUSH_IGNORE_CHANGED)) FLUSH_FORCE_WRITE,
goto err; (param->testflag & T_CREATE_MISSING_KEYS) ?
FLUSH_FORCE_WRITE : FLUSH_IGNORE_CHANGED) ||
if (!(sort_info.key_block= _ma_state_info_write(share, 1|2|4))
alloc_key_blocks(param,
(uint) param->sort_key_blocks,
share->base.max_key_block_length)) ||
init_io_cache(&param->read_cache, info->dfile.file,
(uint) param->read_buffer_length,
READ_CACHE, org_header_length, 1, MYF(MY_WME)) ||
(! rep_quick &&
init_io_cache(&info->rec_cache, info->dfile.file,
(uint) param->write_buffer_length,
WRITE_CACHE,new_header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
goto err; goto err;
sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
info->opt_flag|=WRITE_CACHE_USED;
info->rec_cache.file= info->dfile.file; /* for sort_delete_record */
sort_info.org_data_file_type= info->s->data_file_type;
if (!(sort_param.record=(uchar*) my_malloc((uint) share->base.pack_reclength,
MYF(0))) ||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
info->s->base.default_rec_buff_size))
{
_ma_check_print_error(param, "Not enough memory for extra record");
goto err;
}
if (!rep_quick) if (!rep_quick)
{ {
/* Get real path for data file */ /* Get real path for data file */
...@@ -2951,21 +2918,58 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -2951,21 +2918,58 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
maria_filecopy(param, new_file, info->dfile.file, 0L, maria_filecopy(param, new_file, info->dfile.file, 0L,
new_header_length, "datafile-header")) new_header_length, "datafile-header"))
goto err; goto err;
if (param->testflag & T_UNPACK)
restore_data_file_type(share);
share->state.dellink= HA_OFFSET_ERROR; share->state.dellink= HA_OFFSET_ERROR;
info->rec_cache.file=new_file; info->rec_cache.file= new_file; /* For sort_delete_record */
if (share->data_file_type == BLOCK_RECORD ||
(param->testflag & T_UNPACK))
{
if (create_new_data_handle(&sort_param, new_file))
goto err;
sort_info.new_info->rec_cache.file= new_file;
}
}
if (!(sort_info.key_block=
alloc_key_blocks(param,
(uint) param->sort_key_blocks,
share->base.max_key_block_length)))
goto err;
sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
if (info->s->data_file_type != BLOCK_RECORD)
{
/* We need a read buffer to read rows in big blocks */
if (init_io_cache(&param->read_cache, info->dfile.file,
(uint) param->read_buffer_length,
READ_CACHE, org_header_length, 1, MYF(MY_WME)))
goto err;
}
if (sort_info.new_info->s->data_file_type != BLOCK_RECORD)
{
/* When writing to not block records, we need a write buffer */
if (!rep_quick)
{
if (init_io_cache(&sort_info.new_info->rec_cache, new_file,
(uint) param->write_buffer_length,
WRITE_CACHE, new_header_length, 1,
MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw))
goto err;
sort_info.new_info->opt_flag|= WRITE_CACHE_USED;
}
}
if (!(sort_param.record=(uchar*) my_malloc((uint) share->base.pack_reclength,
MYF(0))) ||
_ma_alloc_buffer(&sort_param.rec_buff, &sort_param.rec_buff_size,
info->s->base.default_rec_buff_size))
{
_ma_check_print_error(param, "Not enough memory for extra record");
goto err;
} }
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
if (!(param->testflag & T_CREATE_MISSING_KEYS)) if (!(param->testflag & T_CREATE_MISSING_KEYS))
{ {
/*
Flush key cache for this file if we are calling this outside
maria_chk
*/
flush_pagecache_blocks(share->pagecache, &share->kfile,
FLUSH_IGNORE_CHANGED);
/* Clear the pointers to the given rows */ /* Clear the pointers to the given rows */
for (i=0 ; i < share->base.keys ; i++) for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR; share->state.key_root[i]= HA_OFFSET_ERROR;
...@@ -2973,22 +2977,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -2973,22 +2977,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
info->state->key_file_length=share->base.keystart; info->state->key_file_length=share->base.keystart;
} }
else else
{
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
FLUSH_FORCE_WRITE))
goto err;
key_map= ~key_map; /* Create the missing keys */ key_map= ~key_map; /* Create the missing keys */
}
sort_info.info= sort_info.new_info= info;
sort_info.param= param;
set_data_file_type(&sort_info, share); param->read_cache.end_of_file= sort_info.filelength=
sort_param.filepos=new_header_length; my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
sort_info.dupp=0;
sort_info.buff=0;
param->read_cache.end_of_file=sort_info.filelength=
my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
sort_param.wordlist=NULL; sort_param.wordlist=NULL;
init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0); init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
...@@ -3005,14 +2997,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -3005,14 +2997,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_param.key_cmp=sort_key_cmp; sort_param.key_cmp=sort_key_cmp;
sort_param.lock_in_memory=maria_lock_memory; sort_param.lock_in_memory=maria_lock_memory;
sort_param.tmpdir=param->tmpdir; sort_param.tmpdir=param->tmpdir;
sort_param.sort_info=&sort_info;
sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master =1; sort_param.master =1;
del=info->state->del; del=info->state->del;
param->glob_crc=0;
if (param->testflag & T_CALC_CHECKSUM)
sort_param.calc_checksum= 1;
rec_per_key_part= param->new_rec_per_key_part; rec_per_key_part= param->new_rec_per_key_part;
for (sort_param.key=0 ; sort_param.key < share->base.keys ; for (sort_param.key=0 ; sort_param.key < share->base.keys ;
...@@ -3091,6 +3078,12 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -3091,6 +3078,12 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_param.key_write= sort_key_write; sort_param.key_write= sort_key_write;
} }
if (sort_info.new_info->s->data_file_type == BLOCK_RECORD)
{
scan_inited= 1;
if (maria_scan_init(sort_info.info))
goto err;
}
if (_ma_create_index_by_sort(&sort_param, if (_ma_create_index_by_sort(&sort_param,
(my_bool) (!(param->testflag & T_VERBOSE)), (my_bool) (!(param->testflag & T_VERBOSE)),
(size_t) param->sort_buffer_length)) (size_t) param->sort_buffer_length))
...@@ -3098,26 +3091,36 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -3098,26 +3091,36 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
param->retry_repair=1; param->retry_repair=1;
goto err; goto err;
} }
if (scan_inited)
{
scan_inited= 0;
maria_scan_end(sort_info.info);
}
/* No need to calculate checksum again. */ /* No need to calculate checksum again. */
sort_param.calc_checksum= 0; sort_param.calc_checksum= 0;
free_root(&sort_param.wordroot, MYF(0)); free_root(&sort_param.wordroot, MYF(0));
/* Set for next loop */ /* Set for next loop */
sort_info.max_records= (ha_rows) info->state->records; sort_info.max_records= (ha_rows) sort_info.new_info->state->records;
if (param->testflag & T_STATISTICS) if (param->testflag & T_STATISTICS)
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part, maria_update_key_parts(sort_param.keyinfo, rec_per_key_part,
sort_param.unique, sort_param.unique,
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS? (param->stats_method ==
sort_param.notnull : NULL, MI_STATS_METHOD_IGNORE_NULLS ?
sort_param.notnull : NULL),
(ulonglong) info->state->records); (ulonglong) info->state->records);
maria_set_key_active(share->state.key_map, sort_param.key); maria_set_key_active(share->state.key_map, sort_param.key);
if (sort_param.fix_datafile) if (sort_param.fix_datafile)
{ {
param->read_cache.end_of_file=sort_param.filepos; param->read_cache.end_of_file=sort_param.filepos;
if (maria_write_data_suffix(&sort_info,1) || end_io_cache(&info->rec_cache)) if (maria_write_data_suffix(&sort_info,1) ||
end_io_cache(&sort_info.new_info->rec_cache))
goto err; goto err;
sort_info.new_info->opt_flag&= ~WRITE_CACHE_USED;
if (param->testflag & T_SAFE_REPAIR) if (param->testflag & T_SAFE_REPAIR)
{ {
/* Don't repair if we loosed more than one row */ /* Don't repair if we loosed more than one row */
...@@ -3127,15 +3130,48 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -3127,15 +3130,48 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
goto err; goto err;
} }
} }
share->state.state.data_file_length = info->state->data_file_length=
sort_param.filepos; if (_ma_flush_table_files_after_repair(param, info))
/* Only whole records */ goto err;
share->state.version=(ulong) time((time_t*) 0);
my_close(info->dfile.file, MYF(0)); sort_info.new_info->state->data_file_length= sort_param.filepos;
info->dfile.file= new_file; if (sort_info.new_info != sort_info.info)
share->data_file_type= sort_info.new_data_file_type; {
org_header_length= (ulong) new_header_length; MARIA_STATE_INFO save_state= sort_info.new_info->s->state;
if (maria_close(sort_info.new_info))
{
_ma_check_print_error(param, "Got error %d on close", my_errno);
goto err;
}
copy_data_file_state(&info->s->state, &save_state);
new_file= -1;
sort_info.new_info= info;
}
share->state.version=(ulong) time((time_t*) 0); /* Force reopen */
/* Replace the actual file with the temporary file */
if (new_file >= 0)
{
my_close(new_file, MYF(MY_WME));
new_file= -1;
}
change_data_file_descriptor(info, -1);
if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
DATA_TMP_EXT,
(param->testflag & T_BACKUP_DATA ?
MYF(MY_REDEL_MAKE_BACKUP): MYF(0)) |
sync_dir) ||
_ma_open_datafile(info, share, -1))
{
goto err;
}
if (param->testflag & T_UNPACK)
restore_data_file_type(share);
org_header_length= share->pack.header_length;
sort_info.org_data_file_type= info->s->data_file_type; sort_info.org_data_file_type= info->s->data_file_type;
sort_info.filelength= info->state->data_file_length;
sort_param.fix_datafile=0; sort_param.fix_datafile=0;
} }
else else
...@@ -3177,6 +3213,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -3177,6 +3213,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
"Can't change size of datafile, error: %d", "Can't change size of datafile, error: %d",
my_errno); my_errno);
} }
if (param->testflag & T_CALC_CHECKSUM) if (param->testflag & T_CALC_CHECKSUM)
info->state->checksum=param->glob_crc; info->state->checksum=param->glob_crc;
...@@ -3200,41 +3237,40 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, ...@@ -3200,41 +3237,40 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
memcpy( &share->state.state, info->state, sizeof(*info->state)); memcpy( &share->state.state, info->state, sizeof(*info->state));
err: err:
VOID(end_io_cache(&info->rec_cache)); if (scan_inited)
maria_scan_end(sort_info.info);
VOID(end_io_cache(&sort_info.new_info->rec_cache));
VOID(end_io_cache(&param->read_cache)); VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
got_error|= _ma_flush_table_files_after_repair(param, info); sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
if (!got_error)
{
/* Replace the actual file with the temporary file */
if (new_file >= 0)
{
my_close(new_file,MYF(0));
info->dfile.file= new_file= -1;
if (maria_change_to_newfile(share->data_file_name,MARIA_NAME_DEXT,
DATA_TMP_EXT,
MYF((param->testflag & T_BACKUP_DATA ?
MY_REDEL_MAKE_BACKUP : 0) |
sync_dir)) ||
_ma_open_datafile(info,share,-1))
got_error=1;
}
}
if (got_error) if (got_error)
{ {
if (! param->error_printed) if (! param->error_printed)
_ma_check_print_error(param,"%d when fixing table",my_errno); _ma_check_print_error(param,"%d when fixing table",my_errno);
(void) _ma_flush_table_files_after_repair(param, info);
if (sort_info.new_info && sort_info.new_info != sort_info.info)
{
unuse_data_file_descriptor(sort_info.new_info);
maria_close(sort_info.new_info);
}
if (new_file >= 0) if (new_file >= 0)
{ {
VOID(my_close(new_file,MYF(0))); VOID(my_close(new_file,MYF(0)));
VOID(my_delete(param->temp_filename, MYF(MY_WME))); VOID(my_delete(param->temp_filename, MYF(MY_WME)));
if (info->dfile.file == new_file)
info->dfile.file= -1;
} }
maria_mark_crashed_on_repair(info); maria_mark_crashed_on_repair(info);
} }
else if (key_map == share->state.key_map) else
{
if (key_map == share->state.key_map)
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
/*
Now that we have flushed and forced everything, we can bump
create_rename_lsn:
*/
write_log_record_for_repair(param, info);
}
share->state.changed|= STATE_NOT_SORTED_PAGES; share->state.changed|= STATE_NOT_SORTED_PAGES;
share->state.changed&= ~STATE_NOT_OPTIMIZED_ROWS; share->state.changed&= ~STATE_NOT_OPTIMIZED_ROWS;
...@@ -3243,8 +3279,6 @@ err: ...@@ -3243,8 +3279,6 @@ err:
my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR)); my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR)); my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR)); my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
if (!got_error && (param->testflag & T_UNPACK))
restore_data_file_type(share);
DBUG_RETURN(got_error); DBUG_RETURN(got_error);
} }
...@@ -3291,7 +3325,7 @@ err: ...@@ -3291,7 +3325,7 @@ err:
*/ */
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)
{ {
#ifndef THREAD #ifndef THREAD
return maria_repair_by_sort(param, info, name, rep_quick); return maria_repair_by_sort(param, info, name, rep_quick);
...@@ -3302,7 +3336,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, ...@@ -3302,7 +3336,7 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
ha_rows start_records; ha_rows start_records;
my_off_t new_header_length,del; my_off_t new_header_length,del;
File new_file; File new_file;
MARIA_SORT_PARAM *sort_param=0; MARIA_SORT_PARAM *sort_param=0, tmp_sort_param;
MARIA_SHARE *share=info->s; MARIA_SHARE *share=info->s;
double *rec_per_key_part; double *rec_per_key_part;
HA_KEYSEG *keyseg; HA_KEYSEG *keyseg;
...@@ -3316,6 +3350,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, ...@@ -3316,6 +3350,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
MY_SYNC_DIR : 0; MY_SYNC_DIR : 0;
DBUG_ENTER("maria_repair_parallel"); DBUG_ENTER("maria_repair_parallel");
initialize_variables_for_repair(param, &sort_info, &tmp_sort_param, info,
rep_quick);
start_records=info->state->records; start_records=info->state->records;
got_error=1; got_error=1;
new_file= -1; new_file= -1;
...@@ -3326,7 +3363,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, ...@@ -3326,7 +3363,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
printf("- parallel recovering (with sort) MARIA-table '%s'\n",name); printf("- parallel recovering (with sort) MARIA-table '%s'\n",name);
printf("Data records: %s\n", llstr(start_records,llbuff)); printf("Data records: %s\n", llstr(start_records,llbuff));
} }
param->testflag|=T_REP; /* for easy checking */
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM; param->testflag|=T_CALC_CHECKSUM;
...@@ -3364,13 +3400,11 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, ...@@ -3364,13 +3400,11 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
} }
*/ */
DBUG_PRINT("info", ("is quick repair: %d", rep_quick)); DBUG_PRINT("info", ("is quick repair: %d", rep_quick));
bzero((char*)&sort_info,sizeof(sort_info));
/* Initialize pthread structures before goto err. */ /* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0); pthread_cond_init(&sort_info.cond, 0);
sort_info.org_data_file_type= info->s->data_file_type;
if (!(sort_info.key_block= if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks, alloc_key_blocks(param, (uint) param->sort_key_blocks,
share->base.max_key_block_length)) || share->base.max_key_block_length)) ||
...@@ -3438,14 +3472,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, ...@@ -3438,14 +3472,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
key_map= ~key_map; /* Create the missing keys */ key_map= ~key_map; /* Create the missing keys */
} }
sort_info.info= sort_info.new_info= info; param->read_cache.end_of_file= sort_info.filelength=
sort_info.param= param; my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
set_data_file_type(&sort_info, share);
sort_info.dupp=0;
sort_info.buff=0;
param->read_cache.end_of_file=sort_info.filelength=
my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
if (sort_info.org_data_file_type == DYNAMIC_RECORD) if (sort_info.org_data_file_type == DYNAMIC_RECORD)
rec_length=max(share->base.min_pack_length+1,share->base.min_block_length); rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
...@@ -3470,7 +3498,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, ...@@ -3470,7 +3498,6 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
(ha_rows) (sort_info.filelength/rec_length+1)); (ha_rows) (sort_info.filelength/rec_length+1));
del=info->state->del; del=info->state->del;
param->glob_crc=0;
if (!(sort_param=(MARIA_SORT_PARAM *) if (!(sort_param=(MARIA_SORT_PARAM *)
my_malloc((uint) share->base.keys * my_malloc((uint) share->base.keys *
...@@ -3722,9 +3749,10 @@ err: ...@@ -3722,9 +3749,10 @@ err:
the share by remove_io_thread() or it was not yet started (if the the share by remove_io_thread() or it was not yet started (if the
error happend before creating the thread). error happend before creating the thread).
*/ */
VOID(end_io_cache(&info->rec_cache)); VOID(end_io_cache(&sort_info.new_info->rec_cache));
VOID(end_io_cache(&param->read_cache)); VOID(end_io_cache(&param->read_cache));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
/* /*
Destroy the new data cache in case of non-quick repair. All slave Destroy the new data cache in case of non-quick repair. All slave
threads did either detach from the share by remove_io_thread() threads did either detach from the share by remove_io_thread()
...@@ -3799,15 +3827,18 @@ static int sort_key_read(MARIA_SORT_PARAM *sort_param, uchar *key) ...@@ -3799,15 +3827,18 @@ static int sort_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
sort_param->key+1); sort_param->key+1);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (_ma_sort_write_record(sort_param))
DBUG_RETURN(1);
sort_param->real_key_length= sort_param->real_key_length=
(info->s->rec_reflength+ (info->s->rec_reflength+
_ma_make_key(info, sort_param->key, key, _ma_make_key(info, sort_param->key, key,
sort_param->record, sort_param->filepos)); sort_param->record, sort_param->current_filepos));
#ifdef HAVE_purify #ifdef HAVE_purify
bzero(key+sort_param->real_key_length, bzero(key+sort_param->real_key_length,
(sort_param->key_length-sort_param->real_key_length)); (sort_param->key_length-sort_param->real_key_length));
#endif #endif
DBUG_RETURN(_ma_sort_write_record(sort_param)); DBUG_RETURN(0);
} /* sort_key_read */ } /* sort_key_read */
...@@ -3826,13 +3857,14 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key) ...@@ -3826,13 +3857,14 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE)); free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
if ((error=sort_get_next_record(sort_param))) if ((error=sort_get_next_record(sort_param)))
DBUG_RETURN(error); DBUG_RETURN(error);
if ((error= _ma_sort_write_record(sort_param)))
DBUG_RETURN(error);
if (!(wptr= _ma_ft_parserecord(info,sort_param->key,sort_param->record, if (!(wptr= _ma_ft_parserecord(info,sort_param->key,sort_param->record,
&sort_param->wordroot))) &sort_param->wordroot)))
DBUG_RETURN(1); DBUG_RETURN(1);
if (wptr->pos) if (wptr->pos)
break; break;
error=_ma_sort_write_record(sort_param);
} }
sort_param->wordptr=sort_param->wordlist=wptr; sort_param->wordptr=sort_param->wordlist=wptr;
} }
...@@ -3845,7 +3877,7 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key) ...@@ -3845,7 +3877,7 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
sort_param->real_key_length=(info->s->rec_reflength+ sort_param->real_key_length=(info->s->rec_reflength+
_ma_ft_make_key(info, sort_param->key, _ma_ft_make_key(info, sort_param->key,
key, wptr++, key, wptr++,
sort_param->filepos)); sort_param->current_filepos));
#ifdef HAVE_purify #ifdef HAVE_purify
if (sort_param->key_length > sort_param->real_key_length) if (sort_param->key_length > sort_param->real_key_length)
bzero(key+sort_param->real_key_length, bzero(key+sort_param->real_key_length,
...@@ -3855,7 +3887,6 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key) ...@@ -3855,7 +3887,6 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
{ {
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE)); free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
sort_param->wordlist=0; sort_param->wordlist=0;
error=_ma_sort_write_record(sort_param);
} }
else else
sort_param->wordptr=(void*)wptr; sort_param->wordptr=(void*)wptr;
...@@ -3891,8 +3922,9 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key) ...@@ -3891,8 +3922,9 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
RETURN RETURN
-1 end of file -1 end of file
0 ok 0 ok
sort_param->filepos points to record position. sort_param->current_filepos points to record position.
sort_param->record contains record sort_param->record contains record
sort_param->max_pos contains position to last byte read
> 0 error > 0 error
*/ */
...@@ -3957,12 +3989,13 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -3957,12 +3989,13 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
info->cur_row.checksum= checksum; info->cur_row.checksum= checksum;
param->glob_crc+= checksum; param->glob_crc+= checksum;
} }
sort_param->start_recpos= sort_param->filepos= info->cur_row.lastpos; sort_param->start_recpos= sort_param->current_filepos=
info->cur_row.lastpos;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if (flag == HA_ERR_END_OF_FILE) if (flag == HA_ERR_END_OF_FILE)
{ {
sort_param->max_pos= sort_info->filelength; sort_param->max_pos= info->state->data_file_length;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
/* Retry only if wrong record, not if disk error */ /* Retry only if wrong record, not if disk error */
...@@ -3986,7 +4019,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -3986,7 +4019,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
sort_param->start_recpos=sort_param->pos; sort_param->start_recpos=sort_param->pos;
if (!sort_param->fix_datafile) if (!sort_param->fix_datafile)
{ {
sort_param->filepos=sort_param->pos; sort_param->current_filepos= sort_param->pos;
if (sort_param->master) if (sort_param->master)
share->state.split++; share->state.split++;
} }
...@@ -4136,7 +4169,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -4136,7 +4169,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (!searching) if (!searching)
_ma_check_print_info(param, _ma_check_print_info(param,
"Found block with impossible length %u at %s; Skipped", "Found block with impossible length %u at %s; Skipped",
block_info.block_len+ (uint) (block_info.filepos-pos), block_info.block_len+
(uint) (block_info.filepos-pos),
llstr(pos,llbuff)); llstr(pos,llbuff));
if (found_record) if (found_record)
goto try_next; goto try_next;
...@@ -4176,7 +4210,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -4176,7 +4210,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
sort_param->find_length=left_length=block_info.rec_len; sort_param->find_length=left_length=block_info.rec_len;
sort_param->start_recpos=pos; sort_param->start_recpos=pos;
if (!sort_param->fix_datafile) if (!sort_param->fix_datafile)
sort_param->filepos=sort_param->start_recpos; sort_param->current_filepos= sort_param->start_recpos;
if (sort_param->fix_datafile && (param->testflag & T_EXTEND)) if (sort_param->fix_datafile && (param->testflag & T_EXTEND))
sort_param->pos=block_info.filepos+1; sort_param->pos=block_info.filepos+1;
else else
...@@ -4348,6 +4382,10 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -4348,6 +4382,10 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
llstr(sort_param->pos,llbuff)); llstr(sort_param->pos,llbuff));
continue; continue;
} }
#ifdef HAVE_purify
bzero(sort_param->rec_buff + block_info.rec_len,
info->s->base.extra_rec_buff_size);
#endif
if (_ma_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record, if (_ma_pack_rec_unpack(info, &sort_param->bit_buff, sort_param->record,
sort_param->rec_buff, block_info.rec_len)) sort_param->rec_buff, block_info.rec_len))
{ {
...@@ -4358,11 +4396,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -4358,11 +4396,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
} }
if (!sort_param->fix_datafile) if (!sort_param->fix_datafile)
{ {
sort_param->filepos=sort_param->pos; sort_param->current_filepos= sort_param->pos;
if (sort_param->master) if (sort_param->master)
share->state.split++; share->state.split++;
} }
sort_param->max_pos=(sort_param->pos=block_info.filepos+ sort_param->max_pos= (sort_param->pos=block_info.filepos+
block_info.rec_len); block_info.rec_len);
info->packed_length=block_info.rec_len; info->packed_length=block_info.rec_len;
...@@ -4380,19 +4418,22 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -4380,19 +4418,22 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
} }
/* /**
Write record to new file. @brief Write record to new file.
SYNOPSIS @fn _ma_sort_write_record()
_ma_sort_write_record() @param sort_param Sort parameters.
sort_param Sort parameters.
NOTE @note
This is only called by a master thread if parallel repair is used. This is only called by a master thread if parallel repair is used.
RETURN @return
0 OK @retval 0 OK
1 Error sort_param->current_filepos points to inserted record for
block_records and to the place for the next record for
other row types.
sort_param->filepos points to end of file
@retval 1 Error
*/ */
int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param) int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
...@@ -4410,13 +4451,15 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param) ...@@ -4410,13 +4451,15 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
if (sort_param->fix_datafile) if (sort_param->fix_datafile)
{ {
sort_param->current_filepos= sort_param->filepos;
switch (sort_info->new_data_file_type) { switch (sort_info->new_data_file_type) {
case BLOCK_RECORD: case BLOCK_RECORD:
if ((sort_param->filepos= (*share->write_record_init)(info, if ((sort_param->current_filepos=
sort_param-> (*share->write_record_init)(info, sort_param->record)) ==
record)) ==
HA_OFFSET_ERROR) HA_OFFSET_ERROR)
DBUG_RETURN(1); DBUG_RETURN(1);
/* Pointer to end of file */
sort_param->filepos= info->state->data_file_length;
break; break;
case STATIC_RECORD: case STATIC_RECORD:
if (my_b_write(&info->rec_cache,sort_param->record, if (my_b_write(&info->rec_cache,sort_param->record,
...@@ -4820,7 +4863,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param, ...@@ -4820,7 +4863,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
} /* sort_insert_key */ } /* sort_insert_key */
/* Delete record when we found a duplicated key */ /* Delete record when we found a duplicated key */
static int sort_delete_record(MARIA_SORT_PARAM *sort_param) static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
{ {
...@@ -4829,57 +4872,61 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param) ...@@ -4829,57 +4872,61 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
uchar *key; uchar *key;
MARIA_SORT_INFO *sort_info=sort_param->sort_info; MARIA_SORT_INFO *sort_info=sort_param->sort_info;
HA_CHECK *param=sort_info->param; HA_CHECK *param=sort_info->param;
MARIA_HA *info=sort_info->info; MARIA_HA *row_info= sort_info->new_info, *key_info= sort_info->info;
DBUG_ENTER("sort_delete_record"); DBUG_ENTER("sort_delete_record");
if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK) if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
{ {
_ma_check_print_error(param, _ma_check_print_error(param,
"Quick-recover aborted; Run recovery without switch -q or with switch -qq"); "Quick-recover aborted; Run recovery without switch -q or with "
"switch -qq");
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (info->s->options & HA_OPTION_COMPRESS_RECORD) if (key_info->s->options & HA_OPTION_COMPRESS_RECORD)
{ {
_ma_check_print_error(param, _ma_check_print_error(param,
"Recover aborted; Can't run standard recovery on compressed tables with errors in data-file. Use switch 'maria_chk --safe-recover' to fix it\n",stderr);; "Recover aborted; Can't run standard recovery on compressed tables "
"with errors in data-file. Use 'maria_chk --safe-recover' "
"to fix it",stderr);;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
old_file= info->dfile.file; old_file= row_info->dfile.file;
info->dfile.file= info->rec_cache.file; /* This only affects static and dynamic row formats */
row_info->dfile.file= row_info->rec_cache.file;
if (sort_info->current_key) if (sort_info->current_key)
{ {
key= info->lastkey+info->s->base.max_key_length; key= key_info->lastkey + key_info->s->base.max_key_length;
if ((error=(*info->s->read_record)(info,sort_param->record, if ((error=(*row_info->s->read_record)(row_info, sort_param->record,
info->cur_row.lastpos)) && key_info->cur_row.lastpos)) &&
error != HA_ERR_RECORD_DELETED) error != HA_ERR_RECORD_DELETED)
{ {
_ma_check_print_error(param,"Can't read record to be removed"); _ma_check_print_error(param,"Can't read record to be removed");
info->dfile.file= old_file; row_info->dfile.file= old_file;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
for (i=0 ; i < sort_info->current_key ; i++) for (i=0 ; i < sort_info->current_key ; i++)
{ {
uint key_length= _ma_make_key(info, i, key, sort_param->record, uint key_length= _ma_make_key(key_info, i, key, sort_param->record,
info->cur_row.lastpos); key_info->cur_row.lastpos);
if (_ma_ck_delete(info, i, key, key_length)) if (_ma_ck_delete(key_info, i, key, key_length))
{ {
_ma_check_print_error(param, _ma_check_print_error(param,
"Can't delete key %d from record to be removed", "Can't delete key %d from record to be removed",
i+1); i+1);
info->dfile.file= old_file; row_info->dfile.file= old_file;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
if (sort_param->calc_checksum) if (sort_param->calc_checksum)
param->glob_crc-=(*info->s->calc_check_checksum)(info, param->glob_crc-=(*key_info->s->calc_check_checksum)(key_info,
sort_param->record); sort_param->record);
} }
error= (flush_io_cache(&info->rec_cache) || error= (flush_io_cache(&row_info->rec_cache) ||
(*info->s->delete_record)(info, sort_param->record)); (*row_info->s->delete_record)(row_info, sort_param->record));
info->dfile.file= old_file; /* restore actual value */ row_info->dfile.file= old_file; /* restore actual value */
info->state->records--; row_info->state->records--;
DBUG_RETURN(error); DBUG_RETURN(error);
} /* sort_delete_record */ } /* sort_delete_record */
...@@ -5184,6 +5231,7 @@ int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile) ...@@ -5184,6 +5231,7 @@ int maria_write_data_suffix(MARIA_SORT_INFO *sort_info, my_bool fix_datafile)
int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update) int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
{ {
MARIA_SHARE *share=info->s; MARIA_SHARE *share=info->s;
DBUG_ENTER("maria_update_state_info");
if (update & UPDATE_OPEN_COUNT) if (update & UPDATE_OPEN_COUNT)
{ {
...@@ -5233,14 +5281,14 @@ int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update) ...@@ -5233,14 +5281,14 @@ int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
share->w_locks=w_locks; share->w_locks=w_locks;
share->tot_locks=r_locks+w_locks; share->tot_locks=r_locks+w_locks;
if (!error) if (!error)
return 0; DBUG_RETURN(0);
} }
err: err:
_ma_check_print_error(param,"%d when updating keyfile",my_errno); _ma_check_print_error(param,"%d when updating keyfile",my_errno);
return 1; DBUG_RETURN(1);
} }
/* /*
Update auto increment value for a table Update auto increment value for a table
When setting the 'repair_only' flag we only want to change the When setting the 'repair_only' flag we only want to change the
old auto_increment value if its wrong (smaller than some given key). old auto_increment value if its wrong (smaller than some given key).
...@@ -5251,7 +5299,7 @@ err: ...@@ -5251,7 +5299,7 @@ err:
If repair_only is not set, we will update the flag to the value in If repair_only is not set, we will update the flag to the value in
param->auto_increment is bigger than the biggest key. param->auto_increment is bigger than the biggest key.
*/ */
void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info, void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info,
my_bool repair_only) my_bool repair_only)
...@@ -5474,9 +5522,6 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows, ...@@ -5474,9 +5522,6 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows,
*/ */
if (! maria_is_any_key_active(key_map)) if (! maria_is_any_key_active(key_map))
return FALSE; /* Can't use sort */ return FALSE; /* Can't use sort */
/* QQ: Remove this when maria_repair_by_sort() works with block format */
if (info->s->data_file_type == BLOCK_RECORD)
return FALSE;
for (i=0 ; i < share->base.keys ; i++,key++) for (i=0 ; i < share->base.keys ; i++,key++)
{ {
if (!force && maria_too_big_key_for_sort(key,rows)) if (!force && maria_too_big_key_for_sort(key,rows))
...@@ -5486,6 +5531,53 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows, ...@@ -5486,6 +5531,53 @@ my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows,
} }
/**
@brief Create a new handle for manipulation the new record file
@note
It's ok for Recovery to have two MARIA_SHARE on the same index file
because the one we create here is not transactional
*/
my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file)
{
MARIA_SORT_INFO *sort_info= param->sort_info;
MARIA_HA *info= sort_info->info;
MARIA_HA *new_info;
DBUG_ENTER("create_new_data_handle");
if (!(sort_info->new_info= maria_open(info->s->open_file_name, O_RDWR,
HA_OPEN_COPY | HA_OPEN_FOR_REPAIR)))
DBUG_RETURN(1);
new_info= sort_info->new_info;
change_data_file_descriptor(new_info, new_file);
maria_lock_database(new_info, F_EXTRA_LCK);
if ((sort_info->param->testflag & T_UNPACK) &&
info->s->data_file_type == COMPRESSED_RECORD)
{
(*new_info->s->once_end)(new_info->s);
(*new_info->s->end)(new_info);
restore_data_file_type(new_info->s);
_ma_setup_functions(new_info->s);
if ((*new_info->s->once_init)(new_info->s, new_file) ||
(*new_info->s->init)(new_info))
DBUG_RETURN(1);
}
_ma_reset_status(new_info);
if (_ma_initialize_data_file(new_info->s, new_file))
DBUG_RETURN(1);
param->filepos= new_info->state->data_file_length;
/* Use new virtual functions for key generation */
info->s->keypos_to_recpos= new_info->s->keypos_to_recpos;
info->s->recpos_to_keypos= new_info->s->recpos_to_keypos;
DBUG_RETURN(0);
}
static void static void
set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share) set_data_file_type(MARIA_SORT_INFO *sort_info, MARIA_SHARE *share)
{ {
...@@ -5525,6 +5617,22 @@ static void change_data_file_descriptor(MARIA_HA *info, File new_file) ...@@ -5525,6 +5617,22 @@ static void change_data_file_descriptor(MARIA_HA *info, File new_file)
{ {
my_close(info->dfile.file, MYF(MY_WME)); my_close(info->dfile.file, MYF(MY_WME));
info->dfile.file= info->s->bitmap.file.file= new_file; info->dfile.file= info->s->bitmap.file.file= new_file;
_ma_bitmap_reset_cache(info->s);
}
/**
@brief Mark the data file to not be used
@note
This is used in repair when we want to ensure the handler will not
write anything to the data file anymore
*/
static void unuse_data_file_descriptor(MARIA_HA *info)
{
info->dfile.file= info->s->bitmap.file.file= -1;
_ma_bitmap_reset_cache(info->s);
} }
...@@ -5701,8 +5809,12 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info) ...@@ -5701,8 +5809,12 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
{ {
MARIA_SHARE *share= info->s; MARIA_SHARE *share= info->s;
/* in case this is maria_chk or recovery... */ /* in case this is maria_chk or recovery... */
if (translog_inited && !maria_in_recovery) if (translog_inited && !maria_in_recovery &&
info->s->base.born_transactional)
{ {
my_bool now_transactional= info->s->now_transactional;
info->s->now_transactional= 1;
/* /*
For now this record is only informative. It could serve when applying For now this record is only informative. It could serve when applying
logs to a backup, but that needs more thought. Assume table became logs to a backup, but that needs more thought. Assume table became
...@@ -5745,6 +5857,7 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info) ...@@ -5745,6 +5857,7 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
*/ */
if (_ma_update_create_rename_lsn(share, lsn, TRUE)) if (_ma_update_create_rename_lsn(share, lsn, TRUE))
return 1; return 1;
info->s->now_transactional= now_transactional;
} }
return 0; return 0;
} }
......
...@@ -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()
......
...@@ -47,40 +47,40 @@ Dying on request without maria_commit()/maria_close() ...@@ -47,40 +47,40 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=2 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=2 (additional aborted work)
...@@ -117,40 +117,40 @@ Dying on request without maria_commit()/maria_close() ...@@ -117,40 +117,40 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=3 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N --testflag=2 --test-undo=3 (additional aborted work)
...@@ -187,40 +187,40 @@ Dying on request without maria_commit()/maria_close() ...@@ -187,40 +187,40 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 81920 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 81920 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 81920 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=1 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=1 (additional aborted work)
...@@ -257,40 +257,40 @@ Dying on request without maria_commit()/maria_close() ...@@ -257,40 +257,40 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=2 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=2 (additional aborted work)
...@@ -327,40 +327,40 @@ Dying on request without maria_commit()/maria_close() ...@@ -327,40 +327,40 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N -b --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=3 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N -b --testflag=2 --test-undo=3 (additional aborted work)
...@@ -397,11 +397,11 @@ Dying on request without maria_commit()/maria_close() ...@@ -397,11 +397,11 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 122880 Keyfile length: 212992
...@@ -410,27 +410,27 @@ testing idempotency ...@@ -410,27 +410,27 @@ testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=2 --test-undo=1 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=2 --test-undo=1 (additional aborted work)
...@@ -467,40 +467,40 @@ Dying on request without maria_commit()/maria_close() ...@@ -467,40 +467,40 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=2 --test-undo=2 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N -H1 --testflag=2 --test-undo=2 (additional aborted work)
...@@ -537,37 +537,37 @@ Dying on request without maria_commit()/maria_close() ...@@ -537,37 +537,37 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 114688 Keyfile length: 204800
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 90112 Keyfile length: 204800 > Datafile length: 90112 Keyfile length: 204800
...@@ -607,11 +607,11 @@ Dying on request without maria_commit()/maria_close() ...@@ -607,11 +607,11 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 81920 Keyfile length: 204800 > Datafile length: 81920 Keyfile length: 204800
...@@ -620,11 +620,11 @@ testing idempotency ...@@ -620,11 +620,11 @@ testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 81920 Keyfile length: 204800 > Datafile length: 81920 Keyfile length: 204800
...@@ -633,11 +633,11 @@ testing applying of CLRs to recreate table ...@@ -633,11 +633,11 @@ testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 81920 Keyfile length: 204800 > Datafile length: 81920 Keyfile length: 204800
...@@ -677,40 +677,40 @@ Dying on request without maria_commit()/maria_close() ...@@ -677,40 +677,40 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing idempotency testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
TEST WITH ma_test1 -s -M -T -c -N -b -H1 --testflag=1 (commit at end) TEST WITH ma_test1 -s -M -T -c -N -b -H1 --testflag=1 (commit at end)
TEST WITH ma_test1 -s -M -T -c -N -b -H1 --testflag=2 --test-undo=2 (additional aborted work) TEST WITH ma_test1 -s -M -T -c -N -b -H1 --testflag=2 --test-undo=2 (additional aborted work)
...@@ -747,11 +747,11 @@ Dying on request without maria_commit()/maria_close() ...@@ -747,11 +747,11 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 122880 Keyfile length: 212992
...@@ -760,11 +760,11 @@ testing idempotency ...@@ -760,11 +760,11 @@ testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 122880 Keyfile length: 212992
...@@ -773,11 +773,11 @@ testing applying of CLRs to recreate table ...@@ -773,11 +773,11 @@ testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 122880 Keyfile length: 212992
...@@ -817,11 +817,11 @@ Dying on request without maria_commit()/maria_close() ...@@ -817,11 +817,11 @@ Dying on request without maria_commit()/maria_close()
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 122880 Keyfile length: 212992
...@@ -830,25 +830,25 @@ testing idempotency ...@@ -830,25 +830,25 @@ testing idempotency
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
testing applying of CLRs to recreate table testing applying of CLRs to recreate table
applying log applying log
Differences in maria_chk -dvv, recovery not yet perfect ! Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START======= ========DIFF START=======
7c7 6c6
< Status: checked,analyzed,optimized keys,sorted index pages < Status: checked,analyzed,optimized keys,sorted index pages
--- ---
> Status: changed > Status: changed
12c12 11c11
< Datafile length: 8192 Keyfile length: 8192 < Datafile length: 8192 Keyfile length: 8192
--- ---
> Datafile length: 122880 Keyfile length: 212992 > Datafile length: 155648 Keyfile length: 212992
========DIFF END======= ========DIFF END=======
...@@ -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)
...@@ -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");
......
...@@ -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