mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed bug in ALTER TABLE DISABLE KEYS and INSERT DELAYED. Bug #478
mysql-test/r/alter_table.result: new results mysql-test/r/lowercase_table.result: new results mysql-test/t/alter_table.test: Test of ALTER TABLE DISABLE KEYS + INSERT DELAYED mysql-test/t/lowercase_table.test: Added test of alias name comparison sql/mysql_priv.h: Made closed_cached_table local sql/sql_table.cc: Fixed bug in ALTER TABLE DISABLE KEYS and INSERT DELAYED
This commit is contained in:
@ -276,3 +276,8 @@ t1 0 a 1 a A 3 NULL NULL YES BTREE
|
|||||||
t1 0 a 2 b A 300 NULL NULL YES BTREE
|
t1 0 a 2 b A 300 NULL NULL YES BTREE
|
||||||
t1 1 b 1 b A 100 NULL NULL YES BTREE
|
t1 1 b 1 b A 100 NULL NULL YES BTREE
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
CREATE TABLE t1 (i int(10), index(i) );
|
||||||
|
ALTER TABLE t1 DISABLE KEYS;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(1),(2),(3);
|
||||||
|
ALTER TABLE t1 ENABLE KEYS;
|
||||||
|
drop table t1;
|
||||||
|
@ -13,3 +13,15 @@ show tables like 't_';
|
|||||||
Tables_in_test (t_)
|
Tables_in_test (t_)
|
||||||
t3
|
t3
|
||||||
drop table t3;
|
drop table t3;
|
||||||
|
create table t1 (a int);
|
||||||
|
select count(*) from T1;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(*) from t1;
|
||||||
|
count(*)
|
||||||
|
0
|
||||||
|
select count(T1.a) from t1;
|
||||||
|
Unknown table 'T1' in field list
|
||||||
|
select count(bags.a) from t1 as Bags;
|
||||||
|
Unknown table 'bags' in field list
|
||||||
|
drop table t1;
|
||||||
|
@ -133,3 +133,12 @@ analyze table t1;
|
|||||||
show keys from t1;
|
show keys from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test of ALTER TABLE DELAYED
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i int(10), index(i) );
|
||||||
|
ALTER TABLE t1 DISABLE KEYS;
|
||||||
|
INSERT DELAYED INTO t1 VALUES(1),(2),(3);
|
||||||
|
ALTER TABLE t1 ENABLE KEYS;
|
||||||
|
drop table t1;
|
||||||
|
@ -12,3 +12,14 @@ ALTER TABLE T2 RENAME T3;
|
|||||||
show tables like 't_';
|
show tables like 't_';
|
||||||
drop table t3;
|
drop table t3;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test alias
|
||||||
|
#
|
||||||
|
create table t1 (a int);
|
||||||
|
select count(*) from T1;
|
||||||
|
select count(*) from t1;
|
||||||
|
--error 1109
|
||||||
|
select count(T1.a) from t1;
|
||||||
|
--error 1109
|
||||||
|
select count(bags.a) from t1 as Bags;
|
||||||
|
drop table t1;
|
||||||
|
@ -422,7 +422,6 @@ bool mysql_rename_table(enum db_type base,
|
|||||||
const char * old_name,
|
const char * old_name,
|
||||||
const char *new_db,
|
const char *new_db,
|
||||||
const char * new_name);
|
const char * new_name);
|
||||||
bool close_cached_table(THD *thd,TABLE *table);
|
|
||||||
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
|
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
|
||||||
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
|
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
|
||||||
List<Alter_drop> &drop_list);
|
List<Alter_drop> &drop_list);
|
||||||
|
133
sql/sql_table.cc
133
sql/sql_table.cc
@ -912,58 +912,76 @@ mysql_rename_table(enum db_type base,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
close table in this thread and force close + reopen in other threads
|
Force all other threads to stop using the table
|
||||||
This assumes that the calling thread has lock on LOCK_open
|
|
||||||
Win32 clients must also have a WRITE LOCK on the table !
|
SYNOPSIS
|
||||||
|
wait_while_table_is_used()
|
||||||
|
thd Thread handler
|
||||||
|
table Table to remove from cache
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
When returning, the table will be unusable for other threads until
|
||||||
|
the table is closed.
|
||||||
|
|
||||||
|
PREREQUISITES
|
||||||
|
Lock on LOCK_open
|
||||||
|
Win32 clients must also have a WRITE LOCK on the table !
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void safe_remove_from_cache(THD *thd,TABLE *table)
|
static void wait_while_table_is_used(THD *thd,TABLE *table)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("safe_remove_from_cache");
|
DBUG_PRINT("enter",("table: %s", table->real_name));
|
||||||
if (table)
|
DBUG_ENTER("wait_while_table_is_used");
|
||||||
{
|
safe_mutex_assert_owner(&LOCK_open);
|
||||||
DBUG_PRINT("enter",("table: %s", table->real_name));
|
|
||||||
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files
|
|
||||||
/* Mark all tables that are in use as 'old' */
|
|
||||||
mysql_lock_abort(thd,table); // end threads waiting on lock
|
|
||||||
|
|
||||||
#if defined(USING_TRANSACTIONS) || defined( __WIN__) || defined( __EMX__) || !defined(OS2)
|
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files
|
||||||
/* Wait until all there are no other threads that has this table open */
|
/* Mark all tables that are in use as 'old' */
|
||||||
while (remove_table_from_cache(thd,table->table_cache_key,
|
mysql_lock_abort(thd, table); // end threads waiting on lock
|
||||||
table->real_name))
|
|
||||||
{
|
/* Wait until all there are no other threads that has this table open */
|
||||||
dropping_tables++;
|
while (remove_table_from_cache(thd,table->table_cache_key,
|
||||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
table->real_name))
|
||||||
dropping_tables--;
|
{
|
||||||
}
|
dropping_tables++;
|
||||||
#else
|
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||||
(void) remove_table_from_cache(thd,table->table_cache_key,
|
dropping_tables--;
|
||||||
table->real_name);
|
|
||||||
#endif
|
|
||||||
/* When lock on LOCK_open is freed other threads can continue */
|
|
||||||
pthread_cond_broadcast(&COND_refresh);
|
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Close a cached table
|
||||||
|
|
||||||
bool close_cached_table(THD *thd,TABLE *table)
|
SYNOPSIS
|
||||||
|
clsoe_cached_table()
|
||||||
|
thd Thread handler
|
||||||
|
table Table to remove from cache
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
Function ends by signaling threads waiting for the table to try to
|
||||||
|
reopen the table.
|
||||||
|
|
||||||
|
PREREQUISITES
|
||||||
|
Lock on LOCK_open
|
||||||
|
Win32 clients must also have a WRITE LOCK on the table !
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool close_cached_table(THD *thd, TABLE *table)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("close_cached_table");
|
DBUG_ENTER("close_cached_table");
|
||||||
safe_mutex_assert_owner(&LOCK_open);
|
|
||||||
|
wait_while_table_is_used(thd,table);
|
||||||
if (table)
|
/* Close lock if this is not got with LOCK TABLES */
|
||||||
|
if (thd->lock)
|
||||||
{
|
{
|
||||||
safe_remove_from_cache(thd,table);
|
mysql_unlock_tables(thd, thd->lock);
|
||||||
/* Close lock if this is not got with LOCK TABLES */
|
thd->lock=0; // Start locked threads
|
||||||
if (thd->lock)
|
|
||||||
{
|
|
||||||
mysql_unlock_tables(thd, thd->lock);
|
|
||||||
thd->lock=0; // Start locked threads
|
|
||||||
}
|
|
||||||
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
|
|
||||||
thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
|
|
||||||
}
|
}
|
||||||
|
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
|
||||||
|
thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
|
||||||
|
|
||||||
|
/* When lock on LOCK_open is freed other threads can continue */
|
||||||
|
pthread_cond_broadcast(&COND_refresh);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1094,10 +1112,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
|
|||||||
|
|
||||||
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
||||||
|
|
||||||
pthread_mutex_lock(&LOCK_open);
|
/* If we could open the table, close it */
|
||||||
close_cached_table(thd,table_list->table);
|
if (table_list->table)
|
||||||
pthread_mutex_unlock(&LOCK_open);
|
{
|
||||||
|
pthread_mutex_lock(&LOCK_open);
|
||||||
|
close_cached_table(thd, table);
|
||||||
|
pthread_mutex_unlock(&LOCK_open);
|
||||||
|
}
|
||||||
if (lock_and_wait_for_table_name(thd,table_list))
|
if (lock_and_wait_for_table_name(thd,table_list))
|
||||||
{
|
{
|
||||||
error= -1;
|
error= -1;
|
||||||
@ -1494,11 +1515,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
*fn_ext(new_name)=0;
|
*fn_ext(new_name)=0;
|
||||||
close_cached_table(thd,table);
|
close_cached_table(thd, table);
|
||||||
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
|
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
|
||||||
error= -1;
|
error= -1;
|
||||||
}
|
}
|
||||||
VOID(pthread_cond_broadcast(&COND_refresh));
|
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
}
|
}
|
||||||
if (!error)
|
if (!error)
|
||||||
@ -1507,12 +1527,18 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
case LEAVE_AS_IS:
|
case LEAVE_AS_IS:
|
||||||
break;
|
break;
|
||||||
case ENABLE:
|
case ENABLE:
|
||||||
safe_remove_from_cache(thd,table);
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
error= table->file->activate_all_index(thd);
|
wait_while_table_is_used(thd, table);
|
||||||
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
|
error= table->file->activate_all_index(thd);
|
||||||
|
/* COND_refresh will be signaled in close_thread_tables() */
|
||||||
break;
|
break;
|
||||||
case DISABLE:
|
case DISABLE:
|
||||||
safe_remove_from_cache(thd,table);
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
|
wait_while_table_is_used(thd, table);
|
||||||
|
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() */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1936,7 +1962,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
close the original table at before doing the rename
|
close the original table at before doing the rename
|
||||||
*/
|
*/
|
||||||
table_name=thd->strdup(table_name); // must be saved
|
table_name=thd->strdup(table_name); // must be saved
|
||||||
if (close_cached_table(thd,table))
|
if (close_cached_table(thd, table))
|
||||||
{ // Aborted
|
{ // Aborted
|
||||||
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
|
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
@ -1970,7 +1996,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
This shouldn't happen. We solve this the safe way by
|
This shouldn't happen. We solve this the safe way by
|
||||||
closing the locked table.
|
closing the locked table.
|
||||||
*/
|
*/
|
||||||
close_cached_table(thd,table);
|
if (table)
|
||||||
|
close_cached_table(thd,table);
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -1980,7 +2007,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
Not table locking or alter table with rename
|
Not table locking or alter table with rename
|
||||||
free locks and remove old table
|
free locks and remove old table
|
||||||
*/
|
*/
|
||||||
close_cached_table(thd,table);
|
if (table)
|
||||||
|
close_cached_table(thd,table);
|
||||||
VOID(quick_rm_table(old_db_type,db,old_name));
|
VOID(quick_rm_table(old_db_type,db,old_name));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2000,7 +2028,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
if (close_data_tables(thd,db,table_name) ||
|
if (close_data_tables(thd,db,table_name) ||
|
||||||
reopen_tables(thd,1,0))
|
reopen_tables(thd,1,0))
|
||||||
{ // This shouldn't happen
|
{ // This shouldn't happen
|
||||||
close_cached_table(thd,table); // Remove lock for table
|
if (table)
|
||||||
|
close_cached_table(thd,table); // Remove lock for table
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user