summaryrefslogtreecommitdiff
path: root/myisam
diff options
context:
space:
mode:
authorunknown <monty@tramp.mysql.fi>2000-10-03 14:18:03 +0300
committerunknown <monty@tramp.mysql.fi>2000-10-03 14:18:03 +0300
commit63b7b45ff7f79a08a673e8b759a69f5ee7e67902 (patch)
treec02cc6a9c6585038615c596332aae70354b44aac /myisam
parent27a17a6ef909533820b2137ab598fb7df220876d (diff)
downloadmariadb-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.c1
-rw-r--r--myisam/sort.c183
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 */