mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Fix BUG#12071: "Windows hang:'Opening tables' or 'Waiting for
table' lockup". Changes from the innodb-5.0-ss92 snapshot. Do not call os_file_create_tmpfile() at runtime. Instead, create all tempfiles at startup and guard access to them with mutexes. innobase/btr/btr0sea.c: Changes from the innodb-5.0ss92 snapshot. innobase/include/buf0buf.h: Changes from the innodb-5.0ss92 snapshot. innobase/include/os0file.h: Changes from the innodb-5.0ss92 snapshot. innobase/include/srv0srv.h: Changes from the innodb-5.0ss92 snapshot. innobase/row/row0ins.c: Changes from the innodb-5.0ss92 snapshot. innobase/srv/srv0srv.c: Changes from the innodb-5.0ss92 snapshot. innobase/srv/srv0start.c: Changes from the innodb-5.0ss92 snapshot. mysql-test/r/innodb.result: Changes from the innodb-5.0ss92 snapshot. mysql-test/t/innodb.test: Changes from the innodb-5.0ss92 snapshot. sql/ha_innodb.cc: Changes from the innodb-5.0ss92 snapshot.
This commit is contained in:
@@ -889,7 +889,8 @@ Drops a page hash index. */
|
|||||||
void
|
void
|
||||||
btr_search_drop_page_hash_index(
|
btr_search_drop_page_hash_index(
|
||||||
/*============================*/
|
/*============================*/
|
||||||
page_t* page) /* in: index page, s- or x-latched */
|
page_t* page) /* in: index page, s- or x-latched, or an index page
|
||||||
|
for which we know that block->buf_fix_count == 0 */
|
||||||
{
|
{
|
||||||
hash_table_t* table;
|
hash_table_t* table;
|
||||||
buf_block_t* block;
|
buf_block_t* block;
|
||||||
|
@@ -831,7 +831,13 @@ struct buf_block_struct{
|
|||||||
records with the same prefix should be
|
records with the same prefix should be
|
||||||
indexed in the hash index */
|
indexed in the hash index */
|
||||||
|
|
||||||
/* The following 6 fields are protected by btr_search_latch: */
|
/* These 6 fields may only be modified when we have
|
||||||
|
an x-latch on btr_search_latch AND
|
||||||
|
a) we are holding an s-latch or x-latch on block->lock or
|
||||||
|
b) we know that block->buf_fix_count == 0.
|
||||||
|
|
||||||
|
An exception to this is when we init or create a page
|
||||||
|
in the buffer pool in buf0buf.c. */
|
||||||
|
|
||||||
ibool is_hashed; /* TRUE if hash index has already been
|
ibool is_hashed; /* TRUE if hash index has already been
|
||||||
built on this page; note that it does
|
built on this page; note that it does
|
||||||
@@ -849,11 +855,7 @@ struct buf_block_struct{
|
|||||||
BTR_SEARCH_RIGHT_SIDE in hash
|
BTR_SEARCH_RIGHT_SIDE in hash
|
||||||
indexing */
|
indexing */
|
||||||
dict_index_t* index; /* Index for which the adaptive
|
dict_index_t* index; /* Index for which the adaptive
|
||||||
hash index has been created.
|
hash index has been created. */
|
||||||
This field may only be modified
|
|
||||||
while holding an s-latch or x-latch
|
|
||||||
on block->lock and an x-latch on
|
|
||||||
btr_search_latch. */
|
|
||||||
/* 6. Debug fields */
|
/* 6. Debug fields */
|
||||||
#ifdef UNIV_SYNC_DEBUG
|
#ifdef UNIV_SYNC_DEBUG
|
||||||
rw_lock_t debug_latch; /* in the debug version, each thread
|
rw_lock_t debug_latch; /* in the debug version, each thread
|
||||||
|
@@ -187,7 +187,7 @@ Creates a temporary file. */
|
|||||||
FILE*
|
FILE*
|
||||||
os_file_create_tmpfile(void);
|
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
|
The os_file_opendir() function opens a directory stream corresponding to the
|
||||||
directory named by the dirname argument. The directory stream is positioned
|
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;
|
extern mutex_t srv_monitor_file_mutex;
|
||||||
/* Temporary file for innodb monitor output */
|
/* Temporary file for innodb monitor output */
|
||||||
extern FILE* srv_monitor_file;
|
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 */
|
/* Server parameters which are read from the initfile */
|
||||||
|
|
||||||
|
@@ -588,20 +588,21 @@ row_ins_set_detailed(
|
|||||||
trx_t* trx, /* in: transaction */
|
trx_t* trx, /* in: transaction */
|
||||||
dict_foreign_t* foreign) /* in: foreign key constraint */
|
dict_foreign_t* foreign) /* in: foreign key constraint */
|
||||||
{
|
{
|
||||||
|
mutex_enter(&srv_misc_tmpfile_mutex);
|
||||||
|
rewind(srv_misc_tmpfile);
|
||||||
|
|
||||||
FILE* tf = os_file_create_tmpfile();
|
if (os_file_set_eof(srv_misc_tmpfile)) {
|
||||||
|
ut_print_name(srv_misc_tmpfile, trx,
|
||||||
if (tf) {
|
foreign->foreign_table_name);
|
||||||
ut_print_name(tf, trx, foreign->foreign_table_name);
|
dict_print_info_on_foreign_key_in_create_format(
|
||||||
dict_print_info_on_foreign_key_in_create_format(tf, trx,
|
srv_misc_tmpfile,
|
||||||
foreign, FALSE);
|
trx, foreign, FALSE);
|
||||||
|
trx_set_detailed_error_from_file(trx, srv_misc_tmpfile);
|
||||||
trx_set_detailed_error_from_file(trx, tf);
|
|
||||||
|
|
||||||
fclose(tf);
|
|
||||||
} else {
|
} else {
|
||||||
trx_set_detailed_error(trx, "temp file creation failed");
|
trx_set_detailed_error(trx, "temp file operation failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_exit(&srv_misc_tmpfile_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
@@ -709,7 +710,7 @@ row_ins_foreign_report_add_err(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rec) {
|
if (rec) {
|
||||||
rec_print(ef, rec, foreign->foreign_index);
|
rec_print(ef, rec, foreign->referenced_index);
|
||||||
}
|
}
|
||||||
putc('\n', ef);
|
putc('\n', ef);
|
||||||
|
|
||||||
|
@@ -397,6 +397,18 @@ mutex_t srv_innodb_monitor_mutex;
|
|||||||
mutex_t srv_monitor_file_mutex;
|
mutex_t srv_monitor_file_mutex;
|
||||||
/* Temporary file for innodb monitor output */
|
/* Temporary file for innodb monitor output */
|
||||||
FILE* srv_monitor_file;
|
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_process_no = 0;
|
||||||
ulint srv_main_thread_id = 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 */
|
/* Restrict the maximum number of file i/o threads */
|
||||||
if (srv_n_file_io_threads > SRV_MAX_N_IO_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);
|
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_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
|
/* 3. Free all InnoDB's own mutexes and the os_fast_mutexes inside
|
||||||
them */
|
them */
|
||||||
|
@@ -2846,4 +2846,33 @@ d varchar(255) character set utf8,
|
|||||||
e varchar(255) character set utf8,
|
e varchar(255) character set utf8,
|
||||||
key (a,b,c,d,e)) engine=innodb;
|
key (a,b,c,d,e)) engine=innodb;
|
||||||
ERROR 42000: Specified key was too long; max key length is 3072 bytes
|
ERROR 42000: Specified key was too long; max key length is 3072 bytes
|
||||||
|
create table t1(a int primary key) row_format=redundant engine=innodb;
|
||||||
|
create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
|
||||||
|
create table t3(a int primary key) row_format=compact engine=innodb;
|
||||||
|
create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
|
||||||
|
insert into t1 values(1);
|
||||||
|
insert into t3 values(1);
|
||||||
|
insert into t2 values(2);
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
|
||||||
|
insert into t4 values(2);
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
|
||||||
|
insert into t2 values(1);
|
||||||
|
insert into t4 values(1);
|
||||||
|
update t1 set a=2;
|
||||||
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
|
||||||
|
update t2 set a=2;
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
|
||||||
|
update t3 set a=2;
|
||||||
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
|
||||||
|
update t4 set a=2;
|
||||||
|
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
|
||||||
|
truncate t1;
|
||||||
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
|
||||||
|
truncate t3;
|
||||||
|
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test/t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
|
||||||
|
truncate t2;
|
||||||
|
truncate t4;
|
||||||
|
truncate t1;
|
||||||
|
truncate t3;
|
||||||
|
drop table t4,t3,t2,t1;
|
||||||
End of 5.0 tests
|
End of 5.0 tests
|
||||||
|
@@ -1833,4 +1833,38 @@ create table t1 (a varchar(255) character set utf8,
|
|||||||
e varchar(255) character set utf8,
|
e varchar(255) character set utf8,
|
||||||
key (a,b,c,d,e)) engine=innodb;
|
key (a,b,c,d,e)) engine=innodb;
|
||||||
|
|
||||||
|
# test that foreign key errors are reported correctly (Bug #15550)
|
||||||
|
|
||||||
|
create table t1(a int primary key) row_format=redundant engine=innodb;
|
||||||
|
create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
|
||||||
|
create table t3(a int primary key) row_format=compact engine=innodb;
|
||||||
|
create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
|
||||||
|
|
||||||
|
insert into t1 values(1);
|
||||||
|
insert into t3 values(1);
|
||||||
|
-- error 1452
|
||||||
|
insert into t2 values(2);
|
||||||
|
-- error 1452
|
||||||
|
insert into t4 values(2);
|
||||||
|
insert into t2 values(1);
|
||||||
|
insert into t4 values(1);
|
||||||
|
-- error 1451
|
||||||
|
update t1 set a=2;
|
||||||
|
-- error 1452
|
||||||
|
update t2 set a=2;
|
||||||
|
-- error 1451
|
||||||
|
update t3 set a=2;
|
||||||
|
-- error 1452
|
||||||
|
update t4 set a=2;
|
||||||
|
-- error 1451
|
||||||
|
truncate t1;
|
||||||
|
-- error 1451
|
||||||
|
truncate t3;
|
||||||
|
truncate t2;
|
||||||
|
truncate t4;
|
||||||
|
truncate t1;
|
||||||
|
truncate t3;
|
||||||
|
|
||||||
|
drop table t4,t3,t2,t1;
|
||||||
|
|
||||||
--echo End of 5.0 tests
|
--echo End of 5.0 tests
|
||||||
|
@@ -5742,6 +5742,7 @@ ha_innobase::update_table_comment(
|
|||||||
uint length = (uint) strlen(comment);
|
uint length = (uint) strlen(comment);
|
||||||
char* str;
|
char* str;
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
||||||
|
long flen;
|
||||||
|
|
||||||
/* We do not know if MySQL can call this function before calling
|
/* We do not know if MySQL can call this function before calling
|
||||||
external_lock(). To be safe, update the thd of the current table
|
external_lock(). To be safe, update the thd of the current table
|
||||||
@@ -5761,17 +5762,18 @@ ha_innobase::update_table_comment(
|
|||||||
trx_search_latch_release_if_reserved(prebuilt->trx);
|
trx_search_latch_release_if_reserved(prebuilt->trx);
|
||||||
str = NULL;
|
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(
|
(ulong) fsp_get_available_space_in_free_extents(
|
||||||
prebuilt->table->space));
|
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);
|
prebuilt->trx, prebuilt->table);
|
||||||
flen = ftell(file);
|
flen = ftell(srv_dict_tmpfile);
|
||||||
if (flen < 0) {
|
if (flen < 0) {
|
||||||
flen = 0;
|
flen = 0;
|
||||||
} else if (length + flen + 3 > 64000) {
|
} else if (length + flen + 3 > 64000) {
|
||||||
@@ -5790,13 +5792,12 @@ ha_innobase::update_table_comment(
|
|||||||
*pos++ = ';';
|
*pos++ = ';';
|
||||||
*pos++ = ' ';
|
*pos++ = ' ';
|
||||||
}
|
}
|
||||||
rewind(file);
|
rewind(srv_dict_tmpfile);
|
||||||
flen = (uint) fread(pos, 1, flen, file);
|
flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile);
|
||||||
pos[flen] = 0;
|
pos[flen] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
|
||||||
}
|
|
||||||
|
|
||||||
prebuilt->trx->op_info = (char*)"";
|
prebuilt->trx->op_info = (char*)"";
|
||||||
|
|
||||||
@@ -5815,6 +5816,7 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||||||
{
|
{
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
|
||||||
char* str = 0;
|
char* str = 0;
|
||||||
|
long flen;
|
||||||
|
|
||||||
ut_a(prebuilt != NULL);
|
ut_a(prebuilt != NULL);
|
||||||
|
|
||||||
@@ -5824,9 +5826,6 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||||||
|
|
||||||
update_thd(current_thd);
|
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,
|
/* In case MySQL calls this in the middle of a SELECT query,
|
||||||
@@ -5835,12 +5834,15 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||||||
|
|
||||||
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 */
|
/* output the data to a temporary file */
|
||||||
dict_print_info_on_foreign_keys(TRUE, file,
|
dict_print_info_on_foreign_keys(TRUE, srv_dict_tmpfile,
|
||||||
prebuilt->trx, prebuilt->table);
|
prebuilt->trx, prebuilt->table);
|
||||||
prebuilt->trx->op_info = (char*)"";
|
prebuilt->trx->op_info = (char*)"";
|
||||||
|
|
||||||
flen = ftell(file);
|
flen = ftell(srv_dict_tmpfile);
|
||||||
if (flen < 0) {
|
if (flen < 0) {
|
||||||
flen = 0;
|
flen = 0;
|
||||||
} else if (flen > 64000 - 1) {
|
} else if (flen > 64000 - 1) {
|
||||||
@@ -5853,17 +5855,12 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||||||
str = my_malloc(flen + 1, MYF(0));
|
str = my_malloc(flen + 1, MYF(0));
|
||||||
|
|
||||||
if (str) {
|
if (str) {
|
||||||
rewind(file);
|
rewind(srv_dict_tmpfile);
|
||||||
flen = (uint) fread(str, 1, flen, file);
|
flen = (uint) fread(str, 1, flen, srv_dict_tmpfile);
|
||||||
str[flen] = 0;
|
str[flen] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
|
||||||
} else {
|
|
||||||
/* unable to create temporary file */
|
|
||||||
str = my_strdup(
|
|
||||||
"/* Error: cannot display foreign key constraints */", MYF(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
return(str);
|
return(str);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user