From 3cb09c98176c794328e209996a26f13f6bc2010e Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Fri, 6 Aug 2004 15:55:50 +0300 Subject: [PATCH 1/3] InnoDB: Add option for disabling innodb_status. files. InnoDB: Implement tmpfile() differently on Windows (Bug #3998) --- innobase/dict/dict0dict.c | 1 + innobase/include/os0file.h | 2 +- innobase/include/srv0srv.h | 2 ++ innobase/lock/lock0lock.c | 1 + innobase/os/os0file.c | 25 +++++++++++++++++++++---- innobase/srv/srv0srv.c | 3 +++ innobase/srv/srv0start.c | 34 ++++++++++++++++++++++------------ sql/ha_innodb.cc | 6 ++++-- sql/ha_innodb.h | 3 ++- sql/mysqld.cc | 5 +++++ 10 files changed, 62 insertions(+), 20 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index e2c2043db74..ccaa5720c20 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -643,6 +643,7 @@ dict_init(void) rw_lock_set_level(&dict_operation_lock, SYNC_DICT_OPERATION); dict_foreign_err_file = os_file_create_tmpfile(); + ut_a(dict_foreign_err_file); mutex_create(&dict_foreign_err_mutex); mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH); } diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 43741f79855..4a8b9623eeb 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -139,7 +139,7 @@ Creates a temporary file. In case of error, causes abnormal termination. */ FILE* os_file_create_tmpfile(void); /*========================*/ - /* out: temporary file handle (never NULL) */ + /* out: temporary file handle, or NULL */ /******************************************************************** A simple function to open or create a file. */ diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 0be13528fd7..57ca1f84f26 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -92,6 +92,8 @@ extern lint srv_conc_n_threads; extern ibool srv_fast_shutdown; +extern ibool srv_innodb_status; + extern ibool srv_use_doublewrite_buf; extern ibool srv_set_thread_priorities; diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 68dd2aa18c1..1c9b1263130 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -509,6 +509,7 @@ lock_sys_create( /* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */ lock_latest_err_file = os_file_create_tmpfile(); + ut_a(lock_latest_err_file); } /************************************************************************* diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index a70333ba6ab..c33066b1476 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -377,16 +377,33 @@ Creates a temporary file. In case of error, causes abnormal termination. */ FILE* os_file_create_tmpfile(void) /*========================*/ - /* out: temporary file handle (never NULL) */ + /* out: temporary file handle, or NULL */ { - FILE* file = tmpfile(); + FILE* file; +#ifdef __WIN__ + int fd = -1; + char* name; + file = NULL; + if (NULL == (name = tempnam(fil_path_to_mysql_datadir, "ib")) + || -1 == (fd = _open(name, _O_CREAT | _O_EXCL | _O_RDWR + | _O_SEQUENTIAL | _O_SHORT_LIVED | _O_TEMPORARY)) + || NULL == (file = fdopen(fd, "w+b"))) { + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Error: unable to create" + " temporary file %s\n", name ? name : "name"); + if (fd != -1) { + _close(fd); + } + } + free(name); +#else /* __WIN__ */ + file = tmpfile(); if (file == NULL) { ut_print_timestamp(stderr); fputs(" InnoDB: Error: unable to create temporary file\n", stderr); - os_file_handle_error(NULL, "tmpfile"); - ut_error; } +#endif /* __WIN__ */ return(file); } diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 174214f9efe..d799ada1e20 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -223,6 +223,9 @@ merge to completion before shutdown */ ibool srv_fast_shutdown = FALSE; +/* Generate a innodb_status. file */ +ibool srv_innodb_status = FALSE; + ibool srv_use_doublewrite_buf = TRUE; ibool srv_set_thread_priorities = TRUE; diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 3223854652f..30c9982068e 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1023,16 +1023,24 @@ NetWare. */ mutex_create(&srv_monitor_file_mutex); mutex_set_level(&srv_monitor_file_mutex, SYNC_NO_ORDER_CHECK); - srv_monitor_file_name = mem_alloc( - strlen(fil_path_to_mysql_datadir) + - 20 + sizeof "/innodb_status."); - sprintf(srv_monitor_file_name, "%s/innodb_status.%lu", - fil_path_to_mysql_datadir, os_proc_get_number()); - srv_monitor_file = fopen(srv_monitor_file_name, "w+"); - if (!srv_monitor_file) { - fprintf(stderr, "InnoDB: unable to create %s: %s\n", - srv_monitor_file_name, strerror(errno)); - return(DB_ERROR); + if (srv_innodb_status) { + srv_monitor_file_name = mem_alloc( + strlen(fil_path_to_mysql_datadir) + + 20 + sizeof "/innodb_status."); + sprintf(srv_monitor_file_name, "%s/innodb_status.%lu", + fil_path_to_mysql_datadir, os_proc_get_number()); + srv_monitor_file = fopen(srv_monitor_file_name, "w+"); + if (!srv_monitor_file) { + fprintf(stderr, "InnoDB: unable to create %s: %s\n", + srv_monitor_file_name, strerror(errno)); + return(DB_ERROR); + } + } else { + srv_monitor_file_name = NULL; + srv_monitor_file = os_file_create_tmpfile(); + if (!srv_monitor_file) { + return(DB_ERROR); + } } /* Restrict the maximum number of file i/o threads */ @@ -1527,8 +1535,10 @@ innobase_shutdown_for_mysql(void) if (srv_monitor_file) { fclose(srv_monitor_file); srv_monitor_file = 0; - unlink(srv_monitor_file_name); - mem_free(srv_monitor_file_name); + if (srv_monitor_file_name) { + unlink(srv_monitor_file_name); + mem_free(srv_monitor_file_name); + } } mutex_free(&srv_monitor_file_mutex); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 21dd7f748c2..6319c1494d3 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -103,6 +103,7 @@ uint innobase_flush_log_at_trx_commit = 1; my_bool innobase_log_archive = FALSE; my_bool innobase_use_native_aio = FALSE; my_bool innobase_fast_shutdown = TRUE; +my_bool innobase_create_status_file = FALSE; static char *internal_innobase_data_file_path = NULL; @@ -861,6 +862,7 @@ innobase_init(void) srv_force_recovery = (ulint) innobase_force_recovery; srv_fast_shutdown = (ibool) innobase_fast_shutdown; + srv_innodb_status = (ibool) innobase_create_status_file; srv_print_verbose_log = mysql_embedded ? 0 : 1; @@ -4270,7 +4272,7 @@ ha_innobase::update_table_comment( trx_search_latch_release_if_reserved(prebuilt->trx); str = NULL; - if (FILE* file = tmpfile()) { + if (FILE* file = os_file_create_tmpfile()) { long flen; /* output the data to a temporary file */ @@ -4330,7 +4332,7 @@ ha_innobase::get_foreign_key_create_info(void) update_thd(current_thd); - if (FILE* file = tmpfile()) { + if (FILE* file = os_file_create_tmpfile()) { long flen; prebuilt->trx->op_info = (char*)"getting info on foreign keys"; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 384b3dec949..5736f70c65c 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -203,7 +203,8 @@ extern char *innobase_log_group_home_dir, *innobase_log_arch_dir; extern char *innobase_unix_file_flush_method; /* The following variables have to be my_bool for SHOW VARIABLES to work */ extern my_bool innobase_log_archive, - innobase_use_native_aio, innobase_fast_shutdown; + innobase_use_native_aio, innobase_fast_shutdown, + innobase_create_status_file; extern "C" { extern ulong srv_max_buf_pool_modified_pct; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 55f58e9970e..3f7c187ccdd 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3458,6 +3458,7 @@ enum options_mysqld { OPT_INNODB_LOCK_WAIT_TIMEOUT, OPT_INNODB_THREAD_CONCURRENCY, OPT_INNODB_FORCE_RECOVERY, + OPT_INNODB_STATUS_FILE, OPT_INNODB_MAX_DIRTY_PAGES_PCT, OPT_BDB_CACHE_SIZE, OPT_BDB_LOG_BUFFER_SIZE, @@ -3625,6 +3626,10 @@ struct my_option my_long_options[] = {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN, "Speeds up server shutdown process", (gptr*) &innobase_fast_shutdown, (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"innodb_status_file", OPT_INNODB_STATUS_FILE, + "Enable SHOW INNODB STATUS output in the innodb_status. file", + (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT, "Percentage of dirty pages allowed in bufferpool", (gptr*) &srv_max_buf_pool_modified_pct, (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, From cd6292d21952e7087b2271801a5207dc63d20e9a Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 10 Aug 2004 14:17:32 +0300 Subject: [PATCH 2/3] InnoDB: Use create_temp_file() when available --- innobase/include/os0file.h | 4 +-- innobase/os/os0file.c | 72 +++++++++++++++++++++++++++----------- sql/ha_innodb.cc | 24 +++++++++++++ 3 files changed, 78 insertions(+), 22 deletions(-) diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 4a8b9623eeb..9727c2b8243 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -134,12 +134,12 @@ void os_io_init_simple(void); /*===================*/ /*************************************************************************** -Creates a temporary file. In case of error, causes abnormal termination. */ +Creates a temporary file. */ FILE* os_file_create_tmpfile(void); /*========================*/ - /* out: temporary file handle, or NULL */ + /* out: temporary file handle, or NULL on error */ /******************************************************************** A simple function to open or create a file. */ diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index c33066b1476..63a86d8ab68 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -371,39 +371,71 @@ os_io_init_simple(void) } } +#ifndef UNIV_HOTBACKUP +/************************************************************************* +Creates a temporary file. This function is defined in ha_innodb.cc. */ + +int +innobase_mysql_tmpfile(void); +/*========================*/ + /* out: temporary file descriptor, or < 0 on error */ +#endif /* !UNIV_HOTBACKUP */ + /*************************************************************************** -Creates a temporary file. In case of error, causes abnormal termination. */ +Creates a temporary file. */ FILE* os_file_create_tmpfile(void) /*========================*/ - /* out: temporary file handle, or NULL */ + /* out: temporary file handle, or NULL on error */ { - FILE* file; -#ifdef __WIN__ + FILE* file = NULL; int fd = -1; - char* name; - file = NULL; - if (NULL == (name = tempnam(fil_path_to_mysql_datadir, "ib")) - || -1 == (fd = _open(name, _O_CREAT | _O_EXCL | _O_RDWR - | _O_SEQUENTIAL | _O_SHORT_LIVED | _O_TEMPORARY)) - || NULL == (file = fdopen(fd, "w+b"))) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Error: unable to create" - " temporary file %s\n", name ? name : "name"); - if (fd != -1) { - _close(fd); +#ifdef UNIV_HOTBACKUP + int tries; + for (tries = 10; tries--; ) { + char* name = tempnam(fil_path_to_mysql_datadir, "ib"); + if (!name) { + break; } + + fd = open(name, +# ifdef __WIN__ + O_SEQUENTIAL | O_SHORT_LIVED | O_TEMPORARY | +# endif /* __WIN__ */ + O_CREAT | O_EXCL | O_RDWR, + S_IREAD | S_IWRITE); + if (fd >= 0) { +# ifndef __WIN__ + unlink(name); +# endif /* !__WIN__ */ + free(name); + break; + } + + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Warning: " + "unable to create temporary file %s, retrying\n", + name); + free(name); } - free(name); -#else /* __WIN__ */ - file = tmpfile(); - if (file == NULL) { +#else /* UNIV_HOTBACKUP */ + fd = innobase_mysql_tmpfile(); +#endif /* UNIV_HOTBACKUP */ + + if (fd >= 0) { + file = fdopen(fd, "w+b"); + } + + if (!file) { ut_print_timestamp(stderr); fputs(" InnoDB: Error: unable to create temporary file\n", stderr); + if (fd >= 0) { + close(fd); + } } -#endif /* __WIN__ */ + return(file); } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 6319c1494d3..f233dd5a5c5 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -406,6 +406,30 @@ innobase_mysql_print_thd( putc('\n', f); } +/************************************************************************* +Creates a temporary file. */ +extern "C" +int +innobase_mysql_tmpfile(void) +/*========================*/ + /* out: temporary file descriptor, or < 0 on error */ +{ + char filename[FN_REFLEN]; + File fd = create_temp_file(filename, NullS, "ib", +#ifdef __WIN__ + O_BINARY | O_TRUNC | O_SEQUENTIAL | + O_TEMPORARY | O_SHORT_LIVED | +#endif /* __WIN__ */ + O_CREAT | O_EXCL | O_RDWR, + MYF(MY_WME)); +#ifndef __WIN__ + if (fd >= 0) { + unlink(filename); + } +#endif /* !__WIN__ */ + return(fd); +} + /************************************************************************* Gets the InnoDB transaction handle for a MySQL handler object, creates an InnoDB transaction struct if the corresponding MySQL thread struct still From 61c509fbd7def7cbc091154f7c65c24dc6842ece Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 10 Aug 2004 16:11:34 +0300 Subject: [PATCH 3/3] os0file.c: os_file_create_tmpfile(): display errno in case of failure --- innobase/os/os0file.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 63a86d8ab68..56f01568ead 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -429,8 +429,9 @@ os_file_create_tmpfile(void) if (!file) { ut_print_timestamp(stderr); - fputs(" InnoDB: Error: unable to create temporary file\n", - stderr); + fprintf(stderr, + " InnoDB: Error: unable to create temporary file;" + " errno: %d\n", errno); if (fd >= 0) { close(fd); }