summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/my_tree.h2
-rw-r--r--myisam/mi_write.c3
-rw-r--r--mysql-test/r/bdb.result4
-rw-r--r--mysql-test/t/bdb.test2
-rw-r--r--mysys/tree.c8
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/mysqld.cc21
-rw-r--r--sql/sql_insert.cc10
-rw-r--r--sql/sql_yacc.yy9
-rw-r--r--sql/table.cc3
-rw-r--r--sql/table.h1
11 files changed, 48 insertions, 18 deletions
diff --git a/include/my_tree.h b/include/my_tree.h
index 8b326a19518..7cc7c615ba6 100644
--- a/include/my_tree.h
+++ b/include/my_tree.h
@@ -76,6 +76,8 @@ int tree_walk(TREE *tree,tree_walk_action action,
void *argument, TREE_WALK visit);
int tree_delete(TREE *tree,void *key);
+#define TREE_ELEMENT_EXTRA_SIZE (sizeof(TREE_ELEMENT) + sizeof(void*))
+
#ifdef __cplusplus
}
#endif
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index cfacd0bc4d5..70a1bea26bb 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -842,8 +842,9 @@ int _mi_init_bulk_insert(MI_INFO *info, ulong cache_size)
{
params->info=info;
params->keynr=i;
+ /* Only allocate a 16'th of the buffer at a time */
init_tree(&info->bulk_insert[i],
- cache_size / num_keys / 4 + 10,
+ cache_size / num_keys / 16 + 10,
cache_size / num_keys, 0,
(qsort_cmp2)keys_compare, 0,
(tree_element_free) keys_free, (void *)params++);
diff --git a/mysql-test/r/bdb.result b/mysql-test/r/bdb.result
index a815f2f8fab..eb97d19136d 100644
--- a/mysql-test/r/bdb.result
+++ b/mysql-test/r/bdb.result
@@ -133,11 +133,11 @@ id parent_id level
1202 107 2
1204 107 2
update ignore t1 set id=1023 where id=1010;
-select * from t1 where parent_id=102;
+select * from t1 where parent_id=102 order by parent_id,id;
id parent_id level
1008 102 2
-1015 102 2
1010 102 2
+1015 102 2
explain select level from t1 where level=1;
table type possible_keys key key_len ref rows Extra
t1 ref level level 1 const 1 Using where; Using index
diff --git a/mysql-test/t/bdb.test b/mysql-test/t/bdb.test
index 0df93b5f220..608d4bf5042 100644
--- a/mysql-test/t/bdb.test
+++ b/mysql-test/t/bdb.test
@@ -39,7 +39,7 @@ select * from t1;
update ignore t1 set id=id+1; # This will change all rows
select * from t1;
update ignore t1 set id=1023 where id=1010;
-select * from t1 where parent_id=102;
+select * from t1 where parent_id=102 order by parent_id,id;
explain select level from t1 where level=1;
explain select level,id from t1 where level=1;
explain select level,id,parent_id from t1 where level=1;
diff --git a/mysys/tree.c b/mysys/tree.c
index 2ac2c88fd66..ea5cf79f084 100644
--- a/mysys/tree.c
+++ b/mysys/tree.c
@@ -45,7 +45,8 @@
#define BLACK 1
#define RED 0
-#define DEFAULT_ALLOC_SIZE (8192-MALLOC_OVERHEAD)
+#define DEFAULT_ALLOC_SIZE 8192
+#define DEFAULT_ALIGN_SIZE 8192
static void delete_tree_element(TREE *,TREE_ELEMENT *);
static int tree_walk_left_root_right(TREE *,TREE_ELEMENT *,
@@ -72,8 +73,9 @@ void init_tree(TREE *tree, uint default_alloc_size, uint memory_limit,
DBUG_ENTER("init_tree");
DBUG_PRINT("enter",("tree: %lx size: %d",tree,size));
- if (!default_alloc_size)
- default_alloc_size= DEFAULT_ALLOC_SIZE;
+ if (default_alloc_size < DEFAULT_ALLOC_SIZE)
+ default_alloc_size= DEFAULT_ALLOC_SIZE;
+ default_alloc_size= MY_ALIGN(default_alloc_size, DEFAULT_ALIGN_SIZE);
bzero((gptr) &tree->null_element,sizeof(tree->null_element));
tree->root= &tree->null_element;
tree->compare=compare;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index db457aa0aa7..43de81cae00 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -83,6 +83,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name);
*/
#define MIN_FILE_LENGTH_TO_USE_ROW_CACHE (16L*1024*1024)
#define MIN_ROWS_TO_USE_TABLE_CACHE 100
+#define MIN_ROWS_TO_USE_BULK_INSERT 100
/*
The following is used to decide if MySQL should use table scanning
@@ -707,7 +708,7 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list);
/* old unireg functions */
void unireg_init(ulong options);
-void unireg_end(int signal);
+void unireg_end(void);
int rea_create_table(my_string file_name,HA_CREATE_INFO *create_info,
List<create_field> &create_field,
uint key_count,KEY *key_info);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 2404b35b00f..ffe3d1be47c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -764,7 +764,7 @@ static void __cdecl kill_server(int sig_ptr)
if (sig != MYSQL_KILL_SIGNAL && sig != 0)
unireg_abort(1); /* purecov: inspected */
else
- unireg_end(0);
+ unireg_end();
pthread_exit(0); /* purecov: deadcode */
RETURN_FROM_KILL_SERVER;
}
@@ -803,12 +803,29 @@ extern "C" sig_handler print_signal_warning(int sig)
#endif
}
+/*
+ cleanup all memory and end program nicely
+
+ SYNOPSIS
+ unireg_end()
+
+ NOTES
+ This function never returns.
+
+ If SIGNALS_DONT_BREAK_READ is defined, this function is called
+ by the main thread. To get MySQL to shut down nicely in this case
+ (Mac OS X) we have to call exit() instead if pthread_exit().
+*/
-void unireg_end(int signal_number __attribute__((unused)))
+void unireg_end(void)
{
clean_up();
my_thread_end();
+#ifdef SIGNALS_DONT_BREAK_READ
+ exit(0);
+#else
pthread_exit(0); // Exit is in main thread
+#endif
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 71f570e4798..2508314c469 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -194,15 +194,19 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
thd->proc_info="update";
if (duplic == DUP_IGNORE || duplic == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
- if ((bulk_insert= (values_list.elements > 1 &&
+ if ((bulk_insert= (values_list.elements >= MIN_ROWS_TO_USE_BULK_INSERT &&
lock_type != TL_WRITE_DELAYED &&
!(specialflag & SPECIAL_SAFE_MODE))))
{
table->file->extra_opt(HA_EXTRA_WRITE_CACHE,
- thd->variables.read_buff_size);
+ min(thd->variables.read_buff_size,
+ table->avg_row_length*values_list.elements));
if (thd->variables.bulk_insert_buff_size)
table->file->extra_opt(HA_EXTRA_BULK_INSERT_BEGIN,
- thd->variables.bulk_insert_buff_size);
+ min(thd->variables.bulk_insert_buff_size,
+ (table->total_key_length +
+ table->keys * TREE_ELEMENT_EXTRA_SIZE)*
+ values_list.elements));
table->bulk_insert= 1;
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 92b49549a06..f6a0c483bb9 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -3107,12 +3107,13 @@ ident:
IDENT { $$=$1; }
| keyword
{
- LEX *lex;
- $$.str=sql_strmake($1.str,$1.length);
+ LEX *lex= Lex;
+ $$.str= lex->thd->strmake($1.str,$1.length);
$$.length=$1.length;
- if ((lex=Lex)->next_state != STATE_END)
+ if (lex->next_state != STATE_END)
lex->next_state=STATE_OPERATOR_OR_IDENT;
- };
+ }
+ ;
ident_or_text:
ident { $$=$1;}
diff --git a/sql/table.cc b/sql/table.cc
index b68edac5fc2..62163819599 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -143,7 +143,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
goto err_not_open; /* purecov: inspected */
bzero((char*) keyinfo,n_length);
outparam->key_info=keyinfo;
- outparam->max_key_length=0;
+ outparam->max_key_length= outparam->total_key_length= 0;
key_part= (KEY_PART_INFO*) (keyinfo+keys);
strpos=disk_buff+6;
@@ -201,6 +201,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
}
set_if_bigger(outparam->max_key_length,keyinfo->key_length+
keyinfo->key_parts);
+ outparam->total_key_length+= keyinfo->key_length;
if (keyinfo->flags & HA_NOSAME)
set_if_bigger(outparam->max_unique_length,keyinfo->key_length);
}
diff --git a/sql/table.h b/sql/table.h
index ca86269b625..f998a0fd4e6 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -58,6 +58,7 @@ struct st_table {
uint reclength; /* Recordlength */
uint rec_buff_length;
uint keys,key_parts,primary_key,max_key_length,max_unique_length;
+ uint total_key_length;
uint uniques;
uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob fields */