diff options
author | unknown <monty@tramp.mysql.fi> | 2000-10-03 14:18:03 +0300 |
---|---|---|
committer | unknown <monty@tramp.mysql.fi> | 2000-10-03 14:18:03 +0300 |
commit | 63b7b45ff7f79a08a673e8b759a69f5ee7e67902 (patch) | |
tree | c02cc6a9c6585038615c596332aae70354b44aac /myisam | |
parent | 27a17a6ef909533820b2137ab598fb7df220876d (diff) | |
download | mariadb-git-63b7b45ff7f79a08a673e8b759a69f5ee7e67902.tar.gz |
First part of automatic repair of MyISAM tables.
Error on full disk on repair.
SIGHUP signal handling.
Update with keys on timestamp
Portability fixes
Docs/manual.texi:
Added documentation about automatic repair of MyISAM tables
client/mysql.cc:
Remove usage of tempnam.
include/my_sys.h:
Added create_temp_file
include/myisam.h:
Fix for disk full on repair
myisam/mi_check.c:
Fix for disk full on repair
myisam/sort.c:
Fix for disk full on repair & removed usage of tempnam()
mysys/mf_cache.c:
Remove usage of tempnam()
mysys/mf_dirname.c:
Changed convert_dirname to return end 0
mysys/my_fopen.c:
Security fixes
mysys/my_tempnam.c:
remove blanks
readline/bind.c:
Portability fixes
readline/complete.c:
Portability fixes
readline/histexpand.c:
Portability fixes
readline/input.c:
Portability fixes
readline/search.c:
Portability fixes
readline/shell.c:
Portability fixes
readline/terminal.c:
Portability fixes
readline/tilde.c:
Portability fixes
readline/undo.c:
Portability fixes
regex/cname.h:
Portability fixes
regex/debug.c:
Portability fixes
regex/main.c:
Portability fixes
regex/regcomp.c:
Portability fixes
regex/regerror.c:
Portability fixes
sql/filesort.cc:
Remove dummy code
sql/ha_myisam.cc:
Automatic repair of MyISAM tables
sql/ha_myisam.h:
Automatic repair of MyISAM tables
sql/handler.cc:
Automatic repair of MyISAM tables
sql/handler.h:
Automatic repair of MyISAM tables
sql/key.cc:
Fix for UPDATE with key on timestamp column
sql/mysql_priv.h:
Automatic repair of MyISAM tables
sql/mysqld.cc:
Automatic repair of MyISAM tables & signal SIGHUP handling
sql/sql_base.cc:
Automatic repair of MyISAM tables
sql/sql_class.cc:
Automatic repair of MyISAM tables
sql/sql_class.h:
Fix for insert with reference to columns
sql/sql_insert.cc:
Fix for insert with reference to columns
sql/table.cc:
Automatic repair of MyISAM tables
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
Diffstat (limited to 'myisam')
-rw-r--r-- | myisam/mi_check.c | 1 | ||||
-rw-r--r-- | myisam/sort.c | 183 |
2 files changed, 73 insertions, 111 deletions
diff --git a/myisam/mi_check.c b/myisam/mi_check.c index ce561e13bd2..f2787546a31 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1759,6 +1759,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, sort_param.key_read=sort_key_read; sort_param.lock_in_memory=lock_memory; sort_param.tmpdir=param->tmpdir; + sort_param.myf_rw=param->myf_rw; sort_param.sort_info=sort_info; del=info->state->del; diff --git a/myisam/sort.c b/myisam/sort.c index 0a5b575242f..80f9b0b0363 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -33,6 +33,7 @@ #define MERGEBUFF2 31 #define MIN_SORT_MEMORY (4096-MALLOC_OVERHEAD) #define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL) +#define DISK_BUFFER_SIZE (IO_SIZE*16) typedef struct st_buffpek { my_off_t file_pos; /* position to buffer */ @@ -47,30 +48,26 @@ extern void print_error _VARARGS((const char *fmt,...)); /* functions defined in this file */ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info,uint keys, - uchar * *sort_keys, + uchar **sort_keys, BUFFPEK *buffpek,int *maxbuffer, - FILE **tempfile, my_string tempname); + IO_CACHE *tempfile); static int NEAR_F write_keys(MI_SORT_PARAM *info,uchar * *sort_keys, - uint count, BUFFPEK *buffpek,FILE **tempfile, - my_string tempname); + uint count, BUFFPEK *buffpek,IO_CACHE *tempfile); static int NEAR_F write_index(MI_SORT_PARAM *info,uchar * *sort_keys, uint count); static int NEAR_F merge_many_buff(MI_SORT_PARAM *info,uint keys, uchar * *sort_keys, BUFFPEK *buffpek,int *maxbuffer, - FILE * *t_file, my_string tempname); -static uint NEAR_F read_to_buffer(FILE *fromfile,BUFFPEK *buffpek, + IO_CACHE *t_file); +static uint NEAR_F read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek, uint sort_length); -static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys,FILE *from_file, - FILE *to_file, uchar * *sort_keys, - BUFFPEK *lastbuff,BUFFPEK *Fb, - BUFFPEK *Tb); +static int NEAR_F merge_buffers(MI_SORT_PARAM *info,uint keys, + IO_CACHE *from_file, IO_CACHE *to_file, + uchar * *sort_keys, BUFFPEK *lastbuff, + BUFFPEK *Fb, BUFFPEK *Tb); static int NEAR_F merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int, - FILE *); + IO_CACHE *); static char **make_char_array(uint fields,uint length,myf my_flag); -static FILE *opentemp(my_string name,const char *temp_dir); -static void closetemp(my_string name,FILE *stream); - /* Creates a index of sorted keys */ /* Returns 0 if everything went ok */ @@ -81,14 +78,14 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, int error,maxbuffer,skr; uint memavl,old_memavl,keys,sort_length; BUFFPEK *buffpek; - char tempname[FN_REFLEN]; ha_rows records; uchar **sort_keys; - FILE *tempfile; + IO_CACHE tempfile; DBUG_ENTER("_create_index_by_sort"); DBUG_PRINT("enter",("sort_length: %d", info->key_length)); - tempfile=0; buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1; + my_b_clear(&tempfile); + buffpek= (BUFFPEK *) NULL; sort_keys= (uchar **) NULL; error= 1; maxbuffer=1; memavl=max(sortbuff_size,MIN_SORT_MEMORY); @@ -139,8 +136,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, if (!no_messages) printf(" - Searching for keys, allocating buffer for %d keys\n",keys); - if ((records=find_all_keys(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile, - tempname)) + if ((records=find_all_keys(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile)) == HA_POS_ERROR) goto err; if (maxbuffer == 0) @@ -157,13 +153,15 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, { if (!no_messages) printf(" - Merging %lu keys\n",records); - if (merge_many_buff(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile, - tempname)) + if (merge_many_buff(info,keys,sort_keys,buffpek,&maxbuffer,&tempfile)) goto err; + if (flush_io_cache(&tempfile) || + reinit_io_cache(&tempfile,READ_CACHE,0L,0,0)) + goto err; } if (!no_messages) puts(" - Last merge and dumping keys"); - if (merge_index(info,keys,sort_keys,buffpek,maxbuffer,tempfile)) + if (merge_index(info,keys,sort_keys,buffpek,maxbuffer,&tempfile)) goto err; } error =0; @@ -173,8 +171,7 @@ err: my_free((gptr) sort_keys,MYF(0)); if (buffpek) my_free((gptr) buffpek,MYF(0)); - if (tempfile) - closetemp(tempname,tempfile); + close_cached_file(&tempfile); DBUG_RETURN(error ? -1 : 0); } /* _create_index_by_sort */ @@ -184,8 +181,7 @@ err: static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, uchar **sort_keys, BUFFPEK *buffpek, - int *maxbuffer, FILE **tempfile, - my_string tempname) + int *maxbuffer, IO_CACHE *tempfile) { int error; uint idx,indexpos; @@ -198,8 +194,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, if ((uint) ++idx == keys) { if (indexpos >= (uint) *maxbuffer || - write_keys(info,sort_keys,idx-1,buffpek+indexpos,tempfile, - tempname)) + write_keys(info,sort_keys,idx-1,buffpek+indexpos,tempfile)) DBUG_RETURN((ha_rows) -1); memcpy(sort_keys[0],sort_keys[idx-1],(size_t) info->key_length); idx=1; indexpos++; @@ -209,7 +204,7 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, DBUG_RETURN(HA_POS_ERROR); /* Aborted by get_key */ if (indexpos) if (indexpos >= (uint) *maxbuffer || - write_keys(info,sort_keys,idx,buffpek+indexpos,tempfile,tempname)) + write_keys(info,sort_keys,idx,buffpek+indexpos,tempfile)) DBUG_RETURN(HA_POS_ERROR); *maxbuffer=(int) indexpos; DBUG_RETURN(indexpos*(keys-1)+idx); @@ -220,18 +215,23 @@ static ha_rows NEAR_F find_all_keys(MI_SORT_PARAM *info, uint keys, static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys, uint count, BUFFPEK *buffpek, - register FILE **tempfile, my_string tempname) + IO_CACHE *tempfile) { + uchar **end; + uint sort_length=info->key_length; DBUG_ENTER("write_keys"); qsort2((byte*) sort_keys,count,sizeof(byte*),(qsort2_cmp) info->key_cmp, info->sort_info); - if (! *tempfile && ! (*tempfile=opentemp(tempname,info->tmpdir))) + if (!my_b_inited(tempfile) && + open_cached_file(tempfile, info->tmpdir, "ST", DISK_BUFFER_SIZE, + info->myf_rw)) DBUG_RETURN(1); - buffpek->file_pos=my_ftell(*tempfile,MYF(0)); + buffpek->file_pos=my_b_tell(tempfile); buffpek->count=count; - while (count--) - if (my_fwrite(*tempfile,(byte*)*sort_keys++,info->key_length,MYF_RW)) + + for (end=sort_keys+count ; sort_keys != end ; sort_keys++) + if (my_b_write(tempfile,(byte*) *sort_keys,(uint) sort_length)) DBUG_RETURN(1); DBUG_RETURN(0); } /* write_keys */ @@ -239,7 +239,8 @@ static int NEAR_F write_keys(MI_SORT_PARAM *info, register uchar **sort_keys, /* Write index */ -static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys, register uint count) +static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys, + register uint count) { DBUG_ENTER("write_index"); @@ -256,22 +257,25 @@ static int NEAR_F write_index(MI_SORT_PARAM *info, register uchar **sort_keys, r static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, uchar **sort_keys, BUFFPEK *buffpek, - int *maxbuffer, FILE **t_file, - my_string t_name) + int *maxbuffer, IO_CACHE *t_file) { register int i; - FILE *from_file,*to_file,*temp; - FILE *t_file2; - char t_name2[FN_REFLEN]; + IO_CACHE t_file2, *from_file, *to_file, *temp; BUFFPEK *lastbuff; DBUG_ENTER("merge_many_buff"); - if (!(t_file2=opentemp(t_name2,info->tmpdir))) - DBUG_RETURN(1); + if (*maxbuffer < MERGEBUFF2) + DBUG_RETURN(0); /* purecov: inspected */ + if (flush_io_cache(t_file) || + open_cached_file(&t_file2,info->tmpdir,"ST",DISK_BUFFER_SIZE, + info->myf_rw)) + DBUG_RETURN(1); /* purecov: inspected */ - from_file= *t_file ; to_file= t_file2; + from_file= t_file ; to_file= &t_file2; while (*maxbuffer >= MERGEBUFF2) { + reinit_io_cache(from_file,READ_CACHE,0L,0,0); + reinit_io_cache(to_file,WRITE_CACHE,0L,0,0); lastbuff=buffpek; for (i=0 ; i <= *maxbuffer-MERGEBUFF*3/2 ; i+=MERGEBUFF) { @@ -282,17 +286,14 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++, buffpek+i,buffpek+ *maxbuffer)) break; - *maxbuffer= (int) (lastbuff-buffpek)-1; + if (flush_io_cache(to_file)) + break; /* purecov: inspected */ temp=from_file; from_file=to_file; to_file=temp; - VOID(my_fseek(to_file,0L,MY_SEEK_SET,MYF(0))); - } - if (to_file == *t_file) - { - closetemp(t_name,to_file); - *t_file=t_file2; - VOID(strmov(t_name,t_name2)); + *maxbuffer= (int) (lastbuff-buffpek)-1; } - else closetemp(t_name2,to_file); + close_cached_file(to_file); // This holds old result + if (to_file == t_file) + *t_file=t_file2; // Copy result file DBUG_RETURN(*maxbuffer >= MERGEBUFF2); /* Return 1 if interrupted */ } /* merge_many_buff */ @@ -301,20 +302,17 @@ static int NEAR_F merge_many_buff(MI_SORT_PARAM *info, uint keys, /* Read data to buffer */ /* This returns (uint) -1 if something goes wrong */ -static uint NEAR_F read_to_buffer(FILE *fromfile, BUFFPEK *buffpek, uint sort_length) +static uint NEAR_F read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek, + uint sort_length) { register uint count; uint length; - count=buffpek->max_keys; - if ((ha_rows) count > buffpek->count) - count=(uint) buffpek->count; - if (count) + if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count))) { - VOID(my_fseek(fromfile,buffpek->file_pos,MY_SEEK_SET,MYF(0))); - if (my_fread(fromfile,(byte*) buffpek->base, - (length= sort_length*count),MYF_RW)) - return((uint) -1); + if (my_pread(fromfile->file,(byte*) buffpek->base, + (length= sort_length*count),buffpek->file_pos,MYF_RW)) + return((uint) -1); /* purecov: inspected */ buffpek->key=buffpek->base; buffpek->file_pos+= length; /* New filepos */ buffpek->count-= count; @@ -328,8 +326,9 @@ static uint NEAR_F read_to_buffer(FILE *fromfile, BUFFPEK *buffpek, uint sort_le /* If to_file == 0 then use info->key_write */ static int NEAR_F -merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file, - uchar **sort_keys, BUFFPEK *lastbuff, BUFFPEK *Fb, BUFFPEK *Tb) +merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file, + IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff, + BUFFPEK *Fb, BUFFPEK *Tb) { int error; uint sort_length,maxcount; @@ -342,12 +341,11 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file, count=error=0; maxcount=keys/((uint) (Tb-Fb) +1); - sort_length=info->key_length; - LINT_INIT(to_start_filepos); if (to_file) - to_start_filepos=my_ftell(to_file,MYF(0)); + to_start_filepos=my_b_tell(to_file); strpos=(uchar*) sort_keys; + sort_length=info->key_length; if (init_queue(&queue,(uint) (Tb-Fb)+1,offsetof(BUFFPEK,key),0, (int (*)(void*, byte *,byte*)) info->key_cmp, @@ -373,8 +371,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file, buffpek=(BUFFPEK*) queue_top(&queue); if (to_file) { - if (my_fwrite(to_file,(byte*) buffpek->key,(uint) sort_length, - MYF_RW | MY_WAIT_IF_FULL)) + if (my_b_write(to_file,(byte*) buffpek->key,(uint) sort_length)) { error=1; goto err; } @@ -417,6 +414,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file, break; /* One buffer have been removed */ } } + else if (error == -1) + goto err; /* purecov: inspected */ queue_replaced(&queue); /* Top element has been replaced */ } } @@ -427,9 +426,8 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file, { if (to_file) { - if (my_fwrite(to_file,(byte*) buffpek->key, - (uint) (sort_length*buffpek->mem_count), - MYF_RW | MY_WAIT_IF_FULL)) + if (my_b_write(to_file,(byte*) buffpek->key, + (sort_length*buffpek->mem_count))) { error=1; goto err; } @@ -454,7 +452,7 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, FILE *from_file, FILE *to_file, lastbuff->count=count; if (to_file) - lastbuff->file_pos=to_start_filepos; /* New block starts here */ + lastbuff->file_pos=to_start_filepos; err: delete_queue(&queue); DBUG_RETURN(error); @@ -465,10 +463,10 @@ err: static int NEAR_F merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys, - BUFFPEK *buffpek, int maxbuffer, FILE *tempfile) + BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile) { DBUG_ENTER("merge_index"); - if (merge_buffers(info,keys,tempfile,(FILE*) 0,sort_keys,buffpek,buffpek, + if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek, buffpek+maxbuffer)) DBUG_RETURN(1); DBUG_RETURN(0); @@ -492,40 +490,3 @@ static char **make_char_array(register uint fields, uint length, myf my_flag) DBUG_RETURN(old_pos); } /* make_char_array */ - - -/* Open a temporary file that will be deleted on close */ - -static FILE *opentemp(my_string name,const char *temp_dir) -{ - FILE *stream; - reg1 my_string str_pos; - DBUG_ENTER("opentemp"); - - if (!(str_pos=my_tempnam(temp_dir,"ST",MYF(MY_WME)))) - DBUG_RETURN(0); - VOID(strmov(name,str_pos)); - (*free)(str_pos); /* Avoid the 'free' macro */ - - stream=my_fopen(name,(int) (O_RDWR | FILE_BINARY | O_CREAT | O_TEMPORARY), - MYF(MY_WME)); -#if O_TEMPORARY == 0 && !defined(CANT_DELETE_OPEN_FILES) - VOID(my_delete(name,MYF(MY_WME | ME_NOINPUT))); -#endif - DBUG_PRINT("exit",("stream: %lx",stream)); - DBUG_RETURN (stream); -} /* opentemp */ - - -static void closetemp(my_string name __attribute__((unused)), FILE *stream) -{ - DBUG_ENTER("closetemp"); - - if (stream) - VOID(my_fclose(stream,MYF(MY_WME))); -#if !(O_TEMPORARY == 0 && !defined(CANT_DELETE_OPEN_FILES)) - if (name) - VOID(my_delete(name,MYF(MY_WME))); -#endif - DBUG_VOID_RETURN; -} /* closetemp */ |