From 689a55b1ad270391708bdff972f524ef9a9f79b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Nov 2001 13:11:37 +0200 Subject: [PATCH 01/10] srv0srv.c: Fix a seg fault if a lock wait timeout is exceeded at the some time someone grants the lock innobase/srv/srv0srv.c: Fix a seg fault if a lock wait timeout is exceeded at the some time someone grants the lock --- innobase/srv/srv0srv.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index bebb0b1f8ea..37bf59b6b9a 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2144,10 +2144,14 @@ loop: /* Timeout exceeded or a wrap-around in system time counter: cancel the lock request queued by the transaction and release possible - other transactions waiting behind */ + other transactions waiting behind; it is + possible that the lock has already been + granted: in that case do nothing */ - lock_cancel_waiting_and_release( - thr_get_trx(slot->thr)->wait_lock); + if (thr_get_trx(slot->thr)->wait_lock) { + lock_cancel_waiting_and_release( + thr_get_trx(slot->thr)->wait_lock); + } } } } From e6309ed96dbc9a4153b48e53e60a91fd0029e456 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2001 12:36:05 +0100 Subject: [PATCH 02/10] typo fixed --- mysql-test/mysql-test-run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index de76c6354f5..daf8b8abd03 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -510,7 +510,7 @@ start_master() --basedir=$MY_BASEDIR \ --port=$MASTER_MYPORT \ --exit-info=256 \ - --core + --core \ --datadir=$MASTER_MYDDIR \ --pid-file=$MASTER_MYPID \ --socket=$MASTER_MYSOCK \ From 0afe57ba58fdfdc8a11a7d1d516a18753f35a37b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2001 15:08:01 +0200 Subject: [PATCH 03/10] Generate core file on Solaris. Docs/manual.texi: ChangeLog sql/mysqld.cc: Cleanup BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + Docs/manual.texi | 8 ++------ sql/mysqld.cc | 35 +++++++++++++++++++---------------- sql/stacktrace.c | 2 ++ 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index cfda01ec450..7f425ebcf80 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -7,3 +7,4 @@ sasha@mysql.sashanet.com heikki@donna.mysql.fi miguel@light.local monty@donna.mysql.fi +monty@bitch.mysql.fi diff --git a/Docs/manual.texi b/Docs/manual.texi index 84048a74aad..6a3311601c7 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -9880,12 +9880,6 @@ that you also probably need to raise the @code{core file size} by adding @code{ulimit -c 1000000} to @code{safe_mysqld} or starting @code{safe_mysqld} with @code{--core-file-sizes=1000000}. @xref{safe_mysqld, , @code{safe_mysqld}}. -To get a core dump on Linux if @code{mysqld} dies with a SIGSEGV signal, you can -start @code{mysqld} with the @code{--core-file} option. Note that you also probably -need to raise the @code{core file size} by adding @code{ulimit -c 1000000} to -@code{safe_mysqld} or starting @code{safe_mysqld} with -@code{--core-file-sizes=1000000}. @xref{safe_mysqld, , @code{safe_mysqld}}. - If you are linking your own MySQL client and get the error: @example @@ -46844,6 +46838,8 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.45 @itemize @bullet @item +@code{--core-file} now works on Solaris. +@item Fixed bug with BDB tables and keys on @code{BLOB}'s. @item Fixed bug in @code{MERGE} tables on OS with 32 bit file pointers. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index bfbe8f8a25a..7303d593bdc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1119,6 +1119,19 @@ static void start_signal_handler(void) } #elif defined(__EMX__) +static void init_signals(void) +{ + signal(SIGQUIT, sig_kill); + signal(SIGKILL, sig_kill); + signal(SIGTERM, sig_kill); + signal(SIGINT, sig_kill); + signal(SIGHUP, sig_reload); // Flush everything + signal(SIGALRM, SIG_IGN); + signal(SIGBREAK,SIG_IGN); + signal_thread = pthread_self(); +} + + static void sig_reload(int signo) { reload_acl_and_cache((THD*) 0,REFRESH_LOG, (TABLE_LIST*) 0); // Flush everything @@ -1135,22 +1148,10 @@ static void sig_kill(int signo) signal(signo, SIG_ACK); } -static void init_signals(void) -{ - signal(SIGQUIT, sig_kill); - signal(SIGKILL, sig_kill); - signal(SIGTERM, sig_kill); - signal(SIGINT, sig_kill); - signal(SIGHUP, sig_reload); // Flush everything - signal(SIGALRM, SIG_IGN); - signal(SIGBREAK,SIG_IGN); - signal_thread = pthread_self(); -} static void start_signal_handler(void) { } - #else /* if ! __WIN__ && ! __EMX__ */ #ifdef HAVE_LINUXTHREADS @@ -1160,10 +1161,12 @@ static void start_signal_handler(void) static sig_handler handle_segfault(int sig) { THD *thd=current_thd; - // strictly speaking, one needs a mutex here - // but since we have got SIGSEGV already, things are a mess - // so not having the mutex is not as bad as possibly using a buggy - // mutex - so we keep things simple + /* + Strictly speaking, we should need a mutex here + but since we have got SIGSEGV already, things are a mess + so not having the mutex is not as bad as possibly using a buggy + mutex - so we keep things simple. + */ if (segfaulted) { fprintf(stderr, "Fatal signal %d while backtracing\n", sig); diff --git a/sql/stacktrace.c b/sql/stacktrace.c index 81d8debc27a..18db1949db9 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -218,5 +218,7 @@ void write_core(int sig) { signal(sig, SIG_DFL); pthread_kill(pthread_self(), sig); + /* On Solaris, the above kill is not enough */ + sigsend(P_PID,P_MYID,sig); } #endif From 680d02190773191b43de2ae5d4826d8eab8ad029 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2001 18:05:11 +0100 Subject: [PATCH 04/10] removed ftfuncs argument for mysql_select it uses now thd->lex.ftfunc_list moved ft-initialization to a separate function re-disabled implicit ft initialization sql/item_func.cc: re-disabled implicit initialization that was re-enabled (by me) for reasons unknown (at least the code passed all the tests) sql/mysql_priv.h: removed ftfuncs argument for mysql_select it uses now thd->lex.ftfunc_list moved ft-initialization to a separate function sql/sql_base.cc: removed ftfuncs argument for mysql_select it uses now thd->lex.ftfunc_list moved ft-initialization to a separate function sql/sql_parse.cc: removed ftfuncs argument for mysql_select it uses now thd->lex.ftfunc_list moved ft-initialization to a separate function sql/sql_select.cc: removed ftfuncs argument for mysql_select it uses now thd->lex.ftfunc_list moved ft-initialization to a separate function --- sql/item_func.cc | 5 +---- sql/mysql_priv.h | 4 ++-- sql/sql_base.cc | 25 +++++++++++++++++++++---- sql/sql_parse.cc | 3 --- sql/sql_select.cc | 36 +++++++++++------------------------- 5 files changed, 35 insertions(+), 38 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index 56e3d562ee8..c5274333008 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1906,10 +1906,7 @@ err: double Item_func_match::val() { if (ft_handler==NULL) - init_search(1); - - if ((null_value= (ft_handler==NULL))) - return 0.0; + return -1.0; if (join_key) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 841d76928e1..ceb9bd9a691 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -309,7 +309,6 @@ int setup_order(THD *thd,TABLE_LIST *tables, List &fields, List &all_fields, ORDER *order); int mysql_select(THD *thd,TABLE_LIST *tables,List &list,COND *conds, - List &ftfuncs, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, uint select_type,select_result *result); Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, @@ -417,7 +416,8 @@ bool setup_tables(TABLE_LIST *tables); int setup_fields(THD *thd,TABLE_LIST *tables,List &item, bool set_query_id,List *sum_func_list); int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); -int setup_ftfuncs(THD *thd,TABLE_LIST *tables, List &ftfuncs); +int setup_ftfuncs(THD *thd); +int init_ftfuncs(THD *thd, bool no_order); void wait_for_refresh(THD *thd); int open_tables(THD *thd,TABLE_LIST *tables); int open_and_lock_tables(THD *thd,TABLE_LIST *tables); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 624377b688e..70dc2ed058d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2199,17 +2199,18 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, DBUG_RETURN(result); } -int setup_ftfuncs(THD *thd,TABLE_LIST *tables, List &ftfuncs) +int setup_ftfuncs(THD *thd) { - List_iterator li(ftfuncs), li2(ftfuncs); + List_iterator li(thd->lex.ftfunc_list), + lj(thd->lex.ftfunc_list); Item_func_match *ftf, *ftf2; while ((ftf=li++)) { if (ftf->fix_index()) return 1; - li2.rewind(); - while ((ftf2=li2++) != ftf) + lj.rewind(); + while ((ftf2=lj++) != ftf) { if (ftf->eq(ftf2) && !ftf2->master) ftf2->master=ftf; @@ -2218,3 +2219,19 @@ int setup_ftfuncs(THD *thd,TABLE_LIST *tables, List &ftfuncs) return 0; } + +int init_ftfuncs(THD *thd, bool no_order) +{ + List_iterator li(thd->lex.ftfunc_list); + Item_func_match *ifm; + DBUG_PRINT("info",("Performing FULLTEXT search")); + thd->proc_info="FULLTEXT initialization"; + + while ((ifm=li++)) + { + ifm->init_search(no_order); + } + + return 0; +} + diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 18ab3c45359..5804060a25a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1133,7 +1133,6 @@ mysql_execute_command(void) { res=mysql_select(thd,tables,lex->item_list, lex->where, - lex->ftfunc_list, (ORDER*) lex->order_list.first, (ORDER*) lex->group_list.first, lex->having, @@ -1283,7 +1282,6 @@ mysql_execute_command(void) { res=mysql_select(thd,tables->next,lex->item_list, lex->where, - lex->ftfunc_list, (ORDER*) lex->order_list.first, (ORDER*) lex->group_list.first, lex->having, @@ -1577,7 +1575,6 @@ mysql_execute_command(void) { res=mysql_select(thd,tables->next,lex->item_list, lex->where, - lex->ftfunc_list, (ORDER*) lex->order_list.first, (ORDER*) lex->group_list.first, lex->having, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d1df2b2aa71..777a10503f6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -35,11 +35,10 @@ const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref", "MAYBE_REF","ALL","range","index","fulltext" }; static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, - DYNAMIC_ARRAY *keyuse,List &ftfuncs); + DYNAMIC_ARRAY *keyuse); static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, JOIN_TAB *join_tab, - uint tables,COND *conds,table_map table_map, - List &ftfuncs); + uint tables,COND *conds,table_map table_map); static int sort_keyuse(KEYUSE *a,KEYUSE *b); static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key); static void find_best_combination(JOIN *join,table_map rest_tables); @@ -150,7 +149,6 @@ static void describe_info(THD *thd, const char *info); int mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, - List &ftfuncs, ORDER *order, ORDER *group,Item *having,ORDER *proc_param, uint select_options,select_result *result) { @@ -193,7 +191,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, if (having->with_sum_func) having->split_sum_func(all_fields); } - if (setup_ftfuncs(thd,tables,ftfuncs)) /* should be after having->fix_fields */ + if (setup_ftfuncs(thd)) /* should be after having->fix_fields */ DBUG_RETURN(-1); /* Check if one one uses a not constant column with group functions @@ -378,7 +376,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, /* Calculate how to do the join */ thd->proc_info="statistics"; - if (make_join_statistics(&join,tables,conds,&keyuse,ftfuncs) || + if (make_join_statistics(&join,tables,conds,&keyuse) || thd->fatal_error) goto err; thd->proc_info="preparing"; @@ -493,8 +491,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, (group && order) || test(select_options & OPTION_BUFFER_RESULT))); - make_join_readinfo(&join, (select_options & SELECT_DESCRIBE) | - (ftfuncs.elements ? 0 : SELECT_USE_CACHE)); // No cache for MATCH + make_join_readinfo(&join, (select_options & SELECT_DESCRIBE) | + (thd->lex.ftfunc_list.elements ? 0 : SELECT_USE_CACHE)); // No cache for MATCH /* Need to tell Innobase that to play it safe, it should fetch all columns of the tables: this is because MySQL @@ -560,18 +558,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, } /* Perform FULLTEXT search before all regular searches */ - if (ftfuncs.elements) - { - List_iterator li(ftfuncs); - Item_func_match *ifm; - DBUG_PRINT("info",("Performing FULLTEXT search")); - thd->proc_info="FULLTEXT searching"; + init_ftfuncs(thd, test(order)); - while ((ifm=li++)) - { - ifm->init_search(test(order)); - } - } /* Create a tmp table if distinct or if the sort is too complicated */ if (need_tmp) { @@ -833,8 +821,7 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table, static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, - DYNAMIC_ARRAY *keyuse_array, - List &ftfuncs) + DYNAMIC_ARRAY *keyuse_array) { int error; uint i,table_count,const_count,found_ref,refs,key,const_ref,eq_part; @@ -946,7 +933,7 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, if (conds || outer_join) if (update_ref_and_keys(join->thd,keyuse_array,stat,join->tables, - conds,~outer_join,ftfuncs)) + conds,~outer_join)) DBUG_RETURN(1); /* loop until no more const tables are found */ @@ -1453,8 +1440,7 @@ sort_keyuse(KEYUSE *a,KEYUSE *b) static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, - uint tables, COND *cond, table_map normal_tables, - List &ftfuncs) + uint tables, COND *cond, table_map normal_tables) { uint and_level,i,found_eq_constant; @@ -1482,7 +1468,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, add_key_part(keyuse,field); } - if (ftfuncs.elements) + if (thd->lex.ftfunc_list.elements) { add_ft_keys(keyuse,join_tab,cond,normal_tables); } From dfbeb93550fedc416bec85191d57acd93ffdd007 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2001 18:25:44 +0100 Subject: [PATCH 05/10] (UPDATE|DELETE) ...WHERE MATCH bugfix --- mysql-test/r/fulltext.result | 4 ++++ mysql-test/t/fulltext.test | 3 +++ sql/sql_delete.cc | 21 ++++++++++----------- sql/sql_update.cc | 4 +++- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index e8a4d87f680..c39210107ae 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -6,6 +6,10 @@ Full-text indexes are called collections a b Full-text indexes are called collections Only MyISAM tables support collections +a b +Only MyISAM tables support collections +Function MATCH ... AGAINST() is used to do a search +some test foobar implements vector space model id id id diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index eedee811f2b..83e328ca616 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -10,6 +10,9 @@ select * from t1 where MATCH(a,b) AGAINST ("collections"); select * from t1 where MATCH(a,b) AGAINST ("indexes"); select * from t1 where MATCH(a,b) AGAINST ("indexes collections"); delete from t1 where a like "MySQL%"; +update t1 set a='some test foobar' where MATCH a,b AGAINST ('model'); +delete from t1 where MATCH(a,b) AGAINST ("indexes"); +select * from t1; drop table t1; # diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index af658ad0346..930e71d7678 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1,15 +1,15 @@ /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -51,8 +51,7 @@ int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table) pthread_mutex_unlock(&LOCK_open); } - - /* If it is a temporary table, close and regenerate it */ + /* If it is a temporary table, close and regenerate it */ if ((table_ptr=find_temporary_table(thd,table_list->db, table_list->real_name))) { @@ -126,7 +125,7 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, TABLE *table; SQL_SELECT *select; READ_RECORD info; - bool using_limit=limit != HA_POS_ERROR; + bool using_limit=limit != HA_POS_ERROR; bool use_generate_table,using_transactions; DBUG_ENTER("mysql_delete"); @@ -163,7 +162,7 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, if (use_generate_table) DBUG_RETURN(generate_table(thd,table_list,table)); table->map=1; - if (setup_conds(thd,table_list,&conds)) + if (setup_conds(thd,table_list,&conds) || setup_ftfuncs(thd)) DBUG_RETURN(-1); table->used_keys=table->quick_keys=0; // Can't use 'only index' @@ -171,7 +170,7 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, if (error) DBUG_RETURN(-1); if ((select && select->check_quick(test(thd->options & SQL_SAFE_UPDATES), - limit)) || + limit)) || !limit) { delete select; @@ -192,9 +191,10 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, } (void) table->file->extra(HA_EXTRA_NO_READCHECK); if (options & OPTION_QUICK) - (void) table->file->extra(HA_EXTRA_QUICK); + (void) table->file->extra(HA_EXTRA_QUICK); init_read_record(&info,thd,table,select,-1,1); ulong deleted=0L; + init_ftfuncs(thd,1); thd->proc_info="updating"; while (!(error=info.read_record(&info)) && !thd->killed) { @@ -223,7 +223,7 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, end_read_record(&info); (void) table->file->extra(HA_EXTRA_READCHECK); if (options & OPTION_QUICK) - (void) table->file->extra(HA_EXTRA_NORMAL); + (void) table->file->extra(HA_EXTRA_NORMAL); using_transactions=table->file->has_transactions(); if (deleted && (error <= 0 || !using_transactions)) { @@ -255,4 +255,3 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, DBUG_RETURN(0); } - diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 2e9a3c5e355..e5e246b3962 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -70,7 +70,8 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List &fields, table->quick_keys=0; want_privilege=table->grant.want_privilege; table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); - if (setup_tables(table_list) || setup_conds(thd,table_list,&conds)) + if (setup_tables(table_list) || setup_conds(thd,table_list,&conds) + || setup_ftfuncs(thd)) DBUG_RETURN(-1); /* purecov: inspected */ old_used_keys=table->used_keys; // Keys used in WHERE @@ -134,6 +135,7 @@ int mysql_update(THD *thd,TABLE_LIST *table_list,List &fields, DBUG_RETURN(1); } } + init_ftfuncs(thd,1); /* Check if we are modifying a key that we are used to search with */ if (select && select->quick) used_key_is_modified= (!select->quick->unique_key_range() && From 497c8426264eab5f40fbf697d3e9dad0c4f2efa5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Nov 2001 18:25:08 -0700 Subject: [PATCH 06/10] backport of shutdown fix for platforms that cannot break a syscall with a signal. Tested to the extent that it does not break Linux. Could not test on Darwin because the machine was not reachable. Will push anyway - at least it does not make things worse. Testing on Darwin is needed, however. sql/mysqld.cc: backport of shutdown fix for platforms that cannot break a syscall with a signal --- sql/mysqld.cc | 64 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5e6b5c098d7..e39e636a036 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -40,6 +40,11 @@ #define ONE_THREAD #endif +#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) +#define HAVE_CLOSE_SERVER_SOCK 1 +void close_server_sock(); +#endif + extern "C" { // Because of SCO 3.2V4.2 #include #include @@ -442,16 +447,7 @@ static void close_connections(void) sql_print_error("Got error %d from pthread_cond_timedwait",error); #endif #if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) - if (ip_sock != INVALID_SOCKET) - { - DBUG_PRINT("error",("closing TCP/IP and socket files")); - VOID(shutdown(ip_sock,2)); - VOID(closesocket(ip_sock)); - VOID(shutdown(unix_sock,2)); - VOID(closesocket(unix_sock)); - VOID(unlink(mysql_unix_port)); - ip_sock=unix_sock= INVALID_SOCKET; - } + close_server_sock(); #endif } (void) pthread_mutex_unlock(&LOCK_thread_count); @@ -566,10 +562,35 @@ static void close_connections(void) DBUG_VOID_RETURN; } +#ifdef HAVE_CLOSE_SERVER_SOCK +void close_server_sock() +{ + DBUG_ENTER("close_server_sock"); + if (ip_sock != INVALID_SOCKET) + { + DBUG_PRINT("info",("closing TCP/IP socket")); + VOID(shutdown(ip_sock,2)); + VOID(closesocket(ip_sock)); + ip_sock=INVALID_SOCKET; + } + if (unix_sock != INVALID_SOCKET) + { + DBUG_PRINT("info",("closing Unix socket")); + VOID(shutdown(unix_sock,2)); + VOID(closesocket(unix_sock)); + VOID(unlink(mysql_unix_port)); + unix_sock=INVALID_SOCKET; + } + DBUG_VOID_RETURN; +} +#endif + void kill_mysql(void) { DBUG_ENTER("kill_mysql"); - +#ifdef SIGNALS_DONT_BREAK_READ + close_server_sock(); /* force accept to wake up */ +#endif #if defined(__WIN__) { if (!SetEvent(hEventShutdown)) @@ -593,6 +614,9 @@ void kill_mysql(void) #endif DBUG_PRINT("quit",("After pthread_kill")); shutdown_in_progress=1; // Safety if kill didn't work +#ifdef SIGNALS_DONT_BREAK_READ + abort_loop=1; +#endif DBUG_VOID_RETURN; } @@ -1049,6 +1073,20 @@ void end_thread(THD *thd, bool put_in_cache) DBUG_VOID_RETURN; } +#ifdef SIGNALS_DONT_BREAK_READ +inline void kill_broken_server() +{ + /* hack to get around signals ignored in syscalls for problem OS's */ + if (unix_sock == INVALID_SOCKET || ip_sock ==INVALID_SOCKET) + { + select_thread_in_use = 0; + kill_server((void*)MYSQL_KILL_SIGNAL); /* never returns */ + } +} +#define MAYBE_BROKEN_SYSCALL kill_broken_server(); +#else +#define MAYBE_BROKEN_SYSCALL +#endif /* Start a cached thread. LOCK_thread_count is locked on entry */ @@ -2251,6 +2289,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) #endif DBUG_PRINT("general",("Waiting for connections.")); + MAYBE_BROKEN_SYSCALL; while (!abort_loop) { readFDs=clientFDs; @@ -2265,6 +2304,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) if (!select_errors++ && !abort_loop) /* purecov: inspected */ sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */ } + MAYBE_BROKEN_SYSCALL; continue; } #endif /* HPUX */ @@ -2306,6 +2346,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) if (new_sock != INVALID_SOCKET || (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN)) break; + MAYBE_BROKEN_SYSCALL; #if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) { @@ -2322,6 +2363,7 @@ pthread_handler_decl(handle_connections_sockets,arg __attribute__((unused))) { if ((error_count++ & 255) == 0) // This can happen often sql_perror("Error in accept"); + MAYBE_BROKEN_SYSCALL; if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE) sleep(1); // Give other threads some time continue; From f0dd11d597e76bfcc7aa18b9e03f143f8a06839d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Nov 2001 03:39:42 +0200 Subject: [PATCH 07/10] Fixed problem when repairing packed MyISAM files. Docs/manual.texi: Changelog --- Docs/manual.texi | 14 +++++++-- myisam/mi_check.c | 75 ++++++++++++++++++++++++++++----------------- myisam/mi_open.c | 5 ++- myisam/mi_packrec.c | 9 +++++- myisam/myisamchk.c | 2 +- myisam/myisamdef.h | 1 + 6 files changed, 70 insertions(+), 36 deletions(-) diff --git a/Docs/manual.texi b/Docs/manual.texi index a779c39a1d0..07959fd2602 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -46838,12 +46838,22 @@ not yet 100% confident in this code. @appendixsubsec Changes in release 3.23.45 @itemize @bullet @item +@code{(UPDATE|DELETE) ...WHERE MATCH} bugfix +@item +shutdown should now work on Darwin (Mac OS X). +@item +Fixed core-dump when repairing corrupted packed MyISAM files. +@item @code{--core-file} now works on Solaris. @item Fix a bug which could cause InnoDB to complain if it cannot find free blocks from the buffer cache during recovery. @item -Fixed a bug in InnoDB insert buffer B-tree handling that could cause crashes. +Fixed bug in InnoDB insert buffer B-tree handling that could cause crashes. +@item +Fixed bug in InnoDB lock timeout handling. +@item +Fixed core dump bug in @code{ALTER TABLE} on a @code{TEMPORARY} InnoDB table. @item Fixed bug in @code{OPTIMIZE TABLE} that reset index cardinality if it was up to date. @@ -46856,8 +46866,6 @@ Fixed bug with BDB tables and keys on @code{BLOB}'s. Fixed bug in @code{MERGE} tables on OS with 32 bit file pointers. @item Fixed bug in @code{TIME_TO_SEC()} when using negative values. -@item -Fixed core dump bug in @code{ALTER TABLE} on a @code{TEMPORARY} InnoDB table. @end itemize @node News-3.23.44, News-3.23.43, News-3.23.45, News-3.23.x diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 93598ce2d76..45a335b68c8 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -41,7 +41,8 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, ha_checksum *key_checksum, uint level); static uint isam_key_length(MI_INFO *info,MI_KEYDEF *keyinfo); static ha_checksum calc_checksum(ha_rows count); -static int writekeys(MI_INFO *info,byte *buff,my_off_t filepos); +static int writekeys(MI_CHECK *param, MI_INFO *info,byte *buff, + my_off_t filepos); static int sort_one_index(MI_CHECK *param, MI_INFO *info,MI_KEYDEF *keyinfo, my_off_t pagepos, File new_file); static int sort_key_read(SORT_INFO *sort_info,void *key); @@ -61,7 +62,8 @@ static void update_key_parts(MI_KEYDEF *keyinfo, ulonglong *unique, ulonglong records); static ha_checksum mi_byte_checksum(const byte *buf, uint length); - +static void set_data_file_type(MI_CHECK *param, SORT_INFO *info, + MYISAM_SHARE *share); #ifdef __WIN__ static double ulonglong2double(ulonglong value) @@ -1179,15 +1181,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, sort_info->dupp=0; sort_info->fix_datafile= (my_bool) (! rep_quick); sort_info->max_records= ~(ha_rows) 0; - if ((sort_info->new_data_file_type=share->data_file_type) == - COMPRESSED_RECORD && param->testflag & T_UNPACK) - { - if (share->options & HA_OPTION_PACK_RECORD) - sort_info->new_data_file_type = DYNAMIC_RECORD; - else - sort_info->new_data_file_type = STATIC_RECORD; - } + set_data_file_type(param, sort_info, share); del=info->state->del; info->state->records=info->state->del=share->state.split=0; info->state->empty=0; @@ -1215,9 +1210,10 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info, lock_memory(param); /* Everything is alloced */ while (!(error=sort_get_next_record(sort_info))) { - if (writekeys(info,(byte*) sort_info->record,sort_info->filepos)) + if (writekeys(param, info,(byte*) sort_info->record,sort_info->filepos)) { - if (my_errno != HA_ERR_FOUND_DUPP_KEY) goto err; + if (my_errno != HA_ERR_FOUND_DUPP_KEY) + goto err; DBUG_DUMP("record",(byte*) sort_info->record,share->base.pack_reclength); mi_check_print_info(param,"Duplicate key %2d for record at %10s against new record at %10s", info->errkey+1, @@ -1356,7 +1352,8 @@ err: /* Uppate keyfile when doing repair */ -static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos) +static int writekeys(MI_CHECK *param, register MI_INFO *info, byte *buff, + my_off_t filepos) { register uint i; uchar *key; @@ -1369,12 +1366,14 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos) { if (info->s->keyinfo[i].flag & HA_FULLTEXT ) { - if (_mi_ft_add(info,i,(char*) key,buff,filepos)) goto err; + if (_mi_ft_add(info,i,(char*) key,buff,filepos)) + goto err; } else { uint key_length=_mi_make_key(info,i,key,buff,filepos); - if (_mi_ck_write(info,i,key,key_length)) goto err; + if (_mi_ck_write(info,i,key,key_length)) + goto err; } } } @@ -1390,16 +1389,21 @@ static int writekeys(register MI_INFO *info,byte *buff,my_off_t filepos) { if (info->s->keyinfo[i].flag & HA_FULLTEXT) { - if (_mi_ft_del(info,i,(char*) key,buff,filepos)) break; + if (_mi_ft_del(info,i,(char*) key,buff,filepos)) + break; } else { uint key_length=_mi_make_key(info,i,key,buff,filepos); - if (_mi_ck_delete(info,i,key,key_length)) break; + if (_mi_ck_delete(info,i,key,key_length)) + break; } } } } + /* Remove checksum that was added to glob_crc in sort_get_next_record */ + if (param->calc_checksum) + param->glob_crc-= info->checksum; DBUG_PRINT("error",("errno: %d",my_errno)); DBUG_RETURN(-1); } /* writekeys */ @@ -1840,15 +1844,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, sort_info->info=info; sort_info->param = param; - if ((sort_info->new_data_file_type=share->data_file_type) == - COMPRESSED_RECORD && param->testflag & T_UNPACK) - { - if (share->options & HA_OPTION_PACK_RECORD) - sort_info->new_data_file_type = DYNAMIC_RECORD; - else - sort_info->new_data_file_type = STATIC_RECORD; - } - + set_data_file_type(param, sort_info, share); sort_info->filepos=new_header_length; sort_info->dupp=0; sort_info->buff=0; @@ -2129,7 +2125,8 @@ static int sort_get_next_record(SORT_INFO *sort_info) if (*sort_info->record) { if (param->calc_checksum) - param->glob_crc+= mi_static_checksum(info,sort_info->record); + param->glob_crc+= (info->checksum= + mi_static_checksum(info,sort_info->record)); DBUG_RETURN(0); } if (!sort_info->fix_datafile) @@ -2582,7 +2579,7 @@ static int sort_key_write(SORT_INFO *sort_info, const void *a) sort_info->key_block-> lastkey), llbuff2)); - param->error_printed=param->retry_without_quick=1; + param->retry_without_quick=1; if (sort_info->param->testflag & T_VERBOSE) _mi_print_key(stdout,sort_info->keyseg,(uchar*) a, USE_WHOLE_KEY); return (sort_delete_record(param)); @@ -3235,3 +3232,25 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, } return TRUE; } + + +static void +set_data_file_type(MI_CHECK *param, SORT_INFO *sort_info, MYISAM_SHARE *share) +{ + if ((sort_info->new_data_file_type=share->data_file_type) == + COMPRESSED_RECORD && param->testflag & T_UNPACK) + { + MYISAM_SHARE tmp; + + if (share->options & HA_OPTION_PACK_RECORD) + sort_info->new_data_file_type = DYNAMIC_RECORD; + else + sort_info->new_data_file_type = STATIC_RECORD; + + /* Set delete_function for sort_delete_record() */ + memcpy((char*) &tmp, share, sizeof(*share)); + tmp.options= ~HA_OPTION_COMPRESS_RECORD; + mi_setup_functions(&tmp); + share->delete_record=tmp.delete_record; + } +} diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 626d51d18b7..617b1cd8d90 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -30,7 +30,6 @@ #include "static.c" #endif -static void setup_functions(MYISAM_SHARE *info); static void setup_key_functions(MI_KEYDEF *keyinfo); #define get_next_element(to,pos,size) { memcpy((char*) to,pos,(size_t) size); \ pos+=size;} @@ -392,7 +391,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) else if (share->options & HA_OPTION_PACK_RECORD) share->data_file_type = DYNAMIC_RECORD; my_afree((gptr) disk_cache); - setup_functions(share); + mi_setup_functions(share); #ifdef THREAD thr_lock_init(&share->lock); VOID(pthread_mutex_init(&share->intern_lock,MY_MUTEX_INIT_FAST)); @@ -566,7 +565,7 @@ ulonglong mi_safe_mul(ulonglong a, ulonglong b) /* Set up functions in structs */ -static void setup_functions(register MYISAM_SHARE *share) +void mi_setup_functions(register MYISAM_SHARE *share) { if (share->options & HA_OPTION_COMPRESS_RECORD) { diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index 68d546b2010..242883a2c4a 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -785,7 +785,10 @@ static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to, if (bits <= 32) { if (bit_buff->pos > bit_buff->end+4) + { + bit_buff->error=1; return; /* Can't be right */ + } bit_buff->current_byte= (bit_buff->current_byte << 32) + ((((uint) bit_buff->pos[3])) + (((uint) bit_buff->pos[2]) << 8) + @@ -829,7 +832,8 @@ static void decode_bytes(MI_COLUMNDEF *rec,MI_BIT_BUFF *bit_buff,uchar *to, #else -static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uchar *end) +static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, + uchar *end) { reg1 uint bits,low_byte; reg3 uint16 *pos; @@ -846,7 +850,10 @@ static void decode_bytes(MI_COLUMNDEF *rec, MI_BIT_BUFF *bit_buff, uchar *to, uc if (bits < table_bits) { if (bit_buff->pos > bit_buff->end+1) + { + bit_buff->error=1; return; /* Can't be right */ + } #if BITS_SAVED == 32 bit_buff->current_byte= (bit_buff->current_byte << 24) + (((uint) ((uchar) bit_buff->pos[2]))) + diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index d8d57863a11..cb321f8fda3 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -204,7 +204,7 @@ static struct option long_options[] = static void print_version(void) { - printf("%s Ver 1.51 for %s at %s\n",my_progname,SYSTEM_TYPE, + printf("%s Ver 1.53 for %s at %s\n",my_progname,SYSTEM_TYPE, MACHINE_TYPE); } diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 33fd1b6946f..260e9665b31 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -635,6 +635,7 @@ void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows); my_bool check_table_is_closed(const char *name, const char *where); int mi_open_datafile(MI_INFO *info, MYISAM_SHARE *share); int mi_open_keyfile(MYISAM_SHARE *share); +void mi_setup_functions(register MYISAM_SHARE *share); /* Functions needed by mi_check */ void mi_check_print_error _VARARGS((MI_CHECK *param, const char *fmt,...)); From 00d5ed8acdbab2c99a95d0deb8a786761a1b0533 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Nov 2001 12:24:06 +0200 Subject: [PATCH 08/10] Add missing resolve_stack_dump to RPM --- support-files/mysql.spec.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 3245908c9b0..428bbdf0862 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -348,6 +348,7 @@ fi %attr(755, root, root) /usr/bin/perror %attr(755, root, root) /usr/bin/replace %attr(755, root, root) /usr/bin/resolveip +%attr(755, root, root) /usr/bin/resolve_stack_dump %attr(755, root, root) /usr/bin/safe_mysqld %attr(755, root, root) /usr/bin/mysqld_multi %attr(755, root, root) /usr/bin/my_print_defaults From e0d3ed73a10f7e5a0d193b93fd77bfdb3f611c92 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Nov 2001 13:07:55 +0200 Subject: [PATCH 09/10] Portability fix --- sql/stacktrace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/stacktrace.c b/sql/stacktrace.c index 18db1949db9..ef4d2f97b90 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -218,7 +218,9 @@ void write_core(int sig) { signal(sig, SIG_DFL); pthread_kill(pthread_self(), sig); +#if defined(P_PID) && defined(P_MYID) /* On Solaris, the above kill is not enough */ sigsend(P_PID,P_MYID,sig); +#endif } #endif From 7ef7d93726929ec678a8b07bed1be7bb56ad4b10 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Nov 2001 13:15:17 +0200 Subject: [PATCH 10/10] Portability fix mysys/my_seek.c: Remove warning --- mysys/my_seek.c | 5 +++-- sql/stacktrace.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mysys/my_seek.c b/mysys/my_seek.c index d8e8cf83b6d..7c4da4f6010 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -20,7 +20,8 @@ /* Seek to position in file */ /*ARGSUSED*/ -my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags) +my_off_t my_seek(File fd, my_off_t pos, int whence, + myf MyFlags __attribute__((unused))) { reg1 os_off_t newpos; DBUG_ENTER("my_seek"); @@ -40,7 +41,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags) /* Tell current position of file */ /* ARGSUSED */ -my_off_t my_tell(File fd, myf MyFlags) +my_off_t my_tell(File fd, myf MyFlags __attribute__((unused))) { os_off_t pos; DBUG_ENTER("my_tell"); diff --git a/sql/stacktrace.c b/sql/stacktrace.c index ef4d2f97b90..fba9927f5dd 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -218,7 +218,7 @@ void write_core(int sig) { signal(sig, SIG_DFL); pthread_kill(pthread_self(), sig); -#if defined(P_PID) && defined(P_MYID) +#if defined(P_MYID) /* On Solaris, the above kill is not enough */ sigsend(P_PID,P_MYID,sig); #endif