diff options
-rw-r--r-- | Docs/manual.texi | 75 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | include/config-win.h | 1 | ||||
-rw-r--r-- | include/ft_global.h | 1 | ||||
-rw-r--r-- | include/my_pthread.h | 76 | ||||
-rw-r--r-- | myisam/Makefile.am | 1 | ||||
-rw-r--r-- | myisam/ft_static.c | 2 | ||||
-rw-r--r-- | myisam/ft_stopwords.c | 13 | ||||
-rw-r--r-- | myisam/mi_create.c | 6 | ||||
-rw-r--r-- | myisam/mi_delete.c | 13 | ||||
-rw-r--r-- | myisam/mi_panic.c | 5 | ||||
-rw-r--r-- | myisam/mi_test2.c | 14 | ||||
-rw-r--r-- | myisam/myisamchk.c | 2 | ||||
-rw-r--r-- | myisam/myisamdef.h | 1 | ||||
-rw-r--r-- | mysys/mf_format.c | 3 | ||||
-rw-r--r-- | mysys/my_wincond.c | 1 | ||||
-rw-r--r-- | mysys/thr_mutex.c | 16 | ||||
-rwxr-xr-x | sql-bench/test-insert.sh | 38 | ||||
-rw-r--r-- | sql/ChangeLog | 5 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 11 | ||||
-rw-r--r-- | sql/log.cc | 4 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_delete.cc | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 12 | ||||
-rw-r--r-- | sql/sql_table.cc | 4 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 16 | ||||
-rw-r--r-- | sql/table.cc | 6 | ||||
-rw-r--r-- | strings/bmove512.c | 8 | ||||
-rw-r--r-- | support-files/mysql.server.sh | 3 |
31 files changed, 257 insertions, 111 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index 0e9d0312afd..653a138a604 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -427,7 +427,7 @@ Functions for use in @code{SELECT} and @code{WHERE} clauses MySQL table types * MyISAM:: MyISAM tables -* MERGE:: +* MERGE:: MERGE tables * ISAM:: ISAM tables * HEAP:: HEAP tables * BDB:: BDB or Berkeley_db tables @@ -2345,21 +2345,21 @@ from the local @strong{MySQL} list. The following @strong{MySQL} mailing lists exist: @table @code -@item announce +@item announce (@email{announce-subscribe@@lists.mysql.com}) This is for announcement of new versions of @strong{MySQL} and related programs. This is a low volume list that we think all @strong{MySQL} users should be on. -@item mysql +@item mysql (@email{mysql-subscribe@@lists.mysql.com}) The main list for general @strong{MySQL} discussion. Please note that some topics are better discussed on the more-specialized lists. If you post to the wrong list, you may not get an answer! -@item mysql-digest +@item mysql-digest (@email{mysql-digest-subscribe@@lists.mysql.com}) The @code{mysql} list in digest form. That means you get all individual messages, sent as one large mail message once a day. -@item bugs +@item bugs (@email{bugs-subscribe@@lists.mysql.com}) On this list you should only post a full, repeatable bug report, using the @code{mysqlbug} script (if you are running on Windows, you should include a description of the operating system and the @strong{MySQL} version). @@ -2371,45 +2371,45 @@ this list will be corrected or documented in the next @strong{MySQL} release! If there are only small code changes involved, we will also post a patch that fixes the problem. -@item bugs-digest +@item bugs-digest (@email{bugs-digest-subscribe@@lists.mysql.com}) The @code{bugs} list in digest form -@item developer +@item developer (@email{developer-subscribe@@lists.mysql.com}) A list for people who work on the @strong{MySQL} code. On this list one can also discuss @strong{MySQL} development and post patches. -@item developer-digest +@item developer-digest (@email{developer-digest-subscribe@@lists.mysql.com}) A digest version of the @code{developer} list. -@item java +@item java (@email{java-subscribe@@lists.mysql.com}) Discussion about @strong{MySQL} and Java. Mostly about the JDBC drivers. -@item java-digest +@item java-digest (@email{java-digest-subscribe@@lists.mysql.com}) A digest version of the @code{java} list. -@item win32 +@item win32 (@email{win32-subscribe@@lists.mysql.com}) All things concerning @strong{MySQL} on Microsoft operating systems such as Win95, Win98, NT and Win2000. -@item win32-digest +@item win32-digest (@email{win32-digest-subscribe@@lists.mysql.com}) A digest version of the @code{win32} list. -@item myodbc +@item myodbc (@email{myodbc-subscribe@@lists.mysql.com}) All things concerning connecting to @strong{MySQL} with ODBC. -@item myodbc-digest +@item myodbc-digest (@email{myodbc-digest-subscribe@@lists.mysql.com}) A digest version of the @code{myodbc} list. -@item plusplus +@item plusplus (@email{plusplus-digest-subscribe@@lists.mysql.com}) All things concerning programming with the C++ API to @strong{MySQL}. -@item plusplus-digest +@item plusplus-digest (@email{plusplus-digest-subscribe@@lists.mysql.com}) A digest version of the @code{plusplus} list. -@item msql-mysql-modules +@item msql-mysql-modules (@email{msql-mysql-modules-subscribe@@lists.mysql.com}) A list about the Perl support in @strong{MySQL}. -@item msql-mysql-modules-digest +@item msql-mysql-modules-digest (@email{msql-mysql-modules-digest-subscribe@@lists.mysql.com}) A digest version of the @code{msql-mysql-modules} list. @end table @@ -4720,7 +4720,7 @@ shell> /usr/sbin/swinstall -s /path/to/depot mysql.developer The depot places binaries and libraries in @file{/opt/mysql} and data in @file{/var/opt/mysql}. The depot also creates the appropriate entries in -@file{/sbin/init.d} and @file{/sbin/rc2.d} to start the server automatically +@file{/etc/init.d} and @file{/etc/rc2.d} to start the server automatically at boot time. Obviously, this entails being @code{root} to install. To install the HP-UX tar.gz distribution, you must have a copy of GNU @@ -17715,6 +17715,8 @@ If you specify the keyword @code{LOW_PRIORITY}, execution of the In this case the client has to wait until the insert statement is completed, which may take a long time if the table is in heavy use. This is in contrast to @code{INSERT DELAYED} which lets the client continue at once. +Note that @code{LOW_PRIORITY} should normally not be used with @code{MyISAM} +tables as this disables concurrent inserts.@xref{MyISAM}. @item If you specify the keyword @code{IGNORE} in an @code{INSERT} with many value @@ -18518,7 +18520,7 @@ the @code{mysql} database. @item @code{TABLES table_name [,table_name...]} @tab Flush only the given tables -@item @code{TABLES WITH READ LOCK} @tab Closes all open tables and locks all tables for all databases with a read until one executes @code{UNLOCK TABLES}. +@item @code{TABLES WITH READ LOCK} @tab Closes all open tables and locks all tables for all databases with a read until one executes @code{UNLOCK TABLES}. This is very convinient way to get backups if you have a file system, like Veritas,that can take snapshots in time. @item @code{STATUS} @tab Resets most status variables to zero. @end multitable @@ -19686,7 +19688,10 @@ table in the server and implemented with @code{pthread_mutex_lock()} and See @ref{Internal locking}, for more information on locking policy. You can also lock all tables in all databases with read locks with the -@code{FLUSH TABLES WITH READ LOCK} command. @xref{FLUSH}. +@code{FLUSH TABLES WITH READ LOCK} command. @xref{FLUSH}. This is very +convinient way to get backups if you have a file system, like Veritas, +that can take snapshots in time. + @findex SET OPTION @node SET OPTION, GRANT, LOCK TABLES, Reference @@ -21351,6 +21356,14 @@ article (item number) for certain traders (dealers). Supposing that each trader has a single fixed price per article, then (@code{item}, @code{trader}) is a primary key for the records. +Start the command line tool @code{mysql} and select a database: + +@example +mysql your-database-name +@end example + +(In most @strong{MySQL} installations, you can use the database-name 'test'). + You can create the example table as: @example @@ -21486,7 +21499,7 @@ In @strong{MySQL} it's best do it in several steps: @enumerate @item -Get the list of (article,maxprice). @xref{example-Maximum-column-group-row}. +Get the list of (article,maxprice). @item For each article get the corresponding rows which have the stored maximum price. @@ -21499,11 +21512,11 @@ CREATE TEMPORARY TABLE tmp ( article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL, price DOUBLE(16,2) DEFAULT '0.00' NOT NULL); -LOCK TABLES article read; +LOCK TABLES shop read; INSERT INTO tmp SELECT article, MAX(price) FROM shop GROUP BY article; -SELECT article, dealer, price FROM shop, tmp +SELECT shop.article, dealer, price FROM shop, tmp WHERE shop.article=tmp.article AND shop.price=tmp.price; UNLOCK TABLES; @@ -28747,6 +28760,10 @@ that when you export data to @strong{MySQL}, the table and column names aren't specified. Another way to around this bug is to upgrade to MyODBC 2.50.33 and @strong{MySQL} 3.23.x, which together provides a workaround for this bug! + +Note that if you are using @strong{MySQL} 3.22, you must to apply the +MDAC patch and use MyODBC 2.50.32 or 2.50.34 and above to go around +this problem. @item Set the ``Return matching rows'' MyODBC option field when connecting to @strong{MySQL}. @@ -36307,10 +36324,18 @@ though, so 3.23 is not released as a stable version yet. @appendixsubsec Changes in release 3.23.25 @itemize @bullet @item +Fixed a bug where @code{FULLTEXT} index always used the koi8_ukr +character set. +@item +Fixed privilege checking for @code{CHECK TABLE}. +@item +The @code{MyISAM} repair/reindex code didn't use the @code{--tempdir} +option for it's temporary files. +@item Fixed a core dump bug when doing @code{FLUSH MASTER} when one didn't give a filename argument to @code{--log-bin} @item -Added missing ha_berkeley.x files to the MySQL windows source distribution. +Added missing ha_berkeley.# files to the windows source distribution. @item Fixed some mutex bugs in the log code that could cause thread blocks if new log files couldn't be created. diff --git a/configure.in b/configure.in index 8170fed6905..d43906b3cfd 100644 --- a/configure.in +++ b/configure.in @@ -1218,7 +1218,7 @@ AC_CHECK_FUNCS(alarm bmove \ pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \ pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \ pthread_condattr_create rwlock_init pthread_rwlock_rdlock \ - crypt dlopen dlerror fchmod getpass getpassphrase initgroups, mlockall) + crypt dlopen dlerror fchmod getpass getpassphrase initgroups mlockall) # Sanity check: We chould not have any fseeko symbol unless # large_file_support=yes diff --git a/include/config-win.h b/include/config-win.h index a0008675d49..4dc3ecd74e2 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -290,6 +290,7 @@ inline double ulonglong2double(ulonglong value) #define MY_NFILE 127 /* This is only used to save filenames */ +#define DO_NOT_REMOVE_THREAD_WRAPPERS #define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V)) /* The following is only used for statistics, so it should be good enough */ #ifdef __NT__ /* This should also work on Win98 but .. */ diff --git a/include/ft_global.h b/include/ft_global.h index 32490dd079f..90641313235 100644 --- a/include/ft_global.h +++ b/include/ft_global.h @@ -43,6 +43,7 @@ typedef struct st_ft_doclist { extern const char *ft_precompiled_stopwords[]; int ft_init_stopwords(const char **); +void ft_free_stopwords(void); FT_DOCLIST * ft_init_search(void *, uint, byte *, uint, my_bool); int ft_read_next(FT_DOCLIST *, char *); diff --git a/include/my_pthread.h b/include/my_pthread.h index 4adcc958590..d5f3fa735b2 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -55,6 +55,7 @@ struct timespec { /* For pthread_cond_timedwait() */ long tv_nsec; }; +typedef int pthread_mutexattr_t; #define win_pthread_self my_thread_var->pthread_self #define pthread_handler_decl(A,B) unsigned __cdecl A(void *B) typedef unsigned (__cdecl *pthread_handler)(void *); @@ -215,42 +216,6 @@ extern int my_pthread_getprio(pthread_t thread_id); #define pthread_handler_decl(A,B) void *A(void *B) typedef void *(* pthread_handler)(void *); -/* safe mutex for debugging */ - -typedef struct st_safe_mutex_t -{ - pthread_mutex_t global,mutex; - char *file; - uint line,count; - pthread_t thread; -} safe_mutex_t; - -int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr); -int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line); -int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); -int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); -int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, - uint line); -int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, - struct timespec *abstime, const char *file, uint line); - -#ifdef SAFE_MUTEX -#undef pthread_mutex_init -#undef pthread_mutex_lock -#undef pthread_mutex_unlock -#undef pthread_mutex_destroy -#undef pthread_mutex_wait -#undef pthread_mutex_timedwait -#undef pthread_mutex_t -#define pthread_mutex_init(A,B) safe_mutex_init((A),(B)) -#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__) -#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) -#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__) -#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) -#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) -#define pthread_mutex_t safe_mutex_t -#endif - /* Test first for RTS or FSU threads */ #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) @@ -424,7 +389,44 @@ struct hostent *my_gethostbyname_r(const char *name, #endif /* defined(__WIN__) */ -/* READ-WRITE thread locking */ + /* safe_mutex adds checking to mutex for easier debugging */ + +typedef struct st_safe_mutex_t +{ + pthread_mutex_t global,mutex; + char *file; + uint line,count; + pthread_t thread; +} safe_mutex_t; + +int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr); +int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line); +int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line); +int safe_mutex_destroy(safe_mutex_t *mp,const char *file, uint line); +int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp,const char *file, + uint line); +int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, + struct timespec *abstime, const char *file, uint line); + + /* Wrappers if safe mutex is actually used */ +#ifdef SAFE_MUTEX +#undef pthread_mutex_init +#undef pthread_mutex_lock +#undef pthread_mutex_unlock +#undef pthread_mutex_destroy +#undef pthread_mutex_wait +#undef pthread_mutex_timedwait +#undef pthread_mutex_t +#define pthread_mutex_init(A,B) safe_mutex_init((A),(B)) +#define pthread_mutex_lock(A) safe_mutex_lock((A),__FILE__,__LINE__) +#define pthread_mutex_unlock(A) safe_mutex_unlock((A),__FILE__,__LINE__) +#define pthread_mutex_destroy(A) safe_mutex_destroy((A),__FILE__,__LINE__) +#define pthread_cond_wait(A,B) safe_cond_wait((A),(B),__FILE__,__LINE__) +#define pthread_cond_timedwait(A,B,C) safe_cond_timedwait((A),(B),(C),__FILE__,__LINE__) +#define pthread_mutex_t safe_mutex_t +#endif /* SAFE_MUTEX */ + + /* READ-WRITE thread locking */ #if defined(USE_MUTEX_INSTEAD_OF_RW_LOCKS) /* use these defs for simple mutex locking */ diff --git a/myisam/Makefile.am b/myisam/Makefile.am index 70976a86b49..edb801f12fd 100644 --- a/myisam/Makefile.am +++ b/myisam/Makefile.am @@ -104,6 +104,7 @@ SUFFIXES = .sh -e 's!@''PERL_DBD_VERSION''@!@PERL_DBD_VERSION@!' \ -e 's!@''PERL_DATA_DUMPER''@!@PERL_DATA_DUMPER@!' \ $< > $@-t + @CHMOD@ +x $@-t @MV@ $@-t $@ # Don't update the files from bitkeeper diff --git a/myisam/ft_static.c b/myisam/ft_static.c index 34b9368d522..00d9d4ed19a 100644 --- a/myisam/ft_static.c +++ b/myisam/ft_static.c @@ -21,7 +21,7 @@ const MI_KEYSEG ft_keysegs[FT_SEGS]={ { HA_KEYTYPE_VARTEXT, /* type */ - 7, /* language */ + 7, /* language (will be overwritten) */ 0, 0, 0, /* null_bit, bit_start, bit_end */ HA_VAR_LENGTH | HA_PACK_KEY, /* flag */ HA_FT_MAXLEN, /* length */ diff --git a/myisam/ft_stopwords.c b/myisam/ft_stopwords.c index 4c13a845b42..ce08fee9e1e 100644 --- a/myisam/ft_stopwords.c +++ b/myisam/ft_stopwords.c @@ -51,8 +51,8 @@ int ft_init_stopwords(const char **sws) if( (sw.len= (uint) strlen(sw.pos=*sws)) < MIN_WORD_LEN) continue; if(!tree_insert(stopwords3, &sw, 0)) { - delete_tree(stopwords3); - return -1; + delete_tree(stopwords3); /* purecov: inspected */ + return -1; /* purecov: inspected */ } } return 0; @@ -66,3 +66,12 @@ int is_stopword(char *word, uint len) return tree_search(stopwords3,&sw) != NULL; } + +void ft_free_stopwords() +{ + if (stopwords3) + { + delete_tree(stopwords3); /* purecov: inspected */ + stopwords3=0; + } +} diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 27c47c5170b..048bbb427a2 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -511,8 +511,12 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, if (mi_keyseg_write(file, &keydefs[i].seg[j])) goto err; for (j=0 ; j < ft_segs ; j++) /* SerG */ - if (mi_keyseg_write(file, &ft_keysegs[j])) + { + MI_KEYSEG seg=ft_keysegs[j]; + seg.language= keydefs[i].seg[0].language; + if (mi_keyseg_write(file, &seg)) goto err; + } } /* Create extra keys for unique definitions */ offset=reclength-uniques*MI_UNIQUE_HASH_LENGTH; diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index d014c07bc96..f8bc37d8e20 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -247,9 +247,9 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, { /* On leaf page */ if (_mi_write_keypage(info,keyinfo,page,anc_buff)) DBUG_RETURN(-1); - if (length <= (uint) keyinfo->underflow_block_length) - DBUG_RETURN(1); /* Page will be update later */ - DBUG_RETURN(0); + /* Page will be update later if we return 1 */ + DBUG_RETURN(test(length <= (info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH : + (uint) keyinfo->underflow_block_length))); } save_flag=1; ret_value=del(info,keyinfo,key,anc_buff,leaf_page,leaf_buff,keypos, @@ -385,7 +385,9 @@ static int del(register MI_INFO *info, register MI_KEYDEF *keyinfo, uchar *key, _mi_kpointer(info,keypos - share->base.key_reflength,next_block); mi_putint(anc_buff,a_length+length,share->base.key_reflength); - DBUG_RETURN( mi_getint(leaf_buff) <= (uint) keyinfo->underflow_block_length); + DBUG_RETURN( mi_getint(leaf_buff) <= + (info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH : + (uint) keyinfo->underflow_block_length)); err: DBUG_RETURN(-1); } /* del */ @@ -537,7 +539,8 @@ static int underflow(register MI_INFO *info, register MI_KEYDEF *keyinfo, } if (_mi_write_keypage(info,keyinfo,leaf_page,leaf_buff)) goto err; - DBUG_RETURN(anc_length <= (uint) keyinfo->underflow_block_length); + DBUG_RETURN(anc_length <= ((info->quick_mode ? MI_MIN_BLOCK_LENGTH : + (uint) keyinfo->underflow_block_length))); } DBUG_PRINT("test",("use left page")); diff --git a/myisam/mi_panic.c b/myisam/mi_panic.c index ae149df3ffe..92fc6f3695c 100644 --- a/myisam/mi_panic.c +++ b/myisam/mi_panic.c @@ -14,7 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "myisamdef.h" +#include "fulltext.h" /* if flag == HA_PANIC_CLOSE then all misam files are closed */ /* if flag == HA_PANIC_WRITE then all misam files are unlocked and @@ -103,7 +103,10 @@ int mi_panic(enum ha_panic_function flag) } } if (flag == HA_PANIC_CLOSE) + { VOID(mi_log(0)); /* Close log if neaded */ + ft_free_stopwords(); + } pthread_mutex_unlock(&THR_LOCK_myisam); if (!error) DBUG_RETURN(0); diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c index 25bc1a4f844..746042554c8 100644 --- a/myisam/mi_test2.c +++ b/myisam/mi_test2.c @@ -44,7 +44,8 @@ static void copy_key(struct st_myisam_info *info,uint inx, static int verbose=0,testflag=0, first_key=0,async_io=0,key_cacheing=0,write_cacheing=0,locking=0, - rec_pointer_size=0,pack_fields=1,use_log=0,silent=0; + rec_pointer_size=0,pack_fields=1,use_log=0,silent=0, + opt_quick_mode=0; static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1, create_flag=0; static ulong key_cache_size=IO_SIZE*16; @@ -212,6 +213,8 @@ int main(int argc, char **argv) mi_lock_database(file,F_WRLCK); if (write_cacheing) mi_extra(file,HA_EXTRA_WRITE_CACHE); + if (opt_quick_mode) + mi_extra(file,HA_EXTRA_QUICK); for (i=0 ; i < recant ; i++) { @@ -778,6 +781,8 @@ end: puts("Key cacheing used"); if (write_cacheing) puts("Write cacheing used"); + if (write_cacheing) + puts("quick mode"); if (async_io && locking) puts("Asyncron io with locking used"); else if (locking) @@ -885,6 +890,9 @@ static void get_options(int argc, char **argv) case 't': testflag=atoi(++pos); /* testmod */ break; + case 'q': + opt_quick_mode=1; + break; case 'c': create_flag|= HA_CREATE_CHECKSUM; break; @@ -894,9 +902,9 @@ static void get_options(int argc, char **argv) case '?': case 'I': case 'V': - printf("%s Ver 1.1 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); + printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); puts("By Monty, for your professional use\n"); - printf("Usage: %s [-?AbBcDIKLPRSsVWltv] [-k#] [-f#] [-m#] [-t#]\n", + printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-t#]\n", progname); exit(0); case '#': diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 5740dcf76f5..ed1681c728c 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -221,7 +221,7 @@ static void usage(void) extreme cases as myisamchk should normally be able to\n\ find out if the table is ok even without this switch\n\ -F, --fast Check only tables that hasn't been closed properly\n\ - -C, --check-changed-tables\n\ + -C, --check-only-changed\n\ Check only tables that has changed since last check\n\ -f, --force Restart with -r if there are any errors in the table\n\ -i, --information Print statistics information about table that is checked\n\ diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 92d48e56786..491c0cb1bc4 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -360,6 +360,7 @@ struct st_myisam_info { #define MI_MAX_KEY_BLOCK_SIZE (MI_MAX_KEY_BLOCK_LENGTH/MI_KEY_BLOCK_LENGTH) #define MI_BLOCK_SIZE(key_length,data_pointer,key_pointer) ((((key_length+data_pointer+key_pointer)*4+key_pointer+2)/MI_KEY_BLOCK_LENGTH+1)*MI_KEY_BLOCK_LENGTH) #define MI_MAX_KEYPTR_SIZE 5 /* For calculating block lengths */ +#define MI_MIN_KEYBLOCK_LENGTH 50 /* When to split delete blocks */ /* The UNIQUE check is done with a hashed long key */ diff --git a/mysys/mf_format.c b/mysys/mf_format.c index 39084799563..0d7bb7b9d9f 100644 --- a/mysys/mf_format.c +++ b/mysys/mf_format.c @@ -95,13 +95,14 @@ my_string fn_format(my_string to, const char *name, const char *dsk, bmove(buff,(char*) name,length); /* Save name for last copy */ name=buff; } - (void) strmov(strnmov(strmov(to,dev),name,length),ext); + pos=strnmov(strmov(to,dev),name,length); #ifdef FN_UPPER_CASE caseup_str(to); #endif #ifdef FN_LOWER_CASE casedn_str(to); #endif + (void) strmov(pos,ext); /* Don't convert extension */ } /* Purify gives a lot of UMR errors when using realpath */ #if defined(HAVE_REALPATH) && !defined(HAVE_purify) diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c index 3643d0ec0a6..0c5b01f90d8 100644 --- a/mysys/my_wincond.c +++ b/mysys/my_wincond.c @@ -19,6 +19,7 @@ ** The following is a simple implementation of posix conditions *****************************************************************************/ +#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */ #include "mysys_priv.h" #if defined(THREAD) && defined(__WIN__) #include <m_string.h> diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 9b9c7a8e407..9d9c3a1ce08 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -107,12 +107,17 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line) abort(); } mp->count--; +#ifdef __WIN__ + pthread_mutex_unlock(&mp->mutex); + error=0; +#else error=pthread_mutex_unlock(&mp->mutex); if (error) { fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %d\n", error, file, line); abort(); } +#endif /* __WIN__ */ pthread_mutex_unlock(&mp->global); return error; } @@ -201,14 +206,23 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line) { + int error; if (mp->count != 0) { fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n", mp->file,mp->line, file, line); abort(); } +#ifdef __WIN__ + error=0; pthread_mutex_destroy(&mp->global); - return pthread_mutex_destroy(&mp->mutex); + pthread_mutex_destroy(&mp->mutex); +#else + if (pthread_mutex_destroy(&mp->global) || + pthread_mutex_destroy(&mp->mutex)) + error=1; +#endif + return error; } #endif /* THREAD && SAFE_MUTEX */ diff --git a/sql-bench/test-insert.sh b/sql-bench/test-insert.sh index 427a42aea35..93f6745742e 100755 --- a/sql-bench/test-insert.sh +++ b/sql-bench/test-insert.sh @@ -353,7 +353,8 @@ check_or_range("id3","select_range_key2"); # Check reading on direct key on id and id3 check_select_key("id","select_key_prefix"); -check_select_key("id3","select_key_key2"); +check_select_key2("id","id2","select_key"); +check_select_key("id3","select_key2"); #### #### A lot of simple selects on ranges @@ -921,7 +922,7 @@ if (!$opt_skip_delete) } $end_time=new Benchmark; - print "Time for delete_big ($count): " . + print "Time for delete_all ($count): " . timestr(timediff($end_time, $loop_time),"all") . "\n\n"; if ($opt_lock_tables) @@ -1113,6 +1114,7 @@ $count=0; for ($i=0 ; $i < 128 ; $i++) { + $count++; $dbh->do("delete from bench1 where field1 = $i") or die $DBI::errstr; } @@ -1258,6 +1260,38 @@ sub check_select_key timestr(timediff($end_time, $loop_time),"all") . "\n"; } +# Same as above, but select on 2 columns + +sub check_select_key2 +{ + my ($column,$column2,$check)= @_; + my ($loop_time,$end_time,$i,$tmp_var,$tmp,$count,$row_count,$estimated); + + $estimated=0; + $loop_time=new Benchmark; + $count=0; + for ($i=1 ; $i <= $opt_loop_count; $i++) + { + $count+=2; + $tmpvar^= ((($tmpvar + 63) + $i)*3 % $opt_loop_count); + $tmp=$tmpvar % ($total_rows); + fetch_all_rows($dbh,"select * from bench1 where $column=$tmp and $column2=$tmp") + or die $DBI::errstr; + $tmp+=$total_rows; + defined($row_count=fetch_all_rows($dbh,"select * from bench1 where $column=$tmp and $column2=$tmp")) or die $DBI::errstr; + die "Found $row_count rows on impossible id: $tmp\n" if ($row_count); + $end_time=new Benchmark; + last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i, + $opt_loop_count)); + } + if ($estimated) + { print "Estimated time"; } + else + { print "Time"; } + print " for $check ($count): " . + timestr(timediff($end_time, $loop_time),"all") . "\n"; +} + # # Search using some very simple queries # diff --git a/sql/ChangeLog b/sql/ChangeLog index df9b2567113..08bbd3bb0db 100644 --- a/sql/ChangeLog +++ b/sql/ChangeLog @@ -1,3 +1,8 @@ +2000-09-17 Michael Widenius <monty@mysql.com> + +* Added option QUICK to DELETE to tell MySQL not to balance the + trees on delete. + 2000-09-15 Michael Widenius <monty@mysql.com> * Added a thd argument to log::write() to get more speed. diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 8ffab93f0e0..77e004ca4ae 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -433,7 +433,8 @@ int ha_myisam::optimize(THD* thd, HA_CHECK_OPT *check_opt) param.op_name = (char*) "optimize"; param.testflag = (check_opt->flags | T_SILENT | T_FORCE_CREATE | T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX); - param.opt_rep_quick++; + if (check_opt->quick) + param.opt_rep_quick++; param.sort_buffer_length= check_opt->sort_buffer_size; return repair(thd,param,1); } @@ -456,8 +457,10 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) VOID(fn_format(fixed_name,file->filename,"",MI_NAME_IEXT, 4+ (param.opt_follow_links ? 16 : 0))); - if (!optimize || file->state->del || - share->state.split != file->state->records) + if (!optimize || + ((file->state->del || share->state.split != file->state->records) && + (!param.opt_rep_quick || + !(share->state.changed & STATE_NOT_OPTIMIZED_KEYS)))) { optimize_done=1; if (mi_test_if_sort_rep(file,file->state->records)) @@ -564,7 +567,7 @@ bool ha_myisam::activate_all_index(THD *thd) myisamchk_init(¶m); param.op_name = (char*) "recreating_index"; param.testflag = (T_SILENT | T_REP_BY_SORT | - T_STATISTICS | T_CREATE_MISSING_KEYS | T_TRUST_HEADER); + T_CREATE_MISSING_KEYS | T_TRUST_HEADER); param.myf_rw&= ~MY_WAIT_IF_FULL; param.sort_buffer_length= myisam_sort_buffer_size; param.opt_rep_quick++; diff --git a/sql/log.cc b/sql/log.cc index c5862621cfd..d23c71e6ef3 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -158,9 +158,9 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if (log_type == LOG_NORMAL) { #ifdef __NT__ - fprintf( file, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port); + fprintf(file, "%s, Version: %s, started with:\nTCP Port: %d, Named Pipe: %s\n", my_progname, server_version, mysql_port, mysql_unix_port); #else - fprintf(file,"%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port); + fprintf(file, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port); #endif fprintf(file,"Time Id Command Argument\n"); (void) fflush(file); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2bf1a8f9305..d3454b0a7b9 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -156,6 +156,7 @@ void sql_element_free(void *ptr); #define OPTION_BIN_LOG OPTION_BUFFER_RESULT*2 #define OPTION_AUTO_COMMIT OPTION_BIN_LOG*2 #define OPTION_BEGIN OPTION_AUTO_COMMIT*2 +#define OPTION_QUICK OPTION_BEGIN*2 #define RAID_BLOCK_SIZE 1024 @@ -324,7 +325,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, thr_lock_type lock_type); void kill_delayed_threads(void); int mysql_delete(THD *thd,TABLE_LIST *table,COND *conds,ha_rows rows, - thr_lock_type lock_type); + thr_lock_type lock_type, ulong options); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update); TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias, bool *refresh); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b8c77d81bd9..cb82c2782da 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -26,6 +26,10 @@ #include <thr_alarm.h> #include <ft_global.h> +#ifndef DBUG_OFF +#define ONE_THREAD +#endif + #ifdef __cplusplus extern "C" { // Because of SCO 3.2V4.2 #endif @@ -915,7 +919,7 @@ void end_thread(THD *thd, bool put_in_cache) (void) pthread_cond_broadcast(&COND_thread_count); (void) pthread_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("info", ("unlocked thread_count mutex")) -#ifndef DBUG_OFF +#ifdef ONE_THREAD if (!(test_flags & TEST_NO_THREADS)) // For debugging under Linux #endif { @@ -1805,7 +1809,7 @@ static void create_new_thread(THD *thd) thd->real_id=pthread_self(); // Keep purify happy /* Start a new thread to handle connection */ -#ifndef DBUG_OFF +#ifdef ONE_THREAD if (test_flags & TEST_NO_THREADS) // For debugging under Linux { thread_cache_size=0; // Safety @@ -2256,7 +2260,7 @@ static struct option long_options[] = { {"memlock", no_argument, 0, (int) OPT_MEMLOCK}, {"new", no_argument, 0, 'n'}, {"old-protocol", no_argument, 0, 'o'}, -#ifndef DBUG_OFF +#ifdef ONE_THREAD {"one-thread", no_argument, 0, (int) OPT_ONE_THREAD}, #endif {"pid-file", required_argument, 0, (int) OPT_PID_FILE}, @@ -2509,7 +2513,7 @@ static void print_version(void) static void use_help(void) { print_version(); - printf("Use %s --help for a list of available options\n",my_progname); + printf("Use '--help' or '--no-defaults --help' for a list of available options\n"); } static void usage(void) @@ -2569,7 +2573,7 @@ static void usage(void) -n, --new Use very new possible 'unsafe' functions\n\ -o, --old-protocol Use the old (3.20) protocol\n\ -P, --port=... Port number to use for connection\n"); -#ifndef DBUG_OFF +#ifdef ONE_THREAD puts("\ --one-thread Only use one thread (for debugging under Linux)\n"); #endif diff --git a/sql/sql_class.h b/sql/sql_class.h index 34379baedd6..7c67b0e7a4a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -275,8 +275,8 @@ public: ~THD(); bool store_globals(); inline time_t query_start() { query_start_used=1; return start_time; } - inline void set_time() { if (!user_time) time(&start_time); } - inline void set_time(time_t t) { start_time=t; user_time=1; } + inline void set_time() { if (!user_time) time_after_lock=time(&start_time); } + inline void set_time(time_t t) { time_after_lock=start_time=t; user_time=1; } inline void lock_time() { time(&time_after_lock); } inline void insert_id(ulonglong id) { last_insert_id=id; insert_id_used=1; } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 3662895a4a3..9cd3c2f0e9b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -101,7 +101,7 @@ int generate_table(THD *thd, TABLE_LIST *table_list, int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, - thr_lock_type lock_type) + thr_lock_type lock_type, ulong options) { int error; TABLE *table; @@ -162,6 +162,8 @@ 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); init_read_record(&info,thd,table,select,1,1); ulong deleted=0L; thd->proc_info="updating"; @@ -188,7 +190,9 @@ int mysql_delete(THD *thd,TABLE_LIST *table_list,COND *conds,ha_rows limit, } thd->proc_info="end"; end_read_record(&info); - VOID(table->file->extra(HA_EXTRA_READCHECK)); + (void) table->file->extra(HA_EXTRA_READCHECK); + if (options & OPTION_QUICK) + (void) table->file->extra(HA_EXTRA_NORMAL); if (deleted) { mysql_update_log.write(thd,thd->query, thd->query_length); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 25fd8b0c9ea..e3347aebd5d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -394,6 +394,7 @@ pthread_handler_decl(handle_one_connection,arg) thd->client_capabilities|=CLIENT_IGNORE_SPACE; thd->proc_info=0; // Remove 'login' + thd->command=COM_SLEEP; thd->version=refresh_version; thd->set_time(); init_sql_alloc(&thd->mem_root,8192,8192); @@ -754,7 +755,7 @@ bool do_command(THD *thd) { mysql_log.write(thd,command,NullS); char buff[200]; - ulong uptime = (ulong) (time((time_t*) 0) - start_time); + ulong uptime = (ulong) (thd->start_time - start_time); sprintf((char*) buff, "Uptime: %ld Threads: %d Questions: %lu Slow queries: %ld Opens: %ld Flush tables: %ld Open tables: %d Queries per second avg: %.3f", uptime, @@ -813,7 +814,9 @@ bool do_command(THD *thd) time_t start_of_query=thd->start_time; thd->set_time(); - if ((ulong) (thd->start_time - start_of_query) > long_query_time) + /* If not reading from backup and if the query took too long */ + if (!thd->user_time && + (ulong) (thd->start_time - start_of_query) > long_query_time) { long_query_count++; mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query); @@ -1355,7 +1358,7 @@ mysql_execute_command(void) // Set privilege for the WHERE clause tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); res = mysql_delete(thd,tables,lex->where,lex->select_limit, - lex->lock_option); + lex->lock_option, lex->options); #ifdef DELETE_ITEMS delete lex->where; #endif @@ -1818,7 +1821,10 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables) return TRUE; // Access denied } if (grant_option) + { + want_access &= ~EXTRA_ACL; // Remove SHOW attribute return check_grant(thd,want_access,org_tables); + } return FALSE; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index fa309a85bc5..9110ae72998 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1015,7 +1015,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { strmov(new_name_buff,new_name); fn_same(new_name_buff,table_name,3); +#ifdef FN_LOWER_CASE + if (!strcasecmp(new_name_buff,table_name)) // Check if name changed +#else if (!strcmp(new_name_buff,table_name)) // Check if name changed +#endif new_name=table_name; // No. Make later check easier else { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5e6863178b9..ead4e38628d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -501,6 +501,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock varchar references opt_on_delete opt_on_delete_list opt_on_delete_item use + opt_delete_options opt_delete_option opt_outer table_list table opt_option opt_place opt_low_priority opt_attribute opt_attribute_list attribute column_list column_list_id opt_column_list grant_privileges opt_table user_list grant_option @@ -2085,10 +2086,21 @@ opt_low_priority: /* Delete rows from a table */ delete: - DELETE_SYM opt_low_priority FROM table where_clause delete_limit_clause - { Lex->sql_command= SQLCOM_DELETE; } + DELETE_SYM + { Lex->sql_command= SQLCOM_DELETE; Lex->options=0; + Lex->lock_option= current_thd->update_lock_default; } + opt_delete_options FROM table + where_clause delete_limit_clause +opt_delete_options: + /* empty */ {} + | opt_delete_option opt_delete_options {} + +opt_delete_option: + QUICK { Lex->options|= OPTION_QUICK; } + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + /* Show things */ show: SHOW { Lex->wild=0;} show_param diff --git a/sql/table.cc b/sql/table.cc index e0270838651..682cd880fe1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -44,7 +44,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, { reg1 uint i; reg2 uchar *strpos; - int j,flag,error; + int j,error; uint rec_buff_length,n_length,int_length,records,key_parts,keys, interval_count,interval_parts,read_length,db_create_options; ulong pos; @@ -80,8 +80,8 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (!outparam->real_name || !outparam->table_name) goto err_end; - flag= (prgflag & CHANGE_FRM) ? O_RDWR : O_RDONLY | O_SHARE; - if ((file=my_open(fn_format(index_file,name,"",reg_ext,4),flag, + if ((file=my_open(fn_format(index_file,name,"",reg_ext,4), + O_RDONLY | O_SHARE, MYF(0))) < 0) { diff --git a/strings/bmove512.c b/strings/bmove512.c index 4b0c3f5c1cb..11dc282d05c 100644 --- a/strings/bmove512.c +++ b/strings/bmove512.c @@ -40,12 +40,10 @@ void bmove512(register gptr to, register const gptr from, register uint length) { - reg1 LONG *f,*t; - reg3 int len; + reg1 LONG *f,*t,*end= (LONG*) ((char*) from+length); f= (LONG*) from; t= (LONG*) to; - len= (int) length; #if defined(m88k) || defined(sparc) || defined(HAVE_LONG_LONG) do { @@ -86,7 +84,7 @@ void bmove512(register gptr to, register const gptr from, register uint length) t[124]=f[124]; t[125]=f[125]; t[126]=f[126]; t[127]=f[127]; t+=128; f+=128; #endif - } while ((len-=512) > 0); + } while (f < end); #else do { *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; @@ -121,7 +119,7 @@ void bmove512(register gptr to, register const gptr from, register uint length) *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; *t++ = *f++; - } while ((len-=512) > 0); + } while (f < end); #endif return; } /* bmove512 */ diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh index 7ce049f573e..2663ab36b66 100644 --- a/support-files/mysql.server.sh +++ b/support-files/mysql.server.sh @@ -45,8 +45,9 @@ do # This could easily be rewritten to gather [xxxxx]-specific entries, # but for now it looks like only the mysqld ones are needed for # server startup scripts + thevar="" eval `sed -n -e '/^$/d' -e '/^#/d' -e 's,[ ],,g' -e '/=/p' $c |\ - # awk -F= -v v=$v '{if ($1 == v) printf ("thevar=\"%s\"\n", $2)}'` + awk -F= -v v=$v '{if ($1 == v) printf ("thevar=\"%s\"\n", $2)}'` # it would be easier if the my.cnf and variable values were # all matched, but since they aren't we need to map them here. |