summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
Diffstat (limited to 'myisam')
-rw-r--r--myisam/mi_check.c10
-rw-r--r--myisam/mi_delete_table.c3
-rw-r--r--myisam/mi_key.c3
-rw-r--r--myisam/myisamchk.c20
4 files changed, 26 insertions, 10 deletions
diff --git a/myisam/mi_check.c b/myisam/mi_check.c
index 467e9a9bcb4..2736e98cea9 100644
--- a/myisam/mi_check.c
+++ b/myisam/mi_check.c
@@ -1464,6 +1464,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
my_off_t index_pos[MI_MAX_POSSIBLE_KEY];
uint r_locks,w_locks;
MYISAM_SHARE *share=info->s;
+ MI_STATE_INFO old_state;
DBUG_ENTER("sort_index");
if (!(param->testflag & T_SILENT))
@@ -1502,9 +1503,10 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
/* Flush key cache for this file if we are calling this outside myisamchk */
flush_key_blocks(share->kfile, FLUSH_IGNORE_CHANGED);
- /* Put same locks as old file */
share->state.version=(ulong) time((time_t*) 0);
+ old_state=share->state; /* save state if not stored */
r_locks=share->r_locks; w_locks=share->w_locks;
+ /* Put same locks as old file */
share->r_locks=share->w_locks=0;
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
VOID(my_close(share->kfile,MYF(MY_WME)));
@@ -1518,6 +1520,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
_mi_readinfo(info,F_WRLCK,0); /* Will lock the table */
info->lock_type=F_WRLCK;
share->r_locks=r_locks; share->w_locks=w_locks;
+ share->state=old_state; /* Restore old state */
info->state->key_file_length=param->new_file_pos;
info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED);
@@ -3144,7 +3147,7 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows)
*/
my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
- my_bool force __attribute__((unused)))
+ my_bool force)
{
MYISAM_SHARE *share=info->s;
uint i;
@@ -3160,7 +3163,8 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows,
is very time-consuming process, it's better to leave it to repair stage
but this repair shouldn't be repair_by_sort (serg)
*/
- if (mi_too_big_key_for_sort(key,rows) || (key->flag & HA_FULLTEXT))
+ if (!force && mi_too_big_key_for_sort(key,rows) ||
+ (key->flag & HA_FULLTEXT))
return FALSE;
}
return TRUE;
diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c
index 360956ad110..995106160ef 100644
--- a/myisam/mi_delete_table.c
+++ b/myisam/mi_delete_table.c
@@ -37,7 +37,8 @@ int mi_delete_table(const char *name)
#ifdef USE_RAID
{
MI_INFO *info;
- if (!(info=mi_open(name, O_RDONLY, 0)))
+ /* we use 'open_for_repair' to be able to delete a crashed table */
+ if (!(info=mi_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
DBUG_RETURN(my_errno);
raid_type = info->s->base.raid_type;
raid_chunks = info->s->base.raid_chunks;
diff --git a/myisam/mi_key.c b/myisam/mi_key.c
index bf2f5c292dd..9f4e2cb1524 100644
--- a/myisam/mi_key.c
+++ b/myisam/mi_key.c
@@ -184,8 +184,9 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
/* Length of key-part used with mi_rkey() always 2 */
uint tmp_length=uint2korr(pos);
k_length-= 2+length;
- set_if_smaller(length,tmp_length);
+ set_if_smaller(length,tmp_length); /* Safety */
store_key_length_inc(key,length);
+ old+=2; /* Skipp length */
memcpy((byte*) key, pos+2,(size_t) length);
key+= length;
continue;
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index 8e794b7e708..7c86ea14c2d 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -189,6 +189,7 @@ static struct option long_options[] =
{"silent", no_argument, 0, 's'},
{"sort-index", no_argument, 0, 'S'},
{"sort-records", required_argument, 0, 'R'},
+ {"sort-recover", no_argument, 0, 'n'},
{"tmpdir", required_argument, 0, 't'},
{"update-state", no_argument, 0, 'U'},
{"unpack", no_argument, 0, 'u'},
@@ -200,7 +201,7 @@ static struct option long_options[] =
static void print_version(void)
{
- printf("%s Ver 1.41 for %s at %s\n",my_progname,SYSTEM_TYPE,
+ printf("%s Ver 1.42 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
}
@@ -255,9 +256,11 @@ static void usage(void)
myisamchk repairs the table a symlink points at.\n\
-r, --recover Can fix almost anything except unique keys that aren't\n\
unique.\n\
+ -n, --sort-recover Force recovering with sorting even if the temporary\n\
+ file would be very big.\n\
-o, --safe-recover Uses old recovery method; Slower than '-r' but can\n\
- handle a couple of cases where '-r' reports that it can't\n\
- fix the data file.\n\
+ handle a couple of cases where '-r' reports that it\n\
+ can't fix the data file.\n\
--character-sets-dir=...\n\
Directory where character sets are\n\
--set-character-set=name\n\
@@ -306,7 +309,8 @@ static void get_options(register int *argc,register char ***argv)
set_all_changeable_vars(changeable_vars);
if (isatty(fileno(stdout)))
check_param.testflag|=T_WRITE_LOOP;
- while ((c=getopt_long(*argc,*argv,"aBcCdeifF?lqrmosSTuUvVw#:b:D:k:O:R:A::t:",
+ while ((c=getopt_long(*argc,*argv,
+ "aBcCdeifF?lqrmnosSTuUvVw#:b:D:k:O:R:A::t:",
long_options, &option_index)) != EOF)
{
switch(c) {
@@ -374,8 +378,13 @@ static void get_options(register int *argc,register char ***argv)
break;
case 'o':
check_param.testflag= (check_param.testflag & ~T_REP_BY_SORT) | T_REP;
+ check_param.force_sort=0;
my_disable_async_io=1; /* More safety */
break;
+ case 'n':
+ check_param.testflag= (check_param.testflag & ~T_REP) | T_REP_BY_SORT;
+ check_param.force_sort=1;
+ break;
case 'q':
check_param.opt_rep_quick++;
break;
@@ -683,7 +692,8 @@ static int myisamchk(MI_CHECK *param, my_string filename)
if ((param->testflag & T_REP_BY_SORT) &&
(share->state.key_map ||
(rep_quick && !param->keys_in_use && !recreate)) &&
- mi_test_if_sort_rep(info, info->state->records, 1))
+ mi_test_if_sort_rep(info, info->state->records,
+ check_param.force_sort))
{
error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick);
state_updated=1;