Commit 11073be8 authored by aivanov@mysql.com's avatar aivanov@mysql.com

Merge aivanov@bk-internal.mysql.com:/home/bk/mysql-5.0

into  mysql.com:/home/alexi/innodb-ss/mysql-5.0-ss92
parents 530e22ed 2e499986
...@@ -889,7 +889,8 @@ Drops a page hash index. */ ...@@ -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{ ...@@ -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{ ...@@ -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. */ ...@@ -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; ...@@ -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( ...@@ -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);
FILE* tf = os_file_create_tmpfile(); rewind(srv_misc_tmpfile);
if (tf) { if (os_file_set_eof(srv_misc_tmpfile)) {
ut_print_name(tf, trx, foreign->foreign_table_name); ut_print_name(srv_misc_tmpfile, trx,
dict_print_info_on_foreign_key_in_create_format(tf, trx, foreign->foreign_table_name);
foreign, FALSE); dict_print_info_on_foreign_key_in_create_format(
srv_misc_tmpfile,
trx_set_detailed_error_from_file(trx, tf); trx, foreign, FALSE);
trx_set_detailed_error_from_file(trx, srv_misc_tmpfile);
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( ...@@ -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; ...@@ -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. */ ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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( ...@@ -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,43 +5762,43 @@ ha_innobase::update_table_comment( ...@@ -5761,43 +5762,43 @@ 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()) { /* output the data to a temporary file */
long flen;
/* output the data to a temporary file */ mutex_enter_noninline(&srv_dict_tmpfile_mutex);
fprintf(file, "InnoDB free: %lu kB", 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) {
flen = 64000 - 3 - length; flen = 64000 - 3 - length;
} }
/* allocate buffer for the full string, and /* allocate buffer for the full string, and
read the contents of the temporary file */ read the contents of the temporary file */
str = my_malloc(length + flen + 3, MYF(0)); str = my_malloc(length + flen + 3, MYF(0));
if (str) { if (str) {
char* pos = str + length; char* pos = str + length;
if (length) { if (length) {
memcpy(str, comment, length); memcpy(str, comment, length);
*pos++ = ';'; *pos++ = ';';
*pos++ = ' '; *pos++ = ' ';
}
rewind(file);
flen = (uint) fread(pos, 1, flen, file);
pos[flen] = 0;
} }
rewind(srv_dict_tmpfile);
fclose(file); flen = (uint) fread(pos, 1, flen, srv_dict_tmpfile);
pos[flen] = 0;
} }
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
prebuilt->trx->op_info = (char*)""; prebuilt->trx->op_info = (char*)"";
return(str ? str : (char*) comment); return(str ? str : (char*) comment);
...@@ -5815,6 +5816,7 @@ ha_innobase::get_foreign_key_create_info(void) ...@@ -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,47 +5826,42 @@ ha_innobase::get_foreign_key_create_info(void) ...@@ -5824,47 +5826,42 @@ ha_innobase::get_foreign_key_create_info(void)
update_thd(current_thd); update_thd(current_thd);
if (FILE* file = os_file_create_tmpfile()) { prebuilt->trx->op_info = (char*)"getting info on foreign keys";
long flen;
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, trx_search_latch_release_if_reserved(prebuilt->trx);
release possible adaptive hash latch to avoid
deadlocks of threads */
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);
if (flen < 0) {
flen = 0;
} else if (flen > 64000 - 1) {
flen = 64000 - 1;
}
/* allocate buffer for the string, and flen = ftell(srv_dict_tmpfile);
read the contents of the temporary file */ if (flen < 0) {
flen = 0;
} else if (flen > 64000 - 1) {
flen = 64000 - 1;
}
str = my_malloc(flen + 1, MYF(0)); /* allocate buffer for the string, and
read the contents of the temporary file */
if (str) { str = my_malloc(flen + 1, MYF(0));
rewind(file);
flen = (uint) fread(str, 1, flen, file);
str[flen] = 0;
}
fclose(file); if (str) {
} else { rewind(srv_dict_tmpfile);
/* unable to create temporary file */ flen = (uint) fread(str, 1, flen, srv_dict_tmpfile);
str = my_strdup( str[flen] = 0;
"/* Error: cannot display foreign key constraints */", MYF(0));
} }
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
return(str); return(str);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment