diff options
-rw-r--r-- | include/my_tree.h | 2 | ||||
-rw-r--r-- | myisam/mi_write.c | 3 | ||||
-rw-r--r-- | mysql-test/r/bdb.result | 4 | ||||
-rw-r--r-- | mysql-test/t/bdb.test | 2 | ||||
-rw-r--r-- | mysys/tree.c | 8 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 21 | ||||
-rw-r--r-- | sql/sql_insert.cc | 10 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 9 | ||||
-rw-r--r-- | sql/table.cc | 3 | ||||
-rw-r--r-- | sql/table.h | 1 |
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 */ |