Commit c19520d1 authored by Michael Widenius's avatar Michael Widenius

Fix for Bug #36578 Maria: maria-recover may fail to autorepair a table

Fixed also some similar issues in MyISAM. This was not noticed before as MyISAM did a second retry without key cache (which just made the second repair attempty slower)

storage/maria/ha_maria.cc:
  Print information if we retry without quick in case of CHECK TABLE table_name QUICK
  Remove T_QUICK flag when retrying repair, but set T_SAFE_REPAIR to ensure we don't loose any rows
  Remember T_RETRY_WITH_QUICK flag when restoring repair flags
  Don't print 'checking table' if we are not checking table in auto-repair
  Don't use T_QUICK in auto repair (safer)
  Changed parameter of type HA_PARAM &param to HA_PARAM *param
storage/maria/ha_maria.h:
  Changed parameter of type HA_PARAM &param to HA_PARAM *param
storage/maria/ma_check.c:
  Added retry without T_QUICK if there is a problem reading a row in BLOCK_RECORD
storage/myisam/ha_myisam.cc:
  Remove T_QUICK flag when retrying repair, but set T_SAFE_REPAIR to ensure we don't loose any rows
  Remember T_RETRY_WITH_QUICK flag when restoring repair flags
parent bf9a6af4
This diff is collapsed.
...@@ -45,7 +45,7 @@ class ha_maria :public handler ...@@ -45,7 +45,7 @@ class ha_maria :public handler
UNDO_BULK_INSERT with/without repair. UNDO_BULK_INSERT with/without repair.
*/ */
uint8 bulk_insert_single_undo; uint8 bulk_insert_single_undo;
int repair(THD * thd, HA_CHECK &param, bool optimize); int repair(THD * thd, HA_CHECK *param, bool optimize);
int zerofill(THD * thd, HA_CHECK_OPT *check_opt); int zerofill(THD * thd, HA_CHECK_OPT *check_opt);
public: public:
......
...@@ -99,6 +99,7 @@ static my_bool _ma_flush_table_files_before_swap(HA_CHECK *param, ...@@ -99,6 +99,7 @@ static my_bool _ma_flush_table_files_before_swap(HA_CHECK *param,
MARIA_HA *info); MARIA_HA *info);
static TrID max_trid_in_system(void); static TrID max_trid_in_system(void);
static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid); static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid);
void retry_if_quick(MARIA_SORT_PARAM *param, int error);
/* Initialize check param with default values */ /* Initialize check param with default values */
...@@ -4632,9 +4633,12 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -4632,9 +4633,12 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
} }
/* Retry only if wrong record, not if disk error */ /* Retry only if wrong record, not if disk error */
if (flag != HA_ERR_WRONG_IN_RECORD) if (flag != HA_ERR_WRONG_IN_RECORD)
{
retry_if_quick(sort_param, flag);
DBUG_RETURN(flag); DBUG_RETURN(flag);
} }
break; }
break; /* Impossible */
} }
case STATIC_RECORD: case STATIC_RECORD:
for (;;) for (;;)
...@@ -4644,8 +4648,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) ...@@ -4644,8 +4648,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
{ {
if (sort_param->read_cache.error) if (sort_param->read_cache.error)
param->out_flag |= O_DATA_LOST; param->out_flag |= O_DATA_LOST;
param->retry_repair=1; retry_if_quick(sort_param, my_errno);
param->testflag|=T_RETRY_WITHOUT_QUICK;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
sort_param->start_recpos=sort_param->pos; sort_param->start_recpos=sort_param->pos;
...@@ -6634,3 +6637,22 @@ static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid) ...@@ -6634,3 +6637,22 @@ static void _ma_check_print_not_visible_error(HA_CHECK *param, TrID used_trid)
} }
} }
} }
/**
Mark that we can retry normal repair if we used quick repair
We shouldn't do this in case of disk error as in this case we are likely
to loose much more than expected.
*/
void retry_if_quick(MARIA_SORT_PARAM *sort_param, int error)
{
HA_CHECK *param=sort_param->sort_info->param;
if (!sort_param->fix_datafile && error >= HA_ERR_FIRST)
{
param->retry_repair=1;
param->testflag|=T_RETRY_WITHOUT_QUICK;
}
}
...@@ -996,7 +996,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) ...@@ -996,7 +996,9 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
if (test_all_bits(param.testflag, if (test_all_bits(param.testflag,
(uint) (T_RETRY_WITHOUT_QUICK | T_QUICK))) (uint) (T_RETRY_WITHOUT_QUICK | T_QUICK)))
{ {
param.testflag&= ~T_RETRY_WITHOUT_QUICK; param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
/* Ensure we don't loose any rows when retrying without quick */
param.testflag|= T_SAFE_REPAIR;
sql_print_information("Retrying repair of: '%s' without quick", sql_print_information("Retrying repair of: '%s' without quick",
table->s->path.str); table->s->path.str);
continue; continue;
...@@ -1130,7 +1132,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize) ...@@ -1130,7 +1132,7 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
error= mi_repair(&param, file, fixed_name, error= mi_repair(&param, file, fixed_name,
test(param.testflag & T_QUICK)); test(param.testflag & T_QUICK));
} }
param.testflag=testflag; param.testflag= testflag | (param.testflag & T_RETRY_WITHOUT_QUICK);
optimize_done=1; optimize_done=1;
} }
if (!error) if (!error)
......
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