Commit d2f8b7d0 authored by Michael Widenius's avatar Michael Widenius

Fix for LP#602604: RQG: ma_blockrec.c:6187:...

Fix for LP#602604: RQG: ma_blockrec.c:6187: _ma_apply_redo_insert_row_head_or_tail: Assertion `0' failed on Maria engine recovery
More DBUG_PRINT (to simplify future debugging)
Aria: Added STATE_IN_REPAIR, which is set on start of repair. This allows us to see if 'crashed' flag was set intentionally.
Aria: Some trivial speedup optimization
Aria: Better warning if table was marked crashed by unfinnished repair


mysql-test/lib/v1/mysql-test-run.pl:
  Fix so one can run RQG
mysql-test/suite/maria/r/maria-recovery2.result:
  Update for new error message.
mysys/stacktrace.c:
  Fixed compiler warning
storage/maria/ha_maria.cc:
  More DBUG_PRINT
  Added STATE_IN_REPAIR flag, which is set on start of repair. This allows us to see if 'crashed' flag was set intentionally.
  Don't log query for dropping temporary table.
storage/maria/ha_maria.h:
  Added prototype for drop_table()
storage/maria/ma_blockrec.c:
  More DBUG_PRINT
  Make read_long_data() inline for most cases. (Trivial speedup optimization)
storage/maria/ma_check.c:
  Better warning if table was marked crashed by unfinnished repair
storage/maria/ma_open.c:
  More DBUG_PRINT
storage/maria/ma_recovery.c:
  Give warning if found crashed table.
  Changed warning for tables that can't be opened.
storage/maria/ma_recovery_util.c:
  Write warnings to DBUG file
storage/maria/maria_chk.c:
  Added STATE_IN_REPAIR flag, which is set on start of repair. This allows us to see if 'crashed' flag was set intentionally.
storage/maria/maria_def.h:
  Added maria_mark_in_repair(x)
storage/maria/maria_read_log.c:
  Added option: --character-sets-dir
storage/maria/trnman.c:
  By default set min_read_from to max value.
  This allows us to remove TRN:s from rows during recovery to get more space.
  This fixes bug LP#602604: RQG: ma_blockrec.c:6187: _ma_apply_redo_insert_row_head_or_tail: Assertion `0' failed on Maria engine recovery
