mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +01:00
Port r87 from branches/5.0:
Work around Bug #12071: Do not call os_file_create_tmpfile() at runtime. Instead, create all tempfiles at startup and guard access to them with mutexes.
This commit is contained in:
parent
213381805c
commit
389c33b746
6 changed files with 118 additions and 77 deletions
|
@ -5768,6 +5768,7 @@ ha_innobase::update_table_comment(
|
|||
uint length = (uint) strlen(comment);
|
||||
char* str;
|
||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
||||
long flen;
|
||||
|
||||
/* We do not know if MySQL can call this function before calling
|
||||
external_lock(). To be safe, update the thd of the current table
|
||||
|
@ -5787,43 +5788,43 @@ ha_innobase::update_table_comment(
|
|||
trx_search_latch_release_if_reserved(prebuilt->trx);
|
||||
str = NULL;
|
||||
|
||||
if (FILE* file = os_file_create_tmpfile()) {
|
||||
long flen;
|
||||
/* output the data to a temporary file */
|
||||
|
||||
/* output the data to a temporary file */
|
||||
fprintf(file, "InnoDB free: %lu kB",
|
||||
mutex_enter_noninline(&srv_dict_tmpfile_mutex);
|
||||
rewind(srv_dict_tmpfile);
|
||||
|
||||
fprintf(srv_dict_tmpfile, "InnoDB free: %lu kB",
|
||||
(ulong) fsp_get_available_space_in_free_extents(
|
||||
prebuilt->table->space));
|
||||
|
||||
dict_print_info_on_foreign_keys(FALSE, file,
|
||||
dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile,
|
||||
prebuilt->trx, prebuilt->table);
|
||||
flen = ftell(file);
|
||||
if (flen < 0) {
|
||||
flen = 0;
|
||||
} else if (length + flen + 3 > 64000) {
|
||||
flen = 64000 - 3 - length;
|
||||
}
|
||||
|
||||
/* allocate buffer for the full string, and
|
||||
read the contents of the temporary file */
|
||||
|
||||
str = my_malloc(length + flen + 3, MYF(0));
|
||||
|
||||
if (str) {
|
||||
char* pos = str + length;
|
||||
if (length) {
|
||||
memcpy(str, comment, length);
|
||||
*pos++ = ';';
|
||||
*pos++ = ' ';
|
||||
}
|
||||
rewind(file);
|
||||
flen = (uint) fread(pos, 1, flen, file);
|
||||
pos[flen] = 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
flen = ftell(srv_dict_tmpfile);
|
||||
if (flen < 0) {
|
||||
flen = 0;
|
||||
} else if (length + flen + 3 > 64000) {
|
||||
flen = 64000 - 3 - length;
|
||||
}
|
||||
|
||||
/* allocate buffer for the full string, and
|
||||
read the contents of the temporary file */
|
||||
|
||||
str = my_malloc(length + flen + 3, MYF(0));
|
||||
|
||||
if (str) {
|
||||
char* pos = str + length;
|
||||
if (length) {
|
||||
memcpy(str, comment, length);
|
||||
*pos++ = ';';
|
||||
*pos++ = ' ';
|
||||
}
|
||||
rewind(srv_dict_tmpfile);
|
||||
flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile);
|
||||
pos[flen] = 0;
|
||||
}
|
||||
|
||||
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
|
||||
|
||||
prebuilt->trx->op_info = (char*)"";
|
||||
|
||||
return(str ? str : (char*) comment);
|
||||
|
@ -5841,6 +5842,7 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||
{
|
||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
||||
char* str = 0;
|
||||
long flen;
|
||||
|
||||
ut_a(prebuilt != NULL);
|
||||
|
||||
|
@ -5850,47 +5852,42 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||
|
||||
update_thd(current_thd);
|
||||
|
||||
if (FILE* file = os_file_create_tmpfile()) {
|
||||
long flen;
|
||||
prebuilt->trx->op_info = (char*)"getting info on foreign keys";
|
||||
|
||||
prebuilt->trx->op_info = (char*)"getting info on foreign keys";
|
||||
/* In case MySQL calls this in the middle of a SELECT query,
|
||||
release possible adaptive hash latch to avoid
|
||||
deadlocks of threads */
|
||||
|
||||
/* In case MySQL calls this in the middle of a SELECT query,
|
||||
release possible adaptive hash latch to avoid
|
||||
deadlocks of threads */
|
||||
trx_search_latch_release_if_reserved(prebuilt->trx);
|
||||
|
||||
trx_search_latch_release_if_reserved(prebuilt->trx);
|
||||
mutex_enter_noninline(&srv_dict_tmpfile_mutex);
|
||||
rewind(srv_dict_tmpfile);
|
||||
|
||||
/* output the data to a temporary file */
|
||||
dict_print_info_on_foreign_keys(TRUE, file,
|
||||
/* output the data to a temporary file */
|
||||
dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile,
|
||||
prebuilt->trx, prebuilt->table);
|
||||
prebuilt->trx->op_info = (char*)"";
|
||||
prebuilt->trx->op_info = (char*)"";
|
||||
|
||||
flen = ftell(file);
|
||||
if (flen < 0) {
|
||||
flen = 0;
|
||||
} else if (flen > 64000 - 1) {
|
||||
flen = 64000 - 1;
|
||||
}
|
||||
|
||||
/* allocate buffer for the string, and
|
||||
read the contents of the temporary file */
|
||||
|
||||
str = my_malloc(flen + 1, MYF(0));
|
||||
|
||||
if (str) {
|
||||
rewind(file);
|
||||
flen = (uint) fread(str, 1, flen, file);
|
||||
str[flen] = 0;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
} else {
|
||||
/* unable to create temporary file */
|
||||
str = my_strdup(
|
||||
"/* Error: cannot display foreign key constraints */", MYF(0));
|
||||
flen = ftell(srv_dict_tmpfile);
|
||||
if (flen < 0) {
|
||||
flen = 0;
|
||||
} else if (flen > 64000 - 1) {
|
||||
flen = 64000 - 1;
|
||||
}
|
||||
|
||||
/* allocate buffer for the string, and
|
||||
read the contents of the temporary file */
|
||||
|
||||
str = my_malloc(flen + 1, MYF(0));
|
||||
|
||||
if (str) {
|
||||
rewind(srv_dict_tmpfile);
|
||||
flen = (uint) fread(str, 1, flen, srv_dict_tmpfile);
|
||||
str[flen] = 0;
|
||||
}
|
||||
|
||||
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
|
||||
|
||||
return(str);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,7 +187,7 @@ Creates a temporary file. */
|
|||
FILE*
|
||||
os_file_create_tmpfile(void);
|
||||
/*========================*/
|
||||
/* out: temporary file handle (never NULL) */
|
||||
/* out: temporary file handle, or NULL on error */
|
||||
/***************************************************************************
|
||||
The os_file_opendir() function opens a directory stream corresponding to the
|
||||
directory named by the dirname argument. The directory stream is positioned
|
||||
|
|
|
@ -34,6 +34,18 @@ extern ibool srv_lower_case_table_names;
|
|||
extern mutex_t srv_monitor_file_mutex;
|
||||
/* Temporary file for innodb monitor output */
|
||||
extern FILE* srv_monitor_file;
|
||||
/* Mutex for locking srv_dict_tmpfile.
|
||||
This mutex has a very high rank; threads reserving it should not
|
||||
be holding any InnoDB latches. */
|
||||
extern mutex_t srv_dict_tmpfile_mutex;
|
||||
/* Temporary file for output from the data dictionary */
|
||||
extern FILE* srv_dict_tmpfile;
|
||||
/* Mutex for locking srv_misc_tmpfile.
|
||||
This mutex has a very low rank; threads reserving it should not
|
||||
acquire any further latches or sleep before releasing this one. */
|
||||
extern mutex_t srv_misc_tmpfile_mutex;
|
||||
/* Temporary file for miscellanous diagnostic output */
|
||||
extern FILE* srv_misc_tmpfile;
|
||||
|
||||
/* Server parameters which are read from the initfile */
|
||||
|
||||
|
|
|
@ -588,20 +588,15 @@ row_ins_set_detailed(
|
|||
trx_t* trx, /* in: transaction */
|
||||
dict_foreign_t* foreign) /* in: foreign key constraint */
|
||||
{
|
||||
|
||||
FILE* tf = os_file_create_tmpfile();
|
||||
mutex_enter(&srv_misc_tmpfile_mutex);
|
||||
rewind(srv_misc_tmpfile);
|
||||
|
||||
if (tf) {
|
||||
ut_print_name(tf, trx, foreign->foreign_table_name);
|
||||
dict_print_info_on_foreign_key_in_create_format(tf, trx,
|
||||
foreign, FALSE);
|
||||
ut_print_name(srv_misc_tmpfile, trx, foreign->foreign_table_name);
|
||||
dict_print_info_on_foreign_key_in_create_format(srv_misc_tmpfile,
|
||||
trx, foreign, FALSE);
|
||||
trx_set_detailed_error_from_file(trx, srv_misc_tmpfile);
|
||||
|
||||
trx_set_detailed_error_from_file(trx, tf);
|
||||
|
||||
fclose(tf);
|
||||
} else {
|
||||
trx_set_detailed_error(trx, "temp file creation failed");
|
||||
}
|
||||
mutex_exit(&srv_misc_tmpfile_mutex);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -397,6 +397,18 @@ mutex_t srv_innodb_monitor_mutex;
|
|||
mutex_t srv_monitor_file_mutex;
|
||||
/* Temporary file for innodb monitor output */
|
||||
FILE* srv_monitor_file;
|
||||
/* Mutex for locking srv_dict_tmpfile.
|
||||
This mutex has a very high rank; threads reserving it should not
|
||||
be holding any InnoDB latches. */
|
||||
mutex_t srv_dict_tmpfile_mutex;
|
||||
/* Temporary file for output from the data dictionary */
|
||||
FILE* srv_dict_tmpfile;
|
||||
/* Mutex for locking srv_misc_tmpfile.
|
||||
This mutex has a very low rank; threads reserving it should not
|
||||
acquire any further latches or sleep before releasing this one. */
|
||||
mutex_t srv_misc_tmpfile_mutex;
|
||||
/* Temporary file for miscellanous diagnostic output */
|
||||
FILE* srv_misc_tmpfile;
|
||||
|
||||
ulint srv_main_thread_process_no = 0;
|
||||
ulint srv_main_thread_id = 0;
|
||||
|
|
|
@ -1180,6 +1180,20 @@ NetWare. */
|
|||
}
|
||||
}
|
||||
|
||||
mutex_create(&srv_dict_tmpfile_mutex);
|
||||
mutex_set_level(&srv_dict_tmpfile_mutex, SYNC_DICT_OPERATION);
|
||||
srv_dict_tmpfile = os_file_create_tmpfile();
|
||||
if (!srv_dict_tmpfile) {
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
mutex_create(&srv_misc_tmpfile_mutex);
|
||||
mutex_set_level(&srv_misc_tmpfile_mutex, SYNC_ANY_LATCH);
|
||||
srv_misc_tmpfile = os_file_create_tmpfile();
|
||||
if (!srv_misc_tmpfile) {
|
||||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
/* Restrict the maximum number of file i/o threads */
|
||||
if (srv_n_file_io_threads > SRV_MAX_N_IO_THREADS) {
|
||||
|
||||
|
@ -1822,8 +1836,19 @@ innobase_shutdown_for_mysql(void)
|
|||
mem_free(srv_monitor_file_name);
|
||||
}
|
||||
}
|
||||
|
||||
if (srv_dict_tmpfile) {
|
||||
fclose(srv_dict_tmpfile);
|
||||
srv_dict_tmpfile = 0;
|
||||
}
|
||||
|
||||
if (srv_misc_tmpfile) {
|
||||
fclose(srv_misc_tmpfile);
|
||||
srv_misc_tmpfile = 0;
|
||||
}
|
||||
|
||||
mutex_free(&srv_monitor_file_mutex);
|
||||
mutex_free(&srv_dict_tmpfile_mutex);
|
||||
mutex_free(&srv_misc_tmpfile_mutex);
|
||||
|
||||
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
|
||||
them */
|
||||
|
|
Loading…
Reference in a new issue