Commit 6156089b authored by Monty's avatar Monty

Fixed several issues with aria_chk

- Made output to be aligned in aria_chk -d
- Aria engine error texts are now written instead of "Undefined error"
- When running with --check --force, tables with wrong TRN's but otherwise
  correct are now zerofilled
- Fixed several bugs in check and recovery related to fulltext
- When doing recovery, store highest found TRID in aria_control_file
  Before this, the
parent ef88c7d3
...@@ -100,12 +100,13 @@ typedef struct st_handler_check_param ...@@ -100,12 +100,13 @@ typedef struct st_handler_check_param
time_t backup_time; /* To sign backup files */ time_t backup_time; /* To sign backup files */
ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; 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]; double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
uint out_flag, warning_printed, error_printed, note_printed, verbose; uint out_flag, error_printed, verbose;
uint opt_sort_key, total_files, max_level; uint opt_sort_key, total_files, max_level;
uint key_cache_block_size, pagecache_block_size; uint key_cache_block_size, pagecache_block_size;
int tmpfile_createflag, err_count; int tmpfile_createflag, err_count;
myf myf_rw; myf myf_rw;
uint16 language; uint16 language;
my_bool warning_printed, note_printed, wrong_trd_printed;
my_bool using_global_keycache, opt_lock_memory, opt_follow_links; my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
my_bool retry_repair, force_sort, calc_checksum, static_row_size; my_bool retry_repair, force_sort, calc_checksum, static_row_size;
char temp_filename[FN_REFLEN]; char temp_filename[FN_REFLEN];
......
...@@ -149,7 +149,7 @@ void maria_chk_init_for_check(HA_CHECK *param, MARIA_HA *info) ...@@ -149,7 +149,7 @@ void maria_chk_init_for_check(HA_CHECK *param, MARIA_HA *info)
*/ */
param->max_trid= ~(TrID) 0; param->max_trid= ~(TrID) 0;
} }
else if (param->max_trid == 0) else if (param->max_trid == 0 || param->max_trid == ~(TrID) 0)
{ {
if (!ma_control_file_inited()) if (!ma_control_file_inited())
param->max_trid= 0; /* Give warning for first trid found */ param->max_trid= 0; /* Give warning for first trid found */
...@@ -179,7 +179,7 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info) ...@@ -179,7 +179,7 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info)
if (share->state.open_count != (uint) (share->global_changed ? 1 : 0)) if (share->state.open_count != (uint) (share->global_changed ? 1 : 0))
{ {
/* Don't count this as a real warning, as check can correct this ! */ /* Don't count this as a real warning, as check can correct this ! */
uint save=param->warning_printed; my_bool save=param->warning_printed;
_ma_check_print_warning(param, _ma_check_print_warning(param,
share->state.open_count==1 ? share->state.open_count==1 ?
"%d client is using or hasn't closed the table properly" : "%d client is using or hasn't closed the table properly" :
...@@ -191,6 +191,7 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info) ...@@ -191,6 +191,7 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info)
} }
if (share->state.create_trid > param->max_trid) if (share->state.create_trid > param->max_trid)
{ {
param->wrong_trd_printed= 1; /* Force should run zerofill */
_ma_check_print_warning(param, _ma_check_print_warning(param,
"Table create_trd (%llu) > current max_transaction id (%llu). Table needs to be repaired or zerofilled to be usable", "Table create_trd (%llu) > current max_transaction id (%llu). Table needs to be repaired or zerofilled to be usable",
share->state.create_trid, param->max_trid); share->state.create_trid, param->max_trid);
...@@ -643,7 +644,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info) ...@@ -643,7 +644,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
(key_part_map) 1, HA_READ_KEY_EXACT)) (key_part_map) 1, HA_READ_KEY_EXACT))
{ {
/* Don't count this as a real warning, as maria_chk can't correct it */ /* Don't count this as a real warning, as maria_chk can't correct it */
uint save=param->warning_printed; my_bool save=param->warning_printed;
_ma_check_print_warning(param, "Found row where the auto_increment " _ma_check_print_warning(param, "Found row where the auto_increment "
"column has the value 0"); "column has the value 0");
param->warning_printed=save; param->warning_printed=save;
...@@ -891,11 +892,10 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -891,11 +892,10 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (level > param->max_level) if (level > param->max_level)
param->max_level=level; param->max_level=level;
if (_ma_get_keynr(share, anc_page->buff) != if (_ma_get_keynr(share, anc_page->buff) != keyinfo->key_nr)
(uint) (keyinfo - share->keyinfo))
_ma_check_print_error(param, "Page at %s is not marked for index %u", _ma_check_print_error(param, "Page at %s is not marked for index %u",
llstr(anc_page->pos, llbuff), llstr(anc_page->pos, llbuff),
(uint) (keyinfo - share->keyinfo)); (uint) keyinfo->key_nr);
if ((page_flag & KEYPAGE_FLAG_HAS_TRANSID) && if ((page_flag & KEYPAGE_FLAG_HAS_TRANSID) &&
!share->base.born_transactional) !share->base.born_transactional)
{ {
...@@ -1011,6 +1011,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo, ...@@ -1011,6 +1011,7 @@ static int chk_index(HA_CHECK *param, MARIA_HA *info, MARIA_KEYDEF *keyinfo,
if (subkeys < 0) if (subkeys < 0)
{ {
ha_rows tmp_keys=0; ha_rows tmp_keys=0;
share->ft2_keyinfo.key_nr= keyinfo->key_nr;
if (chk_index_down(param,info,&share->ft2_keyinfo,record, if (chk_index_down(param,info,&share->ft2_keyinfo,record,
temp_buff,&tmp_keys,key_checksum,1)) temp_buff,&tmp_keys,key_checksum,1))
goto err; goto err;
...@@ -2381,6 +2382,7 @@ static int initialize_variables_for_repair(HA_CHECK *param, ...@@ -2381,6 +2382,7 @@ static int initialize_variables_for_repair(HA_CHECK *param,
param->retry_repair= 0; param->retry_repair= 0;
param->warning_printed= 0; param->warning_printed= 0;
param->error_printed= 0; param->error_printed= 0;
param->wrong_trd_printed= 0;
sort_param->sort_info= sort_info; sort_param->sort_info= sort_info;
sort_param->fix_datafile= ! rep_quick; sort_param->fix_datafile= ! rep_quick;
...@@ -5754,8 +5756,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param, ...@@ -5754,8 +5756,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
a_length= share->keypage_header + nod_flag; a_length= share->keypage_header + nod_flag;
key_block->end_pos= anc_buff + share->keypage_header; key_block->end_pos= anc_buff + share->keypage_header;
bzero(anc_buff, share->keypage_header); bzero(anc_buff, share->keypage_header);
_ma_store_keynr(share, anc_buff, (uint) (sort_param->keyinfo - _ma_store_keynr(share, anc_buff, sort_param->key);
share->keyinfo));
lastkey=0; /* No previous key in block */ lastkey=0; /* No previous key in block */
} }
else else
......
...@@ -583,8 +583,8 @@ int ma_control_file_end(void) ...@@ -583,8 +583,8 @@ int ma_control_file_end(void)
close_error= mysql_file_close(control_file_fd, MYF(MY_WME)); close_error= mysql_file_close(control_file_fd, MYF(MY_WME));
/* /*
As mysql_file_close() frees structures even if close() fails, we do the same, As mysql_file_close() frees structures even if close() fails, we do the
i.e. we mark the file as closed in all cases. same, i.e. we mark the file as closed in all cases.
*/ */
control_file_fd= -1; control_file_fd= -1;
/* /*
......
...@@ -42,7 +42,7 @@ extern LSN last_checkpoint_lsn; ...@@ -42,7 +42,7 @@ extern LSN last_checkpoint_lsn;
*/ */
extern uint32 last_logno; extern uint32 last_logno;
extern TrID max_trid_in_control_file; extern TrID max_trid_in_control_file, max_long_trid;
extern uint8 recovery_failures; extern uint8 recovery_failures;
......
...@@ -153,8 +153,9 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info, ...@@ -153,8 +153,9 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
if (page_size < 4 || page_size > share->max_index_block_size || if (page_size < 4 || page_size > share->max_index_block_size ||
_ma_get_keynr(share, tmp) != keyinfo->key_nr) _ma_get_keynr(share, tmp) != keyinfo->key_nr)
{ {
DBUG_PRINT("error",("page %lu had wrong page length: %u keynr: %u", DBUG_PRINT("error",("page %lu had wrong page length: %u page_header: %u keynr: %u",
(ulong) (pos / block_size), page_size, (ulong) (pos / block_size), page_size,
share->keypage_header,
_ma_get_keynr(share, tmp))); _ma_get_keynr(share, tmp)));
DBUG_DUMP("page", tmp, page_size); DBUG_DUMP("page", tmp, page_size);
info->last_keypage = HA_OFFSET_ERROR; info->last_keypage = HA_OFFSET_ERROR;
......
...@@ -49,7 +49,6 @@ static LSN current_group_end_lsn; ...@@ -49,7 +49,6 @@ static LSN current_group_end_lsn;
/** Current group of REDOs is about this table and only this one */ /** Current group of REDOs is about this table and only this one */
static MARIA_HA *current_group_table; static MARIA_HA *current_group_table;
#endif #endif
static TrID max_long_trid= 0; /**< max long trid seen by REDO phase */
static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */ static my_bool skip_DDLs; /**< if REDO phase should skip DDL records */
/** @brief to avoid writing a checkpoint if recovery did nothing. */ /** @brief to avoid writing a checkpoint if recovery did nothing. */
static my_bool checkpoint_useful; static my_bool checkpoint_useful;
...@@ -62,6 +61,7 @@ static uint recovery_warnings; /**< count of warnings */ ...@@ -62,6 +61,7 @@ static uint recovery_warnings; /**< count of warnings */
static uint recovery_found_crashed_tables; static uint recovery_found_crashed_tables;
HASH tables_to_redo; /* For maria_read_log */ HASH tables_to_redo; /* For maria_read_log */
ulong maria_recovery_force_crash_counter; ulong maria_recovery_force_crash_counter;
TrID max_long_trid= 0; /**< max long trid seen by REDO phase */
#define prototype_redo_exec_hook(R) \ #define prototype_redo_exec_hook(R) \
static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec) static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec)
...@@ -473,6 +473,7 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn, ...@@ -473,6 +473,7 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
fflush(stderr); fflush(stderr);
} }
set_if_bigger(max_trid_in_control_file, max_long_trid);
if (take_checkpoints && checkpoint_useful) if (take_checkpoints && checkpoint_useful)
{ {
/* No dirty pages, all tables are closed, no active transactions, save: */ /* No dirty pages, all tables are closed, no active transactions, save: */
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <my_getopt.h> #include <my_getopt.h>
#include <my_check_opt.h> #include <my_check_opt.h>
#include <my_handler_errors.h>
#ifdef HAVE_SYS_MMAN_H #ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
...@@ -93,12 +94,28 @@ ATTRIBUTE_NORETURN static void my_exit(int exit_code); ...@@ -93,12 +94,28 @@ ATTRIBUTE_NORETURN static void my_exit(int exit_code);
HA_CHECK check_param; HA_CHECK check_param;
/*
Register handler error messages for usage with my_error()
NOTES
This is safe to call multiple times as my_error_register()
will ignore calls to register already registered error numbers.
*/
static const char **get_handler_error_messages(int e __attribute__((unused)))
{
return handler_error_messages;
}
/* Free memory and exit */ /* Free memory and exit */
static void my_exit(int exit_code) static void my_exit(int exit_code)
{ {
free_tmpdir(&maria_chk_tmpdir); free_tmpdir(&maria_chk_tmpdir);
free_defaults(default_argv); free_defaults(default_argv);
my_error_unregister(HA_ERR_FIRST,
HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
my_end(check_param.testflag & T_INFO ? my_end(check_param.testflag & T_INFO ?
MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR); MY_CHECK_ERROR | MY_GIVE_INFO : MY_CHECK_ERROR);
exit(exit_code); exit(exit_code);
...@@ -120,6 +137,8 @@ int main(int argc, char **argv) ...@@ -120,6 +137,8 @@ int main(int argc, char **argv)
maria_quick_table_bits=decode_bits; maria_quick_table_bits=decode_bits;
error=0; error=0;
maria_init(); maria_init();
my_error_register(get_handler_error_messages, HA_ERR_FIRST,
HA_ERR_FIRST+ array_elements(handler_error_messages)-1);
maria_block_size= 0; /* Use block size from control file */ maria_block_size= 0; /* Use block size from control file */
if (!opt_ignore_control_file && if (!opt_ignore_control_file &&
...@@ -160,6 +179,20 @@ int main(int argc, char **argv) ...@@ -160,6 +179,20 @@ int main(int argc, char **argv)
check_param.testflag&= ~T_REP; check_param.testflag&= ~T_REP;
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
if (check_param.wrong_trd_printed &&
(check_param.testflag & T_FORCE_CREATE) &&
!(check_param.error_printed | check_param.warning_printed))
{
/* Only wrong create_trd. Run zerofill */
ulonglong old_testflag= check_param.testflag;
check_param.testflag= T_ZEROFILL;
error|= maria_chk(&check_param, argv[-1]);
check_param.testflag= old_testflag;
check_param.error_printed= 0;
check_param.warning_printed= 0;
fflush(stdout);
fflush(stderr);
}
if ((check_param.error_printed | check_param.warning_printed) && if ((check_param.error_printed | check_param.warning_printed) &&
(check_param.testflag & T_FORCE_CREATE) && (check_param.testflag & T_FORCE_CREATE) &&
(!(check_param.testflag & (T_REP | T_REP_BY_SORT | T_SORT_RECORDS | (!(check_param.testflag & (T_REP | T_REP_BY_SORT | T_SORT_RECORDS |
...@@ -174,7 +207,6 @@ int main(int argc, char **argv) ...@@ -174,7 +207,6 @@ int main(int argc, char **argv)
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
} }
else
error|=new_error; error|=new_error;
if (argc && (!(check_param.testflag & T_SILENT) || if (argc && (!(check_param.testflag & T_SILENT) ||
check_param.testflag & T_INFO)) check_param.testflag & T_INFO))
...@@ -981,8 +1013,8 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -981,8 +1013,8 @@ static int maria_chk(HA_CHECK *param, char *filename)
MARIA_SHARE *share; MARIA_SHARE *share;
DBUG_ENTER("maria_chk"); DBUG_ENTER("maria_chk");
param->out_flag=error=param->warning_printed=param->error_printed= param->out_flag= error= param->error_printed= recreate= 0;
recreate=0; param->warning_printed= param->wrong_trd_printed= 0;
datafile=0; datafile=0;
param->isam_file_name=filename; /* For error messages */ param->isam_file_name=filename; /* For error messages */
warning_printed_by_chk_status= 0; warning_printed_by_chk_status= 0;
...@@ -1649,7 +1681,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name) ...@@ -1649,7 +1681,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
pos=strmov(pos,null_txt); pos=strmov(pos,null_txt);
*pos=0; *pos=0;
printf("%-4d%-6ld%-3d %-8s%-23s", printf("%-4d%-6ld%-3d %-9s%-23s",
key+1,(long) keyseg->start+1,keyseg->length,text,buff); key+1,(long) keyseg->start+1,keyseg->length,text,buff);
if (share->state.key_root[key] != HA_OFFSET_ERROR) if (share->state.key_root[key] != HA_OFFSET_ERROR)
llstr(share->state.key_root[key],buff); llstr(share->state.key_root[key],buff);
......
...@@ -111,7 +111,7 @@ int chk_status(HA_CHECK *param, register MI_INFO *info) ...@@ -111,7 +111,7 @@ int chk_status(HA_CHECK *param, register MI_INFO *info)
if (share->state.open_count != (uint) (info->s->global_changed ? 1 : 0)) if (share->state.open_count != (uint) (info->s->global_changed ? 1 : 0))
{ {
/* Don't count this as a real warning, as check can correct this ! */ /* Don't count this as a real warning, as check can correct this ! */
uint save=param->warning_printed; my_bool save=param->warning_printed;
mi_check_print_warning(param, mi_check_print_warning(param,
share->state.open_count==1 ? share->state.open_count==1 ?
"%d client is using or hasn't closed the table properly" : "%d client is using or hasn't closed the table properly" :
...@@ -526,7 +526,7 @@ int chk_key(HA_CHECK *param, register MI_INFO *info) ...@@ -526,7 +526,7 @@ int chk_key(HA_CHECK *param, register MI_INFO *info)
(key_part_map)1, HA_READ_KEY_EXACT)) (key_part_map)1, HA_READ_KEY_EXACT))
{ {
/* Don't count this as a real warning, as myisamchk can't correct it */ /* Don't count this as a real warning, as myisamchk can't correct it */
uint save=param->warning_printed; my_bool save=param->warning_printed;
mi_check_print_warning(param, "Found row where the auto_increment " mi_check_print_warning(param, "Found row where the auto_increment "
"column has the value 0"); "column has the value 0");
param->warning_printed=save; param->warning_printed=save;
...@@ -1515,7 +1515,8 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info, ...@@ -1515,7 +1515,8 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info,
new_file= -1; new_file= -1;
sort_param.sort_info=&sort_info; sort_param.sort_info=&sort_info;
param->retry_repair= 0; param->retry_repair= 0;
param->warning_printed= param->error_printed= param->note_printed= 0; param->warning_printed= param->note_printed= 0;
param->error_printed= 0;
if (!(param->testflag & T_SILENT)) if (!(param->testflag & T_SILENT))
{ {
...@@ -2210,7 +2211,8 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, ...@@ -2210,7 +2211,8 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
} }
param->testflag|=T_REP_BY_SORT; /* for easy checking */ param->testflag|=T_REP_BY_SORT; /* for easy checking */
param->retry_repair= 0; param->retry_repair= 0;
param->warning_printed= param->error_printed= param->note_printed= 0; param->warning_printed= param->note_printed= 0;
param->error_printed= 0;
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM; param->testflag|=T_CALC_CHECKSUM;
......
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