Commit 6cad0204 authored by unknown's avatar unknown

Added maria_zerofill()

This is used to bzero all not used parts of the index pages and compact and bzero the not used parts of the data pages of block-record type
Added --zerofill (-z) option to maria_chk (Mostly code from Jani)
Added now table states ZEROFILLED and MOVEABLE
Set state.changed with new states when things changes


include/maria.h:
  Added maria_zerofill
include/myisamchk.h:
  Added option for zerofill
  Extend testflag to be 64 to allow for more flags
mysql-test/r/create.result:
  Updated results after merge
mysql-test/r/maria.result:
  Updated results after merge
mysys/my_getopt.c:
  Removed not used variable
sql/sql_show.cc:
  Fixed wrong page type
storage/maria/ma_blockrec.c:
  Renamed compact_page() to ma_compact_block_page() and made it global
  Always zerofill half filled blob pages
  Set share.state.changed on REDO
storage/maria/ma_blockrec.h:
  Added _ma_compact_block_page()
storage/maria/ma_check.c:
  Added maria_zerofill()
  This is used to bzero all not used parts of the index pages and compact and bzero the not used parts of the data pages of block-record type
  This gives the following benefits:
  - Table is smaller if compressed
  - All LSN are removed for transactinal tables and this makes them movable between systems
  Dont set table states of we are using --quick
  Changed log entry for repair to use 8 bytes for flag
storage/maria/ma_delete.c:
  Simplify code
  Update state.changed
storage/maria/ma_key_recover.c:
  Update state.changed
storage/maria/ma_locking.c:
  Set uuid for file on first change if it's not set (table was cleared with zerofill)
storage/maria/ma_loghandler.c:
  Updated log entry for REDO_REPAIR_TABLE
storage/maria/ma_recovery.c:
  Updated log entry for REDO_REPAIR_TABLE (flag is now 8 bytes)
  Set new bits in state.changed
storage/maria/ma_test_all.sh:
  Nicer output
storage/maria/ma_test_recovery.expected:
  Updated results (now states flags are visible)
storage/maria/ma_update.c:
  Update state.changed
storage/maria/ma_write.c:
  Simplify code
  Set state.changed
storage/maria/maria_chk.c:
  Added option --zerofill
  Added printing of states for MOVABLE and ZEROFILLED
  MYD -> MAD
  MYI -> MAI
storage/maria/maria_def.h:
  Added states STATE_NOT_MOVABLE and STATE_NOT_ZEROFILLED
  Added prototype for new functions
storage/maria/unittest/ma_test_all-t:
  More tests, including tests for zerofill
  Removed some not needed 'print' statements
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
  Smaller buffer to not trash devlopment machines totally
