summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <vva@eagle.mysql.r18.ru>2004-04-01 23:13:25 +0500
committerunknown <vva@eagle.mysql.r18.ru>2004-04-01 23:13:25 +0500
commitf2116615bed09a5b2bb6f113ba3ea1beebcb5e54 (patch)
tree495f068123bd4b3ce62777dce35158c7a713c334
parentb26165d3a2eeb748b9bd5573f9bac7b73d5f9a37 (diff)
downloadmariadb-git-f2116615bed09a5b2bb6f113ba3ea1beebcb5e54.tar.gz
added synchronization in mysql_create_like_table
( fixed BUG #2385 CREATE TABLE LIKE lacks locking on source and destination table and added tests for it ) sql/mysql_priv.h: added code TEST_SYNCHRONIZATION for --exit-info option sql/mysqld.cc: fixed -debug prefix sql/sql_table.cc: added synchronization in mysql_create_like_table (fixed BUG #2385 CREATE TABLE LIKE lacks locking on source and destination table)
-rw-r--r--mysql-test/include/have_debug.inc4
-rw-r--r--mysql-test/r/have_debug.require2
-rw-r--r--mysql-test/t/synchronization-master.opt1
-rw-r--r--mysql-test/t/synchronization.test44
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/mysqld.cc4
-rw-r--r--sql/sql_table.cc38
7 files changed, 86 insertions, 9 deletions
diff --git a/mysql-test/include/have_debug.inc b/mysql-test/include/have_debug.inc
new file mode 100644
index 00000000000..63c0c008b21
--- /dev/null
+++ b/mysql-test/include/have_debug.inc
@@ -0,0 +1,4 @@
+-- require r/have_debug.require
+disable_query_log;
+select instr(version(),convert('debug' using utf8))!=0;
+enable_query_log;
diff --git a/mysql-test/r/have_debug.require b/mysql-test/r/have_debug.require
new file mode 100644
index 00000000000..3ef51a3a6db
--- /dev/null
+++ b/mysql-test/r/have_debug.require
@@ -0,0 +1,2 @@
+instr(version(),convert('debug' using utf8))!=0;
+1 \ No newline at end of file
diff --git a/mysql-test/t/synchronization-master.opt b/mysql-test/t/synchronization-master.opt
new file mode 100644
index 00000000000..710a0395d55
--- /dev/null
+++ b/mysql-test/t/synchronization-master.opt
@@ -0,0 +1 @@
+--exit-info=2048 \ No newline at end of file
diff --git a/mysql-test/t/synchronization.test b/mysql-test/t/synchronization.test
new file mode 100644
index 00000000000..84478cf7445
--- /dev/null
+++ b/mysql-test/t/synchronization.test
@@ -0,0 +1,44 @@
+-- source include/have_crypt.inc
+
+#
+# Test for Bug #2385 CREATE TABLE LIKE lacks locking on source and destination table
+#
+
+connect (con_to_sleep,localhost,lock_controller,,);
+connect (con_to_harm_sleeper,localhost,root,,);
+
+# locking of source:
+connection con_to_sleep;
+CREATE TABLE t1 (a int);
+send CREATE TABLE t2 LIKE t1;
+
+connection con_to_harm_sleeper;
+ALTER TABLE t1 add key(a);
+
+connection con_to_sleep;
+sleep 4;
+SHOW CREATE TABLE t2;
+drop table t1, t2;
+
+# locking of destination:
+connection con_to_sleep;
+CREATE TABLE t1 (a int);
+send CREATE TABLE t2 LIKE t1;
+
+connection con_to_harm_sleeper;
+sleep 1;
+CREATE TABLE t2 (b int);
+disable_query_log;
+select "-----------" as "let's take a look at result of create .. like : ";
+enable_query_log;
+
+connection con_to_sleep;
+sleep 1;
+--error 1
+reap;
+disable_query_log;
+select "" as "-----------";
+enable_query_log;
+SHOW CREATE TABLE t2;
+
+drop table t1, t2; \ No newline at end of file
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index bd919d12348..85c909d7057 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -171,6 +171,8 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
#define TEST_CORE_ON_SIGNAL 256 /* Give core if signal */
#define TEST_NO_STACKTRACE 512
#define TEST_SIGINT 1024 /* Allow sigint on threads */
+#define TEST_SYNCHRONIZATION 2048 /* get server to do sleep in some
+ places */
/* options for select set by the yacc parser (stored in lex->options) */
#define SELECT_DISTINCT (1L << 0)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d602c44c8f9..13329c137bd 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2107,8 +2107,10 @@ static int init_common_variables(const char *conf_file_name, int argc,
if (*(MYSQL_SERVER_SUFFIX))
strxmov(strend(server_version),MYSQL_SERVER_SUFFIX,"-debug",NullS);
else
-#endif
+ strmov(strend(server_version),"--debug");
+#else
strmov(strend(server_version),MYSQL_SERVER_SUFFIX);
+#endif
load_defaults(conf_file_name, groups, &argc, &argv);
defaults_argv=argv;
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index db6f9043ec4..8a1ecc115df 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1882,7 +1882,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
char *table_name= table->real_name;
char *src_db= thd->db;
char *src_table= table_ident->table.str;
- int err;
+ int err, res= -1;
+ TABLE_LIST src_tables_list;
DBUG_ENTER("mysql_create_like_table");
/*
@@ -1896,6 +1897,13 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table);
DBUG_RETURN(-1);
}
+
+ src_tables_list.db= table_ident->db.str ? table_ident->db.str : thd->db;
+ src_tables_list.real_name= table_ident->table.str;
+ src_tables_list.next= 0;
+
+ if (lock_and_wait_for_table_name(thd, &src_tables_list))
+ goto err;
if ((tmp_table= find_temporary_table(thd, src_db, src_table)))
strxmov(src_path, (*tmp_table)->path, reg_ext, NullS);
@@ -1906,7 +1914,7 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
if (access(src_path, F_OK))
{
my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table);
- DBUG_RETURN(-1);
+ goto err;
}
}
@@ -1934,9 +1942,14 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
/*
Create a new table by copying from source table
- */
- if (my_copy(src_path, dst_path, MYF(MY_WME)))
- DBUG_RETURN(-1);
+ */
+#ifndef DBUG_OFF
+ // The code stated below is for test synchronization.test Bug #2385
+ if (test_flags & TEST_SYNCHRONIZATION)
+ sleep(3);
+#endif
+ if (my_copy(src_path, dst_path, MYF(MY_WME|MY_DONT_OVERWRITE_FILE)))
+ goto err;
/*
As mysql_truncate don't work on a new table at this stage of
@@ -1952,14 +1965,14 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
(void) rm_temporary_table(create_info->db_type,
dst_path); /* purecov: inspected */
- DBUG_RETURN(-1); /* purecov: inspected */
+ goto err; /* purecov: inspected */
}
}
else if (err)
{
(void) quick_rm_table(create_info->db_type, db,
table_name); /* purecov: inspected */
- DBUG_RETURN(-1); /* purecov: inspected */
+ goto err; /* purecov: inspected */
}
// Must be written before unlock
@@ -1972,9 +1985,18 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
HA_LEX_CREATE_TMP_TABLE));
mysql_bin_log.write(&qinfo);
}
- DBUG_RETURN(0);
+ res= 0;
+
+err:
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, &src_tables_list);
+ pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(res);
table_exists:
+ pthread_mutex_lock(&LOCK_open);
+ unlock_table_name(thd, &src_tables_list);
+ pthread_mutex_unlock(&LOCK_open);
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
char warn_buff[MYSQL_ERRMSG_SIZE];