summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2003-06-04 19:21:51 +0300
committerunknown <monty@narttu.mysql.fi>2003-06-04 19:21:51 +0300
commit0bc40737801e8dc755393f0b0e1d9a5aad347be5 (patch)
tree6b8e47374bf313429416a26678bc409946f34772 /sql/sql_table.cc
parentf2131b4417d7d648d61070c61e1f37453fec1faf (diff)
parent8b752028da938d1259d44545e6d60d5cb52da653 (diff)
downloadmariadb-git-0bc40737801e8dc755393f0b0e1d9a5aad347be5.tar.gz
Merge with 4.0.13
BitKeeper/etc/logging_ok: auto-union BUILD/SETUP.sh: Auto merged BitKeeper/deleted/.del-internals.texi~62b6f580a41c2a43: Auto merged client/mysqltest.c: Auto merged include/config-win.h: Auto merged include/my_global.h: Auto merged include/mysql_com.h: Auto merged innobase/include/srv0srv.h: Auto merged innobase/log/log0log.c: Auto merged innobase/os/os0file.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/srv/srv0start.c: Auto merged innobase/ut/ut0mem.c: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/alter_table.result: Auto merged mysql-test/r/errors.result: Auto merged mysql-test/r/loaddata.result: Auto merged mysql-test/r/rpl_insert_id.result: Auto merged mysql-test/r/rpl_loaddata.result: Auto merged mysql-test/std_data/rpl_loaddata2.dat: Auto merged mysql-test/t/alter_table.test: Auto merged mysql-test/t/loaddata.test: Auto merged mysql-test/t/query_cache.test: Auto merged mysql-test/t/raid.test: Auto merged mysql-test/t/rpl_insert_id.test: Auto merged mysql-test/t/rpl_loaddata.test: Auto merged sql/field.cc: Auto merged sql/ha_innodb.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_update.cc: Auto merged sql/time.cc: Auto merged configure.in: No changes libmysqld/lib_sql.cc: No changes
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc133
1 files changed, 81 insertions, 52 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7cadf187181..c15c824f843 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1081,58 +1081,76 @@ mysql_rename_table(enum db_type base,
}
/*
- close table in this thread and force close + reopen in other threads
- This assumes that the calling thread has lock on LOCK_open
- Win32 clients must also have a WRITE LOCK on the table !
+ Force all other threads to stop using 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");
- if (table)
- {
- 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
+ DBUG_PRINT("enter",("table: %s", table->real_name));
+ DBUG_ENTER("wait_while_table_is_used");
+ safe_mutex_assert_owner(&LOCK_open);
-#if defined(USING_TRANSACTIONS) || defined( __WIN__) || defined( __EMX__) || !defined(OS2)
- /* Wait until all there are no other threads that has this table open */
- while (remove_table_from_cache(thd,table->table_cache_key,
- table->real_name))
- {
- dropping_tables++;
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- dropping_tables--;
- }
-#else
- (void) remove_table_from_cache(thd,table->table_cache_key,
- table->real_name);
-#endif
- /* When lock on LOCK_open is freed other threads can continue */
- pthread_cond_broadcast(&COND_refresh);
+ 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
+
+ /* Wait until all there are no other threads that has this table open */
+ while (remove_table_from_cache(thd,table->table_cache_key,
+ table->real_name))
+ {
+ dropping_tables++;
+ (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
+ dropping_tables--;
}
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");
- safe_mutex_assert_owner(&LOCK_open);
-
- if (table)
+
+ wait_while_table_is_used(thd,table);
+ /* Close lock if this is not got with LOCK TABLES */
+ if (thd->lock)
{
- safe_remove_from_cache(thd,table);
- /* Close lock if this is not got with LOCK TABLES */
- 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);
+ 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);
+
+ /* When lock on LOCK_open is freed other threads can continue */
+ pthread_cond_broadcast(&COND_refresh);
DBUG_RETURN(0);
}
@@ -1261,10 +1279,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
- pthread_mutex_lock(&LOCK_open);
- close_cached_table(thd,table_list->table);
- pthread_mutex_unlock(&LOCK_open);
-
+ /* If we could open the table, close it */
+ if (table_list->table)
+ {
+ 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))
{
error= -1;
@@ -1794,11 +1815,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
else
{
*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))
error= -1;
}
- VOID(pthread_cond_broadcast(&COND_refresh));
VOID(pthread_mutex_unlock(&LOCK_open));
}
if (!error)
@@ -1807,12 +1827,18 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
case LEAVE_AS_IS:
break;
case ENABLE:
- safe_remove_from_cache(thd,table);
- error= table->file->activate_all_index(thd);
+ VOID(pthread_mutex_lock(&LOCK_open));
+ 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;
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);
+ /* COND_refresh will be signaled in close_thread_tables() */
break;
}
}
@@ -2247,7 +2273,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
close the original table at before doing the rename
*/
table_name=thd->strdup(table_name); // must be saved
- if (close_cached_table(thd,table))
+ if (close_cached_table(thd, table))
{ // Aborted
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -2281,7 +2307,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
This shouldn't happen. We solve this the safe way by
closing the locked table.
*/
- close_cached_table(thd,table);
+ if (table)
+ close_cached_table(thd,table);
VOID(pthread_mutex_unlock(&LOCK_open));
goto err;
}
@@ -2291,7 +2318,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
Not table locking or alter table with rename
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));
}
else
@@ -2311,7 +2339,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (close_data_tables(thd,db,table_name) ||
reopen_tables(thd,1,0))
{ // 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));
goto err;
}