summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-07-08 23:58:04 +0300
committerunknown <monty@mashka.mysql.fi>2003-07-08 23:58:04 +0300
commit9388c6fdc06a4634e4e748a3d38b5df2738ebdef (patch)
tree469e4c68e8c5de015364504f40b14cec7177b355
parent09e76fe9639b7df1d801ed75e19beb2e9c86734f (diff)
downloadmariadb-git-9388c6fdc06a4634e4e748a3d38b5df2738ebdef.tar.gz
Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS
Removed double my_thread_end() which caused fatal error on windows if mysqld died on startup myisam/mi_extra.c: Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS mysql-test/r/alter_table.result: Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS mysql-test/t/alter_table.test: Test DISABLE/ENABLE KEY sql/ha_myisam.cc: Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS sql/mysqld.cc: Removed double my_thread_end() which caused fatal error on windows if mysqld died on startup sql/sql_table.cc: Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS sql/table.cc: Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS sql/table.h: Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS
-rw-r--r--myisam/mi_extra.c4
-rw-r--r--mysql-test/r/alter_table.result69
-rw-r--r--mysql-test/t/alter_table.test62
-rw-r--r--sql/ha_myisam.cc7
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/sql_table.cc14
-rw-r--r--sql/table.cc3
-rw-r--r--sql/table.h2
8 files changed, 152 insertions, 10 deletions
diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c
index 75057dd4e6a..ef82a6ef61f 100644
--- a/myisam/mi_extra.c
+++ b/myisam/mi_extra.c
@@ -273,6 +273,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
}
break;
case HA_EXTRA_FORCE_REOPEN:
+ pthread_mutex_lock(&THR_LOCK_myisam);
+ share->last_version= 0L; /* Impossible version */
+ pthread_mutex_unlock(&THR_LOCK_myisam);
+ break;
case HA_EXTRA_PREPARE_FOR_DELETE:
pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index e2d9cc30ad9..7ade3313abe 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -281,3 +281,72 @@ ALTER TABLE t1 DISABLE KEYS;
INSERT DELAYED INTO t1 VALUES(1),(2),(3);
ALTER TABLE t1 ENABLE KEYS;
drop table t1;
+CREATE TABLE t1 (
+Host varchar(16) binary NOT NULL default '',
+User varchar(16) binary NOT NULL default '',
+PRIMARY KEY (Host,User)
+) TYPE=MyISAM;
+ALTER TABLE t1 DISABLE KEYS;
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty');
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 3 NULL NULL BTREE
+ALTER TABLE t1 ENABLE KEYS;
+UNLOCK TABLES;
+CHECK TABLES t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+CREATE TABLE t1 (
+Host varchar(16) binary NOT NULL default '',
+User varchar(16) binary NOT NULL default '',
+PRIMARY KEY (Host,User),
+KEY (Host)
+) TYPE=MyISAM;
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 0 NULL NULL BTREE
+t1 1 Host 1 Host A NULL NULL NULL BTREE disabled
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost','');
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 2 NULL NULL BTREE
+t1 1 Host 1 Host A NULL NULL NULL BTREE disabled
+ALTER TABLE t1 ENABLE KEYS;
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 2 NULL NULL BTREE
+t1 1 Host 1 Host A 1 NULL NULL BTREE
+UNLOCK TABLES;
+CHECK TABLES t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 RENAME t2;
+UNLOCK TABLES;
+select * from t2;
+Host User
+localhost
+localhost root
+DROP TABLE t2;
+CREATE TABLE t1 (
+Host varchar(16) binary NOT NULL default '',
+User varchar(16) binary NOT NULL default '',
+PRIMARY KEY (Host,User),
+KEY (Host)
+) TYPE=MyISAM;
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE
+t1 0 PRIMARY 2 User A 0 NULL NULL BTREE
+t1 1 Host 1 Host A NULL NULL NULL BTREE disabled
+DROP TABLE t1;
diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test
index a3ab62afc69..d438f2d5825 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -142,3 +142,65 @@ ALTER TABLE t1 DISABLE KEYS;
INSERT DELAYED INTO t1 VALUES(1),(2),(3);
ALTER TABLE t1 ENABLE KEYS;
drop table t1;
+
+#
+# Test ALTER TABLE ENABLE/DISABLE keys when things are locked
+#
+
+CREATE TABLE t1 (
+ Host varchar(16) binary NOT NULL default '',
+ User varchar(16) binary NOT NULL default '',
+ PRIMARY KEY (Host,User)
+) TYPE=MyISAM;
+
+ALTER TABLE t1 DISABLE KEYS;
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty');
+SHOW INDEX FROM t1;
+ALTER TABLE t1 ENABLE KEYS;
+UNLOCK TABLES;
+CHECK TABLES t1;
+DROP TABLE t1;
+
+#
+# Test with two keys
+#
+
+CREATE TABLE t1 (
+ Host varchar(16) binary NOT NULL default '',
+ User varchar(16) binary NOT NULL default '',
+ PRIMARY KEY (Host,User),
+ KEY (Host)
+) TYPE=MyISAM;
+
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+LOCK TABLES t1 WRITE;
+INSERT INTO t1 VALUES ('localhost','root'),('localhost','');
+SHOW INDEX FROM t1;
+ALTER TABLE t1 ENABLE KEYS;
+SHOW INDEX FROM t1;
+UNLOCK TABLES;
+CHECK TABLES t1;
+
+# Test RENAME with LOCK TABLES
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 RENAME t2;
+UNLOCK TABLES;
+select * from t2;
+DROP TABLE t2;
+
+#
+# Test disable keys with locking
+#
+CREATE TABLE t1 (
+ Host varchar(16) binary NOT NULL default '',
+ User varchar(16) binary NOT NULL default '',
+ PRIMARY KEY (Host,User),
+ KEY (Host)
+) TYPE=MyISAM;
+
+LOCK TABLES t1 WRITE;
+ALTER TABLE t1 DISABLE KEYS;
+SHOW INDEX FROM t1;
+DROP TABLE t1;
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 202cd90fd88..595123f7ac1 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -715,6 +715,7 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows)
}
}
enable_activate_all_index=1;
+ info(HA_STATUS_CONST); // Read new key info
}
else
enable_activate_all_index=0;
@@ -743,6 +744,7 @@ bool ha_myisam::activate_all_index(THD *thd)
param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
param.tmpdir=mysql_tmpdir;
error=repair(thd,param,0) != HA_ADMIN_OK;
+ info(HA_STATUS_CONST);
thd->proc_info=save_proc_info;
}
else
@@ -926,8 +928,9 @@ void ha_myisam::info(uint flag)
ref_length=info.reflength;
table->db_options_in_use = info.options;
block_size=myisam_block_size;
- table->keys_in_use&= info.key_map;
- table->keys_for_keyread&= info.key_map;
+ table->keys_in_use= (set_bits(key_map, table->keys) &
+ (key_map) info.key_map);
+ table->keys_for_keyread= table->keys_in_use & ~table->read_only_keys;
table->db_record_offset=info.record_offset;
if (table->key_parts)
memcpy((char*) table->key_info[0].rec_per_key,
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4f6f55bce0b..95bf94c8e8b 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -871,7 +871,6 @@ extern "C" void unireg_abort(int exit_code)
sql_print_error("Aborting\n");
clean_up(1); /* purecov: inspected */
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
- my_thread_end();
clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(exit_code); /* purecov: inspected */
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 5a53ba30631..cf430aec35d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -918,7 +918,8 @@ mysql_rename_table(enum db_type base,
wait_while_table_is_used()
thd Thread handler
table Table to remove from cache
-
+ function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted
+ HA_EXTRA_FORCE_REOPEN if table is not be used
NOTES
When returning, the table will be unusable for other threads until
the table is closed.
@@ -928,13 +929,14 @@ mysql_rename_table(enum db_type base,
Win32 clients must also have a WRITE LOCK on the table !
*/
-static void wait_while_table_is_used(THD *thd,TABLE *table)
+static void wait_while_table_is_used(THD *thd,TABLE *table,
+ enum ha_extra_function function)
{
DBUG_PRINT("enter",("table: %s", table->real_name));
DBUG_ENTER("wait_while_table_is_used");
safe_mutex_assert_owner(&LOCK_open);
- VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files
+ VOID(table->file->extra(function));
/* Mark all tables that are in use as 'old' */
mysql_lock_abort(thd, table); // end threads waiting on lock
@@ -970,7 +972,7 @@ static bool close_cached_table(THD *thd, TABLE *table)
{
DBUG_ENTER("close_cached_table");
- wait_while_table_is_used(thd,table);
+ wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE);
/* Close lock if this is not got with LOCK TABLES */
if (thd->lock)
{
@@ -1529,14 +1531,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
break;
case ENABLE:
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table);
+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
error= table->file->activate_all_index(thd);
/* COND_refresh will be signaled in close_thread_tables() */
break;
case DISABLE:
VOID(pthread_mutex_lock(&LOCK_open));
- wait_while_table_is_used(thd, table);
+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
VOID(pthread_mutex_unlock(&LOCK_open));
table->file->deactivate_non_unique_index(HA_POS_ERROR);
/* COND_refresh will be signaled in close_thread_tables() */
diff --git a/sql/table.cc b/sql/table.cc
index a26ab89bd97..e938757cf6c 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -422,7 +422,10 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
/* This has to be done after the above fulltext correction */
index_flags=outparam->file->index_flags(key);
if (!(index_flags & HA_KEY_READ_ONLY))
+ {
+ outparam->read_only_keys|= ((key_map) 1 << key);
outparam->keys_for_keyread&= ~((key_map) 1 << key);
+ }
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
{
diff --git a/sql/table.h b/sql/table.h
index b6935ea6a32..57be97ffbda 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -62,7 +62,7 @@ struct st_table {
uint uniques;
uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob fields */
- key_map keys_in_use, keys_for_keyread;
+ key_map keys_in_use, keys_for_keyread, read_only_keys;
key_map quick_keys, used_keys, keys_in_use_for_query;
KEY *key_info; /* data of keys in database */
TYPELIB keynames; /* Pointers to keynames */