diff options
author | dlenev@mockturtle.local <> | 2007-01-20 14:10:20 +0300 |
---|---|---|
committer | dlenev@mockturtle.local <> | 2007-01-20 14:10:20 +0300 |
commit | 92704745f773421fdae49685796af41abe122472 (patch) | |
tree | 3af61fe7c1d7f9ed8ecb82fdf2521316c54e0e72 /sql/sql_table.cc | |
parent | 4064c89d2400a910e24813ce633f5c9522d1a321 (diff) | |
parent | 7b1a94ef78956cdcda7994faafafa5f349f6f123 (diff) | |
download | mariadb-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.cc | 25 |
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"; |