diff --git a/include/my_sys.h b/include/my_sys.h index 7ceb40e9e06cc70a87e04b81d59b66a2516f1d16..a5bf5f68f0898071020b82df2cf44b3755e02d8d 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -293,6 +293,14 @@ extern struct my_file_info #endif } my_file_info[MY_NFILE]; +typedef struct st_my_tmpdir +{ + char **list; + uint cur, max; +#ifdef THREAD + pthread_mutex_t mutex; +#endif +} MY_TMPDIR; typedef struct st_dynamic_array { @@ -582,6 +590,10 @@ extern void allow_break(void); #define allow_break() #endif +extern my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist); +extern char *my_tmpdir(MY_TMPDIR *tmpdir); +extern void free_tmpdir(MY_TMPDIR *tmpdir); + extern void my_remember_signal(int signal_number,sig_handler (*func)(int)); extern void case_sort(CHARSET_INFO *cs, my_string str,uint length); extern uint dirname_part(my_string to,const char *name); diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 8da25ad101a5fd0a2deb0b5487dd7dd42c33030c..3ddd8afbb4a559953a685da57f5998a5c80cfac6 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -31,7 +31,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\ my_pread.c my_write.c \ mf_keycache.c \ mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \ - my_lock.c mf_brkhant.c my_alarm.c \ + mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \ my_malloc.c my_realloc.c my_once.c mulalloc.c \ my_alloc.c safemalloc.c my_new.cc \ my_fopen.c my_fstream.c \ diff --git a/mysys/mf_tempdir.c b/mysys/mf_tempdir.c new file mode 100644 index 0000000000000000000000000000000000000000..13b170ceee73eb41a041ba97a2ebe275c3c0517a --- /dev/null +++ b/mysys/mf_tempdir.c @@ -0,0 +1,78 @@ +/* Copyright (C) 2000 MySQL 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 */ + +#include "mysys_priv.h" +#include <m_string.h> + +#define DELIM ':' +my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist) +{ + char *end, *copy; + char buff[FN_REFLEN]; + DYNAMIC_ARRAY t_arr; + pthread_mutex_init(&tmpdir->mutex, MY_MUTEX_INIT_FAST); + if (my_init_dynamic_array(&t_arr, sizeof(char*), 1, 5)) + return TRUE; + if (!pathlist || !pathlist[0]) + { + /* Get default temporary directory */ + pathlist=getenv("TMPDIR"); /* Use this if possible */ +#if defined( __WIN__) || defined(OS2) + if (!pathlist) + pathlist=getenv("TEMP"); + if (!pathlist) + pathlist=getenv("TMP"); +#endif + if (!pathlist || !pathlist[0]) + pathlist=(char*) P_tmpdir; + } + do + { + end=strcend(pathlist, DELIM); + convert_dirname(buff, pathlist, end); + if (!(copy=my_strdup(buff, MYF(MY_WME)))) + return TRUE; + if (insert_dynamic(&t_arr, ©)) + return TRUE; + pathlist=end+1; + } + while (*end); + freeze_size(&t_arr); + tmpdir->list=t_arr.buffer; + tmpdir->max=t_arr.elements-1; + tmpdir->cur=0; + return FALSE; +} + +char *my_tmpdir(MY_TMPDIR *tmpdir) +{ + char *dir; + pthread_mutex_lock(&tmpdir->mutex); + dir=tmpdir->list[tmpdir->cur]; + tmpdir->cur= (tmpdir->cur == tmpdir->max) ? 0 : tmpdir->cur+1; + pthread_mutex_unlock(&tmpdir->mutex); + return dir; +} + +void free_tmpdir(MY_TMPDIR *tmpdir) +{ + uint i; + for (i=0; i<=tmpdir->max; i++) + my_free(tmpdir->list[i], MYF(0)); + my_free(tmpdir->list, MYF(0)); + pthread_mutex_destroy(&tmpdir->mutex); +} + diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b74a2da5f6d8bb3de8846cfe76838ca593bf19dc..d8281af6bd140591441d395e6a02eea492ce9960 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -640,8 +640,9 @@ bool open_log(MYSQL_LOG *log, const char *hostname, extern time_t start_time; extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], - mysql_real_data_home[], *charsets_list; -extern my_string mysql_tmpdir; + mysql_real_data_home[], *charsets_list, *opt_mysql_tmpdir; +#define mysql_tmpdir (my_tmpdir(&mysql_tmpdir_list)) +extern MY_TMPDIR mysql_tmpdir_list; extern const char *command_name[]; extern const char *first_keyword, *localhost, *delayed_user; extern const char **errmesg; /* Error messages */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a3a82d96b2e9c133792b16979cef6990c6241e55..1b4713706fb70290325233407a4de24ca85dfebc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -395,7 +395,8 @@ const char *myisam_recover_options_str="OFF"; const char *sql_mode_str="OFF"; ulong rpl_recovery_rank=0; -my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL, mysql_tmpdir=NULL; +my_string mysql_unix_port=NULL, opt_mysql_tmpdir=NULL; +MY_TMPDIR mysql_tmpdir_list; ulong my_bind_addr; /* the address we bind to */ char *my_bind_addr_str; DATE_FORMAT dayord; @@ -852,7 +853,7 @@ void clean_up(bool print_message) if (defaults_argv) free_defaults(defaults_argv); my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); + free_tmpdir(&mysql_tmpdir_list); my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); x_free(opt_bin_logname); x_free(opt_relay_logname); @@ -1834,17 +1835,6 @@ int main(int argc, char **argv) load_defaults(MYSQL_CONFIG_NAME,load_default_groups,&argc,&argv); defaults_argv=argv; - /* Get default temporary directory */ - opt_mysql_tmpdir=getenv("TMPDIR"); /* Use this if possible */ -#if defined( __WIN__) || defined(OS2) - if (!opt_mysql_tmpdir) - opt_mysql_tmpdir=getenv("TEMP"); - if (!opt_mysql_tmpdir) - opt_mysql_tmpdir=getenv("TMP"); -#endif - if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0]) - opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ - set_options(); get_options(argc,argv); if (opt_log || opt_update_log || opt_slow_log || opt_bin_log) @@ -3320,12 +3310,13 @@ struct my_option my_long_options[] = "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"tmpdir", 't', "Path for temporary files", (gptr*) &opt_mysql_tmpdir, + {"tmpdir", 't', + "Path for temporary files. Several paths may be specified, separated by a colon (:), in this case they are used in a round-robin fashion.", + (gptr*) &opt_mysql_tmpdir, (gptr*) &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"transaction-isolation", OPT_TX_ISOLATION, "Default transaction isolation level", 0, 0, 0, GET_NO_ARG, REQUIRED_ARG, 0, - 0, 0, 0, - 0, 0}, + 0, 0, 0, 0, 0}, {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running", (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -4498,9 +4489,7 @@ static void fix_paths(void) charsets_dir=mysql_charsets_dir; } - char *end=convert_dirname(buff, opt_mysql_tmpdir, NullS); - if (!(mysql_tmpdir= my_memdup((byte*) buff,(uint) (end-buff)+1, - MYF(MY_FAE)))) + if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) exit(1); if (!slave_load_tmpdir) { diff --git a/sql/set_var.cc b/sql/set_var.cc index b221a3f98ff320cefbf87b17f522ac5391e1f9ed..72579664a3eef12785d288cadf3b59a18441657d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -541,7 +541,7 @@ struct show_var_st init_vars[]= { {"timezone", time_zone, SHOW_CHAR}, #endif {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS}, - {"tmpdir", (char*) &mysql_tmpdir, SHOW_CHAR_PTR}, + {"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR}, {"version", server_version, SHOW_CHAR}, {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS}, {NullS, NullS, SHOW_LONG} diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 78774b376b1b5cfd303c68d2179ac1b5e396834d..46afddf09672d81081ba547fcb3caebd4aad3ddd 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2286,30 +2286,32 @@ fill_record(Field **ptr,List<Item> &values) static void mysql_rm_tmp_tables(void) { - uint idx; - char filePath[FN_REFLEN]; + uint i, idx; + char filePath[FN_REFLEN], *tmpdir; MY_DIR *dirp; FILEINFO *file; DBUG_ENTER("mysql_rm_tmp_tables"); + for (i=0; i<=mysql_tmpdir_list.max; i++) + { + tmpdir=mysql_tmpdir_list.list[i]; /* See if the directory exists */ - if (!(dirp = my_dir(mysql_tmpdir,MYF(MY_WME | MY_DONT_SORT)))) - DBUG_VOID_RETURN; /* purecov: inspected */ + if (!(dirp = my_dir(tmpdir,MYF(MY_WME | MY_DONT_SORT)))) + continue; - /* - ** Remove all SQLxxx tables from directory - */ + /* Remove all SQLxxx tables from directory */ for (idx=2 ; idx < (uint) dirp->number_off_files ; idx++) { file=dirp->dir_entry+idx; if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length)) { - sprintf(filePath,"%s%s",mysql_tmpdir,file->name); /* purecov: inspected */ - VOID(my_delete(filePath,MYF(MY_WME))); /* purecov: inspected */ + sprintf(filePath,"%s%s",tmpdir,file->name); + VOID(my_delete(filePath,MYF(MY_WME))); } } my_dirend(dirp); + } DBUG_VOID_RETURN; }