From b67d11e17ca6ae8b4b0a0d5a5b5fccceff641a26 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 2 Sep 2001 13:47:00 +0300 Subject: [PATCH] Changed DB_TYPE_INNOBASE to DB_TYPE_INNODB Fix that DROP DATABASE works with all table types Use BULK_INSERT when inserting more than one row Better TRUNCATE TABLE BitKeeper/deleted/.del-compilation_finished.au.gz~70bd14095a918139: Delete: sounds/compilation_finished.au.gz BUILD/FINISH.sh: Removed 'finished' sound as this isn't a general solution. Docs/manual.texi: Added upgrading from 3.23 configure.in: Fixed version number sql/ha_innobase.cc: Default creation of InnoDB tables. sql/ha_myisam.cc: Disable BULK_INSERT of using safe mode sql/handler.cc: Changed DB_TYPE_INNOBASE to DB_TYPE_INNODB sql/handler.h: Changed DB_TYPE_INNOBASE to DB_TYPE_INNODB sql/lock.cc: Added lock_and_wait_for_table_name sql/mysql_priv.h: Better TRUNCATE TABLE sql/sql_db.cc: Fix that DROP DATABASE works with all table types sql/sql_delete.cc: Better TRUNCATE TABLE sql/sql_insert.cc: Use BULK_INSERT when inserting more than one row sql/sql_load.cc: Small bug fix. sql/sql_parse.cc: Better TRUNCATE TABLE sql/sql_select.cc: Change INNOBASE -> INNODB sql/sql_table.cc: Better TRUNCATE TABLE sql/sql_yacc.yy: INNOBASE -> INNODB sql/thr_malloc.cc: Fix for replication --- BUILD/FINISH.sh | 8 - Docs/manual.texi | 52 +++++-- configure.in | 2 +- sounds/compilation_finished.au.gz | Bin 12406 -> 0 bytes sql/ha_innobase.cc | 9 +- sql/ha_myisam.cc | 3 +- sql/handler.cc | 10 +- sql/handler.h | 4 +- sql/lock.cc | 31 +++- sql/mysql_priv.h | 8 +- sql/sql_db.cc | 105 ++++++------- sql/sql_delete.cc | 239 +++++++++++++++--------------- sql/sql_insert.cc | 30 +++- sql/sql_load.cc | 8 +- sql/sql_parse.cc | 24 ++- sql/sql_select.cc | 2 +- sql/sql_table.cc | 81 +++++----- sql/sql_yacc.yy | 2 +- sql/thr_malloc.cc | 4 +- 19 files changed, 365 insertions(+), 257 deletions(-) delete mode 100644 sounds/compilation_finished.au.gz diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh index 5900223f3d5..368ab339c2b 100644 --- a/BUILD/FINISH.sh +++ b/BUILD/FINISH.sh @@ -45,11 +45,3 @@ then else echo "$commands" fi - -comp_finished=sounds/compilation_finished.au.gz - -if [ -c /dev/audio ] && [ -f "$comp_finished" ] -then - gunzip -c $comp_finished > /dev/audio -fi - diff --git a/Docs/manual.texi b/Docs/manual.texi index f341dd9a289..1a7abb44841 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -326,6 +326,7 @@ Post-installation Setup and Testing Upgrading/Downgrading MySQL +* Upgrading-from-3.23:: * Upgrading-from-3.22:: Upgrading from a 3.22 version to 3.23 * Upgrading-from-3.21:: Upgrading from a 3.21 version to 3.22 * Upgrading-from-3.20:: Upgrading from a 3.20 version to 3.21 @@ -643,7 +644,6 @@ Replication in MySQL MySQL Full-text Search -* Fulltext Search:: * Fulltext Fine-tuning:: * Fulltext Features to Appear in MySQL 4.0:: * Fulltext TODO:: @@ -10828,15 +10828,39 @@ particularly if you notice symptoms such as all your @code{DBI} scripts dumping core after you upgrade @strong{MySQL}. @menu +* Upgrading-from-3.23:: * Upgrading-from-3.22:: Upgrading from a 3.22 version to 3.23 * Upgrading-from-3.21:: Upgrading from a 3.21 version to 3.22 * Upgrading-from-3.20:: Upgrading from a 3.20 version to 3.21 * Upgrading-to-arch:: Upgrading to another architecture @end menu +@cindex compatibility, between MySQL versions +@cindex upgrading, 3.23 to 4.0 +@node Upgrading-from-3.23, Upgrading-from-3.22, Upgrade, Upgrade +@subsection Upgrading From Version 3.23 to Version 4.0 + +You can use your old data files without any modification with Version 4.0 + +All old clients will work with a Version 4.0 server. + +The following lists tell what you have to watch out for when upgrading to +Version 4.0; + +@itemize @bullet +@item +You should use @code{TRUNCATE TABLE} when you want to delete all rows +from a table and you don't care of how many rows where deleted. +(Because @code{TRUNCATE TABLE} is faster than @code{DELETE FROM table_name}). +@item +You will get an error if you have an active @code{LOCK TABLES} or +transaction when trying to execute @code{TRUNCATE TABLE} or @code{DROP +DATABASE}. +@end itemize + @cindex compatibility, between MySQL versions @cindex upgrading, 3.22 to 3.23 -@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrade, Upgrade +@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade @subsection Upgrading From Version 3.22 to Version 3.23 @strong{MySQL} Version 3.23 supports tables of the new @code{MyISAM} type and @@ -20108,16 +20132,19 @@ the @code{LIMIT} value. TRUNCATE TABLE table_name @end example -Is in 3.23 and the same thing as @code{DELETE FROM table_name}. @xref{DELETE}. -The differences are: +In 3.23 @code{TRUNCATE TABLE} is mapped to +@code{COMMIT ; DELETE FROM table_name}. @xref{DELETE}. + +The differences between @code{TRUNCATE TABLE} and @code{DELETE FROM ..} +are: @itemize @bullet @item -Implemented as a drop and re-create of the table, which makes this -much faster when deleting many rows. +Truncates does a drop and re-create of the table, which is much faster +than deleting rows one by one. @item -Not transaction-safe; @code{TRUNCATE TABLE} will automatically end the current -transaction as if @code{COMMIT} would have been called. +Not transaction-safe; You will get an error if you have an active +transaction or an active table lock. @item Doesn't return the number of deleted rows. @item @@ -25970,7 +25997,7 @@ Finland @cindex tables, @code{BDB} @cindex tables, @code{Berkeley DB} -@node BDB, , InnoDB, Table types +@node BDB, , InnoDB, Table types @section BDB or Berkeley_DB Tables @menu @@ -45722,6 +45749,13 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @itemize @bullet @item +@code{TRUNCATE TABLE} and @code{DELETE FROM table_name} are now separate +functions. One bonus is that @code{DELETE FROM table_name} now returns +the number of deleted rows. +@item +@code{DROP DATABASE} now executes a @code{DROP TABLE} on all tables in +the database, which fixes a problem with InnoDB tables. +@item Changed WEEK(#,0) to match the calender in the USA. @item Cleaned up global lock handling for @code{FLUSH TABLES WITH READ LOCK} diff --git a/configure.in b/configure.in index 852fd2fd9a6..71089e47963 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.0.0) +AM_INIT_AUTOMAKE(mysql, 4.0.0-alpha) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 diff --git a/sounds/compilation_finished.au.gz b/sounds/compilation_finished.au.gz deleted file mode 100644 index f0ed06c0698dc02f7c45789f95c0fc639ec94d95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12406 zcmV-+Fp19}iwFp{mv}n>17mM(aA|B|bZKvHUuJ1;X>(|0WG-QK09Aa+ZrfP)cXd~H zr7DA+(UT@mvSrDVAP9sY2m}ExxZr{-F7E@}$EbgI*O00tPU4KVEO{O@Ll6W(5D0L= z1s7a#$@P5;F1~XID*2Rn5=HXdGycxuIoC804ozKCRn0VXUDFXE*whux#39BAV?sjs z8{q(cfjgM;&V-8~%w8d(Cz_^-QAmFx1m6t9 zB%U7{N>zsY)4vTkU;-T~kfQ6RZW@{*%Zka!p_ic-Lc+=r2hD5=C}_d)df za2v$$3G@>BG5R_B3ULr%{wKXF{G+!v;GPC2jK0HOa25J3`eGEo9Z5jw%Hib$6X?>} z;ypj&3H%G$s_DluqmZ3SX=L9h#lTU@0(xzFdwN?0#27kA0w^&kDex=(+vJ49Cv-!6 z7XHGFP|OKpS4DzJ^j1^=OawRtYJ#~a1S3PnNcMvZl`j_-OeF+&=KsYDenDnP(ERdj zF+OK1y8@>{+>sD3pp2mJ;ZXd;oag-h2y+diG%&7EQn+x~6{#K=j0q-UGJ-#Jy4tyT z3@(w7u^BGJ*UY5C2w@bGfXjn$TByW)_8$FM$PNn4A`x+vQS4e=UxaQjq39Y|imFk% z=I?SjQNkHf^Z=)eYGVM#BUcnzGpM#QRi!5)rjCd+-DK=zoMnUpi9)dn<?4#a#59LpfLg*JQsReZ&>?%wH;8&`UOwr*(k(oQlgiczo@_|6Oh5kXRD^_$K4loPMB*n;o8Mbipn}*>ft(6;h4_~ zg_FRD>qZ!@jGH6S!DEQHiqH&`xekJu?+W31Zh$ERsX_?9F!xv>HcA^+9v%w>;rs;3L10A0?SNS*_wJE2n8Tzu2${?D1AaSdsqCFlc-TlxerRg+ zE-a=o715%X&fOF9qf}ZtkGo80%;|jZt)lB8ZcM_XhLLVFe;Lws`z+Q9|G^y<91hUj zn7HAv=uRnPQqs7Ae6>Oq;n~2E-UHqYA_H zf++;oF}NiQTO7Vm=`vxceUG1Bn6| zmk^IZoFBr3g=1l><}¼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.all))) #define ha_rollback(thd) (ha_rollback_trans((thd), &((thd)->transaction.all))) +#define ha_supports_generate(T) (T != DB_TYPE_INNODB) + handler *get_new_handler(TABLE *table, enum db_type db_type); my_off_t ha_get_ptr(byte *ptr, uint pack_length); void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos); diff --git a/sql/lock.cc b/sql/lock.cc index 561ce94f88b..f523f10b3a7 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -370,6 +370,36 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, ** This is used when we need total access to a closed, not open table *****************************************************************************/ +/* + Lock and wait for the named lock. + Returns 0 on ok +*/ + +int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list) +{ + int lock_retcode; + int error= -1; + DBUG_ENTER("lock_and_wait_for_table_name"); + + if (wait_if_global_read_lock(thd,0)) + DBUG_RETURN(1); + VOID(pthread_mutex_lock(&LOCK_open)); + if ((lock_retcode = lock_table_name(thd, table_list)) < 0) + goto end; + if (lock_retcode && wait_for_locked_table_names(thd, table_list)) + { + unlock_table_name(thd, table_list); + goto end; + } + error=0; + +end: + start_waiting_global_read_lock(thd); + pthread_mutex_unlock(&LOCK_open); + DBUG_RETURN(error); +} + + /* Put a not open table with an old refresh version in the table cache. This will force any other threads that uses the table to release it @@ -381,7 +411,6 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, > 0 table locked, but someone is using it */ - int lock_table_name(THD *thd, TABLE_LIST *table_list) { TABLE *table; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c73df4eaaeb..11cacf44e8c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -237,6 +237,8 @@ inline THD *_current_thd(void) int mysql_create_db(THD *thd, char *db, uint create_info); void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags); int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists); +int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, + bool log_query); int quick_rm_table(enum db_type base,const char *db, const char *table_name); bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list); @@ -268,10 +270,6 @@ bool check_access(THD *thd,uint access,const char *db=0,uint *save_priv=0, bool check_table_access(THD *thd,uint want_access, TABLE_LIST *tables); bool check_process_priv(THD *thd=0); -int generate_table(THD *thd, TABLE_LIST *table_list, - TABLE *locked_table); - - int mysql_backup_table(THD* thd, TABLE_LIST* table_list); int mysql_restore_table(THD* thd, TABLE_LIST* table_list); @@ -364,6 +362,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table,List &fields, void kill_delayed_threads(void); int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, ORDER *order, ha_rows rows, thr_lock_type lock_type, ulong options); +int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok=0); 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); @@ -592,6 +591,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh); void start_waiting_global_read_lock(THD *thd); /* Lock based on name */ +int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list); int lock_table_name(THD *thd, TABLE_LIST *table_list); void unlock_table_name(THD *thd, TABLE_LIST *table_list); bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 21d44d3b41d..3c5a6efd9a5 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -25,7 +25,8 @@ #include #endif -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *path, +static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, + const char *db, const char *path, uint level); /* db-name is already validated when we come here */ @@ -121,17 +122,20 @@ exit: DBUG_RETURN(error); } -const char *del_exts[]= -{".frm",".ISM",".ISD",".ISM",".HSH",".DAT",".MRG",".MYI",".MYD", ".db", ".BAK", NullS}; +const char *del_exts[]= {".frm", ".BAK", NullS}; static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts}; -/* db-name is already validated when we come here */ -/* If thd == 0, do not write any messages - This is useful in replication when we want to remove - a stale database before replacing it with the new one +/* + Drop all tables in a database. + + db-name is already validated when we come here + If thd == 0, do not write any messages; This is useful in replication + when we want to remove a stale database before replacing it with the new one */ + + int mysql_rm_db(THD *thd,char *db,bool if_exists) { long deleted=0; @@ -144,31 +148,15 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists) VOID(pthread_mutex_lock(&LOCK_open)); // do not drop database if another thread is holding read lock - if (global_read_lock) - { - if (thd->global_read_lock) - { - net_printf(&thd->net, ER_DROP_DB_WITH_READ_LOCK); - goto exit; - } - while (global_read_lock && ! thd->killed) - { - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); - } - - if (thd->killed) - { - net_printf(&thd->net, ER_SERVER_SHUTDOWN); - goto exit; - } - } + if (wait_if_global_read_lock(thd,0)) + goto exit; (void) sprintf(path,"%s/%s",mysql_data_home,db); unpack_dirname(path,path); // Convert if not unix /* See if the directory exists */ if (!(dirp = my_dir(path,MYF(MY_WME | MY_DONT_SORT)))) { - if(thd) + if (thd) { if (!if_exists) net_printf(&thd->net,ER_DB_DROP_EXISTS,db); @@ -180,7 +168,8 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists) } remove_db_from_cache(db); - if ((deleted=mysql_rm_known_files(thd, dirp, path,0)) >= 0 && thd) + error = -1; + if ((deleted=mysql_rm_known_files(thd, dirp, db, path,0)) >= 0 && thd) { if (!thd->query) { @@ -206,27 +195,31 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists) exit: VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); + start_waiting_global_read_lock(thd); + DBUG_RETURN(error); } /* Removes files with known extensions plus all found subdirectories that are 2 digits (raid directories). + thd MUST be set when calling this function! */ -/* This one also needs to work with thd == 0 for replication */ -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path, - uint level) +static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, + const char *org_path, uint level) { long deleted=0; ulong found_other_files=0; char filePath[FN_REFLEN]; + TABLE_LIST *tot_list=0, **tot_list_next; DBUG_ENTER("mysql_rm_known_files"); DBUG_PRINT("enter",("path: %s", org_path)); - /* remove all files with known extensions */ + + tot_list_next= &tot_list; for (uint idx=2 ; - idx < (uint) dirp->number_off_files && (!thd || !thd->killed) ; + idx < (uint) dirp->number_off_files && !thd->killed ; idx++) { FILEINFO *file=dirp->dir_entry+idx; @@ -243,7 +236,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path, if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT)))) { DBUG_PRINT("my",("New subdir found: %s", newpath)); - if ((mysql_rm_known_files(thd,new_dirp,newpath,1)) < 0) + if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1)) < 0) { my_dirend(dirp); DBUG_RETURN(-1); @@ -257,24 +250,39 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path, continue; } strxmov(filePath,org_path,"/",file->name,NullS); - unpack_filename(filePath,filePath); - if (my_delete_with_symlink(filePath,MYF(MY_WME))) + if (db && !strcasecmp(fn_ext(file->name), reg_ext)) { - if(thd) - net_printf(&thd->net,ER_DB_DROP_DELETE,filePath,my_error); - my_dirend(dirp); - DBUG_RETURN(-1); + /* Drop the table nicely */ + *fn_ext(file->name)=0; // Remove extension + TABLE_LIST *table_list=(TABLE_LIST*) + thd->calloc(sizeof(*table_list)+ strlen(db)+strlen(file->name)+1); + if (!table_list) + { + my_dirend(dirp); + DBUG_RETURN(-1); + } + table_list->db= (char*) (table_list+1); + strmov(table_list->real_name=strmov(table_list->db,db)+1, + file->name); + /* Link into list */ + (*tot_list_next)= table_list; + tot_list_next= &table_list->next; } - deleted++; - } + else + { + if (my_delete_with_symlink(filePath,MYF(MY_WME))) + { + my_dirend(dirp); + DBUG_RETURN(-1); + } + deleted++; + } + } my_dirend(dirp); - if (thd && thd->killed) - { - send_error(&thd->net,ER_SERVER_SHUTDOWN); + if (thd->killed || (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 1))) DBUG_RETURN(-1); - } /* If the directory is a symbolic link, remove the link first, then @@ -294,22 +302,19 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *org_path, /* Don't give errors if we can't delete 'RAID' directory */ if (level) DBUG_RETURN(deleted); - if(thd) - send_error(&thd->net); DBUG_RETURN(-1); } path=filePath; } #endif - /* Remove last FN_LIBCHAR to not cause a probelm on OS/2 */ + /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */ char *pos=strend(path); if (pos > path && pos[-1] == FN_LIBCHAR) *--pos=0; /* Don't give errors if we can't delete 'RAID' directory */ if (rmdir(path) < 0 && !level) { - if(thd) - net_printf(&thd->net,ER_DB_DROP_RMDIR, path,errno); + my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno); DBUG_RETURN(-1); } } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 2fb9e3780a1..d9b6970b72d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -15,113 +15,28 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Delete of records */ +/* + Delete of records and truncate of tables. + + Multi-table deletes were introduced by Monty and Sinisa +*/ + -/* Multi-table deletes were introduced by Monty and Sinisa */ #include "mysql_priv.h" #include "ha_innobase.h" #include "sql_select.h" -/* - Optimize delete of all rows by doing a full generate of the table - This will work even if the .ISM and .ISD tables are destroyed -*/ - -int generate_table(THD *thd, TABLE_LIST *table_list, TABLE *locked_table) -{ - char path[FN_REFLEN]; - int error; - TABLE **table_ptr; - DBUG_ENTER("generate_table"); - - if (wait_if_global_read_lock(thd,0)) - DBUG_RETURN(1); - thd->proc_info="generate_table"; - - /* If it is a temporary table, close and regenerate it */ - if ((table_ptr=find_temporary_table(thd,table_list->db, - table_list->real_name))) - { - TABLE *table= *table_ptr; - HA_CREATE_INFO create_info; - table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); - bzero((char*) &create_info,sizeof(create_info)); - create_info.auto_increment_value= table->file->auto_increment_value; - db_type table_type=table->db_type; - - strmov(path,table->path); - *table_ptr= table->next; // Unlink table from list - close_temporary(table,0); - *fn_ext(path)=0; // Remove the .frm extension - ha_create_table(path, &create_info,1); - if ((error= (int) !(open_temporary_table(thd, path, table_list->db, - table_list->real_name, 1)))) - { - (void) rm_temporary_table(table_type, path); - } - } - else - { - (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db, - table_list->real_name,reg_ext); - fn_format(path,path,"","",4); - VOID(pthread_mutex_lock(&LOCK_open)); - if (locked_table) - mysql_lock_abort(thd,locked_table); // end threads waiting on lock - // close all copies in use - if (remove_table_from_cache(thd,table_list->db,table_list->real_name)) - { - if (!locked_table) - { - VOID(pthread_mutex_unlock(&LOCK_open)); - start_waiting_global_read_lock(thd); - DBUG_RETURN(1); // We must get a lock on table - } - } - if (locked_table) - locked_table->file->extra(HA_EXTRA_FORCE_REOPEN); - if (thd->locked_tables) - close_data_tables(thd,table_list->db,table_list->real_name); - else - close_thread_tables(thd,1); - HA_CREATE_INFO create_info; - bzero((char*) &create_info,sizeof(create_info)); - *fn_ext(path)=0; // Remove the .frm extension - error= ha_create_table(path,&create_info,1) ? -1 : 0; - if (thd->locked_tables && reopen_tables(thd,1,0)) - error= -1; - VOID(pthread_mutex_unlock(&LOCK_open)); - } - if (!error) - { - mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query); - mysql_bin_log.write(&qinfo); - } - send_ok(&thd->net); // This should return record count - } - start_waiting_global_read_lock(thd); - DBUG_RETURN(error ? -1 : 0); -} - - -int mysql_delete(THD *thd, - TABLE_LIST *table_list, - COND *conds, - ORDER *order, - ha_rows limit, - thr_lock_type lock_type, - ulong options) +int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, + ha_rows limit, thr_lock_type lock_type, ulong options) { int error; TABLE *table; - SQL_SELECT *select; + SQL_SELECT *select=0; READ_RECORD info; bool using_limit=limit != HA_POS_ERROR; - bool use_generate_table,using_transactions; + bool using_transactions; + ha_rows deleted; DBUG_ENTER("mysql_delete"); if (!table_list->db) @@ -132,34 +47,33 @@ int mysql_delete(THD *thd, DBUG_RETURN(1); } - use_generate_table= (!using_limit && !conds && - !(specialflag & - (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && - !(thd->options & - (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))); -#ifdef HAVE_INNOBASE_DB - /* We need to add code to not generate table based on the table type */ - if (!innodb_skip) - use_generate_table=0; // Innobase can't use re-generate table -#endif - if (use_generate_table && ! thd->open_tables) - { - error=generate_table(thd,table_list,(TABLE*) 0); - if (error <= 0) - DBUG_RETURN(error); // Error or ok - } - if (!(table = open_ltable(thd,table_list, - limit != HA_POS_ERROR ? TL_WRITE_LOW_PRIORITY : - lock_type))) + if (!(table = open_ltable(thd,table_list, lock_type))) DBUG_RETURN(-1); table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; - if (use_generate_table) - DBUG_RETURN(generate_table(thd,table_list,table)); table->map=1; if (setup_conds(thd,table_list,&conds)) DBUG_RETURN(-1); + /* Test if the user wants to delete all rows */ + if (!using_limit && (!conds || conds->const_item()) && + !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE))) + { + deleted= table->file->records; + if (!(error=table->file->delete_all_rows())) + { + error= -1; // ok + goto cleanup; + } + if (error != HA_ERR_WRONG_COMMAND) + { + table->file->print_error(error,MYF(0)); + error=0; + goto cleanup; + } + /* Handler didn't support fast delete; Delete rows one by one */ + } + table->used_keys=table->quick_keys=0; // Can't use 'only index' select=make_select(table,0,0,conds,&error); if (error) @@ -215,7 +129,7 @@ int mysql_delete(THD *thd, } init_read_record(&info,thd,table,select,1,1); - ulong deleted=0L; + deleted=0L; thd->proc_info="updating"; while (!(error=info.read_record(&info)) && !thd->killed) { @@ -244,6 +158,8 @@ int mysql_delete(THD *thd, (void) table->file->extra(HA_EXTRA_READCHECK); if (options & OPTION_QUICK) (void) table->file->extra(HA_EXTRA_NORMAL); + +cleanup: using_transactions=table->file->has_transactions(); if (deleted && (error <= 0 || !using_transactions)) { @@ -555,3 +471,90 @@ bool multi_delete::send_eof() ::send_ok(&thd->net,deleted); return 0; } + + +/*************************************************************************** +* TRUNCATE TABLE +****************************************************************************/ + +/* + Optimize delete of all rows by doing a full generate of the table + This will work even if the .ISM and .ISD tables are destroyed + + dont_send_ok should be set if: + - We should always wants to generate the table (even if the table type + normally can't safely do this. + - We don't want an ok to be sent to the end user. + - We don't want to log the truncate command +*/ + +int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) +{ + HA_CREATE_INFO create_info; + char path[FN_REFLEN]; + TABLE **table_ptr; + int error; + DBUG_ENTER("mysql_truncate"); + + /* If it is a temporary table, close and regenerate it */ + if ((table_ptr=find_temporary_table(thd,table_list->db, + table_list->real_name))) + { + TABLE *table= *table_ptr; + HA_CREATE_INFO create_info; + table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); + bzero((char*) &create_info,sizeof(create_info)); + create_info.auto_increment_value= table->file->auto_increment_value; + db_type table_type=table->db_type; + + strmov(path,table->path); + *table_ptr= table->next; // Unlink table from list + close_temporary(table,0); + *fn_ext(path)=0; // Remove the .frm extension + ha_create_table(path, &create_info,1); + if ((error= (int) !(open_temporary_table(thd, path, table_list->db, + table_list->real_name, 1)))) + (void) rm_temporary_table(table_type, path); + DBUG_RETURN(error ? -1 : 0); + } + + (void) sprintf(path,"%s/%s/%s%s",mysql_data_home,table_list->db, + table_list->real_name,reg_ext); + fn_format(path,path,"","",4); + + if (!dont_send_ok) + { + db_type table_type; + if ((table_type=get_table_type(path)) == DB_TYPE_UNKNOWN) + { + my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->real_name); + DBUG_RETURN(-1); + } + if (!ha_supports_generate(table_type)) + { + /* Probably InnoDB table */ + DBUG_RETURN(mysql_delete(thd,table_list, (COND*) 0, (ORDER*) 0, + (ha_rows) 0, TL_WRITE, 0)); + } + if (lock_and_wait_for_table_name(thd, table_list)) + DBUG_RETURN(-1); + } + + bzero((char*) &create_info,sizeof(create_info)); + *fn_ext(path)=0; // Remove the .frm extension + error= ha_create_table(path,&create_info,1) ? -1 : 0; + VOID(pthread_mutex_unlock(&LOCK_open)); + + if (!error && !dont_send_ok) + { + mysql_update_log.write(thd,thd->query,thd->query_length); + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query); + mysql_bin_log.write(&qinfo); + } + send_ok(&thd->net); // This should return record count + } + unlock_table_name(thd, table_list); + DBUG_RETURN(error ? -1 : 0); +} diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c21e7668a02..f53dd12016b 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -103,7 +103,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, int error; bool log_on= ((thd->options & OPTION_UPDATE_LOG) || !(thd->master_access & PROCESS_ACL)); - bool using_transactions; + bool using_transactions, bulk_insert=0; uint value_count; uint save_time_stamp; ulong counter = 1; @@ -193,6 +193,14 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &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 && + lock_type != TL_WRITE_DELAYED && + !(specialflag & SPECIAL_SAFE_MODE)))) + { + table->file->extra(HA_EXTRA_WRITE_CACHE); + table->file->extra(HA_EXTRA_BULK_INSERT_BEGIN); + } + while ((values = its++)) { if (fields.elements || !value_count) @@ -257,6 +265,25 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, } else { + if (bulk_insert) + { + if (table->file->extra(HA_EXTRA_NO_CACHE)) + { + if (!error) + { + table->file->print_error(my_errno,MYF(0)); + error=1; + } + } + if (table->file->extra(HA_EXTRA_BULK_INSERT_END)) + { + if (!error) + { + table->file->print_error(my_errno,MYF(0)); + error=1; + } + } + } if (id && values_list.elements != 1) thd->insert_id(id); // For update log else if (table->next_number_field) @@ -289,7 +316,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, thd->next_insert_id=0; // Reset this if wrongly used if (duplic == DUP_IGNORE || duplic == DUP_REPLACE) table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - if (error) goto abort; diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 5b02586a24c..d7f273bfaa4 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -243,6 +243,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, table->time_stamp=0; table->next_number_field=table->found_next_number_field; VOID(table->file->extra(HA_EXTRA_WRITE_CACHE)); + VOID(table->file->extra(HA_EXTRA_BULK_INSERT_BEGIN)); if (handle_duplicates == DUP_IGNORE || handle_duplicates == DUP_REPLACE) table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); @@ -252,9 +253,10 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, error=read_fixed_length(thd,info,table,fields,read_info); else error=read_sep_field(thd,info,table,fields,read_info,*enclosed); - if (table->file->extra(HA_EXTRA_NO_CACHE) || - table->file->activate_all_index(thd)) - error=1; /* purecov: inspected */ + if (table->file->extra(HA_EXTRA_NO_CACHE)) + error=1; /* purecov: inspected */ + if (table->file->activate_all_index(thd)) + error=1; /* purecov: inspected */ table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->time_stamp=save_time_stamp; table->next_number_field=0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c43540d77e6..dac9af6d9fb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1619,9 +1619,19 @@ mysql_execute_command(void) break; } case SQLCOM_TRUNCATE: - select_lex->where=0; - select_lex->select_limit=HA_POS_ERROR; - /* Fall through */ + if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege)) + goto error; /* purecov: inspected */ + /* + Don't allow this within a transaction because we want to use + re-generate table + */ + if (thd->locked_tables || thd->active_transaction()) + { + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); + goto error; + } + res=mysql_truncate(thd,tables); + break; case SQLCOM_DELETE: { if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege)) @@ -1958,9 +1968,13 @@ mysql_execute_command(void) net_printf(&thd->net,ER_WRONG_DB_NAME, lex->name); break; } - if (check_access(thd,DROP_ACL,lex->name,0,1) || - end_active_trans(thd)) + if (check_access(thd,DROP_ACL,lex->name,0,1)) break; + if (thd->locked_tables || thd->active_transaction()) + { + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); + goto error; + } mysql_rm_db(thd,lex->name,lex->drop_if_exists); break; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1fb6a8d070a..12cd7a94e7f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -547,7 +547,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, for (uint i_h = join.const_tables; i_h < join.tables; i_h++) { TABLE* table_h = join.join_tab[i_h].table; - if (table_h->db_type == DB_TYPE_INNOBASE) + if (table_h->db_type == DB_TYPE_INNODB) table_h->file->extra(HA_EXTRA_DONT_USE_CURSOR_TO_UPDATE); } } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f8c3aa59d65..f248c675e8e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -43,12 +43,7 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) { - char path[FN_REFLEN]; - String wrong_tables; - bool some_tables_deleted=0; - uint error; - db_type table_type; - TABLE_LIST *table; + int error; DBUG_ENTER("mysql_rm_table"); /* mark for close and remove all cached entries */ @@ -74,7 +69,35 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) } } - + error=mysql_rm_table_part2(thd,tables,if_exists,0); + + err: + VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh + pthread_mutex_unlock(&LOCK_open); + + pthread_mutex_lock(&thd->mysys_var->mutex); + thd->mysys_var->current_mutex= 0; + thd->mysys_var->current_cond= 0; + pthread_mutex_unlock(&thd->mysys_var->mutex); + + if (error) + DBUG_RETURN(-1); + send_ok(&thd->net); + DBUG_RETURN(0); +} + + +int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, + bool dont_log_query) +{ + TABLE_LIST *table; + char path[FN_REFLEN]; + String wrong_tables; + db_type table_type; + int error; + bool some_tables_deleted=0; + DBUG_ENTER("mysql_rm_table_part2"); + for (table=tables ; table ; table=table->next) { char *db=table->db ? table->db : thd->db; @@ -137,7 +160,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) wrong_tables.append(String(table->real_name)); } } - if (some_tables_deleted) + if (some_tables_deleted && !dont_log_query) { mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) @@ -148,24 +171,12 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) } error = 0; - err: - VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh - pthread_mutex_unlock(&LOCK_open); - - pthread_mutex_lock(&thd->mysys_var->mutex); - thd->mysys_var->current_mutex= 0; - thd->mysys_var->current_cond= 0; - pthread_mutex_unlock(&thd->mysys_var->mutex); - if (wrong_tables.length()) { my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr()); error=1; } - if(error) - DBUG_RETURN(-1); - send_ok(&thd->net); - DBUG_RETURN(0); + DBUG_RETURN(error); } @@ -837,21 +848,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name); - int lock_retcode; - pthread_mutex_lock(&LOCK_open); - if ((lock_retcode = lock_table_name(thd, table)) < 0) - { - pthread_mutex_unlock(&LOCK_open); + if (lock_and_wait_for_table_name(thd,table)) DBUG_RETURN(-1); - } - - if (lock_retcode && wait_for_locked_table_names(thd, table)) - { - unlock_table_name(thd, table); - pthread_mutex_unlock(&LOCK_open); - DBUG_RETURN(-1); - } - pthread_mutex_unlock(&LOCK_open); if (my_copy(src_path, fn_format(dst_path, dst_path,"", @@ -862,25 +860,18 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) DBUG_RETURN(send_check_errmsg(thd, table, "restore", "Failed copying .frm file")); } - bool save_no_send_ok = thd->net.no_send_ok; - thd->net.no_send_ok = 1; - // generate table will try to send OK which messes up the output - // for the client - - if (generate_table(thd, table, 0)) + if (mysql_truncate(thd, table, 1)) { unlock_table_name(thd, table); - thd->net.no_send_ok = save_no_send_ok; DBUG_RETURN(send_check_errmsg(thd, table, "restore", "Failed generating table from .frm file")); } - - thd->net.no_send_ok = save_no_send_ok; + /* truncate has released name lock */ } - DBUG_RETURN(0); } + static int mysql_admin_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt, const char *operator_name, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index efc6f66fa0e..566a9a22e4c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -796,7 +796,7 @@ table_types: | MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; } | HEAP_SYM { $$= DB_TYPE_HEAP; } | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } - | INNOBASE_SYM { $$= DB_TYPE_INNOBASE; } + | INNOBASE_SYM { $$= DB_TYPE_INNODB; } | GEMINI_SYM { $$= DB_TYPE_GEMINI; } row_types: diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index deb304443df..4017b7c30b8 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -22,7 +22,9 @@ extern "C" { void sql_alloc_error_handler(void) { - current_thd->fatal_error=1; /* purecov: inspected */ + THD *thd=current_thd; + if (thd) // QQ; To be removed + thd->fatal_error=1; /* purecov: inspected */ sql_print_error(ER(ER_OUT_OF_RESOURCES)); } }