Commit e13e857c authored by unknown's avatar unknown

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
parent 4c2d3b05
...@@ -273,6 +273,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) ...@@ -273,6 +273,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
} }
break; break;
case HA_EXTRA_FORCE_REOPEN: 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: case HA_EXTRA_PREPARE_FOR_DELETE:
pthread_mutex_lock(&THR_LOCK_myisam); pthread_mutex_lock(&THR_LOCK_myisam);
share->last_version= 0L; /* Impossible version */ share->last_version= 0L; /* Impossible version */
......
...@@ -281,3 +281,72 @@ ALTER TABLE t1 DISABLE KEYS; ...@@ -281,3 +281,72 @@ ALTER TABLE t1 DISABLE KEYS;
INSERT DELAYED INTO t1 VALUES(1),(2),(3); INSERT DELAYED INTO t1 VALUES(1),(2),(3);
ALTER TABLE t1 ENABLE KEYS; ALTER TABLE t1 ENABLE KEYS;
drop table t1; 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;
...@@ -142,3 +142,65 @@ ALTER TABLE t1 DISABLE KEYS; ...@@ -142,3 +142,65 @@ ALTER TABLE t1 DISABLE KEYS;
INSERT DELAYED INTO t1 VALUES(1),(2),(3); INSERT DELAYED INTO t1 VALUES(1),(2),(3);
ALTER TABLE t1 ENABLE KEYS; ALTER TABLE t1 ENABLE KEYS;
drop table t1; 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;
...@@ -715,6 +715,7 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows) ...@@ -715,6 +715,7 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows)
} }
} }
enable_activate_all_index=1; enable_activate_all_index=1;
info(HA_STATUS_CONST); // Read new key info
} }
else else
enable_activate_all_index=0; enable_activate_all_index=0;
...@@ -743,6 +744,7 @@ bool ha_myisam::activate_all_index(THD *thd) ...@@ -743,6 +744,7 @@ bool ha_myisam::activate_all_index(THD *thd)
param.sort_buffer_length= thd->variables.myisam_sort_buff_size; param.sort_buffer_length= thd->variables.myisam_sort_buff_size;
param.tmpdir=mysql_tmpdir; param.tmpdir=mysql_tmpdir;
error=repair(thd,param,0) != HA_ADMIN_OK; error=repair(thd,param,0) != HA_ADMIN_OK;
info(HA_STATUS_CONST);
thd->proc_info=save_proc_info; thd->proc_info=save_proc_info;
} }
else else
...@@ -926,8 +928,9 @@ void ha_myisam::info(uint flag) ...@@ -926,8 +928,9 @@ void ha_myisam::info(uint flag)
ref_length=info.reflength; ref_length=info.reflength;
table->db_options_in_use = info.options; table->db_options_in_use = info.options;
block_size=myisam_block_size; block_size=myisam_block_size;
table->keys_in_use&= info.key_map; table->keys_in_use= (set_bits(key_map, table->keys) &
table->keys_for_keyread&= info.key_map; (key_map) info.key_map);
table->keys_for_keyread= table->keys_in_use & ~table->read_only_keys;
table->db_record_offset=info.record_offset; table->db_record_offset=info.record_offset;
if (table->key_parts) if (table->key_parts)
memcpy((char*) table->key_info[0].rec_per_key, memcpy((char*) table->key_info[0].rec_per_key,
......
...@@ -871,7 +871,6 @@ extern "C" void unireg_abort(int exit_code) ...@@ -871,7 +871,6 @@ extern "C" void unireg_abort(int exit_code)
sql_print_error("Aborting\n"); sql_print_error("Aborting\n");
clean_up(1); /* purecov: inspected */ clean_up(1); /* purecov: inspected */
DBUG_PRINT("quit",("done with cleanup in unireg_abort")); DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
my_thread_end();
clean_up_mutexes(); clean_up_mutexes();
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
exit(exit_code); /* purecov: inspected */ exit(exit_code); /* purecov: inspected */
......
...@@ -918,7 +918,8 @@ mysql_rename_table(enum db_type base, ...@@ -918,7 +918,8 @@ mysql_rename_table(enum db_type base,
wait_while_table_is_used() wait_while_table_is_used()
thd Thread handler thd Thread handler
table Table to remove from cache 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 NOTES
When returning, the table will be unusable for other threads until When returning, the table will be unusable for other threads until
the table is closed. the table is closed.
...@@ -928,13 +929,14 @@ mysql_rename_table(enum db_type base, ...@@ -928,13 +929,14 @@ mysql_rename_table(enum db_type base,
Win32 clients must also have a WRITE LOCK on the table ! 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_PRINT("enter",("table: %s", table->real_name));
DBUG_ENTER("wait_while_table_is_used"); DBUG_ENTER("wait_while_table_is_used");
safe_mutex_assert_owner(&LOCK_open); 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' */ /* Mark all tables that are in use as 'old' */
mysql_lock_abort(thd, table); // end threads waiting on lock mysql_lock_abort(thd, table); // end threads waiting on lock
...@@ -970,7 +972,7 @@ static bool close_cached_table(THD *thd, TABLE *table) ...@@ -970,7 +972,7 @@ static bool close_cached_table(THD *thd, TABLE *table)
{ {
DBUG_ENTER("close_cached_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 */ /* Close lock if this is not got with LOCK TABLES */
if (thd->lock) if (thd->lock)
{ {
...@@ -1529,14 +1531,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -1529,14 +1531,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
break; break;
case ENABLE: case ENABLE:
VOID(pthread_mutex_lock(&LOCK_open)); 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)); VOID(pthread_mutex_unlock(&LOCK_open));
error= table->file->activate_all_index(thd); error= table->file->activate_all_index(thd);
/* COND_refresh will be signaled in close_thread_tables() */ /* COND_refresh will be signaled in close_thread_tables() */
break; break;
case DISABLE: case DISABLE:
VOID(pthread_mutex_lock(&LOCK_open)); 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)); VOID(pthread_mutex_unlock(&LOCK_open));
table->file->deactivate_non_unique_index(HA_POS_ERROR); table->file->deactivate_non_unique_index(HA_POS_ERROR);
/* COND_refresh will be signaled in close_thread_tables() */ /* COND_refresh will be signaled in close_thread_tables() */
......
...@@ -422,7 +422,10 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -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 */ /* This has to be done after the above fulltext correction */
index_flags=outparam->file->index_flags(key); index_flags=outparam->file->index_flags(key);
if (!(index_flags & HA_KEY_READ_ONLY)) if (!(index_flags & HA_KEY_READ_ONLY))
{
outparam->read_only_keys|= ((key_map) 1 << key);
outparam->keys_for_keyread&= ~((key_map) 1 << key); outparam->keys_for_keyread&= ~((key_map) 1 << key);
}
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
{ {
......
...@@ -62,7 +62,7 @@ struct st_table { ...@@ -62,7 +62,7 @@ struct st_table {
uint uniques; uint uniques;
uint null_fields; /* number of null fields */ uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob 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_map quick_keys, used_keys, keys_in_use_for_query;
KEY *key_info; /* data of keys in database */ KEY *key_info; /* data of keys in database */
TYPELIB keynames; /* Pointers to keynames */ TYPELIB keynames; /* Pointers to keynames */
......
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