parent 1e9ee8ab
......@@ -398,6 +398,7 @@ 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, MARIA_HA *info, char * name, uint rep_quick);
int maria_sort_index(HA_CHECK *param, MARIA_HA *info, char * name);
int maria_zerofill(HA_CHECK *param, MARIA_HA *info, const 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,
......
......@@ -59,6 +59,7 @@
#define T_VERY_SILENT (1L << 29)
#define T_WAIT_FOREVER (1L << 30)
#define T_WRITE_LOOP ((ulong) 1L << 31)
#define T_ZEROFILL ((ulonglong) 1L << 32)
#define T_REP_ANY (T_REP | T_REP_BY_SORT | T_REP_PARALLEL)
......@@ -129,13 +130,14 @@ typedef struct st_handler_check_param
ha_checksum tmp_key_crc[HA_MAX_POSSIBLE_KEY];
ha_checksum tmp_record_checksum;
ulonglong org_key_map;
ulonglong testflag;
size_t use_buffers, read_buffer_length, write_buffer_length;
size_t sort_buffer_length, sort_key_blocks;
ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
uint out_flag, warning_printed, error_printed, verbose;
uint opt_sort_key, total_files, max_level;
uint testflag, key_cache_block_size, pagecache_block_size;
uint key_cache_block_size, pagecache_block_size;
int tmpfile_createflag, err_count;
myf myf_rw;
uint8 language;
......
......@@ -1717,7 +1717,7 @@ t1 CREATE TABLE `t1` (
`TIME` bigint(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext
) ENGINE=MARIA DEFAULT CHARSET=utf8
) ENGINE=MARIA DEFAULT CHARSET=utf8 PAGE_CHECKSUM=1
drop table t1;
create temporary table t1 like information_schema.processlist;
show create table t1;
......
......@@ -2055,7 +2055,7 @@ maria_log_purge_type immediate
maria_max_sort_file_size 9223372036854775807
maria_page_checksum OFF
maria_pagecache_age_threshold 300
maria_pagecache_buffer_size 8388572
maria_pagecache_buffer_size 8388600
maria_pagecache_division_limit 100
maria_repair_threads 1
maria_sort_buffer_size 8388608
......
......@@ -867,7 +867,7 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
bool *fix)
{
bool adjusted= FALSE;
ulonglong old= num, mod;
ulonglong old= num;
char buf1[255], buf2[255];
if ((ulonglong) num > (ulonglong) optp->max_value &&
......
......@@ -3574,7 +3574,7 @@ static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
tmp_buff= "Compact";
break;
case ROW_TYPE_PAGE:
tmp_buff= "Paged";
tmp_buff= "Page";
break;
}
table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
......
......@@ -337,8 +337,6 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
#ifndef DBUG_OFF
static void _ma_print_directory(uchar *buff, uint block_size);
#endif
static void compact_page(uchar *buff, uint block_size, uint rownr,
my_bool extend_block);
static uchar *store_page_range(uchar *to, MARIA_BITMAP_BLOCK *block,
uint block_size, ulong length,
uint *tot_ranges);
......@@ -533,6 +531,7 @@ void _ma_end_block_record(MARIA_HA *info)
my_free((uchar*) info->cur_row.empty_bits, MYF(MY_ALLOW_ZERO_PTR));
delete_dynamic(&info->bitmap_blocks);
my_free((uchar*) info->cur_row.extents, MYF(MY_ALLOW_ZERO_PTR));
my_free(info->blob_buff, MYF(MY_ALLOW_ZERO_PTR));
/*
The data file is closed, when needed, in ma_once_end_block_record().
The following protects us from doing an extra, not allowed, close
......@@ -700,7 +699,7 @@ static void check_directory(uchar *buff, uint block_size)
- If new data fits in old block, use old block.
- Extend block with empty space before block. If enough, use it.
- Extend block with empty space after block. If enough, use it.
- Use compact_page() to get all empty space at dir.
- Use _ma_compact_block_page() to get all empty space at dir.
@note
The given directory entry is set to rec length.
......@@ -794,7 +793,7 @@ static my_bool extend_area_on_page(uchar *buff, uchar *dir,
int2store(dir, rec_offset);
/* Reset length, as this may be a deleted block */
int2store(dir+2, 0);
compact_page(buff, block_size, rownr, 1);
_ma_compact_block_page(buff, block_size, rownr, 1);
rec_offset= uint2korr(dir);
length= uint2korr(dir+2);
if (length < request_length)
......@@ -818,28 +817,6 @@ static my_bool extend_area_on_page(uchar *buff, uchar *dir,
}
/*
Check that a region is all zero
SYNOPSIS
check_if_zero()
pos Start of memory to check
length length of memory region
NOTES
Used mainly to detect rows with wrong extent information
*/
my_bool _ma_check_if_zero(uchar *pos, uint length)
{
uchar *end;
for (end= pos+ length; pos != end ; pos++)
if (pos[0] != 0)
return 1;
return 0;
}
/*
@brief Copy not changed fields from 'from' to 'to'
......@@ -937,7 +914,7 @@ make_space_for_directory(uchar *buff, uint block_size, uint max_entry,
if ((uint) (first_dir - buff) < *first_pos + length_needed)
{
/* Create place for directory */
compact_page(buff, block_size, max_entry - 1, 0);
_ma_compact_block_page(buff, block_size, max_entry - 1, 0);
*first_pos= (uint2korr(first_dir) + uint2korr(first_dir + 2));
*empty_space= uint2korr(buff + EMPTY_SPACE_OFFSET);
if (*empty_space < length_needed)
......@@ -979,7 +956,8 @@ make_space_for_directory(uchar *buff, uint block_size, uint max_entry,
then use it and change it to be the size of the empty block
after the previous entry. This guarantees that all row entries
are stored on disk in inverse directory order, which makes life easier for
'compact_page()' and to know if there is free space after any block.
'_ma_compact_block_page()' and to know if there is free space after any
block.
If there is no free entry (entry with position == 0), then we create
a new one. If there is not space for the directory entry (because
......@@ -1312,7 +1290,7 @@ static void calc_record_size(MARIA_HA *info, const uchar *record,
Remove TRANSID from rows that are visible to all transactions
SYNOPSIS
compact_page()
_ma_compact_block_page()
buff Page to compact
block_size Size of page
rownr Put empty data after this row
......@@ -1321,13 +1299,13 @@ static void calc_record_size(MARIA_HA *info, const uchar *record,
*/
static void compact_page(uchar *buff, uint block_size, uint rownr,
my_bool extend_block)
void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr,
my_bool extend_block)
{
uint max_entry= (uint) buff[DIR_COUNT_OFFSET];
uint page_pos, next_free_pos, start_of_found_block, diff, end_of_found_block;
uchar *dir, *end;
DBUG_ENTER("compact_page");
DBUG_ENTER("_ma_compact_block_page");
DBUG_PRINT("enter", ("rownr: %u", rownr));
DBUG_ASSERT(max_entry > 0 &&
max_entry < (block_size - PAGE_HEADER_SIZE -
......@@ -1566,7 +1544,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
{
if (res->empty_space + res->length >= length)
{
compact_page(res->buff, block_size, res->rownr, 1);
_ma_compact_block_page(res->buff, block_size, res->rownr, 1);
/* All empty space are now after current position */
dir= dir_entry_pos(res->buff, block_size, res->rownr);
res->length= res->empty_space= uint2korr(dir+2);
......@@ -1916,11 +1894,14 @@ static my_bool write_full_pages(MARIA_HA *info,
memcpy(buff + LSN_SIZE + PAGE_TYPE_SIZE, data, copy_length);
length-= copy_length;
#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
/*
Zero out old information from the block. This removes possible
sensitive information from the block and also makes the file
easier to compress and easier to compare after recovery.
*/
if (copy_length != data_size)
bzero(buff + block_size - PAGE_SUFFIX_SIZE - (data_size - copy_length),
(data_size - copy_length) + PAGE_SUFFIX_SIZE);
#endif
DBUG_ASSERT(share->pagecache->block_size == block_size);
if (pagecache_write(share->pagecache,
......@@ -3450,7 +3431,7 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
(new_row->total_length <= head_length &&
org_empty_size + head_length >= new_row->total_length)))
{
compact_page(buff, block_size, rownr, 1);
_ma_compact_block_page(buff, block_size, rownr, 1);
org_empty_size= 0;
head_length= uint2korr(dir + 2);
}
......@@ -5748,6 +5729,9 @@ 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));
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
end_of_page= (page + 1) * share->block_size;
if (end_of_page > info->state->data_file_length)
{
......@@ -5938,7 +5922,8 @@ uint _ma_apply_redo_purge_row_head_or_tail(MARIA_HA *info, LSN lsn,
(ulong) ma_recordpos(page, rownr),
(ulong) page, rownr));
info->keyread_buff_used= 1;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
if (!(buff= pagecache_read(share->pagecache, &info->dfile,
page, 0, 0,
......@@ -6019,6 +6004,9 @@ uint _ma_apply_redo_free_blocks(MARIA_HA *info,
uint ranges;
DBUG_ENTER("_ma_apply_redo_free_blocks");
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
ranges= pagerange_korr(header);
header+= PAGERANGE_STORE_SIZE;
DBUG_ASSERT(ranges > 0);
......@@ -6078,6 +6066,9 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
my_bool res;
DBUG_ENTER("_ma_apply_redo_free_head_or_tail");
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
page= page_korr(header);
if (!(buff= pagecache_read(share->pagecache,
......@@ -6153,6 +6144,9 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
uint blob_count, ranges;
DBUG_ENTER("_ma_apply_redo_insert_row_blobs");
share->state.changed|= (STATE_CHANGED | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
ranges= pagerange_korr(header);
header+= PAGERANGE_STORE_SIZE;
blob_count= pagerange_korr(header);
......
......@@ -147,7 +147,6 @@ my_bool _ma_once_init_block_record(MARIA_SHARE *share, File dfile);
my_bool _ma_once_end_block_record(MARIA_SHARE *share);
my_bool _ma_init_block_record(MARIA_HA *info);
void _ma_end_block_record(MARIA_HA *info);
my_bool _ma_check_if_zero(uchar *pos, uint length);
my_bool _ma_update_block_record(MARIA_HA *info, MARIA_RECORD_POS pos,
const uchar *oldrec, const uchar *newrec);
......@@ -173,6 +172,8 @@ my_bool _ma_write_block_record(MARIA_HA *info, const uchar *record);
my_bool _ma_write_abort_block_record(MARIA_HA *info);
my_bool _ma_compare_block_record(register MARIA_HA *info,
register const uchar *record);
void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr,
my_bool extend_block);
/* ma_bitmap.c */
my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
......
......@@ -263,7 +263,7 @@ wrong:
} /* maria_chk_del */
/* Check delete links in index file */
/* Check delete links in index file */
static int check_k_link(HA_CHECK *param, register MARIA_HA *info,
my_off_t next_link)
......@@ -2470,8 +2470,9 @@ err:
if (!got_error && (param->testflag & T_UNPACK))
restore_data_file_type(share);
share->state.changed|= (STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES |
STATE_NOT_ANALYZED);
share->state.changed&= ~STATE_NOT_OPTIMIZED_ROWS;
STATE_NOT_ANALYZED | STATE_NOT_ZEROFILLED);
if (!rep_quick)
share->state.changed&= ~(STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_MOVABLE);
DBUG_RETURN(got_error);
}
......@@ -2847,14 +2848,214 @@ err:
} /* sort_one_index */
/*
Let temporary file replace old file.
This assumes that the new file was created in the same
directory as given by realpath(filename).
This will ensure that any symlinks that are used will still work.
Copy stats from old file to new file, deletes orignal and
changes new file name to old file name
*/
/**
@brief Fill empty space in index file with zeroes
@return
@retval 0 Ok
@retval 1 Error
*/
static my_bool maria_zerofill_index(HA_CHECK *param, MARIA_HA *info,
const char *name)
{
MARIA_SHARE *share= info->s;
MARIA_PINNED_PAGE page_link;
char llbuff[21];
uchar *buff;
ulonglong page;
my_off_t pos;
my_off_t key_file_length= share->state.state.key_file_length;
uint block_size= share->block_size;
my_bool transactional= share->base.born_transactional;
DBUG_ENTER("maria_zerofill_index");
if (!(param->testflag & T_SILENT))
printf("- Zerofilling index for MARIA-table '%s'\n",name);
/* Go through the index file */
for (pos= share->base.keystart, page= (ulonglong) (pos / block_size);
pos < key_file_length;
pos+= block_size, page++)
{
uint length;
if (!(buff= pagecache_read(share->pagecache,
&share->kfile, page,
DFLT_INIT_HITS, 0,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
{
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
_ma_check_print_error(param,
"Page %9s: Got error %d when reading index file",
llstr(pos, llbuff), my_errno);
DBUG_RETURN(1);
}
if (transactional)
bzero(buff, LSN_SIZE);
length= _ma_get_page_used(share, buff);
if (length < block_size)
bzero(buff + share->keypage_header + length, block_size - length -
share->keypage_header);
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
}
if (flush_pagecache_blocks(share->pagecache, &share->kfile,
FLUSH_FORCE_WRITE))
DBUG_RETURN(1);
DBUG_RETURN(0);
}
/**
@brief Fill empty space in index file with zeroes
@todo
Zerofill all pages marked in bitmap as empty and change them to
be of type UNALLOCATED_PAGE
@return
@retval 0 Ok
@retval 1 Error
*/
static my_bool maria_zerofill_data(HA_CHECK *param, MARIA_HA *info,
const char *name)
{
MARIA_SHARE *share= info->s;
MARIA_PINNED_PAGE page_link;
char llbuff[21];
my_off_t pos;
ulonglong page;
uint block_size= share->block_size;
DBUG_ENTER("maria_zerofill_data");
/* This works only with BLOCK_RECORD files */
if (share->data_file_type != BLOCK_RECORD)
DBUG_RETURN(0);
if (!(param->testflag & T_SILENT))
printf("- Zerofilling data for MARIA-table '%s'\n",name);
/* Go through the record file */
for (page= 1, pos= block_size;
pos < info->state->data_file_length;
pos+= block_size, page++)
{
uchar *buff;
uint page_type;
/* Ignore bitmap pages */
if ((page % share->bitmap.pages_covered) == 0)
continue;
if (!(buff= pagecache_read(share->pagecache,
&info->dfile,
page, 1, 0,
PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE,
&page_link.link)))
{
_ma_check_print_error(param,
"Page %9s: Got error: %d when reading datafile",
llstr(pos, llbuff), my_errno);
goto err;
}
page_type= buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK;
switch ((enum en_page_type) page_type) {
case UNALLOCATED_PAGE:
bzero(buff, block_size);
break;
case BLOB_PAGE:
bzero(buff, LSN_SIZE);
break;
case HEAD_PAGE:
case TAIL_PAGE:
{
uint max_entry= (uint) buff[DIR_COUNT_OFFSET];
uint offset, dir_start;
uchar *dir;
bzero(buff, LSN_SIZE);
if (max_entry != 0)
{
dir= dir_entry_pos(buff, block_size, max_entry - 1);
_ma_compact_block_page(buff, block_size, max_entry -1, 0);
/* Zerofille the not used part */
offset= uint2korr(dir) + uint2korr(dir+2);
dir_start= (uint) (dir - buff);
if (dir_start > offset)
bzero(buff + offset, dir_start - offset);
}
break;
}
default:
_ma_check_print_error(param,
"Page %9s: Found unrecognizable block of type %d",
llstr(pos, llbuff), page_type);
goto err;
}
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 1);
}
if (flush_pagecache_blocks(share->pagecache, &info->dfile,
FLUSH_FORCE_WRITE))
DBUG_RETURN(1);
DBUG_RETURN(0);
err:
pagecache_unlock_by_link(share->pagecache, page_link.link,
PAGECACHE_LOCK_WRITE_UNLOCK,
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0);
DBUG_RETURN(1);
}
/**
@brief Fill empty space in index and data files with zeroes
@return
@retval 0 Ok
@retval 1 Error
*/
int maria_zerofill(HA_CHECK *param, MARIA_HA *info, const char *name)
{
DBUG_ENTER("maria_zerofill");
if (maria_zerofill_index(param, info, name))
DBUG_RETURN(1);
if (maria_zerofill_data(param, info, name))
DBUG_RETURN(1);
if (_ma_set_uuid(info, 0))
DBUG_RETURN(1);
/*
Mark that table is movable and that we have done zerofill of data and
index
*/
info->s->state.changed&= ~(STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
/* Ensure state are flushed to disk */
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
DBUG_RETURN(0);
}
/*
Let temporary file replace old file.
This assumes that the new file was created in the same
directory as given by realpath(filename).
This will ensure that any symlinks that are used will still work.
Copy stats from old file to new file, deletes orignal and
changes new file name to old file name
*/
int maria_change_to_newfile(const char * filename, const char * old_ext,
const char * new_ext, myf MyFlags)
......@@ -3326,7 +3527,9 @@ err:
write_log_record_for_repair(param, info);
}
share->state.changed|= STATE_NOT_SORTED_PAGES;
share->state.changed&= ~STATE_NOT_OPTIMIZED_ROWS;
if (!rep_quick)
share->state.changed&= ~(STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
my_free(sort_param.rec_buff, MYF(MY_ALLOW_ZERO_PTR));
my_free(sort_param.record,MYF(MY_ALLOW_ZERO_PTR));
......@@ -3336,6 +3539,7 @@ err:
DBUG_RETURN(got_error);
}
/*
Threaded repair of table using sorting
......@@ -3833,7 +4037,9 @@ err:
else if (key_map == share->state.key_map)
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
share->state.changed|= STATE_NOT_SORTED_PAGES;
share->state.changed&= ~STATE_NOT_OPTIMIZED_ROWS;
if (!rep_quick)
share->state.changed&= ~(STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
pthread_cond_destroy (&sort_info.cond);
pthread_mutex_destroy(&sort_info.mutex);
......@@ -5917,16 +6123,16 @@ static int write_log_record_for_repair(const HA_CHECK *param, MARIA_HA *info)
record).
*/
LEX_STRING log_array[TRANSLOG_INTERNAL_PARTS + 1];
uchar log_data[FILEID_STORE_SIZE + 4 + 8];
uchar log_data[FILEID_STORE_SIZE + 8 + 8];
LSN lsn;
/*
testflag gives an idea of what REPAIR did (in particular T_QUICK
or not: did it touch the data file or not?).
*/
int4store(log_data + FILEID_STORE_SIZE, param->testflag);
int8store(log_data + FILEID_STORE_SIZE, param->testflag);
/* org_key_map is used when recreating index after a load data infile */
int8store(log_data + FILEID_STORE_SIZE + 4, param->org_key_map);
int8store(log_data + FILEID_STORE_SIZE + 8, param->org_key_map);
log_array[TRANSLOG_INTERNAL_PARTS + 0].str= (char*) log_data;
log_array[TRANSLOG_INTERNAL_PARTS + 0].length= sizeof(log_data);
......
......@@ -109,11 +109,14 @@ int maria_delete(MARIA_HA *info,const uchar *record)
if ((*share->delete_record)(info, record))
goto err; /* Remove record from database */
info->state->checksum+= - !share->now_transactional *
info->cur_row.checksum;
if (!share->now_transactional)
{
info->state->checksum-= info->cur_row.checksum;
info->state->records--;
}
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
info->state->records-= !share->now_transactional;
share->state.changed|= STATE_NOT_OPTIMIZED_ROWS;
share->state.changed|= (STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_MOVABLE |
STATE_NOT_ZEROFILLED);
mi_sizestore(lastpos, info->cur_row.lastpos);
VOID(_ma_writeinfo(info,WRITEINFO_UPDATE_KEYFILE));
......
......@@ -556,7 +556,8 @@ uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn,
/* Set header to point at key data */
share->state.changed|= (STATE_CHANGED | STATE_NOT_OPTIMIZED_KEYS |
STATE_NOT_SORTED_PAGES);
STATE_NOT_SORTED_PAGES | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
header+= PAGE_STORE_SIZE * 2 + KEY_NR_STORE_SIZE + 1;
length-= PAGE_STORE_SIZE * 2 + KEY_NR_STORE_SIZE + 1;
......@@ -670,7 +671,8 @@ uint _ma_apply_redo_index_free_page(MARIA_HA *info,
(ulong) page, (ulong) free_page));
share->state.changed|= (STATE_CHANGED | STATE_NOT_OPTIMIZED_KEYS |
STATE_NOT_SORTED_PAGES);
STATE_NOT_SORTED_PAGES | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
share->state.key_del= (my_off_t) page * share->block_size;
old_link= ((free_page != IMPOSSIBLE_PAGE_NO) ?
......@@ -695,7 +697,6 @@ uint _ma_apply_redo_index_free_page(MARIA_HA *info,
_ma_store_keynr(share, buff, (uchar) MARIA_DELETE_KEY_NR);
_ma_store_page_used(share, buff, share->keypage_header + 8);
mi_sizestore(buff + share->keypage_header, old_link);
share->state.changed|= STATE_NOT_SORTED_PAGES;
#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
{
......@@ -942,7 +943,8 @@ my_bool _ma_apply_undo_key_insert(MARIA_HA *info, LSN undo_lsn,
DBUG_ENTER("_ma_apply_undo_key_insert");
share->state.changed|= (STATE_CHANGED | STATE_NOT_OPTIMIZED_KEYS |
STATE_NOT_SORTED_PAGES);
STATE_NOT_SORTED_PAGES | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
keynr= key_nr_korr(header);
length-= KEY_NR_STORE_SIZE;
......@@ -987,7 +989,8 @@ my_bool _ma_apply_undo_key_delete(MARIA_HA *info, LSN undo_lsn,
DBUG_ENTER("_ma_apply_undo_key_delete");
share->state.changed|= (STATE_CHANGED | STATE_NOT_OPTIMIZED_KEYS |
STATE_NOT_SORTED_PAGES);
STATE_NOT_SORTED_PAGES | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
keynr= key_nr_korr(header);
length-= KEY_NR_STORE_SIZE;
......
......@@ -537,15 +537,45 @@ int _ma_mark_file_changed(MARIA_HA *info)
{
mi_int2store(buff,share->state.open_count);
buff[2]=1; /* Mark that it's changed */
DBUG_RETURN(my_pwrite(share->kfile.file, buff, sizeof(buff),
sizeof(share->state.header) +
MARIA_FILE_OPEN_COUNT_OFFSET,
MYF(MY_NABP)));
if (my_pwrite(share->kfile.file, buff, sizeof(buff),
sizeof(share->state.header) +
MARIA_FILE_OPEN_COUNT_OFFSET,
MYF(MY_NABP)))
DBUG_RETURN(1);
}
/* Set uuid of file if not yet set (zerofilled file) */
if (share->base.born_transactional &&
!(share->state.changed & STATE_NOT_MOVABLE))
{
/* Lock table to current installation */
if (_ma_set_uuid(info, 0))
DBUG_RETURN(1);
share->state.changed|= STATE_NOT_MOVABLE;
}
}
DBUG_RETURN(0);
}
/*
Check that a region is all zero
SYNOPSIS
check_if_zero()
pos Start of memory to check
length length of memory region
NOTES
Used mainly to detect rows with wrong extent information
*/
my_bool _ma_check_if_zero(uchar *pos, size_t length)
{
uchar *end;
for (end= pos+ length; pos != end ; pos++)
if (pos[0] != 0)
return 1;
return 0;
}
/*
This is only called by close or by extra(HA_FLUSH) if the OS has the pwrite()
......@@ -584,15 +614,45 @@ int _ma_decrement_open_count(MARIA_HA *info)
/** @brief mark file as crashed */
int _ma_mark_file_crashed(MARIA_SHARE *share)
void _ma_mark_file_crashed(MARIA_SHARE *share)
{
uchar buff[2];
DBUG_ENTER("_ma_mark_file_crashed");
share->state.changed|= STATE_CRASHED;
mi_int2store(buff, share->state.changed);
DBUG_RETURN(my_pwrite(share->kfile.file, buff, sizeof(buff),
sizeof(share->state.header) +
MARIA_FILE_CHANGED_OFFSET,
MYF(MY_NABP)));
/*
We can ignore the errors, as if the mark failed, there isn't anything
else we can do; The user should already have got an error that the
table was crashed.
*/
(void) my_pwrite(share->kfile.file, buff, sizeof(buff),
sizeof(share->state.header) +
MARIA_FILE_CHANGED_OFFSET,
MYF(MY_NABP));
}
/**
@brief Set uuid of for a Maria file
@fn _ma_set_uuid()
@param info Maria handler
@param reset_uuid Instead of setting file to maria_uuid, set it to
0 to mark it as movable
*/
my_bool _ma_set_uuid(MARIA_HA *info, my_bool reset_uuid)
{
uchar buff[MY_UUID_SIZE], *uuid;
uuid= maria_uuid;
if (reset_uuid)
{
bzero(buff, sizeof(buff));
uuid= buff;
}
return (my_bool) my_pwrite(info->s->kfile.file, uuid, MY_UUID_SIZE,
mi_uint2korr(info->s->state.header.base_pos),
MYF(MY_NABP));
}
......@@ -562,7 +562,7 @@ static LOG_DESC INIT_LOGREC_REDO_DELETE_ALL=
"redo_delete_all", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
static LOG_DESC INIT_LOGREC_REDO_REPAIR_TABLE=
{LOGRECTYPE_FIXEDLENGTH, FILEID_STORE_SIZE + 4 + 8, FILEID_STORE_SIZE + 4 + 8,
{LOGRECTYPE_FIXEDLENGTH, FILEID_STORE_SIZE + 8 + 8, FILEID_STORE_SIZE + 8 + 8,
NULL, NULL, NULL, 0,
"redo_repair_table", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
......
......@@ -1021,11 +1021,11 @@ prototype_redo_exec_hook(REDO_REPAIR_TABLE)
maria_chk_init(&param);
param.isam_file_name= name= info->s->open_file_name;
param.testflag= uint4korr(rec->header + FILEID_STORE_SIZE);
param.testflag= uint8korr(rec->header + FILEID_STORE_SIZE);
param.tmpdir= maria_tmpdir;
DBUG_ASSERT(maria_tmpdir);
info->s->state.key_map= uint8korr(rec->header + FILEID_STORE_SIZE + 4);
info->s->state.key_map= uint8korr(rec->header + FILEID_STORE_SIZE + 8);
quick_repair= param.testflag & T_QUICK;
......@@ -1615,7 +1615,8 @@ prototype_redo_exec_hook(UNDO_ROW_INSERT)
}
share->state.state.checksum+= ha_checksum_korr(buff);
}
info->s->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
info->s->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
}
tprint(tracef, " rows' count %lu\n", (ulong)info->s->state.state.records);
/* Unpin all pages, stamp them with UNDO's LSN */
......@@ -1651,8 +1652,9 @@ prototype_redo_exec_hook(UNDO_ROW_DELETE)
}
share->state.state.checksum+= ha_checksum_korr(buff);
}
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_OPTIMIZED_ROWS;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
}
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
_ma_unpin_all_pages(info, rec->lsn);
......@@ -1683,7 +1685,8 @@ prototype_redo_exec_hook(UNDO_ROW_UPDATE)
}
share->state.state.checksum+= ha_checksum_korr(buff);
}
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
}
_ma_unpin_all_pages(info, rec->lsn);
return 0;
......@@ -1878,7 +1881,8 @@ prototype_redo_exec_hook(CLR_END)
}
if (row_entry && share->calc_checksum)
share->state.state.checksum+= ha_checksum_korr(logpos);
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
}
if (row_entry)
tprint(tracef, " rows' count %lu\n", (ulong)share->state.state.records);
......@@ -1906,9 +1910,9 @@ prototype_undo_exec_hook(UNDO_ROW_INSERT)
return 1;
}
share= info->s;
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_OPTIMIZED_ROWS;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_OPTIMIZED_ROWS | STATE_NOT_ZEROFILLED |
STATE_NOT_MOVABLE);
record_ptr= rec->header;
if (share->calc_checksum)
{
......@@ -1953,7 +1957,8 @@ prototype_undo_exec_hook(UNDO_ROW_DELETE)
return 1;
share= info->s;
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
translog_read_record(rec->lsn, 0, rec->record_length,
......@@ -1988,8 +1993,8 @@ prototype_undo_exec_hook(UNDO_ROW_UPDATE)
return 1;
share= info->s;
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
translog_read_record(rec->lsn, 0, rec->record_length,
......@@ -2032,7 +2037,8 @@ prototype_undo_exec_hook(UNDO_KEY_INSERT)
}
share= info->s;
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
......@@ -2077,7 +2083,8 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE)
}
share= info->s;
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
......@@ -2122,7 +2129,8 @@ prototype_undo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT)
}
share= info->s;
share->state.changed|= STATE_CHANGED | STATE_NOT_ANALYZED;
share->state.changed|= (STATE_CHANGED | STATE_NOT_ANALYZED |
STATE_NOT_ZEROFILLED | STATE_NOT_MOVABLE);
enlarge_buffer(rec);
if (log_record_buffer.str == NULL ||
......
......@@ -4,4 +4,4 @@
# unittest/ma_test_all-t
#
./unittest/ma_test_all-t
perl ../../unittest/unit.pl run unittest/ma_test_all-t
This diff is collapsed.
......@@ -172,6 +172,7 @@ int maria_update(register MARIA_HA *info, const uchar *oldrec, uchar *newrec)
it
*/
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | key_changed);
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
/*
Every Maria function that updates Maria table must end with
......
......@@ -205,19 +205,24 @@ int maria_write(MARIA_HA *info, uchar *record)
@todo when we enable multiple writers, we will have to protect
'records' and 'checksum' somehow.
*/
info->state->checksum+= !share->now_transactional *
info->cur_row.checksum;
if (!share->now_transactional)
info->state->checksum+= info->cur_row.checksum;
}
if ((share->base.auto_key != 0) & !share->now_transactional)
if (!share->now_transactional)
{
const HA_KEYSEG *keyseg= share->keyinfo[share->base.auto_key-1].seg;
const uchar *key= record + keyseg->start;
set_if_bigger(share->state.auto_increment,
ma_retrieve_auto_increment(key, keyseg->type));
if (share->base.auto_key != 0)
{
const HA_KEYSEG *keyseg= share->keyinfo[share->base.auto_key-1].seg;
const uchar *key= record + keyseg->start;
set_if_bigger(share->state.auto_increment,
ma_retrieve_auto_increment(key, keyseg->type));
}
info->state->records++;
}
info->update= (HA_STATE_CHANGED | HA_STATE_AKTIV | HA_STATE_WRITTEN |
HA_STATE_ROW_CHANGED);
info->state->records+= !share->now_transactional; /*otherwise already done*/
share->state.changed|= STATE_NOT_MOVABLE | STATE_NOT_ZEROFILLED;
info->cur_row.lastpos= filepos;
VOID(_ma_writeinfo(info, WRITEINFO_UPDATE_KEYFILE));
if (info->invalidator != 0)
......
......@@ -138,7 +138,7 @@ int main(int argc, char **argv)
ulonglong old_testflag=check_param.testflag;
if (!(check_param.testflag & T_REP))
check_param.testflag|= T_REP_BY_SORT;
check_param.testflag&= ~T_EXTEND; /* Don't needed */
check_param.testflag&= ~T_EXTEND; /* Not needed */
error|=maria_chk(&check_param, argv[-1]);
check_param.testflag= old_testflag;
VOID(fflush(stdout));
......@@ -195,7 +195,7 @@ static struct my_option my_long_options[] =
"No help available.",
0, 0, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"backup", 'B',
"Make a backup of the .MYD file as 'filename-time.BAK'.",
"Make a backup of the .MAD file as 'filename-time.BAK'.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.",
......@@ -355,12 +355,15 @@ static struct my_option my_long_options[] =
"Use stopwords from this file instead of built-in list.",
(uchar**) &ft_stopword_file, (uchar**) &ft_stopword_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"stats_method", OPT_STATS_METHOD,
"Specifies how index statistics collection code should treat NULLs. "
"Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
"\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
{ "stats_method", OPT_STATS_METHOD,
"Specifies how index statistics collection code should treat NULLs. "
"Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
"\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
(uchar**) &maria_stats_method_str, (uchar**) &maria_stats_method_str, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ "zerofill", 'z',
"Fill empty space in data and index files with zeroes",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
......@@ -382,7 +385,7 @@ static void usage(void)
puts("This software comes with NO WARRANTY: see the PUBLIC for details.\n");
puts("Description, check and repair of MARIA tables.");
puts("Used without options all tables on the command will be checked for errors");
printf("Usage: %s [OPTIONS] tables[.MYI]\n", my_progname_short);
printf("Usage: %s [OPTIONS] tables[.MAI]\n", my_progname_short);
printf("\nGlobal options:\n");
#ifndef DBUG_OFF
printf("\
......@@ -430,7 +433,7 @@ static void usage(void)
-T, --read-only Don't mark table as checked.\n");
puts("Recover (repair)/ options (When using '-r' or '-o'):\n\
-B, --backup Make a backup of the .MYD file as 'filename-time.BAK'.\n\
-B, --backup Make a backup of the .MAD file as 'filename-time.BAK'.\n\
--correct-checksum Correct checksum information for table.\n\
-D, --data-file-length=# Max length of data file (when recreating data\n\
file when it's full).\n\
......@@ -489,7 +492,8 @@ static void usage(void)
data much more localized and may speed up things\n\
(It may be VERY slow to do a sort the first time!).\n\
-b, --block-search=#\n\
Find a record, a block at given offset belongs to.");
Find a record, a block at given offset belongs to.\n\
--zerofill Fill empty space in data and index files with zeroes.");
print_defaults("my", load_default_groups);
my_print_variables(my_long_options);
......@@ -750,6 +754,12 @@ get_one_option(int optid,
check_param.start_check_pos= strtoull(argument, NULL, 0);
break;
#endif
case 'z':
if (argument == disabled_my_option)
check_param.testflag&= ~T_ZEROFILL;
else
check_param.testflag|= T_ZEROFILL;
break;
case 'H':
my_print_help(my_long_options);
exit(0);
......@@ -1035,7 +1045,8 @@ static int maria_chk(HA_CHECK *param, char *filename)
goto end2;
}
if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX))
if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX |
T_ZEROFILL))
{
/* Mark table as not transactional to avoid logging */
maria_disable_logging(info);
......@@ -1047,20 +1058,21 @@ static int maria_chk(HA_CHECK *param, char *filename)
param->keys_in_use);
if (tmp != share->state.key_map)
info->update|=HA_STATE_CHANGED;
}
if (rep_quick &&
maria_chk_del(param, info, param->testflag & ~T_VERBOSE))
{
if (param->testflag & T_FORCE_CREATE)
{
rep_quick=0;
_ma_check_print_info(param,"Creating new data file\n");
}
else
if (rep_quick &&
maria_chk_del(param, info, param->testflag & ~T_VERBOSE))
{
error=1;
_ma_check_print_error(param,
"Quick-recover aborted; Run recovery without switch 'q'");
if (param->testflag & T_FORCE_CREATE)
{
rep_quick=0;
_ma_check_print_info(param,"Creating new data file\n");
}
else
{
error=1;
_ma_check_print_error(param,
"Quick-recover aborted; Run recovery without switch 'q'");
}
}
}
if (!error)
......@@ -1075,6 +1087,9 @@ static int maria_chk(HA_CHECK *param, char *filename)
if (share->base.born_transactional)
share->state.create_rename_lsn= share->state.is_of_horizon=
LSN_REPAIRED_BY_MARIA_CHK;
}
if (!error && (param->testflag & T_REP_ANY))
{
if ((param->testflag & (T_REP_BY_SORT | T_REP_PARALLEL)) &&
(maria_is_any_key_active(share->state.key_map) ||
(rep_quick && !param->keys_in_use && !recreate)) &&
......@@ -1088,10 +1103,10 @@ static int maria_chk(HA_CHECK *param, char *filename)
error=maria_repair_parallel(param,info,filename,rep_quick);
state_updated=1;
}
else if (param->testflag & T_REP_ANY)
else
error=maria_repair(param, info,filename,rep_quick);
}
if (!error && param->testflag & T_SORT_RECORDS)
if (!error && (param->testflag & T_SORT_RECORDS))
{
/*
The data file is nowadays reopened in the repair code so we should
......@@ -1134,8 +1149,10 @@ static int maria_chk(HA_CHECK *param, char *filename)
}
}
}
if (!error && param->testflag & T_SORT_INDEX)
error=maria_sort_index(param,info,filename);
if (!error && (param->testflag & T_SORT_INDEX))
error= maria_sort_index(param,info,filename);
if (!error && (param->testflag & T_ZEROFILL))
error= maria_zerofill(param, info, filename);
if (!error)
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR);
......@@ -1271,7 +1288,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
reg3 MARIA_KEYDEF *keyinfo;
reg2 HA_KEYSEG *keyseg;
reg4 const char *text;
char buff[160],length[10],*pos,*end;
char buff[200],length[10],*pos,*end;
enum en_fieldtype type;
MARIA_SHARE *share= info->s;
char llbuff[22],llbuff2[22];
......@@ -1326,6 +1343,10 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
pos=strmov(pos,"optimized keys,");
if (!(share->state.changed & STATE_NOT_SORTED_PAGES))
pos=strmov(pos,"sorted index pages,");
if (!(share->state.changed & STATE_NOT_ZEROFILLED))
pos=strmov(pos,"zerofilled,");
if (!(share->state.changed & STATE_NOT_MOVABLE))
pos=strmov(pos,"movable,");
pos[-1]=0; /* Remove extra ',' */
}
printf("Status: %s\n",buff);
......
......@@ -539,13 +539,15 @@ struct st_maria_handler
/* bits in state.changed */
#define STATE_CHANGED 1
#define STATE_CRASHED 2
#define STATE_CRASHED_ON_REPAIR 4
#define STATE_NOT_ANALYZED 8
#define STATE_CHANGED 1
#define STATE_CRASHED 2
#define STATE_CRASHED_ON_REPAIR 4
#define STATE_NOT_ANALYZED 8
#define STATE_NOT_OPTIMIZED_KEYS 16
#define STATE_NOT_SORTED_PAGES 32
#define STATE_NOT_SORTED_PAGES 32
#define STATE_NOT_OPTIMIZED_ROWS 64
#define STATE_NOT_ZEROFILLED 128
#define STATE_NOT_MOVABLE 256
/* options to maria_read_cache */
......@@ -808,7 +810,9 @@ extern int _ma_readinfo(MARIA_HA *info, int lock_flag, int check_keybuffer);
extern int _ma_writeinfo(MARIA_HA *info, uint options);
extern int _ma_test_if_changed(MARIA_HA *info);
extern int _ma_mark_file_changed(MARIA_HA *info);
extern int _ma_mark_file_crashed(MARIA_SHARE *share);
extern void _ma_mark_file_crashed(MARIA_SHARE *share);
extern my_bool _ma_set_uuid(MARIA_HA *info, my_bool reset_uuid);
extern my_bool _ma_check_if_zero(uchar *pos, size_t size);
extern int _ma_decrement_open_count(MARIA_HA *info);
extern int _ma_check_index(MARIA_HA *info, int inx);
extern int _ma_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
......
......@@ -127,6 +127,7 @@ sub run_check_tests
["-m10000 -e4096 -K","-sm"],
["-m10000 -e8192 -K","-sm"],
["-m10000 -e16384 -E16384 -K -L","-sm"],
["-L -K -W -P -b32768", "-se"],
["-c -b65000","-se"] );
if ($count)
......@@ -188,6 +189,8 @@ sub run_repair_tests()
"$maria_path/maria_chk$suffix -se test1",
"$maria_path/maria_chk$suffix -rqos --correct-checksum test1",
"$maria_path/maria_chk$suffix -se test1",
"$maria_path/maria_chk$suffix -sz test1",
"$maria_path/maria_chk$suffix -se test1",
"$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",
......@@ -196,7 +199,10 @@ sub run_repair_tests()
"$maria_path/ma_test2$suffix $silent -c $row_type",
"$maria_path/maria_chk$suffix -se test2",
"$maria_path/maria_chk$suffix -sr test2",
"$maria_path/maria_chk$suffix -se test2"
"$maria_path/maria_chk$suffix -se test2",
"$maria_path/ma_test2$suffix $silent -c -t4 $row_type",
"$maria_path/maria_chk$suffix -sz test1",
"$maria_path/maria_chk$suffix -se test1"
);
if ($count)
......@@ -285,15 +291,15 @@ sub run_tests_on_warnings_and_errors
ok("$maria_path/ma_test2$suffix $silent -L -K -W -P -S -R1 -m500",
$verbose, 0);
ok("$maria_path/maria_chk$suffix -sm test2", $verbose, 0);
print "ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135\n";
# ma_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135\n
# In the following a failure is a success and success is a failure
$com= "$maria_path/ma_test2$suffix $silent -L -K -R1 -m2000 ";
$com.= ">ma_test2_message.txt 2>&1 && false";
ok($com, $verbose, 0, 1);
ok("cat ma_test2_message.txt", $verbose, 0);
ok("grep \"Error: 135\" ma_test2_message.txt > /dev/null", $verbose, 0);
print "$maria_path/maria_chk$suffix -sm test2 will warn that\n";
print "'Datafile is almost full'\n";
# maria_path/maria_chk$suffix -sm test2 will warn that
# Datafile is almost full
ok("$maria_path/maria_chk$suffix -sm test2 >ma_test2_message.txt 2>&1",
$verbose, 0);
ok("cat ma_test2_message.txt", $verbose, 0);
......@@ -327,21 +333,34 @@ sub run_tests_on_clrs
my ($verbose, $count)= @_;
my ($i, $nr_tests);
my @t1= ("$maria_path/ma_test2 -s -L -K -W -P -M -T -c -b -t2 -u1",
my @t1= ("$maria_path/ma_test2 -s -L -K -W -P -M -T -c -b -t2 -A1",
"cp maria_log_control tmp",
"$maria_path/maria_read_log -a -s",
"$maria_path/maria_chk -s -e test2",
"cp tmp/maria_log_control .",
"rm test2.MA?",
"$maria_path/maria_read_log -a -s",
"$maria_path/maria_chk -s -e test2"
"$maria_path/maria_chk -s -e test2",
"rm test2.MA?"
);
my @t2= ("$maria_path/ma_test2 -s -L -K -W -P -M -T -c -b -t2 -u1",
my @t2= ("$maria_path/ma_test2 -s -L -K -W -P -M -T -c -b -t2 -A1",
"$maria_path/maria_read_log -a -s",
"$maria_path/maria_chk -s -e test2",
"rm test2.MA?",
"$maria_path/maria_read_log -a -s",
"$maria_path/maria_chk -e -s test2"
"$maria_path/maria_chk -e -s test2",
"rm test2.MA?"
);
my @t3= ("ma_test2 -s -L -K -W -P -M -T -c -b32768 -t4 -A1",
"maria_read_log -a -s",
"maria_chk -es test2",
"maria_read_log -a -s",
"maria_chk -es test2",
"rm test2.MA?",
"maria_read_log -a -s",
"maria_chk -es test2",
"rm test2.MA?"
);
if ($count)
......@@ -349,6 +368,7 @@ sub run_tests_on_clrs
$nr_tests= 0;
for ($i= 0; defined($t1[$i]); $i++) { $nr_tests++; }
for ($i= 0; defined($t2[$i]); $i++) { $nr_tests++; }
for ($i= 0; defined($t3[$i]); $i++) { $nr_tests++; }
return $nr_tests;
}
......@@ -363,6 +383,12 @@ sub run_tests_on_clrs
{
ok($t2[$i], $verbose, $i + 1);
}
unlink <maria_log.* maria_log_control>;
for ($i= 0; defined($t3[$i]); $i++)
{
ok($t3[$i], $verbose, $i + 1);
}
return 0;
}
......
......@@ -16,7 +16,7 @@ static const char *default_dbug_option;
/*#define LOG_FLAGS TRANSLOG_SECTOR_PROTECTION | TRANSLOG_PAGE_CRC */
#define LOG_FLAGS 0
/*#define LONG_BUFFER_SIZE (1024L*1024L*1024L + 1024L*1024L*512)*/
#define LONG_BUFFER_SIZE (1024L*1024L*1024L)
#define LONG_BUFFER_SIZE (512L*1024L*1024L)
#define MIN_REC_LENGTH 30
#define SHOW_DIVIDER 10
#define LOG_FILE_SIZE (1024L*1024L*1024L + 1024L*1024L*512)
......
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