diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.cc | 3 | ||||
-rw-r--r-- | sql/lock.cc | 19 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 4 | ||||
-rw-r--r-- | sql/sql_base.cc | 46 |
5 files changed, 62 insertions, 11 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index fb33888e91e..52ec910dd01 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -473,7 +473,8 @@ int handler::ha_open(const char *name, int mode, int test_if_locked) int error; DBUG_ENTER("handler::open"); DBUG_PRINT("enter",("name: %s db_type: %d db_stat: %d mode: %d lock_test: %d", - name, table->db_type, table->db_stat, mode, test_if_locked)); + name, table->db_type, table->db_stat, mode, + test_if_locked)); if ((error=open(name,mode,test_if_locked))) { diff --git a/sql/lock.cc b/sql/lock.cc index 4c84bbb6e69..64456e6ec36 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -313,6 +313,25 @@ void mysql_lock_abort(THD *thd, TABLE *table) } +/* Abort one thread / table combination */ + +void mysql_lock_abort_for_thread(THD *thd, TABLE *table) +{ + MYSQL_LOCK *locked; + TABLE *write_lock_used; + DBUG_ENTER("mysql_lock_abort_for_thread"); + + if ((locked = get_lock_data(thd,&table,1,1,&write_lock_used))) + { + for (uint i=0; i < locked->lock_count; i++) + thr_abort_locks_for_thread(locked->locks[i]->lock, + table->in_use->real_id); + my_free((gptr) locked,MYF(0)); + } + DBUG_VOID_RETURN; +} + + MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b) { MYSQL_LOCK *sql_lock; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 83b41359192..7d830859fb2 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -711,6 +711,7 @@ void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock); void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count); void mysql_lock_remove(THD *thd, MYSQL_LOCK *locked,TABLE *table); void mysql_lock_abort(THD *thd, TABLE *table); +void mysql_lock_abort_for_thread(THD *thd, TABLE *table); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); bool lock_global_read_lock(THD *thd); void unlock_global_read_lock(THD *thd); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2e47312f588..a5241d33132 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4416,8 +4416,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case (int) OPT_SAFE: opt_specialflag|= SPECIAL_SAFE_MODE; delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE; - myisam_recover_options= HA_RECOVER_NONE; // To be changed - ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE); + myisam_recover_options= HA_RECOVER_DEFAULT; + ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE); break; case (int) OPT_SKIP_PRIOR: opt_specialflag|= SPECIAL_NO_PRIOR; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b53c05c0357..4d1e57f0c1e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1244,25 +1244,44 @@ bool drop_locked_tables(THD *thd,const char *db, const char *table_name) } -/* lock table to force abort of any threads trying to use table */ +/* + If we have the table open, which only happens when a LOCK TABLE has been + done on the table, change the lock type to a lock that will abort all + other threads trying to get the lock. +*/ void abort_locked_tables(THD *thd,const char *db, const char *table_name) { TABLE *table; - for (table=thd->open_tables; table ; table=table->next) + for (table= thd->open_tables; table ; table= table->next) { if (!strcmp(table->real_name,table_name) && !strcmp(table->table_cache_key,db)) + { mysql_lock_abort(thd,table); + break; + } } } -/**************************************************************************** -** open_unireg_entry -** Purpose : Load a table definition from file and open unireg table -** Args : entry with DB and table given -** Returns : 0 if ok -** Note that the extra argument for open is taken from thd->open_options + +/* + Load a table definition from file and open unireg table + + SYNOPSIS + open_unireg_entry() + thd Thread handle + entry Store open table definition here + db Database name + name Table name + alias Alias name + + NOTES + Extra argument for open is taken from thd->open_options + + RETURN + 0 ok + # Error */ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db, @@ -2277,6 +2296,17 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, } pthread_mutex_unlock(&in_use->mysys_var->mutex); } + /* + Now we must abort all tables locks used by this thread + as the thread may be waiting to get a lock for another table + */ + for (TABLE *thd_table= in_use->open_tables; + thd_table ; + thd_table= thd_table->next) + { + if (thd_table->db_stat) // If table is open + mysql_lock_abort_for_thread(thd, thd_table); + } } else result= result || return_if_owned_by_thd; |