summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authordlenev@mockturtle.local <>2007-01-20 14:10:20 +0300
committerdlenev@mockturtle.local <>2007-01-20 14:10:20 +0300
commit92704745f773421fdae49685796af41abe122472 (patch)
tree3af61fe7c1d7f9ed8ecb82fdf2521316c54e0e72 /sql/sql_table.cc
parent4064c89d2400a910e24813ce633f5c9522d1a321 (diff)
parent7b1a94ef78956cdcda7994faafafa5f349f6f123 (diff)
downloadmariadb-git-92704745f773421fdae49685796af41abe122472.tar.gz
Merge bk-internal.mysql.com:/home/bk/mysql-5.0-runtime
into mockturtle.local:/home/dlenev/src/mysql-5.0-bg25044
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc25
1 files changed, 23 insertions, 2 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 4f5f4c29854..d9dadfbfd81 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3163,19 +3163,30 @@ view_err:
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
!table->s->tmp_table) // no need to touch frm
{
- VOID(pthread_mutex_lock(&LOCK_open));
-
switch (alter_info->keys_onoff) {
case LEAVE_AS_IS:
error= 0;
break;
case ENABLE:
+ /*
+ wait_while_table_is_used() ensures that table being altered is
+ opened only by this thread and that TABLE::TABLE_SHARE::version
+ of TABLE object corresponding to this table is 0.
+ The latter guarantees that no DML statement will open this table
+ until ALTER TABLE finishes (i.e. until close_thread_tables())
+ while the fact that the table is still open gives us protection
+ from concurrent DDL statements.
+ */
+ VOID(pthread_mutex_lock(&LOCK_open));
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
+ VOID(pthread_mutex_unlock(&LOCK_open));
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* 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, HA_EXTRA_FORCE_REOPEN);
+ VOID(pthread_mutex_unlock(&LOCK_open));
error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
/* COND_refresh will be signaled in close_thread_tables() */
break;
@@ -3188,6 +3199,16 @@ view_err:
error= 0;
}
+ VOID(pthread_mutex_lock(&LOCK_open));
+ /*
+ Unlike to the above case close_cached_table() below will remove ALL
+ instances of TABLE from table cache (it will also remove table lock
+ held by this thread). So to make actual table renaming and writing
+ to binlog atomic we have to put them into the same critical section
+ protected by LOCK_open mutex. This also removes gap for races between
+ access() and mysql_rename_table() calls.
+ */
+
if (!error && (new_name != table_name || new_db != db))
{
thd->proc_info="rename";