diff options
-rw-r--r-- | sql/sql_base.cc | 41 | ||||
-rw-r--r-- | sql/sql_table.cc | 62 |
2 files changed, 52 insertions, 51 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 39e6f976f3b..47d709e8225 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -439,6 +439,9 @@ static void table_def_unuse_table(TABLE *table) { DBUG_ASSERT(table->in_use); + /* We shouldn't put the table to 'unused' list if the share is old. */ + DBUG_ASSERT(table->s->version == refresh_version); + table->in_use= 0; /* Remove table from the list of tables used in this share. */ table->s->used_tables.remove(table); @@ -2233,11 +2236,14 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, DBUG_ASSERT(table == thd->open_tables); handlerton *table_type= table->s->db_type(); - /* Ensure the table is removed from the cache. */ - table->s->version= 0; table->file->extra(HA_EXTRA_PREPARE_FOR_DROP); close_thread_table(thd, &thd->open_tables); + /* Remove the table share from the table cache. */ + mysql_mutex_lock(&LOCK_open); + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db_name, table_name); + mysql_mutex_unlock(&LOCK_open); + /* Remove the table from the storage engine and rm the .frm. */ quick_rm_table(table_type, db_name, table_name, 0); } DBUG_VOID_RETURN; @@ -3028,17 +3034,11 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, my_free(table, MYF(0)); if (error == 7) - { - share->version= 0; (void) ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER, table_list); - } else if (share->crashed) - { - share->version= 0; (void) ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR, table_list); - } goto err_unlock; } @@ -3824,7 +3824,7 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) TABLE_SHARE *share; TABLE *entry; int not_used; - bool result= FALSE; + bool result= TRUE; my_hash_value_type hash_value; cache_key_length= create_table_def_key(thd, cache_key, table_list, 0); @@ -3839,20 +3839,19 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) cache_key_length, OPEN_VIEW, ¬_used, hash_value))) - { - mysql_mutex_unlock(&LOCK_open); - return TRUE; - } + goto end_unlock; if (share->is_view) - goto end_with_lock_open; + { + release_table_share(share); + goto end_unlock; + } if (!(entry= (TABLE*)my_malloc(sizeof(TABLE), MYF(MY_WME)))) { - result= TRUE; - goto end_with_lock_open; + release_table_share(share); + goto end_unlock; } - share->version= 0; mysql_mutex_unlock(&LOCK_open); if (open_table_from_share(thd, share, table_list->alias, @@ -3871,19 +3870,21 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) share->table_name.str); if (entry->file) closefrm(entry, 0); - result= TRUE; } else { thd->clear_error(); // Clear error message closefrm(entry, 0); + result= FALSE; } my_free(entry, MYF(0)); mysql_mutex_lock(&LOCK_open); - -end_with_lock_open: release_table_share(share); + /* Remove the repaired share from the table cache. */ + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, + table_list->db, table_list->table_name); +end_unlock: mysql_mutex_unlock(&LOCK_open); return result; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 843fb5b35d2..3e9d26bd253 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -85,19 +85,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); -#ifndef DBUG_OFF - -/* Wait until we get a 'mysql_kill' signal */ - -static void wait_for_kill_signal(THD *thd) -{ - while (thd->killed == 0) - sleep(1); - // Reset signal and continue as if nothing happend - thd->killed= THD::NOT_KILLED; -} -#endif - /** @brief Helper function for explain_filename @@ -4877,18 +4864,30 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, /* purecov: end */ } - /* Close all instances of the table to allow repair to rename files */ - if (lock_type == TL_WRITE && table->table->s->version) + /* + Close all instances of the table to allow MyISAM "repair" + to rename files. + @todo: This code does not close all instances of the table. + It only closes instances in other connections, but if this + connection has LOCK TABLE t1 a READ, t1 b WRITE, + both t1 instances will be kept open. + There is no need to execute this branch for InnoDB, which does + repair by recreate. There is no need to do it for OPTIMIZE, + which doesn't move files around. + Hence, this code should be moved to prepare_for_repair(), + and executed only for MyISAM engine. + */ + if (lock_type == TL_WRITE && !table->table->s->tmp_table) { if (wait_while_table_is_used(thd, table->table, HA_EXTRA_PREPARE_FOR_RENAME)) goto err; - DBUG_EXECUTE_IF("wait_in_mysql_admin_table", - wait_for_kill_signal(thd); - if (thd->killed) - goto err;); /* Flush entries in the query cache involving this table. */ query_cache_invalidate3(thd, table->table, 0); + /* + XXX: hack: switch off open_for_modify to skip the + flush that is made later in the execution flow. + */ open_for_modify= 0; } @@ -5148,20 +5147,21 @@ send_result_message: } if (table->table) { - if (fatal_error) - table->table->s->version=0; // Force close of table - else if (open_for_modify) + if (table->table->s->tmp_table) { - if (table->table->s->tmp_table) + if (open_for_modify) table->table->file->info(HA_STATUS_CONST); - else - { - TABLE_LIST *save_next_global= table->next_global; - table->next_global= 0; - close_cached_tables(thd, table, FALSE, FALSE); - table->next_global= save_next_global; - } - /* May be something modified consequently we have to invalidate cache */ + } + else if (open_for_modify || fatal_error) + { + mysql_mutex_lock(&LOCK_open); + tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, + table->db, table->table_name); + mysql_mutex_unlock(&LOCK_open); + /* + May be something modified. Consequently, we have to + invalidate the query cache. + */ query_cache_invalidate3(thd, table->table, 0); } } |