parent cf86a5ae
...@@ -3970,7 +3970,7 @@ sub mysqld_arguments ($$$$) { ...@@ -3970,7 +3970,7 @@ sub mysqld_arguments ($$$$) {
} }
} }
mtr_add_arg($args, "%s--character-set-server-set=latin1", $prefix); mtr_add_arg($args, "%s--character-set-server=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language); mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix); mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
......
...@@ -136,7 +136,7 @@ ERROR HY000: Lost connection to MySQL server during query ...@@ -136,7 +136,7 @@ ERROR HY000: Lost connection to MySQL server during query
* recovery happens * recovery happens
check table t_corrupted1 extended; check table t_corrupted1 extended;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
mysqltest.t_corrupted1 check warning Table is marked as crashed and last repair failed mysqltest.t_corrupted1 check warning Last repair was aborted before finishing
mysqltest.t_corrupted1 check status OK mysqltest.t_corrupted1 check status OK
* testing that checksum after recovery is as expected * testing that checksum after recovery is as expected
Checksum-check Checksum-check
......
...@@ -86,7 +86,7 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)), ...@@ -86,7 +86,7 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
#if BACKTRACE_DEMANGLE #if BACKTRACE_DEMANGLE
char __attribute__ ((weak)) *my_demangle(const char *mangled_name, int *status) char __attribute__ ((weak)) *my_demangle(const char *mangled_name __attribute__((unused)), int *status __attribute__((unused)))
{ {
return NULL; return NULL;
} }
......
...@@ -749,6 +749,9 @@ static int maria_create_trn_for_mysql(MARIA_HA *info) ...@@ -749,6 +749,9 @@ static int maria_create_trn_for_mysql(MARIA_HA *info)
(uchar*) thd->query(), (uchar*) thd->query(),
thd->query_length()); thd->query_length());
} }
else
DBUG_PRINT("info", ("lock_type: %d trnman_flags: %u",
info->lock_type, trnman_get_flags(trn))); /* QQ */
#endif #endif
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -1055,7 +1058,8 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) ...@@ -1055,7 +1058,8 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
if (!maria_is_crashed(file) && if (!maria_is_crashed(file) &&
(((param.testflag & T_CHECK_ONLY_CHANGED) && (((param.testflag & T_CHECK_ONLY_CHANGED) &&
!(share->state.changed & (STATE_CHANGED | STATE_CRASHED | !(share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR)) && STATE_CRASHED_ON_REPAIR |
STATE_IN_REPAIR)) &&
share->state.open_count == 0) || share->state.open_count == 0) ||
((param.testflag & T_FAST) && (share->state.open_count == ((param.testflag & T_FAST) && (share->state.open_count ==
(uint) (share->global_changed ? 1 : (uint) (share->global_changed ? 1 :
...@@ -1092,14 +1096,15 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt) ...@@ -1092,14 +1096,15 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
if (!error) if (!error)
{ {
if ((share->state.changed & (STATE_CHANGED | if ((share->state.changed & (STATE_CHANGED |
STATE_CRASHED_ON_REPAIR | STATE_CRASHED_ON_REPAIR | STATE_IN_REPAIR |
STATE_CRASHED | STATE_NOT_ANALYZED)) || STATE_CRASHED | STATE_NOT_ANALYZED)) ||
(param.testflag & T_STATISTICS) || maria_is_crashed(file)) (param.testflag & T_STATISTICS) || maria_is_crashed(file))
{ {
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
pthread_mutex_lock(&share->intern_lock); pthread_mutex_lock(&share->intern_lock);
share->state.changed &= ~(STATE_CHANGED | STATE_CRASHED | DBUG_PRINT("info", ("Reseting crashed state"));
STATE_CRASHED_ON_REPAIR); share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR | STATE_IN_REPAIR);
if (!(table->db_stat & HA_READ_ONLY)) if (!(table->db_stat & HA_READ_ONLY))
error= maria_update_state_info(&param, file, error= maria_update_state_info(&param, file,
UPDATE_TIME | UPDATE_OPEN_COUNT | UPDATE_TIME | UPDATE_OPEN_COUNT |
...@@ -1513,8 +1518,9 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize) ...@@ -1513,8 +1518,9 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
{ {
if ((share->state.changed & STATE_CHANGED) || maria_is_crashed(file)) if ((share->state.changed & STATE_CHANGED) || maria_is_crashed(file))
{ {
share->state.changed &= ~(STATE_CHANGED | STATE_CRASHED | DBUG_PRINT("info", ("Reseting crashed state"));
STATE_CRASHED_ON_REPAIR); share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR | STATE_IN_REPAIR);
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
} }
/* /*
...@@ -2360,6 +2366,15 @@ int ha_maria::delete_table(const char *name) ...@@ -2360,6 +2366,15 @@ int ha_maria::delete_table(const char *name)
} }
/* This is mainly for temporary tables, so no logging necessary */
void ha_maria::drop_table(const char *name)
{
(void) close();
(void) maria_delete_table(name);
}
int ha_maria::external_lock(THD *thd, int lock_type) int ha_maria::external_lock(THD *thd, int lock_type)
{ {
DBUG_ENTER("ha_maria::external_lock"); DBUG_ENTER("ha_maria::external_lock");
......
...@@ -135,6 +135,7 @@ class ha_maria :public handler ...@@ -135,6 +135,7 @@ class ha_maria :public handler
ulonglong *nb_reserved_values); ulonglong *nb_reserved_values);
int rename_table(const char *from, const char *to); int rename_table(const char *from, const char *to);
int delete_table(const char *name); int delete_table(const char *name);
void drop_table(const char *name);
int check(THD * thd, HA_CHECK_OPT * check_opt); int check(THD * thd, HA_CHECK_OPT * check_opt);
int analyze(THD * thd, HA_CHECK_OPT * check_opt); int analyze(THD * thd, HA_CHECK_OPT * check_opt);
int repair(THD * thd, HA_CHECK_OPT * check_opt); int repair(THD * thd, HA_CHECK_OPT * check_opt);
......
...@@ -1377,7 +1377,8 @@ void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr, ...@@ -1377,7 +1377,8 @@ void _ma_compact_block_page(uchar *buff, uint block_size, uint rownr,
uint freed_size= 0; uint freed_size= 0;
uchar *dir, *end; uchar *dir, *end;
DBUG_ENTER("_ma_compact_block_page"); DBUG_ENTER("_ma_compact_block_page");
DBUG_PRINT("enter", ("rownr: %u", rownr)); DBUG_PRINT("enter", ("rownr: %u min_read_from: %lu", rownr,
(ulong) min_read_from));
DBUG_ASSERT(max_entry > 0 && DBUG_ASSERT(max_entry > 0 &&
max_entry < (block_size - PAGE_HEADER_SIZE - max_entry < (block_size - PAGE_HEADER_SIZE -
PAGE_SUFFIX_SIZE) / DIR_ENTRY_SIZE); PAGE_SUFFIX_SIZE) / DIR_ENTRY_SIZE);
...@@ -3407,13 +3408,14 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info, ...@@ -3407,13 +3408,14 @@ static my_bool allocate_and_write_block_record(MARIA_HA *info,
DBUG_ASSERT(row->checksum == (info->s->calc_checksum)(info, record)); DBUG_ASSERT(row->checksum == (info->s->calc_checksum)(info, record));
} }
} }
DBUG_PRINT("info", ("rowid: %lu (%lu:%u) length: %u", (ulong) row->lastpos,
(ulong) ma_recordpos_to_page(row->lastpos),
ma_recordpos_to_dir_entry(row->lastpos),
row_pos.length));
if (write_block_record(info, (uchar*) 0, record, row, if (write_block_record(info, (uchar*) 0, record, row,
blocks, blocks->block->org_bitmap_value != 0, blocks, blocks->block->org_bitmap_value != 0,
&row_pos, undo_lsn, 0)) &row_pos, undo_lsn, 0))
goto err; /* Error reading bitmap */ goto err;
DBUG_PRINT("exit", ("rowid: %lu (%lu:%u)", (ulong) row->lastpos,
(ulong) ma_recordpos_to_page(row->lastpos),
ma_recordpos_to_dir_entry(row->lastpos)));
/* Now let checkpoint happen but don't commit */ /* Now let checkpoint happen but don't commit */
DBUG_EXECUTE_IF("maria_over_alloc_bitmap", sleep(1000);); DBUG_EXECUTE_IF("maria_over_alloc_bitmap", sleep(1000););
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -4404,13 +4406,15 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent, ...@@ -4404,13 +4406,15 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
1 error 1 error
*/ */
static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length, static my_bool read_long_data2(MARIA_HA *info, uchar *to, ulong length,
MARIA_EXTENT_CURSOR *extent, MARIA_EXTENT_CURSOR *extent,
uchar **data, uchar **end_of_data) uchar **data, uchar **end_of_data)
{ {
DBUG_ENTER("read_long_data"); uint left_length;
left_length= (uint) (*end_of_data - *data);
DBUG_ENTER("read_long_data2");
DBUG_PRINT("enter", ("length: %lu left_length: %u", DBUG_PRINT("enter", ("length: %lu left_length: %u",
length, (uint) (*end_of_data - *data))); length, left_length));
DBUG_ASSERT(*data <= *end_of_data); DBUG_ASSERT(*data <= *end_of_data);
/* /*
...@@ -4422,14 +4426,15 @@ static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length, ...@@ -4422,14 +4426,15 @@ static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length,
This may change in the future, which is why we have the loop written This may change in the future, which is why we have the loop written
the way it's written. the way it's written.
*/ */
if (extent->first_extent && length > (ulong) (*end_of_data - *data)) if (extent->first_extent && length > left_length)
{
*end_of_data= *data; *end_of_data= *data;
left_length= 0;
}
for(;;) for(;;)
{ {
uint left_length; if (unlikely(left_length >= length))
left_length= (uint) (*end_of_data - *data);
if (likely(left_length >= length))
{ {
memcpy(to, *data, length); memcpy(to, *data, length);
(*data)+= length; (*data)+= length;
...@@ -4441,10 +4446,25 @@ static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length, ...@@ -4441,10 +4446,25 @@ static my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length,
length-= left_length; length-= left_length;
if (!(*data= read_next_extent(info, extent, end_of_data))) if (!(*data= read_next_extent(info, extent, end_of_data)))
break; break;
left_length= (uint) (*end_of_data - *data);
} }
DBUG_RETURN(1); DBUG_RETURN(1);
} }
static inline my_bool read_long_data(MARIA_HA *info, uchar *to, ulong length,
MARIA_EXTENT_CURSOR *extent,
uchar **data, uchar **end_of_data)
{
uint left_length= (uint) (*end_of_data - *data);
if (likely(left_length >= length))
{
memcpy(to, *data, length);
(*data)+= length;
return 0;
}
return read_long_data2(info, to, length, extent, data, end_of_data);
}
/* /*
Read a record from page (helper function for _ma_read_block_record()) Read a record from page (helper function for _ma_read_block_record())
......
...@@ -154,6 +154,9 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info) ...@@ -154,6 +154,9 @@ int maria_chk_status(HA_CHECK *param, MARIA_HA *info)
if (maria_is_crashed_on_repair(info)) if (maria_is_crashed_on_repair(info))
_ma_check_print_warning(param, _ma_check_print_warning(param,
"Table is marked as crashed and last repair failed"); "Table is marked as crashed and last repair failed");
else if (maria_in_repair(info))
_ma_check_print_warning(param,
"Last repair was aborted before finishing");
else if (maria_is_crashed(info)) else if (maria_is_crashed(info))
_ma_check_print_warning(param, _ma_check_print_warning(param,
"Table is marked as crashed"); "Table is marked as crashed");
...@@ -2242,7 +2245,7 @@ static my_bool protect_against_repair_crash(MARIA_HA *info, ...@@ -2242,7 +2245,7 @@ static my_bool protect_against_repair_crash(MARIA_HA *info,
if ((param->testflag & T_NO_CREATE_RENAME_LSN) == 0) if ((param->testflag & T_NO_CREATE_RENAME_LSN) == 0)
{ {
/* this can be true only for a transactional table */ /* this can be true only for a transactional table */
maria_mark_crashed_on_repair(info); maria_mark_in_repair(info);
if (_ma_state_info_write(share, if (_ma_state_info_write(share,
MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET | MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET |
MA_STATE_INFO_WRITE_LOCK)) MA_STATE_INFO_WRITE_LOCK))
......
...@@ -209,6 +209,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name, ...@@ -209,6 +209,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name,
DBUG_RETURN(m_info); DBUG_RETURN(m_info);
err: err:
DBUG_PRINT("error", ("error: %d", my_errno));
save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE; save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
if ((save_errno == HA_ERR_CRASHED) || if ((save_errno == HA_ERR_CRASHED) ||
(save_errno == HA_ERR_CRASHED_ON_USAGE) || (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
...@@ -918,10 +919,15 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) ...@@ -918,10 +919,15 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
if (!(m_info= maria_clone_internal(share, name, mode, data_file))) if (!(m_info= maria_clone_internal(share, name, mode, data_file)))
goto err; goto err;
if (maria_is_crashed(m_info))
DBUG_PRINT("warning", ("table is crashed: changed: %u",
share->state.changed));
pthread_mutex_unlock(&THR_LOCK_maria); pthread_mutex_unlock(&THR_LOCK_maria);
DBUG_RETURN(m_info); DBUG_RETURN(m_info);
err: err:
DBUG_PRINT("error", ("error: %d errpos: %d", my_errno, errpos));
save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE; save_errno=my_errno ? my_errno : HA_ERR_END_OF_FILE;
if ((save_errno == HA_ERR_CRASHED) || if ((save_errno == HA_ERR_CRASHED) ||
(save_errno == HA_ERR_CRASHED_ON_USAGE) || (save_errno == HA_ERR_CRASHED_ON_USAGE) ||
......
/* Copyright (C) 2006, 2007 MySQL AB /* Copyright (C) 2006, 2007 MySQL AB
Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -56,6 +57,7 @@ static ulong skipped_undo_phase; ...@@ -56,6 +57,7 @@ static ulong skipped_undo_phase;
static ulonglong now; /**< for tracking execution time of phases */ static ulonglong now; /**< for tracking execution time of phases */
static int (*save_error_handler_hook)(uint, const char *,myf); static int (*save_error_handler_hook)(uint, const char *,myf);
static uint recovery_warnings; /**< count of warnings */ static uint recovery_warnings; /**< count of warnings */
static uint recovery_found_crashed_tables;
#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)
...@@ -219,7 +221,7 @@ int maria_recovery_from_log(void) ...@@ -219,7 +221,7 @@ int maria_recovery_from_log(void)
TRUE, TRUE, TRUE, &warnings_count); TRUE, TRUE, TRUE, &warnings_count);
if (!res) if (!res)
{ {
if (warnings_count == 0) if (warnings_count == 0 && recovery_found_crashed_tables == 0)
tprint(trace_file, "SUCCESS\n"); tprint(trace_file, "SUCCESS\n");
else else
tprint(trace_file, "DOUBTFUL (%u warnings, check previous output)\n", tprint(trace_file, "DOUBTFUL (%u warnings, check previous output)\n",
...@@ -265,7 +267,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, ...@@ -265,7 +267,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
DBUG_ASSERT(apply == MARIA_LOG_APPLY || !should_run_undo_phase); DBUG_ASSERT(apply == MARIA_LOG_APPLY || !should_run_undo_phase);
DBUG_ASSERT(!maria_multi_threaded); DBUG_ASSERT(!maria_multi_threaded);
recovery_warnings= 0; recovery_warnings= recovery_found_crashed_tables= 0;
maria_recovery_changed_data= 0; maria_recovery_changed_data= 0;
/* checkpoints can happen only if TRNs have been built */ /* checkpoints can happen only if TRNs have been built */
DBUG_ASSERT(should_run_undo_phase || !take_checkpoints); DBUG_ASSERT(should_run_undo_phase || !take_checkpoints);
...@@ -456,7 +458,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, ...@@ -456,7 +458,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply,
log_record_buffer.str= NULL; log_record_buffer.str= NULL;
log_record_buffer.length= 0; log_record_buffer.length= 0;
ma_checkpoint_end(); ma_checkpoint_end();
*warnings_count= recovery_warnings; *warnings_count= recovery_warnings + recovery_found_crashed_tables;
if (recovery_message_printed != REC_MSG_NONE) if (recovery_message_printed != REC_MSG_NONE)
{ {
if (procent_printed) if (procent_printed)
...@@ -726,9 +728,12 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE) ...@@ -726,9 +728,12 @@ prototype_redo_exec_hook(REDO_CREATE_TABLE)
maria_close(info); maria_close(info);
info= NULL; info= NULL;
} }
else /* one or two files absent, or header corrupted... */ else
tprint(tracef, "Table '%s' can't be opened, probably does not exist\n", {
name); /* one or two files absent, or header corrupted... */
tprint(tracef, "Table '%s' can't be opened (Error: %d)\n",
name, my_errno);
}
/* if does not exist, or is older, overwrite it */ /* if does not exist, or is older, overwrite it */
ptr= name + strlen(name) + 1; ptr= name + strlen(name) + 1;
if ((flags= ptr[0] ? HA_DONT_TOUCH_DATA : 0)) if ((flags= ptr[0] ? HA_DONT_TOUCH_DATA : 0))
...@@ -1206,6 +1211,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) ...@@ -1206,6 +1211,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
*/ */
tprint(tracef, ", record is corrupted"); tprint(tracef, ", record is corrupted");
info= NULL; info= NULL;
recovery_warnings++;
goto end; goto end;
} }
tprint(tracef, "Table '%s', id %u", name, sid); tprint(tracef, "Table '%s', id %u", name, sid);
...@@ -1215,6 +1221,8 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) ...@@ -1215,6 +1221,8 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
tprint(tracef, ", is absent (must have been dropped later?)" tprint(tracef, ", is absent (must have been dropped later?)"
" or its header is so corrupted that we cannot open it;" " or its header is so corrupted that we cannot open it;"
" we skip it"); " we skip it");
if (my_errno != ENOENT)
recovery_found_crashed_tables++;
error= 0; error= 0;
goto end; goto end;
} }
...@@ -1238,6 +1246,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) ...@@ -1238,6 +1246,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
*/ */
tprint(tracef, ", is not transactional. Ignoring open request"); tprint(tracef, ", is not transactional. Ignoring open request");
error= -1; error= -1;
recovery_warnings++;
goto end; goto end;
} }
if (cmp_translog_addr(lsn_of_file_id, share->state.create_rename_lsn) <= 0) if (cmp_translog_addr(lsn_of_file_id, share->state.create_rename_lsn) <= 0)
...@@ -1246,6 +1255,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) ...@@ -1246,6 +1255,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
" LOGREC_FILE_ID's LSN (%lu,0x%lx), ignoring open request", " LOGREC_FILE_ID's LSN (%lu,0x%lx), ignoring open request",
LSN_IN_PARTS(share->state.create_rename_lsn), LSN_IN_PARTS(share->state.create_rename_lsn),
LSN_IN_PARTS(lsn_of_file_id)); LSN_IN_PARTS(lsn_of_file_id));
recovery_warnings++;
error= -1; error= -1;
goto end; goto end;
/* /*
...@@ -1257,6 +1267,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) ...@@ -1257,6 +1267,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
{ {
eprint(tracef, "Table '%s' is crashed, skipping it. Please repair it with" eprint(tracef, "Table '%s' is crashed, skipping it. Please repair it with"
" maria_chk -r", share->open_file_name.str); " maria_chk -r", share->open_file_name.str);
recovery_found_crashed_tables++;
error= -1; /* not fatal, try with other tables */ error= -1; /* not fatal, try with other tables */
goto end; goto end;
/* /*
...@@ -1275,6 +1286,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id) ...@@ -1275,6 +1286,7 @@ static int new_table(uint16 sid, const char *name, LSN lsn_of_file_id)
(kfile_len == MY_FILEPOS_ERROR)) (kfile_len == MY_FILEPOS_ERROR))
{ {
tprint(tracef, ", length unknown\n"); tprint(tracef, ", length unknown\n");
recovery_warnings++;
goto end; goto end;
} }
if (share->state.state.data_file_length != dfile_len) if (share->state.state.data_file_length != dfile_len)
......
...@@ -57,8 +57,16 @@ void tprint(FILE *trace_file __attribute__ ((unused)), ...@@ -57,8 +57,16 @@ void tprint(FILE *trace_file __attribute__ ((unused)),
const char *format __attribute__ ((unused)), ...) const char *format __attribute__ ((unused)), ...)
{ {
va_list args; va_list args;
#ifndef DBUG_OFF
{
char buff[1024];
va_start(args, format);
vsnprintf(buff, sizeof(buff)-1, format, args);
DBUG_PRINT("info", ("%s", buff));
va_end(args);
}
#endif
va_start(args, format); va_start(args, format);
DBUG_PRINT("info", ("%s", format));
if (trace_file != NULL) if (trace_file != NULL)
{ {
if (procent_printed) if (procent_printed)
......
...@@ -990,7 +990,7 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -990,7 +990,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
if ((param->testflag & (T_REP_ANY | T_SORT_RECORDS)) && if ((param->testflag & (T_REP_ANY | T_SORT_RECORDS)) &&
((share->state.changed & (STATE_CHANGED | STATE_CRASHED | ((share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR) || STATE_CRASHED_ON_REPAIR | STATE_IN_REPAIR) ||
!(param->testflag & T_CHECK_ONLY_CHANGED)))) !(param->testflag & T_CHECK_ONLY_CHANGED))))
need_to_check=1; need_to_check=1;
...@@ -1008,7 +1008,7 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -1008,7 +1008,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
} }
if ((param->testflag & T_CHECK_ONLY_CHANGED) && if ((param->testflag & T_CHECK_ONLY_CHANGED) &&
(share->state.changed & (STATE_CHANGED | STATE_CRASHED | (share->state.changed & (STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR))) STATE_CRASHED_ON_REPAIR | STATE_IN_REPAIR)))
need_to_check=1; need_to_check=1;
if (!need_to_check) if (!need_to_check)
{ {
...@@ -1225,8 +1225,11 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -1225,8 +1225,11 @@ static int maria_chk(HA_CHECK *param, char *filename)
if (!error && (param->testflag & T_ZEROFILL)) if (!error && (param->testflag & T_ZEROFILL))
error= maria_zerofill(param, info, filename); error= maria_zerofill(param, info, filename);
if (!error) if (!error)
{
DBUG_PRINT("info", ("Reseting crashed state"));
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED | share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR); STATE_CRASHED_ON_REPAIR | STATE_IN_REPAIR);
}
else else
maria_mark_crashed(info); maria_mark_crashed(info);
} }
...@@ -1278,8 +1281,9 @@ static int maria_chk(HA_CHECK *param, char *filename) ...@@ -1278,8 +1281,9 @@ static int maria_chk(HA_CHECK *param, char *filename)
if ((share->state.changed & STATE_CHANGED) && if ((share->state.changed & STATE_CHANGED) &&
(param->testflag & T_UPDATE_STATE)) (param->testflag & T_UPDATE_STATE))
info->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED; info->update|=HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
DBUG_PRINT("info", ("Reseting crashed state"));
share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED | share->state.changed&= ~(STATE_CHANGED | STATE_CRASHED |
STATE_CRASHED_ON_REPAIR); STATE_CRASHED_ON_REPAIR | STATE_IN_REPAIR);
} }
else if (!maria_is_crashed(info) && else if (!maria_is_crashed(info) &&
(param->testflag & T_UPDATE_STATE)) (param->testflag & T_UPDATE_STATE))
......
...@@ -611,6 +611,7 @@ struct st_maria_handler ...@@ -611,6 +611,7 @@ struct st_maria_handler
#define STATE_NOT_ZEROFILLED 128 #define STATE_NOT_ZEROFILLED 128
#define STATE_NOT_MOVABLE 256 #define STATE_NOT_MOVABLE 256
#define STATE_MOVED 512 /* set if base->uuid != maria_uuid */ #define STATE_MOVED 512 /* set if base->uuid != maria_uuid */
#define STATE_IN_REPAIR 1024 /* We are running repair on table */
/* options to maria_read_cache */ /* options to maria_read_cache */
...@@ -666,11 +667,17 @@ struct st_maria_handler ...@@ -666,11 +667,17 @@ struct st_maria_handler
#define maria_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \ #define maria_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \
STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \ STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \
(x)->update|= HA_STATE_CHANGED; \ (x)->update|= HA_STATE_CHANGED; \
DBUG_PRINT("error", \ DBUG_PRINT("error", ("Marked table crashed on repair")); \
("Marked table crashed")); \ }while(0)
#define maria_mark_in_repair(x) do{(x)->s->state.changed|= \
STATE_CRASHED | STATE_IN_REPAIR; \
(x)->update|= HA_STATE_CHANGED; \
DBUG_PRINT("error", ("Marked table crashed for repair")); \
}while(0) }while(0)
#define maria_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED) #define maria_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED)
#define maria_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR) #define maria_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR)
#define maria_in_repair(x) ((x)->s->state.changed & STATE_IN_REPAIR)
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
/** /**
Brings additional information in certain debug builds and in standalone Brings additional information in certain debug builds and in standalone
......
/* Copyright (C) 2007 MySQL AB /* Copyright (C) 2007 MySQL AB
Copyright (C) 2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -150,6 +151,9 @@ int main(int argc, char **argv) ...@@ -150,6 +151,9 @@ int main(int argc, char **argv)
#include "ma_check_standalone.h" #include "ma_check_standalone.h"
enum options_mc {
OPT_CHARSETS_DIR=256
};
static struct my_option my_long_options[] = static struct my_option my_long_options[] =
{ {
...@@ -158,6 +162,9 @@ static struct my_option my_long_options[] = ...@@ -158,6 +162,9 @@ static struct my_option my_long_options[] =
" Displays a lot of information if not run with --silent", " Displays a lot of information if not run with --silent",
(uchar **) &opt_apply, (uchar **) &opt_apply, 0, (uchar **) &opt_apply, (uchar **) &opt_apply, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-sets-dir", OPT_CHARSETS_DIR,
"Directory where character sets are.",
(uchar**) &charsets_dir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"check", 'c', {"check", 'c',
"if --display-only, check if record is fully readable (for debugging)", "if --display-only, check if record is fully readable (for debugging)",
(uchar **) &opt_check, (uchar **) &opt_check, 0, (uchar **) &opt_check, (uchar **) &opt_check, 0,
...@@ -206,7 +213,7 @@ static struct my_option my_long_options[] = ...@@ -206,7 +213,7 @@ static struct my_option my_long_options[] =
static void print_version(void) static void print_version(void)
{ {
VOID(printf("%s Ver 1.2 for %s on %s\n", VOID(printf("%s Ver 1.3 for %s on %s\n",
my_progname_short, SYSTEM_TYPE, MACHINE_TYPE)); my_progname_short, SYSTEM_TYPE, MACHINE_TYPE));
NETWARE_SET_SCREEN_MODE(1); NETWARE_SET_SCREEN_MODE(1);
} }
......
...@@ -176,6 +176,7 @@ int trnman_init(TrID initial_trid) ...@@ -176,6 +176,7 @@ int trnman_init(TrID initial_trid)
trnman_active_transactions= 0; trnman_active_transactions= 0;
trnman_committed_transactions= 0; trnman_committed_transactions= 0;
trnman_allocated_transactions= 0; trnman_allocated_transactions= 0;
dummy_transaction_object.min_read_from= ~(TrID) 0; /* for recovery */
pool= 0; pool= 0;
global_trid_generator= initial_trid; global_trid_generator= initial_trid;
......
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