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
ulonglong unique[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 maxbuffers, keys, find_length, sort_keys_length;
my_bool fix_datafile, master;
......@@ -392,18 +392,16 @@ typedef struct st_maria_sort_param
/* functions in maria_check */
void maria_chk_init(HA_CHECK *param);
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_key(HA_CHECK *param, MARIA_HA *info);
int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, int extend);
int maria_repair(HA_CHECK *param, register MARIA_HA *info,
char * name, int rep_quick);
int maria_sort_index(HA_CHECK *param, register MARIA_HA *info,
char * name);
int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
const char *name, int rep_quick);
int maria_repair(HA_CHECK *param, MARIA_HA *info, char * name, uint rep_quick);
int maria_sort_index(HA_CHECK *param, MARIA_HA *info, char * name);
int maria_repair_by_sort(HA_CHECK *param, MARIA_HA *info,
const char *name, uint rep_quick);
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,
const char *new_ext, myf myflags);
void maria_lock_memory(HA_CHECK *param);
......
......@@ -625,7 +625,7 @@ t1 1 a 1 a A NULL NULL NULL YES BTREE disabled
alter table t1 enable keys;
show keys from t1;
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 disable keys;
Warnings:
......@@ -1957,12 +1957,12 @@ create table t2 like t1;
insert into t2 select * from t1;
analyze table t2;
Table Op Msg_type Msg_text
test.t2 analyze status OK
test.t2 analyze status Table is already up to date
delete from t2;
insert into t2 select * from t1;
analyze table t2;
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;
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;
......
......@@ -1834,6 +1834,7 @@ int end_io_cache(IO_CACHE *info)
pthread_mutex_destroy(&info->append_buffer_lock);
#endif
}
info->share= 0;
DBUG_RETURN(error);
} /* end_io_cache */
......
......@@ -124,9 +124,6 @@
#include "maria_def.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_TAIL_PAGE 7
......@@ -187,7 +184,6 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
return 1;
bitmap->file.file= file;
bitmap->changed= 0;
bitmap->block_size= share->block_size;
/* Size needs to be alligned on 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)
pthread_mutex_init(&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW);
/*
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.
*/
_ma_bitmap_reset_cache(share);
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)
{
/* Start scanning for free space from start of file */
......@@ -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'
......@@ -1630,7 +1651,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
{
MARIA_SHARE *share= info->s;
my_bool res= 1;
uint full_page_size, position;
uint position;
uint head_length, row_length, rest_length, extents_length;
ulonglong bitmap_page;
DBUG_ENTER("_ma_bitmap_find_new_place");
......@@ -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' */
row_length= find_where_to_split_row(share, row, extents_length, free_size);
full_page_size= FULL_PAGE_SIZE(share->block_size);
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 */
use_head(info, page, row_length, position);
rest_length= head_length - row_length;
......
......@@ -456,6 +456,7 @@ my_bool _ma_once_end_block_record(MARIA_SHARE *share)
my_bool _ma_init_block_record(MARIA_HA *info)
{
MARIA_ROW *row= &info->cur_row, *new_row= &info->new_row;
uint default_extents;
DBUG_ENTER("_ma_init_block_record");
if (!my_multi_malloc(MY_WME,
......@@ -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 */
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,
sizeof(MARIA_BITMAP_BLOCK),
ELEMENTS_RESERVED_FOR_MAIN_PART, 16))
sizeof(MARIA_BITMAP_BLOCK), default_extents,
64))
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;
/*
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'
*/
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,
column < end_column; column++)
{
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)))
goto err;
memcpy(record + column->offset, data, column_length);
......@@ -3731,7 +3742,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
case FIELD_NORMAL: /* Fixed length field */
case FIELD_SKIP_PRESPACE:
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)))
goto err;
memcpy(field_pos, data, column->length);
......@@ -4991,6 +5002,7 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
MARIA_PINNED_PAGE page_link;
enum pagecache_page_lock unlock_method;
enum pagecache_page_pin unpin_method;
my_off_t end_of_page;
DBUG_ENTER("_ma_apply_redo_insert_row_head_or_tail");
page= page_korr(header);
......@@ -5000,8 +5012,12 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn,
(ulong) ma_recordpos(page, rownr),
(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
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,
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.
*/
{
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);
err:
......
......@@ -29,8 +29,8 @@
PAGE_SUFFIX_SIZE)
#define BLOCK_RECORD_POINTER_SIZE 6
#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - PAGE_TYPE_SIZE - \
PAGE_SUFFIX_SIZE)
#define FULL_PAGE_SIZE(block_size) ((block_size) - LSN_SIZE - \
PAGE_TYPE_SIZE - PAGE_SUFFIX_SIZE)
#define ROW_EXTENT_PAGE_SIZE 5
#define ROW_EXTENT_COUNT_SIZE 2
......@@ -40,12 +40,16 @@
#define TAIL_BIT 0x8000 /* Bit in page_count to signify tail */
/* Number of extents reserved MARIA_BITMAP_BLOCKS to store head part */
#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 */
#define EXTRA_LENGTH_FIELDS 3
/* Size for the different parts in the row header (and head page) */
#define FLAG_SIZE 1
#define TRANSID_SIZE 6
#define VERPTR_SIZE 7
#define DIR_ENTRY_SIZE 4
#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,
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
my_bool _ma_bitmap_end(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,
MARIA_BITMAP_BLOCKS *result_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);
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 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,
MARIA_HA *info, uchar *record);
static void copy_data_file_state(MARIA_STATE_INFO *to,
MARIA_STATE_INFO *from);
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);
my_bool create_new_data_handle(MARIA_SORT_PARAM *param, File new_file);
void maria_chk_init(HA_CHECK *param)
{
......@@ -2031,6 +2034,38 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info,int extend)
} /* 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
......@@ -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,
char *name, int rep_quick)
char *name, uint rep_quick)
{
int error, got_error= 1;
uint i;
......@@ -2071,26 +2106,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
MY_SYNC_DIR : 0);
DBUG_ENTER("maria_repair");
bzero((char *)&sort_info, sizeof(sort_info));
bzero((char *)&sort_param, sizeof(sort_param));
initialize_variables_for_repair(param, &sort_info, &sort_param, info,
rep_quick);
start_records=info->state->records;
new_header_length=(param->testflag & T_UNPACK) ? 0L :
share->pack.header_length;
new_header_length= ((param->testflag & T_UNPACK) ? 0L :
share->pack.header_length);
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))
{
printf("- recovering (with keycache) MARIA-table '%s'\n",name);
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
......@@ -2121,43 +2148,18 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
new_header_length, "datafile-header"))
goto err;
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 ||
(param->testflag & T_UNPACK))
{
MARIA_HA *new_info;
/*
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;
}
_ma_reset_status(sort_info.new_info);
if (_ma_initialize_data_file(sort_info.new_info->s, new_file))
if (create_new_data_handle(&sort_param, 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;
sort_info.new_info->rec_cache.file= new_file;
}
}
block_record= sort_info.new_info->s->data_file_type == BLOCK_RECORD;
if (org_data_file_type != BLOCK_RECORD)
{
/* 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,
{
/* When writing to not block records, we need a write buffer */
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,
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;
info->opt_flag|=WRITE_CACHE_USED;
sort_info.new_info->opt_flag|=WRITE_CACHE_USED;
}
}
else
else if (block_record)
{
scan_inited= 1;
if (maria_scan_init(sort_info.info))
......@@ -2193,26 +2197,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
goto err;
}
sort_info.param = param;
sort_param.read_cache=param->read_cache;
sort_param.pos=sort_param.max_pos=share->pack.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));
sort_info.dupp=0;
sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master=1;
sort_info.max_records= ~(ha_rows) 0;
set_data_file_type(&sort_info, share);
del=info->state->del;
info->state->records=info->state->del=share->state.split=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
......@@ -2235,8 +2230,6 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
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. */
while (!(error=sort_get_next_record(&sort_param)))
{
......@@ -2248,7 +2241,8 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
if (my_errno != HA_ERR_FOUND_DUPP_KEY)
goto err;
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,
llstr(sort_param.start_recpos,llbuff),
llstr(info->dup_key_pos,llbuff2));
......@@ -2279,11 +2273,17 @@ int maria_repair(HA_CHECK *param, register MARIA_HA *info,
}
/* purecov: end */
}
if (!block_record && _ma_sort_write_record(&sort_param))
goto err;
if (!block_record)
{
if (_ma_sort_write_record(&sort_param))
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) ||
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;
if (param->testflag & T_WRITE_LOOP)
......@@ -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)
{
sort_info.new_info->state->data_file_length= sort_param.filepos;
if (sort_info.new_info != sort_info.info)
{
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,
}
copy_data_file_state(&info->s->state, &save_state);
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 */
/* Replace the actual file with the temporary file */
......@@ -2376,38 +2381,25 @@ err:
maria_scan_end(sort_info.info);
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);
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
/* 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 (! param->error_printed)
_ma_check_print_error(param,"%d for record at pos %s",my_errno,
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)
{
/**
@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;
unuse_data_file_descriptor(sort_info.new_info);
maria_close(sort_info.new_info);
}
if (new_file >= 0)
{
VOID(my_close(new_file,MYF(0)));
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);
}
......@@ -2439,7 +2431,7 @@ static int writekeys(MARIA_SORT_PARAM *sort_param)
uchar *key;
MARIA_HA *info= sort_param->sort_info->info;
uchar *buff= sort_param->record;
my_off_t filepos= sort_param->filepos;
my_off_t filepos= sort_param->current_filepos;
DBUG_ENTER("writekeys");
key= info->lastkey+info->s->base.max_key_length;
......@@ -2866,7 +2858,7 @@ err:
*/
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;
uint i;
......@@ -2883,57 +2875,32 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
ulonglong key_map=share->state.key_map;
myf sync_dir= ((share->now_transactional && !share->temporary) ?
MY_SYNC_DIR : 0);
my_bool scan_inited= 0;
DBUG_ENTER("maria_repair_by_sort");
bzero((char*)&sort_info,sizeof(sort_info));
bzero((char *)&sort_param, sizeof(sort_param));
start_records=info->state->records;
start_records= info->state->records;
initialize_variables_for_repair(param, &sort_info, &sort_param, info,
rep_quick);
got_error=1;
new_file= -1;
org_header_length= share->pack.header_length;
new_header_length= (param->testflag & T_UNPACK) ? 0 : org_header_length;
sort_param.filepos= new_header_length;
if (!(param->testflag & T_SILENT))
{
printf("- recovering (with sort) MARIA-table '%s'\n",name);
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,
FLUSH_FORCE_WRITE, FLUSH_IGNORE_CHANGED))
goto err;
if (!(sort_info.key_block=
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)))
FLUSH_FORCE_WRITE,
(param->testflag & T_CREATE_MISSING_KEYS) ?
FLUSH_FORCE_WRITE : FLUSH_IGNORE_CHANGED) ||
_ma_state_info_write(share, 1|2|4))
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)
{
/* Get real path for data file */
......@@ -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,
new_header_length, "datafile-header"))
goto err;
if (param->testflag & T_UNPACK)
restore_data_file_type(share);
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))
{
/*
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 */
for (i=0 ; i < share->base.keys ; i++)
share->state.key_root[i]= HA_OFFSET_ERROR;
......@@ -2973,22 +2977,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
info->state->key_file_length=share->base.keystart;
}
else
{
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
FLUSH_FORCE_WRITE))
goto err;
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);
sort_param.filepos=new_header_length;
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));
param->read_cache.end_of_file= sort_info.filelength=
my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
sort_param.wordlist=NULL;
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,
sort_param.key_cmp=sort_key_cmp;
sort_param.lock_in_memory=maria_lock_memory;
sort_param.tmpdir=param->tmpdir;
sort_param.sort_info=&sort_info;
sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master =1;
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;
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,
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,
(my_bool) (!(param->testflag & T_VERBOSE)),
(size_t) param->sort_buffer_length))
......@@ -3098,26 +3091,36 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
param->retry_repair=1;
goto err;
}
if (scan_inited)
{
scan_inited= 0;
maria_scan_end(sort_info.info);
}
/* No need to calculate checksum again. */
sort_param.calc_checksum= 0;
free_root(&sort_param.wordroot, MYF(0));
/* 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)
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part,
sort_param.unique,
param->stats_method == MI_STATS_METHOD_IGNORE_NULLS?
sort_param.notnull : NULL,
(param->stats_method ==
MI_STATS_METHOD_IGNORE_NULLS ?
sort_param.notnull : NULL),
(ulonglong) info->state->records);
maria_set_key_active(share->state.key_map, sort_param.key);
if (sort_param.fix_datafile)
{
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;
sort_info.new_info->opt_flag&= ~WRITE_CACHE_USED;
if (param->testflag & T_SAFE_REPAIR)
{
/* 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,
goto err;
}
}
share->state.state.data_file_length = info->state->data_file_length=
sort_param.filepos;
/* Only whole records */
share->state.version=(ulong) time((time_t*) 0);
my_close(info->dfile.file, MYF(0));
info->dfile.file= new_file;
share->data_file_type= sort_info.new_data_file_type;
org_header_length= (ulong) new_header_length;
if (_ma_flush_table_files_after_repair(param, info))
goto err;
sort_info.new_info->state->data_file_length= sort_param.filepos;
if (sort_info.new_info != sort_info.info)
{
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.filelength= info->state->data_file_length;
sort_param.fix_datafile=0;
}
else
......@@ -3177,6 +3213,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
"Can't change size of datafile, error: %d",
my_errno);
}
if (param->testflag & T_CALC_CHECKSUM)
info->state->checksum=param->glob_crc;
......@@ -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));
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));
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
got_error|= _ma_flush_table_files_after_repair(param, info);
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;
}
}
sort_info.new_info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
if (got_error)
{
if (! param->error_printed)
_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)
{
VOID(my_close(new_file,MYF(0)));
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);
}
else if (key_map == share->state.key_map)
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
else
{
if (key_map == share->state.key_map)
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_OPTIMIZED_ROWS;
......@@ -3243,8 +3279,6 @@ err:
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(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
if (!got_error && (param->testflag & T_UNPACK))
restore_data_file_type(share);
DBUG_RETURN(got_error);
}
......@@ -3291,7 +3325,7 @@ err:
*/
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
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,
ha_rows start_records;
my_off_t new_header_length,del;
File new_file;
MARIA_SORT_PARAM *sort_param=0;
MARIA_SORT_PARAM *sort_param=0, tmp_sort_param;
MARIA_SHARE *share=info->s;
double *rec_per_key_part;
HA_KEYSEG *keyseg;
......@@ -3316,6 +3350,9 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
MY_SYNC_DIR : 0;
DBUG_ENTER("maria_repair_parallel");
initialize_variables_for_repair(param, &sort_info, &tmp_sort_param, info,
rep_quick);
start_records=info->state->records;
got_error=1;
new_file= -1;
......@@ -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("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;
......@@ -3364,13 +3400,11 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
}
*/
DBUG_PRINT("info", ("is quick repair: %d", rep_quick));
bzero((char*)&sort_info,sizeof(sort_info));
/* Initialize pthread structures before goto err. */
pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&sort_info.cond, 0);
sort_info.org_data_file_type= info->s->data_file_type;
if (!(sort_info.key_block=
alloc_key_blocks(param, (uint) param->sort_key_blocks,
share->base.max_key_block_length)) ||
......@@ -3438,14 +3472,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
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);
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));
param->read_cache.end_of_file= sort_info.filelength=
my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
if (sort_info.org_data_file_type == DYNAMIC_RECORD)
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,
(ha_rows) (sort_info.filelength/rec_length+1));
del=info->state->del;
param->glob_crc=0;
if (!(sort_param=(MARIA_SORT_PARAM *)
my_malloc((uint) share->base.keys *
......@@ -3722,9 +3749,10 @@ err:
the share by remove_io_thread() or it was not yet started (if the
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));
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
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)
sort_param->key+1);
DBUG_RETURN(1);
}
if (_ma_sort_write_record(sort_param))
DBUG_RETURN(1);
sort_param->real_key_length=
(info->s->rec_reflength+
_ma_make_key(info, sort_param->key, key,
sort_param->record, sort_param->filepos));
sort_param->record, sort_param->current_filepos));
#ifdef HAVE_purify
bzero(key+sort_param->real_key_length,
(sort_param->key_length-sort_param->real_key_length));
#endif
DBUG_RETURN(_ma_sort_write_record(sort_param));
DBUG_RETURN(0);
} /* sort_key_read */
......@@ -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));
if ((error=sort_get_next_record(sort_param)))
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,
&sort_param->wordroot)))
DBUG_RETURN(1);
if (wptr->pos)
break;
error=_ma_sort_write_record(sort_param);
}
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)
sort_param->real_key_length=(info->s->rec_reflength+
_ma_ft_make_key(info, sort_param->key,
key, wptr++,
sort_param->filepos));
sort_param->current_filepos));
#ifdef HAVE_purify
if (sort_param->key_length > 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)
{
free_root(&sort_param->wordroot, MYF(MY_MARK_BLOCKS_FREE));
sort_param->wordlist=0;
error=_ma_sort_write_record(sort_param);
}
else
sort_param->wordptr=(void*)wptr;
......@@ -3891,8 +3922,9 @@ static int sort_maria_ft_key_read(MARIA_SORT_PARAM *sort_param, uchar *key)
RETURN
-1 end of file
0 ok
sort_param->filepos points to record position.
sort_param->current_filepos points to record position.
sort_param->record contains record
sort_param->max_pos contains position to last byte read
> 0 error
*/
......@@ -3957,12 +3989,13 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
info->cur_row.checksum= 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);
}
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);
}
/* Retry only if wrong record, not if disk error */
......@@ -3986,7 +4019,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
sort_param->start_recpos=sort_param->pos;
if (!sort_param->fix_datafile)
{
sort_param->filepos=sort_param->pos;
sort_param->current_filepos= sort_param->pos;
if (sort_param->master)
share->state.split++;
}
......@@ -4136,7 +4169,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (!searching)
_ma_check_print_info(param,
"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));
if (found_record)
goto try_next;
......@@ -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->start_recpos=pos;
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))
sort_param->pos=block_info.filepos+1;
else
......@@ -4348,6 +4382,10 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
llstr(sort_param->pos,llbuff));
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,
sort_param->rec_buff, block_info.rec_len))
{
......@@ -4358,12 +4396,12 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
if (!sort_param->fix_datafile)
{
sort_param->filepos=sort_param->pos;
sort_param->current_filepos= sort_param->pos;
if (sort_param->master)
share->state.split++;
}
sort_param->max_pos=(sort_param->pos=block_info.filepos+
block_info.rec_len);
sort_param->max_pos= (sort_param->pos=block_info.filepos+
block_info.rec_len);
info->packed_length=block_info.rec_len;
if (sort_param->calc_checksum)
......@@ -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
_ma_sort_write_record()
sort_param Sort parameters.
@fn _ma_sort_write_record()
@param sort_param Sort parameters.
NOTE
This is only called by a master thread if parallel repair is used.
@note
This is only called by a master thread if parallel repair is used.
RETURN
0 OK
1 Error
@return
@retval 0 OK
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)
......@@ -4410,13 +4451,15 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
if (sort_param->fix_datafile)
{
sort_param->current_filepos= sort_param->filepos;
switch (sort_info->new_data_file_type) {
case BLOCK_RECORD:
if ((sort_param->filepos= (*share->write_record_init)(info,
sort_param->
record)) ==
if ((sort_param->current_filepos=
(*share->write_record_init)(info, sort_param->record)) ==
HA_OFFSET_ERROR)
DBUG_RETURN(1);
/* Pointer to end of file */
sort_param->filepos= info->state->data_file_length;
break;
case STATIC_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,
} /* 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)
{
......@@ -4829,57 +4872,61 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
uchar *key;
MARIA_SORT_INFO *sort_info=sort_param->sort_info;
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");
if ((param->testflag & (T_FORCE_UNIQUENESS|T_QUICK)) == T_QUICK)
{
_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);
}
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
if (key_info->s->options & HA_OPTION_COMPRESS_RECORD)
{
_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);
}
old_file= info->dfile.file;
info->dfile.file= info->rec_cache.file;
old_file= row_info->dfile.file;
/* This only affects static and dynamic row formats */
row_info->dfile.file= row_info->rec_cache.file;
if (sort_info->current_key)
{
key= info->lastkey+info->s->base.max_key_length;
if ((error=(*info->s->read_record)(info,sort_param->record,
info->cur_row.lastpos)) &&
key= key_info->lastkey + key_info->s->base.max_key_length;
if ((error=(*row_info->s->read_record)(row_info, sort_param->record,
key_info->cur_row.lastpos)) &&
error != HA_ERR_RECORD_DELETED)
{
_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);
}
for (i=0 ; i < sort_info->current_key ; i++)
{
uint key_length= _ma_make_key(info, i, key, sort_param->record,
info->cur_row.lastpos);
if (_ma_ck_delete(info, i, key, key_length))
uint key_length= _ma_make_key(key_info, i, key, sort_param->record,
key_info->cur_row.lastpos);
if (_ma_ck_delete(key_info, i, key, key_length))
{
_ma_check_print_error(param,
"Can't delete key %d from record to be removed",
i+1);
info->dfile.file= old_file;
row_info->dfile.file= old_file;
DBUG_RETURN(1);
}
}
if (sort_param->calc_checksum)
param->glob_crc-=(*info->s->calc_check_checksum)(info,
sort_param->record);
param->glob_crc-=(*key_info->s->calc_check_checksum)(key_info,
sort_param->record);
}
error= (flush_io_cache(&info->rec_cache) ||
(*info->s->delete_record)(info, sort_param->record));
info->dfile.file= old_file; /* restore actual value */
info->state->records--;
error= (flush_io_cache(&row_info->rec_cache) ||
(*row_info->s->delete_record)(row_info, sort_param->record));
row_info->dfile.file= old_file; /* restore actual value */
row_info->state->records--;
DBUG_RETURN(error);
} /* sort_delete_record */
......@@ -5145,7 +5192,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
(*org_info)->state->empty=info.state->empty;
(*org_info)->state->data_file_length=info.state->data_file_length;
if (maria_update_state_info(param,*org_info,UPDATE_TIME | UPDATE_STAT |
UPDATE_OPEN_COUNT))
UPDATE_OPEN_COUNT))
goto end;
error=0;
end:
......@@ -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)
{
MARIA_SHARE *share=info->s;
DBUG_ENTER("maria_update_state_info");
if (update & UPDATE_OPEN_COUNT)
{
......@@ -5233,25 +5281,25 @@ int maria_update_state_info(HA_CHECK *param, MARIA_HA *info,uint update)
share->w_locks=w_locks;
share->tot_locks=r_locks+w_locks;
if (!error)
return 0;
DBUG_RETURN(0);
}
err:
_ma_check_print_error(param,"%d when updating keyfile",my_errno);
return 1;
DBUG_RETURN(1);
}
/*
Update auto increment value for a table
When setting the 'repair_only' flag we only want to change the
old auto_increment value if its wrong (smaller than some given key).
The reason is that we shouldn't change the auto_increment value
for a table without good reason when only doing a repair; If the
user have inserted and deleted rows, the auto_increment value
may be bigger than the biggest current row and this is ok.
If repair_only is not set, we will update the flag to the value in
param->auto_increment is bigger than the biggest key.
*/
/*
Update auto increment value for a table
When setting the 'repair_only' flag we only want to change the
old auto_increment value if its wrong (smaller than some given key).
The reason is that we shouldn't change the auto_increment value
for a table without good reason when only doing a repair; If the
user have inserted and deleted rows, the auto_increment value
may be bigger than the biggest current row and this is ok.
If repair_only is not set, we will update the flag to the value in
param->auto_increment is bigger than the biggest key.
*/
void _ma_update_auto_increment_key(HA_CHECK *param, MARIA_HA *info,
my_bool repair_only)
......@@ -5462,7 +5510,7 @@ void maria_disable_non_unique_index(MARIA_HA *info, ha_rows rows)
*/
my_bool maria_test_if_sort_rep(MARIA_HA *info, ha_rows rows,
ulonglong key_map, my_bool force)
ulonglong key_map, my_bool force)
{
MARIA_SHARE *share=info->s;
MARIA_KEYDEF *key=share->keyinfo;
......@@ -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))
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++)
{
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,
}
/**
@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
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)
{
my_close(info->dfile.file, MYF(MY_WME));
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)
{
MARIA_SHARE *share= info->s;
/* 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
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)
*/
if (_ma_update_create_rename_lsn(share, lsn, TRUE))
return 1;
info->s->now_transactional= now_transactional;
}
return 0;
}
......
......@@ -86,8 +86,7 @@ int maria_close(register MARIA_HA *info)
may be using the file at this point
IF using --external-locking, which does not apply to Maria.
*/
if (share->mode != O_RDONLY &&
((share->changed && share->base.born_transactional) ||
if (((share->changed && share->base.born_transactional) ||
maria_is_crashed(info)))
{
/*
......
......@@ -73,7 +73,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
LSN *res_lsn, void *extra_msg)
{
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];
struct st_msg_to_write_hook_for_clr_end msg;
my_bool res;
......@@ -81,10 +82,8 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
/* undo_lsn must be first for compression to work */
lsn_store(log_data, undo_lsn);
clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE,
undo_type);
log_array[TRANSLOG_INTERNAL_PARTS + 0].length=
sizeof(log_data) - HA_CHECKSUM_STORE_SIZE;
clr_type_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE, undo_type);
log_pos= log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE + CLR_TYPE_STORE_SIZE;
/* Extra_msg is handled in write_hook_for_clr_end() */
msg.undone_record_type= undo_type;
......@@ -95,11 +94,24 @@ my_bool _ma_write_clr(MARIA_HA *info, LSN undo_lsn,
if (store_checksum)
{
msg.checksum_delta= checksum;
ha_checksum_store(log_data + LSN_STORE_SIZE + FILEID_STORE_SIZE +
CLR_TYPE_STORE_SIZE, checksum);
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
ha_checksum_store(log_pos, checksum);
log_pos+= HA_CHECKSUM_STORE_SIZE;
}
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].length= (uint) (log_pos - log_data);
res= translog_write_record(res_lsn, LOGREC_CLR_END,
info->trn, info, log_array[TRANSLOG_INTERNAL_PARTS
......@@ -141,8 +153,8 @@ my_bool write_hook_for_clr_end(enum translog_record_type type
case LOGREC_UNDO_ROW_UPDATE:
share->state.state.checksum+= msg->checksum_delta;
break;
case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE:
case LOGREC_UNDO_KEY_INSERT_WITH_ROOT:
case LOGREC_UNDO_KEY_DELETE_WITH_ROOT:
{
/* Update key root */
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
*extra_msg->root= extra_msg->value;
break;
}
case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE:
break;
default:
DBUG_ASSERT(0);
}
......@@ -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.value= new_root;
msg.keynr= keynr;
if (_ma_write_clr(info, undo_lsn, LOGREC_UNDO_KEY_INSERT, 1, 0, &lsn,
(void*) &msg))
if (_ma_write_clr(info, undo_lsn, *msg.root == msg.value ?
LOGREC_UNDO_KEY_INSERT : LOGREC_UNDO_KEY_INSERT_WITH_ROOT,
0, 0, &lsn, (void*) &msg))
res= 1;
_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,
msg.root= &share->state.key_root[keynr];
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))
res= 1;
......
......@@ -35,6 +35,7 @@ struct st_msg_to_write_hook_for_undo_key
{
my_off_t *root;
my_off_t value;
uint keynr;
};
......
......@@ -490,6 +490,13 @@ static LOG_DESC INIT_LOGREC_UNDO_KEY_INSERT=
NULL, write_hook_for_undo_key, NULL, 1,
"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=
{LOGRECTYPE_VARIABLE_LENGTH, 0,
LSN_STORE_SIZE + FILEID_STORE_SIZE + KEY_NR_STORE_SIZE,
......@@ -605,6 +612,8 @@ static void loghandler_init()
INIT_LOGREC_UNDO_ROW_UPDATE;
log_record_type_descriptor[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]=
INIT_LOGREC_UNDO_KEY_DELETE;
log_record_type_descriptor[LOGREC_UNDO_KEY_DELETE_WITH_ROOT]=
......
......@@ -123,6 +123,7 @@ enum translog_record_type
LOGREC_UNDO_ROW_DELETE,
LOGREC_UNDO_ROW_UPDATE,
LOGREC_UNDO_KEY_INSERT,
LOGREC_UNDO_KEY_INSERT_WITH_ROOT,
LOGREC_UNDO_KEY_DELETE,
LOGREC_UNDO_KEY_DELETE_WITH_ROOT,
LOGREC_PREPARE,
......
......@@ -613,7 +613,8 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->base.null_bytes +
share->base.pack_bytes +
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 +
KEYPAGE_USED_SIZE);
......@@ -672,6 +673,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
MARIA_REC_BUFF_OFFSET);
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,
end_pos);
for (i= j= 0 ; i < share->base.fields ; i++)
......@@ -1042,6 +1048,9 @@ static void setup_key_functions(register MARIA_KEYDEF *keyinfo)
uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite)
{
uint res;
if (share->options & HA_OPTION_READ_ONLY_DATA)
return 0;
if (pWrite & 4)
pthread_mutex_lock(&share->intern_lock);
else if (maria_multi_threaded)
......@@ -1091,7 +1100,7 @@ uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite)
uchar *ptr=buff;
uint i, keys= (uint) state->header.keys;
size_t res;
DBUG_ENTER("_ma_state_info_write");
DBUG_ENTER("_ma_state_info_write_sub");
memcpy_fixed(ptr,&state->header,sizeof(state->header));
ptr+=sizeof(state->header);
......
......@@ -44,7 +44,9 @@
{ bits-=(bit+1); break; } \
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
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));
if (!(share->decode_tables=(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))))
goto err1;
tmp_buff=share->decode_tables+length;
......@@ -255,6 +258,11 @@ static my_bool _ma_read_pack_info(MARIA_SHARE *share, File file,
(uint) (share->pack.header_length-sizeof(header)),
MYF(MY_NABP)))
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);
init_bit_buffer(&bit_buff, disk_cache,
......
......@@ -1147,7 +1147,7 @@ static int new_table(uint16 sid, const char *name,
tprint(tracef, ", has wrong state.key_file_length (fixing it)");
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");
/* Recovery will fix this, no error */
......@@ -1669,9 +1669,10 @@ prototype_redo_exec_hook(CLR_END)
enum translog_record_type undone_record_type;
const LOG_DESC *log_desc;
my_bool row_entry= 0;
DBUG_ENTER("exec_REDO_LOGREC_CLR_END");
if (info == NULL)
return 0;
DBUG_RETURN(0);
share= info->s;
previous_undo_lsn= lsn_korr(rec->header);
undone_record_type=
......@@ -1699,6 +1700,28 @@ prototype_redo_exec_hook(CLR_END)
case LOGREC_UNDO_KEY_INSERT:
case LOGREC_UNDO_KEY_DELETE:
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:
DBUG_ASSERT(0);
}
......@@ -1710,7 +1733,7 @@ prototype_redo_exec_hook(CLR_END)
buff, NULL) != HA_CHECKSUM_STORE_SIZE)
{
tprint(tracef, "Failed to read record\n");
return 1;
DBUG_RETURN(1);
}
share->state.state.checksum+= ha_checksum_korr(buff);
}
......@@ -1719,7 +1742,7 @@ prototype_redo_exec_hook(CLR_END)
if (row_entry)
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
_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,
uchar **sort_keys;
IO_CACHE tempfile, tempfile_for_exceptions;
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)
{
......
......@@ -169,6 +169,11 @@ run_pack_tests()
$maria_path/maria_chk$suffix -rus 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/maria_chk$suffix -se test1
$maria_path/maria_chk$suffix -ros test1
......@@ -184,10 +189,10 @@ run_pack_tests()
$maria_path/ma_test2$suffix $silent -c -d1 $row_type
$maria_path/maria_chk$suffix -s --parallel-recover 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_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
}
......@@ -233,6 +238,30 @@ $maria_path/maria_chk$suffix -ssm test2
#
/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
#
......
......@@ -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
# save the index file (because we want to test idempotency afterwards)
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
$maria_path/maria_chk -s -e --read-only $table
checksum2=`$maria_path/maria_chk -dss $table`
if test "$checksum" != "$checksum2"
then
......@@ -47,7 +40,6 @@ check_table_is_same()
cat $tmp/maria_chk_diff.txt
echo "========DIFF END======="
fi
mv tmp/$table.MAI .
}
apply_log()
......
......@@ -47,40 +47,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========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=2 --test-undo=2 (additional aborted work)
......@@ -117,40 +117,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========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=2 --test-undo=3 (additional aborted work)
......@@ -187,40 +187,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========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=2 --test-undo=1 (additional aborted work)
......@@ -257,40 +257,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========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=2 --test-undo=2 (additional aborted work)
......@@ -327,40 +327,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========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=2 --test-undo=3 (additional aborted work)
......@@ -397,11 +397,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
......@@ -410,27 +410,27 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========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=2 --test-undo=1 (additional aborted work)
......@@ -467,40 +467,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========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=2 --test-undo=2 (additional aborted work)
......@@ -537,37 +537,37 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
> Datafile length: 114688 Keyfile length: 204800
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 90112 Keyfile length: 204800
......@@ -607,11 +607,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
......@@ -620,11 +620,11 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
......@@ -633,11 +633,11 @@ testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 81920 Keyfile length: 204800
......@@ -677,40 +677,40 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========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=2 --test-undo=2 (additional aborted work)
......@@ -747,11 +747,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
......@@ -760,11 +760,11 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
......@@ -773,11 +773,11 @@ testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
......@@ -817,11 +817,11 @@ Dying on request without maria_commit()/maria_close()
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
......@@ -830,25 +830,25 @@ testing idempotency
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
testing applying of CLRs to recreate table
applying log
Differences in maria_chk -dvv, recovery not yet perfect !
========DIFF START=======
7c7
6c6
< Status: checked,analyzed,optimized keys,sorted index pages
---
> Status: changed
12c12
11c11
< Datafile length: 8192 Keyfile length: 8192
---
> Datafile length: 122880 Keyfile length: 212992
> Datafile length: 155648 Keyfile length: 212992
========DIFF END=======
......@@ -135,7 +135,7 @@ int main(int argc, char **argv)
{ /* Only if descript */
char buff[22],buff2[22];
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),
llstr(check_param.total_deleted,buff2));
}
......@@ -624,9 +624,13 @@ get_one_option(int optid,
break;
case 'u':
if (argument == disabled_my_option)
check_param.testflag&= ~(T_UNPACK | T_REP_BY_SORT);
check_param.testflag&= ~T_UNPACK;
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;
case 'v': /* Verbose */
if (argument == disabled_my_option)
......@@ -802,13 +806,13 @@ static int maria_chk(HA_CHECK *param, char *filename)
datafile=0;
param->isam_file_name=filename; /* For error messages */
if (!(info=maria_open(filename,
(param->testflag & (T_DESCRIPT | T_READONLY)) ?
O_RDONLY : O_RDWR,
HA_OPEN_FOR_REPAIR |
((param->testflag & T_WAIT_FOREVER) ?
HA_OPEN_WAIT_IF_LOCKED :
(param->testflag & T_DESCRIPT) ?
HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED))))
(param->testflag & (T_DESCRIPT | T_READONLY)) ?
O_RDONLY : O_RDWR,
HA_OPEN_FOR_REPAIR |
((param->testflag & T_WAIT_FOREVER) ?
HA_OPEN_WAIT_IF_LOCKED :
(param->testflag & T_DESCRIPT) ?
HA_OPEN_IGNORE_IF_LOCKED : HA_OPEN_ABORT_IF_LOCKED))))
{
/* Avoid twice printing of isam file name */
param->error_printed=1;
......@@ -852,7 +856,6 @@ static int maria_chk(HA_CHECK *param, char *filename)
DBUG_RETURN(1);
}
share=info->s;
share->options&= ~HA_OPTION_READ_ONLY_DATA; /* We are modifing it */
share->tot_locks-= share->r_locks;
share->r_locks=0;
maria_block_size= share->base.block_size;
......@@ -871,10 +874,10 @@ static int maria_chk(HA_CHECK *param, char *filename)
goto end2;
}
/* 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;
param->testflag&= ~T_REP_PARALLEL;
param->testflag|= T_REP_BY_SORT;
}
}
......@@ -1255,7 +1258,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
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("Crashsafe: %s\n",
share->base.born_transactional ? "yes" : "no");
......
......@@ -118,7 +118,7 @@ typedef struct st_maria_state_info
#define MARIA_STATE_KEYBLOCK_SIZE 8
#define MARIA_STATE_KEYSEG_SIZE 12
#define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
#define MARIA_KEYDEF_SIZE (2+ 5*2)
#define MARIA_KEYDEF_SIZE (2+ 5*2)
#define MARIA_UNIQUEDEF_SIZE (2+1+1)
#define HA_KEYSEG_SIZE (6+ 2*2 + 4*2)
#define MARIA_COLUMNDEF_SIZE (6+2+2+2+2+2+1+1)
......@@ -507,6 +507,7 @@ struct st_maria_handler
#define USE_WHOLE_KEY 65535 /* Use whole key in _search() */
#define F_EXTRA_LCK -1
#define TRANSID_SIZE 6
/* bits in opt_flag */
#define MEMMAP_USED 32
......@@ -540,7 +541,8 @@ struct st_maria_handler
#define KEYPAGE_FLAG_SIZE 1
#define KEYPAGE_CHECKSUM_SIZE 4
#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) \
(((uint) mi_uint2korr(x + (info)->s->keypage_header - KEYPAGE_USED_SIZE)) & \
......@@ -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_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; \
DBUG_PRINT("error", ("Marked table crashed")); \
}while(0)
......
......@@ -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";
#endif
#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;
static ulong opt_page_buffer_size;
......@@ -84,8 +84,8 @@ int main(int argc, char **argv)
goto err;
}
if (opt_only_display)
printf("You are using --only-display, NOTHING will be written to disk\n");
if (opt_display_only)
printf("You are using --display-only, NOTHING will be written to disk\n");
/* LSN could be also --start-from-lsn=# */
lsn= translog_first_lsn_in_log();
......@@ -138,7 +138,7 @@ static struct my_option my_long_options[] =
(uchar **) &opt_apply, (uchar **) &opt_apply, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"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,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
......@@ -147,8 +147,8 @@ static struct my_option my_long_options[] =
#endif
{"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"only-display", 'o', "display brief info read from records' header",
(uchar **) &opt_only_display, (uchar **) &opt_only_display, 0, GET_BOOL,
{"display-only", 'o', "display brief info read from records' header",
(uchar **) &opt_display_only, (uchar **) &opt_display_only, 0, GET_BOOL,
NO_ARG,0, 0, 0, 0, 0, 0},
{ "page_buffer_size", 'P', "",
(uchar**) &opt_page_buffer_size, (uchar**) &opt_page_buffer_size, 0,
......@@ -225,7 +225,7 @@ static void get_options(int *argc,char ***argv)
if (!opt_apply)
opt_apply_undo= FALSE;
if ((opt_only_display + opt_apply) != 1)
if ((opt_display_only + opt_apply) != 1)
{
usage();
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