diff options
author | unknown <monty@donna.mysql.com> | 2000-10-17 16:19:24 +0300 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2000-10-17 16:19:24 +0300 |
commit | 2ad8320b97ec7e4068a02e91169f4851e9d3f10f (patch) | |
tree | 27d0e6155df4adf8bc2ba4032977ecad637026a2 /myisam | |
parent | 08bb74b631c5b405b0a6cad155f6abc06a5fbf51 (diff) | |
download | mariadb-git-2ad8320b97ec7e4068a02e91169f4851e9d3f10f.tar.gz |
Fixes for automatic recover of MyISAM tables
Docs/manual.texi:
Update of automatic recover of MyISAM tables
myisam/mi_check.c:
Let the repair function rename files; This made the rest of the recover code simpler.
myisam/mi_page.c:
More debug information
myisam/myisamchk.c:
Addapt to new mi_check code; Fixed bug when a recover on RAID tables where aborted.
mysys/my_winthread.c:
Portability fix
sql/ha_myisam.cc:
Fix for automatic recover
sql/sql_table.cc:
Close all instances of table before running recover / optimize
Diffstat (limited to 'myisam')
-rw-r--r-- | myisam/mi_check.c | 110 | ||||
-rw-r--r-- | myisam/mi_page.c | 3 | ||||
-rw-r--r-- | myisam/myisamchk.c | 21 |
3 files changed, 106 insertions, 28 deletions
diff --git a/myisam/mi_check.c b/myisam/mi_check.c index b95767d33cb..e55065b795e 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1186,7 +1186,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, sort_info->dupp++; if (rep_quick == 1) { - param->error_printed=1; + param->error_printed=param->retry_without_quick=1; goto err; } continue; @@ -1218,6 +1218,16 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, param->retry_repair=param->retry_without_quick=1; goto err; } + if (param->testflag & T_SAFE_REPAIR) + { + /* Don't repair if we loosed more than one row */ + if (info->state->records+1 < start_records) + { + info->state->records=start_records; + got_error=1; + goto err; + } + } if (!rep_quick) { @@ -1226,7 +1236,6 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, info->state->data_file_length=sort_info->filepos; /* Only whole records */ share->state.split=info->state->records+info->state->del; - param->out_flag|=O_NEW_DATA; /* Data in new file */ share->state.version=(ulong) time((time_t*) 0); /* Force reopen */ } else @@ -1248,6 +1257,21 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, memcpy( &share->state.state, info->state, sizeof(*info->state)); err: + if (!got_error) + { + /* Replace the actual file with the temporary file */ + if (new_file >= 0) + { + my_close(new_file,MYF(0)); + info->dfile=new_file= -1; + if (change_to_newfile(share->filename,MI_NAME_DEXT, + DATA_TMP_EXT, share->base.raid_chunks, + (param->testflag & T_BACKUP_DATA ? + MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || + mi_open_datafile(info,share)) + got_error=1; + } + } if (got_error) { if (! param->error_printed) @@ -1275,7 +1299,8 @@ err: share->pack.header_length=0; share->data_file_type=sort_info->new_data_file_type; } - share->state.changed|=STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES; + share->state.changed|= (STATE_NOT_OPTIMIZED_KEYS | STATE_NOT_SORTED_PAGES | + STATE_NOT_ANALYZED); DBUG_RETURN(got_error); } @@ -1454,14 +1479,17 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) flush_key_blocks(info->s->kfile, FLUSH_IGNORE_CHANGED); /* Put same locks as old file */ - if (lock_file(param,new_file,0L,F_WRLCK,"tempfile",param->temp_filename)) - goto err; info->s->state.version=(ulong) time((time_t*) 0); VOID(_mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE)); VOID(my_close(info->s->kfile,MYF(MY_WME))); - param->out_flag|=O_NEW_INDEX; /* Data in new file */ + info->s->kfile = -1; + VOID(my_close(new_file,MYF(MY_WME))); + if (change_to_newfile(info->s->filename,MI_NAME_IEXT,INDEX_TMP_EXT,0, + MYF(0)) || + mi_open_keyfile(info->s)) + goto err2; + _mi_readinfo(info,F_WRLCK,0); - info->s->kfile=new_file; info->state->key_file_length=param->new_file_pos; info->update= (short) (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED); for (key=0 ; key < info->s->base.keys ; key++) @@ -1474,6 +1502,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name) err: VOID(my_close(new_file,MYF(MY_WME))); +err2: VOID(my_delete(param->temp_filename,MYF(MY_WME))); DBUG_RETURN(-1); } /* sort_index */ @@ -1843,7 +1872,6 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, /* Only whole records */ share->state.split=info->state->records+info->state->del; share->state.version=(ulong) time((time_t*) 0); - param->out_flag|=O_NEW_DATA; /* Data in new file */ my_close(info->dfile,MYF(0)); info->dfile=new_file; share->data_file_type=sort_info->new_data_file_type; @@ -1910,18 +1938,34 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, memcpy( &share->state.state, info->state, sizeof(*info->state)); err: + got_error|= flush_blocks(param,share->kfile); + VOID(end_io_cache(&info->rec_cache)); + if (!got_error) + { + /* Replace the actual file with the temporary file */ + if (new_file >= 0) + { + my_close(new_file,MYF(0)); + info->dfile=new_file= -1; + if (change_to_newfile(share->filename,MI_NAME_DEXT, + DATA_TMP_EXT, share->base.raid_chunks, + (param->testflag & T_BACKUP_DATA ? + MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) || + mi_open_datafile(info,share)) + got_error=1; + } + } if (got_error) { if (! param->error_printed) mi_check_print_error(param,"%d when fixing table",my_errno); if (new_file >= 0) { - VOID(end_io_cache(&info->rec_cache)); VOID(my_close(new_file,MYF(0))); - VOID(my_raid_delete(param->temp_filename,info->s->base.raid_chunks, + VOID(my_raid_delete(param->temp_filename,share->base.raid_chunks, MYF(MY_WME))); if (info->dfile == new_file) - info->dfile=0; + info->dfile= -1; } mi_mark_crashed_on_repair(info); } @@ -1933,7 +1977,6 @@ err: my_free(sort_info->record,MYF(MY_ALLOW_ZERO_PTR)); my_free(sort_info->buff,MYF(MY_ALLOW_ZERO_PTR)); VOID(end_io_cache(¶m->read_cache)); - VOID(end_io_cache(&info->rec_cache)); info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED); if (!got_error && (param->testflag & T_UNPACK)) { @@ -2441,6 +2484,7 @@ static int sort_key_write(SORT_INFO *sort_info, const void *a) sort_info->key_block-> lastkey), llbuff2)); + param->error_printed=param->retry_without_quick=1; if (sort_info->param->testflag & T_VERBOSE) _mi_print_key(stdout,sort_info->keyseg,(uchar*) a, USE_WHOLE_KEY); return (sort_delete_record(param)); @@ -2475,7 +2519,7 @@ static int sort_insert_key(MI_CHECK *param, my_off_t prev_block) { uint a_length,t_length,nod_flag; - my_off_t filepos; + my_off_t filepos,key_file_length; uchar *anc_buff,*lastkey; MI_KEY_PARAM s_temp; MI_INFO *info; @@ -2526,11 +2570,20 @@ static int sort_insert_key(MI_CHECK *param, mi_putint(anc_buff,key_block->last_length,nod_flag); bzero((byte*) anc_buff+key_block->last_length, sort_info->keyinfo->block_length- key_block->last_length); + key_file_length=info->state->key_file_length; if ((filepos=_mi_new(info,sort_info->keyinfo)) == HA_OFFSET_ERROR) - return 1; - if (my_pwrite(info->s->kfile,(byte*) anc_buff, - (uint) sort_info->keyinfo->block_length,filepos, - param->myf_rw)) + DBUG_RETURN(1); + + /* If we read the page from the key cache, we have to write it back to it */ + if (key_file_length == info->state->key_file_length) + { + if (_mi_write_keypage(info, sort_info->keyinfo, filepos, + anc_buff)) + DBUG_RETURN(1); + } + else if (my_pwrite(info->s->kfile,(byte*) anc_buff, + (uint) sort_info->keyinfo->block_length,filepos, + param->myf_rw)) DBUG_RETURN(1); DBUG_DUMP("buff",(byte*) anc_buff,mi_getint(anc_buff)); @@ -2608,7 +2661,7 @@ static int sort_delete_record(MI_CHECK *param) static int flush_pending_blocks(MI_CHECK *param) { uint nod_flag,length; - my_off_t filepos; + my_off_t filepos,key_file_length; MI_INFO *info; SORT_KEY_BLOCKS *key_block; SORT_INFO *sort_info= ¶m->sort_info; @@ -2623,18 +2676,27 @@ static int flush_pending_blocks(MI_CHECK *param) length=mi_getint(key_block->buff); if (nod_flag) _mi_kpointer(info,key_block->end_pos,filepos); - if ((filepos=_mi_new(info,sort_info->keyinfo)) == HA_OFFSET_ERROR) - DBUG_RETURN(1); + key_file_length=info->state->key_file_length; bzero((byte*) key_block->buff+length, sort_info->keyinfo->block_length-length); - if (my_pwrite(info->s->kfile,(byte*) key_block->buff, - (uint) sort_info->keyinfo->block_length,filepos, - param->myf_rw)) + if ((filepos=_mi_new(info,sort_info->keyinfo)) == HA_OFFSET_ERROR) + DBUG_RETURN(1); + + /* If we read the page from the key cache, we have to write it back */ + if (key_file_length == info->state->key_file_length) + { + if (_mi_write_keypage(info, sort_info->keyinfo, filepos, + key_block->buff)) + DBUG_RETURN(1); + } + else if (my_pwrite(info->s->kfile,(byte*) key_block->buff, + (uint) sort_info->keyinfo->block_length,filepos, + param->myf_rw)) DBUG_RETURN(1); DBUG_DUMP("buff",(byte*) key_block->buff,length); nod_flag=1; } - info->s->state.key_root[sort_info->key]=filepos; /* Last is root for tree */ + info->s->state.key_root[sort_info->key]=filepos; /* Last is root for tree */ DBUG_RETURN(0); } /* flush_pending_blocks */ diff --git a/myisam/mi_page.c b/myisam/mi_page.c index bc0394aedca..f8e2a977754 100644 --- a/myisam/mi_page.c +++ b/myisam/mi_page.c @@ -99,6 +99,7 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos) my_off_t old_link; char buff[8]; DBUG_ENTER("_mi_dispose"); + DBUG_PRINT("enter",("pos: %ld", (long) pos)); old_link=info->s->state.key_del[keyinfo->block_size]; info->s->state.key_del[keyinfo->block_size]=pos; @@ -141,6 +142,6 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo) info->s->state.key_del[keyinfo->block_size]=mi_sizekorr(buff); } info->s->state.changed|= STATE_NOT_SORTED_PAGES; - DBUG_PRINT("exit",("Pos: %d",pos)); + DBUG_PRINT("exit",("Pos: %ld",(long) pos)); DBUG_RETURN(pos); } /* _mi_new */ diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 26e1699a07c..7d9ba9b7c28 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -481,6 +481,7 @@ static int myisamchk(MI_CHECK *param, my_string filename) File datafile; char fixed_name[FN_REFLEN]; char llbuff[22],llbuff2[22]; + my_bool state_updated=0; MYISAM_SHARE *share; DBUG_ENTER("myisamchk"); @@ -665,12 +666,20 @@ static int myisamchk(MI_CHECK *param, my_string filename) (share->state.key_map || (rep_quick && !param->keys_in_use && !recreate)) && mi_test_if_sort_rep(info, info->state->records, 1)) + { error=mi_repair_by_sort(&check_param,info,fixed_name,rep_quick); + state_updated=1; + } else if (param->testflag & (T_REP | T_REP_BY_SORT)) error=mi_repair(&check_param, info,fixed_name,rep_quick); } if (!error && param->testflag & T_SORT_RECORDS) { + /* + The data file is nowadays reopened in the repair code so we should + soon remove the following reopen-code + */ +#ifndef TO_BE_REMOVED if (param->out_flag & O_NEW_DATA) { /* Change temp file to org file */ VOID(my_close(info->dfile,MYF(MY_WME))); /* Close new file */ @@ -682,6 +691,7 @@ static int myisamchk(MI_CHECK *param, my_string filename) param->out_flag&= ~O_NEW_DATA; /* We are using new datafile */ param->read_cache.file=info->dfile; } +#endif if (! error) { uint key; @@ -737,7 +747,11 @@ static int myisamchk(MI_CHECK *param, my_string filename) { error|=chk_key(param, info); if (!error && (param->testflag & (T_STATISTICS | T_AUTO_INC))) - error=update_state_info(param, info, UPDATE_STAT); + error=update_state_info(param, info, + ((param->testflag & T_STATISTICS) ? + UPDATE_STAT : 0) | + ((param->testflag & T_AUTO_INC) ? + UPDATE_AUTO_INC : 0)); } if ((!rep_quick && !error) || !(param->testflag & (T_FAST | T_FORCE_CREATE))) @@ -788,7 +802,8 @@ static int myisamchk(MI_CHECK *param, my_string filename) error|=update_state_info(param, info, UPDATE_OPEN_COUNT | (((param->testflag & (T_REP | T_REP_BY_SORT)) ? - UPDATE_TIME | UPDATE_STAT : 0) | + UPDATE_TIME : 0) | + (state_updated ? UPDATE_STAT : 0) | ((param->testflag & T_SORT_RECORDS) ? UPDATE_SORT : 0))); VOID(lock_file(param, share->kfile,0L,F_UNLCK,"indexfile",filename)); @@ -1244,7 +1259,7 @@ err: { VOID(end_io_cache(&info->rec_cache)); (void) my_close(new_file,MYF(MY_WME)); - (void) my_raid_delete(param->temp_filename, share->base.raid_chunksize, + (void) my_raid_delete(param->temp_filename, share->base.raid_chunks, MYF(MY_WME)); } if (temp_buff) |