summaryrefslogtreecommitdiff
path: root/storage/myisam
diff options
context:
space:
mode:
authorunknown <knielsen@knielsen-hq.org>2013-05-28 15:39:56 +0200
committerunknown <knielsen@knielsen-hq.org>2013-05-28 15:39:56 +0200
commita0fd7382bc1e4a8ba0affd27d3034f445a4bb453 (patch)
treec8b4b1dabddbc47829a890d74025f7889e692425 /storage/myisam
parent08ce9bfe057b6cd31e7fbca4e4e9e48edde242fb (diff)
parentee2b7db3f88f6882022a8aa71b30043ed8b40792 (diff)
downloadmariadb-git-a0fd7382bc1e4a8ba0affd27d3034f445a4bb453.tar.gz
Merge 10.0-base -> 10.0
Diffstat (limited to 'storage/myisam')
-rw-r--r--storage/myisam/ha_myisam.cc2
-rw-r--r--storage/myisam/mi_check.c2
-rw-r--r--storage/myisam/myisam_ftdump.c2
-rw-r--r--storage/myisam/myisamchk.c44
-rw-r--r--storage/myisam/myisamdef.h9
-rw-r--r--storage/myisam/sort.c289
6 files changed, 221 insertions, 127 deletions
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 17dbcba8db9..2b422608597 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -78,7 +78,7 @@ static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONGLONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
"The buffer that is allocated when sorting the index when doing "
"a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE", NULL, NULL,
- 8192 * 1024, MIN_SORT_BUFFER + MALLOC_OVERHEAD, SIZE_T_MAX, 1);
+ SORT_BUFFER_INIT, MIN_SORT_BUFFER, SIZE_T_MAX, 1);
static MYSQL_SYSVAR_BOOL(use_mmap, opt_myisam_use_mmap, PLUGIN_VAR_NOCMDARG,
"Use memory mapping for reading and writing MyISAM tables", NULL, NULL, FALSE);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 056aff5a72b..97ea1d17c26 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -91,7 +91,7 @@ void myisamchk_init(HA_CHECK *param)
param->opt_follow_links=1;
param->keys_in_use= ~(ulonglong) 0;
param->search_after_block=HA_OFFSET_ERROR;
- param->use_buffers=USE_BUFFER_INIT;
+ param->use_buffers= KEY_BUFFER_INIT;
param->read_buffer_length=READ_BUFFER_INIT;
param->write_buffer_length=READ_BUFFER_INIT;
param->sort_buffer_length=SORT_BUFFER_INIT;
diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c
index ce0d7be3f0b..e1ea9f2de37 100644
--- a/storage/myisam/myisam_ftdump.c
+++ b/storage/myisam/myisam_ftdump.c
@@ -84,7 +84,7 @@ int main(int argc,char *argv[])
usage();
}
- init_key_cache(dflt_key_cache,MI_KEY_BLOCK_LENGTH,USE_BUFFER_INIT, 0, 0, 0);
+ init_key_cache(dflt_key_cache, MI_KEY_BLOCK_LENGTH, KEY_BUFFER_INIT, 0, 0, 0);
if (!(info=mi_open(argv[0], O_RDONLY,
HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER)))
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 7be84599d86..d5c13e9cba3 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -134,7 +134,7 @@ int main(int argc, char **argv)
enum options_mc {
OPT_CHARSETS_DIR=256, OPT_SET_COLLATION,OPT_START_CHECK_POS,
- OPT_CORRECT_CHECKSUM, OPT_KEY_BUFFER_SIZE,
+ OPT_CORRECT_CHECKSUM, OPT_CREATE_MISSING_KEYS, OPT_KEY_BUFFER_SIZE,
OPT_KEY_CACHE_BLOCK_SIZE, OPT_MYISAM_BLOCK_SIZE,
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
@@ -165,6 +165,11 @@ static struct my_option my_long_options[] =
{"correct-checksum", OPT_CORRECT_CHECKSUM,
"Correct checksum information for table.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"create-missing-keys", OPT_CREATE_MISSING_KEYS,
+ "Create missing keys. This assumes that the data file is correct and that "
+ "the the number of rows stored in the index file is correct. Enables "
+ "--quick",
+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifndef DBUG_OFF
{"debug", '#',
"Output debug log. Often this is 'd:t:o,filename'.",
@@ -270,7 +275,7 @@ static struct my_option my_long_options[] =
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{ "key_buffer_size", OPT_KEY_BUFFER_SIZE, "",
&check_param.use_buffers, &check_param.use_buffers, 0,
- GET_ULL, REQUIRED_ARG, USE_BUFFER_INIT, MALLOC_OVERHEAD,
+ GET_ULL, REQUIRED_ARG, KEY_BUFFER_INIT, MALLOC_OVERHEAD,
SIZE_T_MAX, MALLOC_OVERHEAD, IO_SIZE, 0},
{ "key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "",
&opt_key_cache_block_size,
@@ -395,10 +400,18 @@ static void usage(void)
-e, --extend-check Try to recover every possible row from the data file\n\
Normally this will also find a lot of garbage rows;\n\
Don't use this option if you are not totally desperate.\n\
- -f, --force Overwrite old temporary files.\n\
+ -f, --force Overwrite old temporary files. Add another --force to\n\
+ avoid 'myisam_sort_buffer_size is too small' errors.\n\
+ In this case we will attempt to do the repair with the\n\
+ given myisam_sort_buffer_size and dynamically allocate\n\
+ as many management buffers as needed.\n\
-k, --keys-used=# Tell MyISAM to update only some specific keys. # is a\n\
bit mask of which keys to use. This can be used to\n\
get faster inserts.\n\
+ --create-missing-keys\n\
+ Create missing keys. This assumes that the data\n\
+ file is correct and that the the number of rows stored\n\
+ in the index file is correct. Enables --quick\n\
--max-record-length=#\n\
Skip rows bigger than this if myisamchk can't allocate\n\
memory to hold it.\n\
@@ -541,10 +554,13 @@ get_one_option(int optid,
if (argument == disabled_my_option)
{
check_param.tmpfile_createflag= O_RDWR | O_TRUNC | O_EXCL;
- check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE);
+ check_param.testflag&= ~(T_FORCE_CREATE | T_UPDATE_STATE |
+ T_FORCE_SORT_MEMORY);
}
else
{
+ if (check_param.testflag & T_FORCE_CREATE)
+ check_param.testflag= T_FORCE_SORT_MEMORY;
check_param.tmpfile_createflag= O_RDWR | O_TRUNC;
check_param.testflag|= T_FORCE_CREATE | T_UPDATE_STATE;
}
@@ -597,8 +613,26 @@ get_one_option(int optid,
if (argument == disabled_my_option)
check_param.testflag&= ~(T_QUICK | T_FORCE_UNIQUENESS);
else
+ {
+ /*
+ If T_QUICK was specified before, but not OPT_CREATE_MISSING_KEYS,
+ then add T_FORCE_UNIQUENESS.
+ */
check_param.testflag|=
- (check_param.testflag & T_QUICK) ? T_FORCE_UNIQUENESS : T_QUICK;
+ ((check_param.testflag & (T_QUICK | T_CREATE_MISSING_KEYS)) ==
+ T_QUICK ? T_FORCE_UNIQUENESS : T_QUICK);
+ }
+ break;
+ case OPT_CREATE_MISSING_KEYS:
+ if (argument == disabled_my_option)
+ check_param.testflag&= ~(T_QUICK | T_CREATE_MISSING_KEYS);
+ else
+ {
+ check_param.testflag|= T_QUICK | T_CREATE_MISSING_KEYS;
+ /* Use repair by sort by default */
+ if (!(check_param.testflag & T_REP_ANY))
+ check_param.testflag|= T_REP_BY_SORT;
+ }
break;
case 'u':
if (argument == disabled_my_option)
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index a0377e34130..178660d6249 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -629,10 +629,11 @@ typedef struct st_mi_block_info /* Parameter to _mi_get_block_info */
#define UPDATE_AUTO_INC 8
#define UPDATE_OPEN_COUNT 16
-#define USE_BUFFER_INIT (((1024L*512L-MALLOC_OVERHEAD)/IO_SIZE)*IO_SIZE)
-#define READ_BUFFER_INIT (1024L*256L-MALLOC_OVERHEAD)
-#define SORT_BUFFER_INIT (2048L*1024L-MALLOC_OVERHEAD)
-#define MIN_SORT_BUFFER (4096-MALLOC_OVERHEAD)
+/* We use MY_ALIGN_DOWN here mainly to ensure that we get stable values for mysqld --help ) */
+#define KEY_BUFFER_INIT MY_ALIGN_DOWN(1024L*1024L-MALLOC_OVERHEAD, IO_SIZE)
+#define READ_BUFFER_INIT MY_ALIGN_DOWN(1024L*256L-MALLOC_OVERHEAD, 1024)
+#define SORT_BUFFER_INIT MY_ALIGN_DOWN(1024L*1024L*128L-MALLOC_OVERHEAD, 1024)
+#define MIN_SORT_BUFFER 4096
enum myisam_log_commands
{
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index 4af45ea02e9..4bff7b14e1a 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -34,8 +34,10 @@
#define MERGEBUFF 15
#define MERGEBUFF2 31
#define MYF_RW MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL)
-#define DISK_BUFFER_SIZE (IO_SIZE*16)
+#define DISK_BUFFER_SIZE (IO_SIZE*128)
+/* How many keys we can keep in memory */
+typedef ulonglong ha_keys;
/*
Pointers of functions for store and read keys from temp file
@@ -45,42 +47,42 @@ extern void print_error(const char *fmt,...);
/* Functions defined in this file */
-static ha_rows find_all_keys(MI_SORT_PARAM *info,uint keys,
+static ha_rows find_all_keys(MI_SORT_PARAM *info, ha_keys keys,
uchar **sort_keys,
- DYNAMIC_ARRAY *buffpek,int *maxbuffer,
+ DYNAMIC_ARRAY *buffpek,uint *maxbuffer,
IO_CACHE *tempfile,
IO_CACHE *tempfile_for_exceptions);
static int write_keys(MI_SORT_PARAM *info,uchar **sort_keys,
- uint count, BUFFPEK *buffpek,IO_CACHE *tempfile);
+ ha_keys count, BUFFPEK *buffpek,IO_CACHE *tempfile);
static int write_key(MI_SORT_PARAM *info, uchar *key,
IO_CACHE *tempfile);
static int write_index(MI_SORT_PARAM *info,uchar * *sort_keys,
- uint count);
-static int merge_many_buff(MI_SORT_PARAM *info,uint keys,
+ ha_keys count);
+static int merge_many_buff(MI_SORT_PARAM *info, ha_keys keys,
uchar * *sort_keys,
- BUFFPEK *buffpek,int *maxbuffer,
+ BUFFPEK *buffpek, uint *maxbuffer,
IO_CACHE *t_file);
-static uint read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
- uint sort_length);
-static int merge_buffers(MI_SORT_PARAM *info,uint keys,
+static my_off_t read_to_buffer(IO_CACHE *fromfile,BUFFPEK *buffpek,
+ uint sort_length);
+static int merge_buffers(MI_SORT_PARAM *info, ha_keys keys,
IO_CACHE *from_file, IO_CACHE *to_file,
uchar * *sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Fb, BUFFPEK *Tb);
-static int merge_index(MI_SORT_PARAM *,uint,uchar **,BUFFPEK *, int,
+static int merge_index(MI_SORT_PARAM *,ha_keys,uchar **,BUFFPEK *, uint,
IO_CACHE *);
static int flush_ft_buf(MI_SORT_PARAM *info);
static int write_keys_varlen(MI_SORT_PARAM *info,uchar **sort_keys,
- uint count, BUFFPEK *buffpek,
+ ha_keys count, BUFFPEK *buffpek,
IO_CACHE *tempfile);
-static uint read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
+static my_off_t read_to_buffer_varlen(IO_CACHE *fromfile,BUFFPEK *buffpek,
uint sort_length);
static int write_merge_key(MI_SORT_PARAM *info, IO_CACHE *to_file,
- uchar *key, uint sort_length, uint count);
+ uchar *key, uint sort_length, ha_keys count);
static int write_merge_key_varlen(MI_SORT_PARAM *info,
IO_CACHE *to_file,
uchar* key, uint sort_length,
- uint count);
+ ha_keys count);
static inline int
my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
@@ -101,15 +103,15 @@ my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs);
int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
ulonglong sortbuff_size)
{
- int error,maxbuffer,skr;
- uint sort_length, keys;
+ int error;
+ uint sort_length, maxbuffer;
ulonglong memavl, old_memavl;
DYNAMIC_ARRAY buffpek;
- ha_rows records;
+ ha_rows records, keys;
uchar **sort_keys;
IO_CACHE tempfile, tempfile_for_exceptions;
DBUG_ENTER("_create_index_by_sort");
- DBUG_PRINT("enter",("sort_length: %d", info->key_length));
+ DBUG_PRINT("enter",("sort_length: %u", info->key_length));
if (info->keyinfo->flag & HA_VAR_LENGTH_KEY)
{
@@ -135,37 +137,55 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
sort_length= info->key_length;
LINT_INIT(keys);
- if ((memavl - sizeof(BUFFPEK)) / (sort_length + sizeof(char *)) > UINT_MAX32)
- memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *));
-
while (memavl >= MIN_SORT_BUFFER)
{
- if ((records < UINT_MAX32) &&
- ((my_off_t) (records + 1) *
- (sort_length + sizeof(char*)) <= (my_off_t) memavl))
- keys= (uint)records+1;
+ /* Check if we can fit all keys into memory */
+ if (((ulonglong) (records + 1) *
+ (sort_length + sizeof(char*)) <= memavl))
+ keys= records+1;
+ else if ((info->sort_info->param->testflag &
+ (T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
+ T_FORCE_SORT_MEMORY)
+ {
+ /*
+ Use all of the given sort buffer for key data.
+ Allocate 1000 buffers at a start for new data. More buffers
+ will be allocated when needed.
+ */
+ keys= memavl / (sort_length+sizeof(char*));
+ maxbuffer= (uint) min((ulonglong) 1000, (records / keys)+1);
+ }
else
+ {
+ /*
+ All keys can't fit in memory.
+ Calculate how many keys + buffers we can keep in memory
+ */
+ uint maxbuffer_org;
do
{
- skr=maxbuffer;
- if (memavl < sizeof(BUFFPEK)*(uint) maxbuffer ||
- (keys=(memavl-sizeof(BUFFPEK)*(uint) maxbuffer)/
+ maxbuffer_org= maxbuffer;
+ if (memavl < sizeof(BUFFPEK) * maxbuffer ||
+ (keys= (memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
- keys < (uint) maxbuffer)
+ keys < maxbuffer)
{
mi_check_print_error(info->sort_info->param,
- "myisam_sort_buffer_size is too small");
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) records,
+ sort_length);
my_errno= ENOMEM;
goto err;
}
}
- while ((maxbuffer= (int) (records/(keys-1)+1)) != skr);
+ while ((maxbuffer= (uint) (records/(keys-1)+1)) != maxbuffer_org);
+ }
if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+
HA_FT_MAXBYTELEN, MYF(0))))
{
if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer,
- maxbuffer/2, MYF(0)))
+ min(maxbuffer/2, 1000), MYF(0)))
{
my_free(sort_keys);
sort_keys= 0;
@@ -179,24 +199,30 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
}
if (memavl < MIN_SORT_BUFFER)
{
- mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */
- my_errno= ENOMEM; /* purecov: tested */
- goto err; /* purecov: tested */
+ /* purecov: begin inspected */
+ mi_check_print_error(info->sort_info->param,
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) records, sort_length);
+ my_errno= ENOMEM;
+ goto err;
+ /* purecov: end inspected */
}
(*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
if (!no_messages)
- printf(" - Searching for keys, allocating buffer for %d keys\n",keys);
+ my_fprintf(stdout,
+ " - Searching for keys, allocating buffer for %llu keys\n",
+ (ulonglong) keys);
- if ((records=find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
- &tempfile,&tempfile_for_exceptions))
+ if ((records= find_all_keys(info,keys,sort_keys,&buffpek,&maxbuffer,
+ &tempfile,&tempfile_for_exceptions))
== HA_POS_ERROR)
goto err; /* purecov: tested */
if (maxbuffer == 0)
{
if (!no_messages)
- printf(" - Dumping %lu keys\n", (ulong) records);
- if (write_index(info,sort_keys, (uint) records))
+ my_fprintf(stdout, " - Dumping %llu keys\n", (ulonglong) records);
+ if (write_index(info, sort_keys, (ha_keys) records))
goto err; /* purecov: inspected */
}
else
@@ -205,7 +231,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (maxbuffer >= MERGEBUFF2)
{
if (!no_messages)
- printf(" - Merging %lu keys\n", (ulong) records); /* purecov: tested */
+ my_fprintf(stdout, " - Merging %llu keys\n",
+ (ulonglong) records); /* purecov: tested */
if (merge_many_buff(info,keys,sort_keys,
dynamic_element(&buffpek,0,BUFFPEK *),&maxbuffer,&tempfile))
goto err; /* purecov: inspected */
@@ -259,13 +286,13 @@ err:
/* Search after all keys and place them in a temp. file */
-static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys,
+static ha_rows find_all_keys(MI_SORT_PARAM *info, ha_rows keys,
uchar **sort_keys, DYNAMIC_ARRAY *buffpek,
- int *maxbuffer, IO_CACHE *tempfile,
+ uint *maxbuffer, IO_CACHE *tempfile,
IO_CACHE *tempfile_for_exceptions)
{
int error;
- uint idx;
+ ha_rows idx;
DBUG_ENTER("find_all_keys");
idx=error=0;
@@ -314,9 +341,10 @@ pthread_handler_t thr_find_all_keys(void *arg)
{
MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
int error;
- ulonglong memavl, old_memavl;
- uint keys, sort_length;
- uint idx, maxbuffer;
+ ulonglong memavl, old_memavl, sortbuff_size;
+ ha_keys keys, idx;
+ uint sort_length;
+ uint maxbuffer;
uchar **sort_keys=0;
LINT_INIT(keys);
@@ -351,37 +379,47 @@ pthread_handler_t thr_find_all_keys(void *arg)
bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
sort_keys= (uchar **) NULL;
- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
- idx= (uint)sort_param->sort_info->max_records;
+ sortbuff_size= sort_param->sortbuff_size;
+ memavl= max(sortbuff_size, MIN_SORT_BUFFER);
+ idx= (ha_keys) sort_param->sort_info->max_records;
sort_length= sort_param->key_length;
maxbuffer= 1;
- if ((memavl - sizeof(BUFFPEK)) / (sort_length +
- sizeof(char *)) > UINT_MAX32)
- memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *));
-
while (memavl >= MIN_SORT_BUFFER)
{
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
(my_off_t) memavl)
keys= idx+1;
+ else if ((sort_param->sort_info->param->testflag &
+ (T_FORCE_SORT_MEMORY | T_CREATE_MISSING_KEYS)) ==
+ T_FORCE_SORT_MEMORY)
+ {
+ /*
+ Use all of the given sort buffer for key data.
+ Allocate 1000 buffers at a start for new data. More buffers
+ will be allocated when needed.
+ */
+ keys= memavl / (sort_length+sizeof(char*));
+ maxbuffer= (uint) min((ulonglong) 1000, (idx / keys)+1);
+ }
else
{
- uint skr;
+ uint maxbuffer_org;
do
{
- skr= maxbuffer;
+ maxbuffer_org= maxbuffer;
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
keys < (uint) maxbuffer)
{
mi_check_print_error(sort_param->sort_info->param,
- "myisam_sort_buffer_size is too small");
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) idx, sort_length);
goto err;
}
}
- while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
+ while ((maxbuffer= (uint) (idx/(keys-1)+1)) != maxbuffer_org);
}
if ((sort_keys= (uchar**)
my_malloc(keys*(sort_length+sizeof(char*))+
@@ -389,7 +427,7 @@ pthread_handler_t thr_find_all_keys(void *arg)
HA_FT_MAXBYTELEN : 0), MYF(0))))
{
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
- maxbuffer, maxbuffer/2, MYF(0)))
+ maxbuffer, min(maxbuffer/2, 1000), MYF(0)))
{
my_free(sort_keys);
sort_keys= (uchar **) NULL; /* for err: label */
@@ -404,14 +442,19 @@ pthread_handler_t thr_find_all_keys(void *arg)
}
if (memavl < MIN_SORT_BUFFER)
{
+ /* purecov: begin inspected */
mi_check_print_error(sort_param->sort_info->param,
- "MyISAM sort buffer too small");
- goto err; /* purecov: tested */
+ "myisam_sort_buffer_size is too small. Current myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
+ sortbuff_size, (ulonglong) idx, sort_length);
+ my_errno= ENOMEM;
+ goto err;
+ /* purecov: end inspected */
}
if (sort_param->sort_info->param->testflag & T_VERBOSE)
- printf("Key %d - Allocating buffer for %d keys\n",
- sort_param->key + 1, keys);
+ my_fprintf(stdout,
+ "Key %d - Allocating buffer for %llu keys\n",
+ sort_param->key + 1, (ulonglong) keys);
sort_param->sort_keys= sort_keys;
idx= error= 0;
@@ -436,7 +479,8 @@ pthread_handler_t thr_find_all_keys(void *arg)
&sort_param->tempfile))
goto err;
sort_keys[0]= (uchar*) (sort_keys+keys);
- memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
+ memcpy(sort_keys[0], sort_keys[idx - 1],
+ (size_t) sort_param->key_length);
idx= 1;
}
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
@@ -454,7 +498,6 @@ pthread_handler_t thr_find_all_keys(void *arg)
else
sort_param->keys= idx;
- sort_param->sort_keys_length= keys;
goto ok;
err:
@@ -527,7 +570,9 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
{
if (param->testflag & T_VERBOSE)
{
- printf("Key %d - Dumping %u keys\n",sinfo->key+1, sinfo->keys);
+ my_fprintf(stdout,
+ "Key %d - Dumping %llu keys\n", sinfo->key+1,
+ (ulonglong) sinfo->keys);
fflush(stdout);
}
if (write_index(sinfo, sinfo->sort_keys, sinfo->keys) ||
@@ -584,10 +629,12 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
if (maxbuffer >= MERGEBUFF2)
{
if (param->testflag & T_VERBOSE)
- printf("Key %d - Merging %u keys\n",sinfo->key+1, sinfo->keys);
+ my_fprintf(stdout,
+ "Key %d - Merging %llu keys\n",
+ sinfo->key+1, (ulonglong) sinfo->keys);
if (merge_many_buff(sinfo, keys, (uchar **)mergebuf,
dynamic_element(&sinfo->buffpek, 0, BUFFPEK *),
- (int*) &maxbuffer, &sinfo->tempfile))
+ &maxbuffer, &sinfo->tempfile))
{
got_error=1;
continue;
@@ -651,12 +698,15 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
/* Write all keys in memory to file for later merge */
static int write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
- uint count, BUFFPEK *buffpek, IO_CACHE *tempfile)
+ ha_keys count, BUFFPEK *buffpek, IO_CACHE *tempfile)
{
uchar **end;
uint sort_length=info->key_length;
DBUG_ENTER("write_keys");
+ if (!buffpek)
+ DBUG_RETURN(1); /* Out of memory */
+
my_qsort2((uchar*) sort_keys,count,sizeof(uchar*),(qsort2_cmp) info->key_cmp,
info);
if (!my_b_inited(tempfile) &&
@@ -669,7 +719,7 @@ static int write_keys(MI_SORT_PARAM *info, register uchar **sort_keys,
for (end=sort_keys+count ; sort_keys != end ; sort_keys++)
{
- if (my_b_write(tempfile,(uchar*) *sort_keys,(uint) sort_length))
+ if (my_b_write(tempfile,(uchar*) *sort_keys, sort_length))
DBUG_RETURN(1); /* purecov: inspected */
}
DBUG_RETURN(0);
@@ -693,13 +743,16 @@ my_var_write(MI_SORT_PARAM *info, IO_CACHE *to_file, uchar *bufs)
static int write_keys_varlen(MI_SORT_PARAM *info,
register uchar **sort_keys,
- uint count, BUFFPEK *buffpek,
+ ha_keys count, BUFFPEK *buffpek,
IO_CACHE *tempfile)
{
uchar **end;
int err;
DBUG_ENTER("write_keys_varlen");
+ if (!buffpek)
+ DBUG_RETURN(1); /* Out of memory */
+
my_qsort2((uchar*) sort_keys,count,sizeof(uchar*),(qsort2_cmp) info->key_cmp,
info);
if (!my_b_inited(tempfile) &&
@@ -738,7 +791,7 @@ static int write_key(MI_SORT_PARAM *info, uchar *key, IO_CACHE *tempfile)
/* Write index */
static int write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
- register uint count)
+ register ha_keys count)
{
DBUG_ENTER("write_index");
@@ -755,11 +808,11 @@ static int write_index(MI_SORT_PARAM *info, register uchar **sort_keys,
/* Merge buffers to make < MERGEBUFF2 buffers */
-static int merge_many_buff(MI_SORT_PARAM *info, uint keys,
+static int merge_many_buff(MI_SORT_PARAM *info, ha_keys keys,
uchar **sort_keys, BUFFPEK *buffpek,
- int *maxbuffer, IO_CACHE *t_file)
+ uint *maxbuffer, IO_CACHE *t_file)
{
- register int i;
+ register uint i;
IO_CACHE t_file2, *from_file, *to_file, *temp;
BUFFPEK *lastbuff;
DBUG_ENTER("merge_many_buff");
@@ -777,7 +830,7 @@ static int merge_many_buff(MI_SORT_PARAM *info, uint keys,
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)
+ for (i=0 ; i + MERGEBUFF*3/2 <= *maxbuffer ; i+=MERGEBUFF)
{
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1))
@@ -789,7 +842,7 @@ static int merge_many_buff(MI_SORT_PARAM *info, uint keys,
if (flush_io_cache(to_file))
break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp;
- *maxbuffer= (int) (lastbuff-buffpek)-1;
+ *maxbuffer= (uint) (lastbuff-buffpek)-1;
}
cleanup:
close_cached_file(to_file); /* This holds old result */
@@ -818,35 +871,36 @@ cleanup:
-1 Error
*/
-static uint read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+static my_off_t read_to_buffer(IO_CACHE *fromfile, BUFFPEK *buffpek,
+ uint sort_length)
{
- register uint count;
- uint length;
+ register ha_keys count;
+ my_off_t length;
- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
+ if ((count= (ha_keys) min((ha_rows) buffpek->max_keys,buffpek->count)))
{
if (mysql_file_pread(fromfile->file, (uchar*) buffpek->base,
- (length= sort_length*count),
+ (length= sort_length * count),
buffpek->file_pos, MYF_RW))
- return((uint) -1); /* purecov: inspected */
+ return(HA_OFFSET_ERROR); /* purecov: inspected */
buffpek->key=buffpek->base;
- buffpek->file_pos+= length; /* New filepos */
+ buffpek->file_pos+= length; /* New filepos */
buffpek->count-= count;
buffpek->mem_count= count;
}
- return (count*sort_length);
+ return (((my_off_t) count) * sort_length);
} /* read_to_buffer */
-static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
- uint sort_length)
+
+static my_off_t read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
+ uint sort_length)
{
- register uint count;
+ register ha_keys count;
uint16 length_of_key = 0;
uint idx;
uchar *buffp;
- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
+ if ((count= (ha_keys) min((ha_rows) buffpek->max_keys,buffpek->count)))
{
buffp = buffpek->base;
@@ -854,11 +908,11 @@ static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
{
if (mysql_file_pread(fromfile->file, (uchar*)&length_of_key,
sizeof(length_of_key), buffpek->file_pos, MYF_RW))
- return((uint) -1);
+ return(HA_OFFSET_ERROR);
buffpek->file_pos+=sizeof(length_of_key);
if (mysql_file_pread(fromfile->file, (uchar*) buffp,
length_of_key, buffpek->file_pos, MYF_RW))
- return((uint) -1);
+ return(HA_OFFSET_ERROR);
buffpek->file_pos+=length_of_key;
buffp = buffp + sort_length;
}
@@ -866,15 +920,15 @@ static uint read_to_buffer_varlen(IO_CACHE *fromfile, BUFFPEK *buffpek,
buffpek->count-= count;
buffpek->mem_count= count;
}
- return (count*sort_length);
+ return (((my_off_t) count) * sort_length);
} /* read_to_buffer_varlen */
static int write_merge_key_varlen(MI_SORT_PARAM *info,
IO_CACHE *to_file, uchar* key,
- uint sort_length, uint count)
+ uint sort_length, ha_keys count)
{
- uint idx;
+ ha_keys idx;
uchar *bufs = key;
for (idx=1;idx<=count;idx++)
@@ -890,32 +944,37 @@ static int write_merge_key_varlen(MI_SORT_PARAM *info,
static int write_merge_key(MI_SORT_PARAM *info __attribute__((unused)),
IO_CACHE *to_file, uchar *key,
- uint sort_length, uint count)
+ uint sort_length, ha_keys count)
{
- return my_b_write(to_file, key, (size_t) sort_length*count);
+ return my_b_write(to_file, key, ((size_t) sort_length) * count);
}
/*
Merge buffers to one buffer
If to_file == 0 then use info->key_write
+
+ Return:
+ 0 ok
+ 1 error
*/
static int
-merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
+merge_buffers(MI_SORT_PARAM *info, ha_keys keys, IO_CACHE *from_file,
IO_CACHE *to_file, uchar **sort_keys, BUFFPEK *lastbuff,
BUFFPEK *Fb, BUFFPEK *Tb)
{
- int error;
- uint sort_length,maxcount;
+ int error= 1;
+ uint sort_length;
+ ha_keys maxcount;
ha_rows count;
- my_off_t UNINIT_VAR(to_start_filepos);
+ my_off_t UNINIT_VAR(to_start_filepos), read_length;
uchar *strpos;
BUFFPEK *buffpek,**refpek;
QUEUE queue;
DBUG_ENTER("merge_buffers");
count=error=0;
- maxcount=keys/((uint) (Tb-Fb) +1);
+ maxcount= keys/((uint) (Tb-Fb) +1);
DBUG_ASSERT(maxcount > 0);
LINT_INIT(to_start_filepos);
if (to_file)
@@ -932,10 +991,10 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
{
count+= buffpek->count;
buffpek->base= (uchar*) strpos;
- buffpek->max_keys=maxcount;
- strpos+= (uint) (error=(int) info->read_to_buffer(from_file,buffpek,
- sort_length));
- if (error == -1)
+ buffpek->max_keys= maxcount;
+ strpos+= (read_length= info->read_to_buffer(from_file,buffpek,
+ sort_length));
+ if (read_length == HA_OFFSET_ERROR)
goto err; /* purecov: inspected */
queue_insert(&queue,(uchar*) buffpek);
}
@@ -966,10 +1025,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
/* It's enough to check for killedptr before a slow operation */
if (killed_ptr(info->sort_info->param))
{
- error=1;
goto err;
}
- if (!(error=(int) info->read_to_buffer(from_file,buffpek,sort_length)))
+ if (!(read_length= info->read_to_buffer(from_file,buffpek,sort_length)))
{
uchar *base= buffpek->base;
uint max_keys=buffpek->max_keys;
@@ -996,9 +1054,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
break; /* One buffer have been removed */
}
+ else if (read_length == HA_OFFSET_ERROR)
+ goto err; /* purecov: inspected */
}
- else if (error == -1)
- goto err; /* purecov: inspected */
queue_replace_top(&queue); /* Top element has been replaced */
}
}
@@ -1030,8 +1088,9 @@ merge_buffers(MI_SORT_PARAM *info, uint keys, IO_CACHE *from_file,
}
}
}
- while ((error=(int) info->read_to_buffer(from_file,buffpek,sort_length)) != -1 &&
- error != 0);
+ while ((read_length= info->read_to_buffer(from_file,buffpek,sort_length)) != HA_OFFSET_ERROR && read_length != 0);
+ if (read_length == 0)
+ error= 0;
lastbuff->count=count;
if (to_file)
@@ -1045,8 +1104,8 @@ err:
/* Do a merge to output-file (save only positions) */
static int
-merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
- BUFFPEK *buffpek, int maxbuffer, IO_CACHE *tempfile)
+merge_index(MI_SORT_PARAM *info, ha_keys keys, uchar **sort_keys,
+ BUFFPEK *buffpek, uint maxbuffer, IO_CACHE *tempfile)
{
DBUG_ENTER("merge_index");
if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
@@ -1055,6 +1114,7 @@ merge_index(MI_SORT_PARAM *info, uint keys, uchar **sort_keys,
DBUG_RETURN(0);
} /* merge_index */
+
static int
flush_ft_buf(MI_SORT_PARAM *info)
{
@@ -1067,4 +1127,3 @@ flush_ft_buf(MI_SORT_PARAM *info)
}
return err;
}
-