diff options
author | Sergey Vojtovich <svoj@sun.com> | 2009-10-09 21:16:29 +0500 |
---|---|---|
committer | Sergey Vojtovich <svoj@sun.com> | 2009-10-09 21:16:29 +0500 |
commit | adbd70aa12b513e3fe15afdc283830a4df52a8c8 (patch) | |
tree | 12dae5d03212639ae5c30aa8df421e3a7feef318 /storage | |
parent | 1d1a293b26b08d17b5f32bf4cf2354cb8364b3b6 (diff) | |
download | mariadb-git-adbd70aa12b513e3fe15afdc283830a4df52a8c8.tar.gz |
BUG#47073 - valgrind errs, corruption,failed repair of partition,
low myisam_sort_buffer_size
Repair by sort (default) or parallel repair of a MyISAM table
(doesn't matter partitioned or not) as well as bulk inserts
and enable indexes some times didn't failover to repair with
key cache.
The problem was that after unsuccessful attempt, data file was
closed. Whereas repair with key cache requires open data file.
Fixed by reopening data file.
Also fixed a valgrind warning, which may appear during repair
by sort or parallel repair with certain myisam_sort_buffer_size
number of rows and length of an index entry (very dependent).
mysql-test/r/myisam.result:
A test case for BUG#47073.
mysql-test/t/myisam.test:
A test case for BUG#47073.
storage/myisam/ha_myisam.cc:
Reverted fix for BUG25289. Not needed anymore.
storage/myisam/mi_check.c:
Reopen data file, when repair by sort or parallel repair
fails.
When repair by sort is requested to rebuild data file, data file
gets rebuilt while fixing first index. When rebuild is completed,
info->dfile is pointing to temporary data file, original data file
is closed.
It may happen that repair has successfully fixed first index and
rebuilt data file, but failed to fix second index. E.g.
myisam_sort_buffer_size was big enough to fix first shorter index,
but not enough to fix subsequent longer index.
In this case we end up with info->dfile pointing to temporary file,
which is removed and info->dfile is set to -1.
Though repair by sort failed, the upper layer may still want to
try repair with key cache. But it needs info->dfile pointing to
valid data file.
storage/myisam/sort.c:
When performing a copy of IO_CACHE structure, current_pos and
current_end must be updated separatly to point to memory we're
copying to (not to memory we're copying from).
As t_file2 is always WRITE cache, proper members are write_pos
and write_end accordingly.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/myisam/ha_myisam.cc | 16 | ||||
-rw-r--r-- | storage/myisam/mi_check.c | 10 | ||||
-rw-r--r-- | storage/myisam/sort.c | 4 |
3 files changed, 10 insertions, 20 deletions
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 5198e685817..aa9a2eeb77a 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1087,22 +1087,6 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize) ha_rows rows= file->state->records; DBUG_ENTER("ha_myisam::repair"); - /* - Normally this method is entered with a properly opened table. If the - repair fails, it can be repeated with more elaborate options. Under - special circumstances it can happen that a repair fails so that it - closed the data file and cannot re-open it. In this case file->dfile - is set to -1. We must not try another repair without an open data - file. (Bug #25289) - */ - if (file->dfile == -1) - { - sql_print_information("Retrying repair of: '%s' failed. " - "Please try REPAIR EXTENDED or myisamchk", - table->s->path.str); - DBUG_RETURN(HA_ADMIN_FAILED); - } - param.db_name= table->s->db.str; param.table_name= table->alias; param.tmpfile_createflag = O_RDWR | O_TRUNC; diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 1c33ffa90f5..8f7b1399aa2 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -2561,8 +2561,9 @@ err: VOID(my_close(new_file,MYF(0))); VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks, MYF(MY_WME))); - if (info->dfile == new_file) - info->dfile= -1; + if (info->dfile == new_file) /* Retry with key cache */ + if (unlikely(mi_open_datafile(info, share, name, -1))) + param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); } @@ -3095,8 +3096,9 @@ err: VOID(my_close(new_file,MYF(0))); VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks, MYF(MY_WME))); - if (info->dfile == new_file) - info->dfile= -1; + if (info->dfile == new_file) /* Retry with key cache */ + if (unlikely(mi_open_datafile(info, share, name, -1))) + param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); } diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index f31edbe1249..fb16af9cddf 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -788,7 +788,11 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, cleanup: close_cached_file(to_file); /* This holds old result */ if (to_file == t_file) + { *t_file=t_file2; /* Copy result file */ + t_file->current_pos= &t_file->write_pos; + t_file->current_end= &t_file->write_end; + } DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ } /* merge_many_buff */ |