Fixed two bugs with CREATE OR REPLACE and LOCK TABLES:
MDEV-6560 Assertion `! is_set() ' failed in Diagnostics_area::set_ok_status on killing CREATE OR REPLACE MDEV-6525 Assertion `table->pos_in_locked _tables == __null || table->pos_in_locked_tables->table = table' failed in mark_used_tables_as_free_for_reuse, locking problems and binlogging problems on CREATE OR REPLACE under lock. mysql-test/r/create_or_replace.result: Added test for MDEV-6560 mysql-test/t/create_or_replace.test: Added test for MDEV-6560 mysql-test/valgrind.supp: Added suppression for OpenSuse 12.3 sql/sql_base.cc: More DBUG sql/sql_class.cc: Changed that thd_sqlcom_can_generate_row_events() does not report that CREATE OR REPLACE is generating row events. This is safe as this function is only used by InnoDB/XtraDB to check if a query is generating row events as part of another transaction. As CREATE is always run as it's own transaction, this isn't a problem. This fixed MDEV-6525. sql/sql_table.cc: Remember if reopen_tables() generates an error (which can only happen in case of KILL). This fixed MDEV-6560
This commit is contained in:
parent
0835f57489
commit
9c79227c96
@ -427,4 +427,16 @@ THREAD_ID LOCK_MODE LOCK_DURATION LOCK_TYPE TABLE_SCHEMA TABLE_NAME
|
||||
# MDL_SHARED_READ MDL_EXPLICIT Table metadata lock test t2
|
||||
drop table t1;
|
||||
unlock tables;
|
||||
#
|
||||
# MDEV-6560
|
||||
# Assertion `! is_set() ' failed in Diagnostics_area::set_ok_status
|
||||
#
|
||||
CREATE TABLE t1 (col_int_nokey INT) ENGINE=InnoDB;
|
||||
CREATE OR REPLACE TEMPORARY TABLE tmp LIKE t1;
|
||||
LOCK TABLE t1 WRITE;
|
||||
CREATE OR REPLACE TABLE t1 LIKE tmp;;
|
||||
KILL QUERY 3;
|
||||
CREATE OR REPLACE TABLE t1 (a int);;
|
||||
KILL QUERY 3;
|
||||
drop table t1;
|
||||
DROP TABLE t2;
|
||||
|
31
mysql-test/suite/rpl/r/create_or_replace2.result
Normal file
31
mysql-test/suite/rpl/r/create_or_replace2.result
Normal file
@ -0,0 +1,31 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
#
|
||||
# MDEV-6525 ; Problems with CREATE OR REPLACE under lock
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN ( SELECT MAX(a) FROM t1 );
|
||||
connect con1,localhost,root,,test;
|
||||
CREATE TEMPORARY TABLE tmp (b INT) ENGINE=InnoDB;
|
||||
LOCK TABLE t1 WRITE;
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
connection default;
|
||||
set session lock_wait_timeout=1;
|
||||
SELECT f1();
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
set session lock_wait_timeout=@@global.lock_wait_timeout;
|
||||
SELECT f1();
|
||||
connection con1;
|
||||
unlock tables;
|
||||
connection default;
|
||||
ERROR 42S22: Unknown column 'a' in 'field list'
|
||||
disconnect con1;
|
||||
drop function f1;
|
||||
drop table t1;
|
||||
include/rpl_end.inc
|
44
mysql-test/suite/rpl/t/create_or_replace2.test
Normal file
44
mysql-test/suite/rpl/t/create_or_replace2.test
Normal file
@ -0,0 +1,44 @@
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_binlog_format_row_or_statement.inc
|
||||
--source include/have_metadata_lock_info.inc
|
||||
--source include/master-slave.inc
|
||||
--enable_connect_log
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-6525 ; Problems with CREATE OR REPLACE under lock
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
|
||||
CREATE FUNCTION f1() RETURNS INT RETURN ( SELECT MAX(a) FROM t1 );
|
||||
|
||||
--connect (con1,localhost,root,,test)
|
||||
|
||||
CREATE TEMPORARY TABLE tmp (b INT) ENGINE=InnoDB;
|
||||
LOCK TABLE t1 WRITE;
|
||||
|
||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
|
||||
CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
||||
--connection default
|
||||
set session lock_wait_timeout=1;
|
||||
--error 1205
|
||||
SELECT f1();
|
||||
|
||||
set session lock_wait_timeout=@@global.lock_wait_timeout;
|
||||
--send SELECT f1()
|
||||
--connection con1
|
||||
# This is here just in case, any timeout should be ok
|
||||
--sleep 1
|
||||
unlock tables;
|
||||
--connection default
|
||||
--error 1054
|
||||
--reap
|
||||
--disconnect con1
|
||||
|
||||
# Cleanup
|
||||
drop function f1;
|
||||
drop table t1;
|
||||
--disable_connect_log
|
||||
--source include/rpl_end.inc
|
@ -332,6 +332,38 @@ select * from information_schema.metadata_lock_info;
|
||||
drop table t1;
|
||||
unlock tables;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-6560
|
||||
--echo # Assertion `! is_set() ' failed in Diagnostics_area::set_ok_status
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (col_int_nokey INT) ENGINE=InnoDB;
|
||||
|
||||
--let $con_id = `SELECT CONNECTION_ID()`
|
||||
CREATE OR REPLACE TEMPORARY TABLE tmp LIKE t1;
|
||||
LOCK TABLE t1 WRITE;
|
||||
|
||||
--connect (con1,localhost,root,,test)
|
||||
|
||||
--connection default
|
||||
--send CREATE OR REPLACE TABLE t1 LIKE tmp;
|
||||
--connection con1
|
||||
eval KILL QUERY $con_id;
|
||||
|
||||
--connection default
|
||||
--error 0,ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
--send CREATE OR REPLACE TABLE t1 (a int);
|
||||
|
||||
--connection con1
|
||||
eval KILL QUERY $con_id;
|
||||
|
||||
--connection default
|
||||
--error 0,ER_QUERY_INTERRUPTED
|
||||
--reap
|
||||
--disconnect con1
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
|
@ -412,6 +412,17 @@
|
||||
fun:__libc_start_main
|
||||
}
|
||||
|
||||
#
|
||||
# dl_init reports leaked memory in memalign on OpenSuse 12.3
|
||||
|
||||
{
|
||||
memory "loss" from _dl_init
|
||||
Memcheck:Leak
|
||||
fun:memalign
|
||||
...
|
||||
fun:call_init
|
||||
fun:_dl_init
|
||||
}
|
||||
|
||||
#
|
||||
# dlclose can allocate memory for error message, the memory will be
|
||||
|
@ -2925,6 +2925,7 @@ Locked_tables_list::reopen_tables(THD *thd)
|
||||
size_t reopen_count= 0;
|
||||
MYSQL_LOCK *lock;
|
||||
MYSQL_LOCK *merged_lock;
|
||||
DBUG_ENTER("Locked_tables_list::reopen_tables");
|
||||
|
||||
for (TABLE_LIST *table_list= m_locked_tables;
|
||||
table_list; table_list= table_list->next_global)
|
||||
@ -2936,7 +2937,7 @@ Locked_tables_list::reopen_tables(THD *thd)
|
||||
if (open_table(thd, table_list, thd->mem_root, &ot_ctx))
|
||||
{
|
||||
unlink_all_closed_tables(thd, 0, reopen_count);
|
||||
return TRUE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
table_list->table->pos_in_locked_tables= table_list;
|
||||
/* See also the comment on lock type in init_locked_tables(). */
|
||||
@ -2968,11 +2969,11 @@ Locked_tables_list::reopen_tables(THD *thd)
|
||||
unlink_all_closed_tables(thd, lock, reopen_count);
|
||||
if (! thd->killed)
|
||||
my_error(ER_LOCK_DEADLOCK, MYF(0));
|
||||
return TRUE;
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
thd->lock= merged_lock;
|
||||
}
|
||||
return FALSE;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4453,9 +4453,18 @@ extern "C" bool thd_binlog_filter_ok(const MYSQL_THD thd)
|
||||
return binlog_filter->db_ok(thd->db);
|
||||
}
|
||||
|
||||
/*
|
||||
This is similar to sqlcom_can_generate_row_events, with the expection
|
||||
that we only return 1 if we are going to generate row events in a
|
||||
transaction.
|
||||
CREATE OR REPLACE is always safe to do as this will run in it's own
|
||||
transaction.
|
||||
*/
|
||||
|
||||
extern "C" bool thd_sqlcom_can_generate_row_events(const MYSQL_THD thd)
|
||||
{
|
||||
return sqlcom_can_generate_row_events(thd);
|
||||
return (sqlcom_can_generate_row_events(thd) && thd->lex->sql_command !=
|
||||
SQLCOM_CREATE_TABLE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -5029,7 +5029,10 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
|
||||
*/
|
||||
thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
|
||||
if (thd->locked_tables_list.reopen_tables(thd))
|
||||
{
|
||||
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||
result= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TABLE *table= pos_in_locked_tables->table;
|
||||
@ -5292,6 +5295,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
|
||||
if (res)
|
||||
{
|
||||
/* is_error() may be 0 if table existed and we generated a warning */
|
||||
res= thd->is_error();
|
||||
goto err;
|
||||
}
|
||||
@ -5374,7 +5378,10 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
*/
|
||||
thd->locked_tables_list.add_back_last_deleted_lock(pos_in_locked_tables);
|
||||
if (thd->locked_tables_list.reopen_tables(thd))
|
||||
{
|
||||
thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
|
||||
res= 1; // We got an error
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user