From de3381459ba56cd3b29d436ea024b716c1e3f2fb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 19 Sep 2000 16:17:19 -0600 Subject: [PATCH] added reopen_name_locked_table() changed RESTORE TABLE to use name lock sql/mysql_priv.h: added reopen_name_locked_table() sql/sql_base.cc: added reopen_name_locked_table() sql/sql_table.cc: fixed repare_for_restore() to use fn_format() power changed RESTORE TABLE to use name lock --- sql/mysql_priv.h | 1 + sql/sql_base.cc | 41 +++++++++++++++++++++++++++++++++++++++++ sql/sql_table.cc | 32 ++++++++++++++++++++------------ 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2bf1a8f9305..f74dd0f281c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -328,6 +328,7 @@ int mysql_delete(THD *thd,TABLE_LIST *table,COND *conds,ha_rows rows, TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update); TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias, bool *refresh); +TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table); TABLE *find_locked_table(THD *thd, const char *db,const char *table_name); bool reopen_table(TABLE *table,bool locked=0); bool reopen_tables(THD *thd,bool get_locks,bool in_refresh); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a37506bcbf4..e5f8981d174 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -841,6 +841,47 @@ void wait_for_refresh(THD *thd) pthread_mutex_unlock(&thd->mysys_var->mutex); } +TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list) +{ + DBUG_ENTER("reopen_name_locked_table"); + if (thd->killed) + DBUG_RETURN(0); + TABLE* table; + if(!(table = table_list->table)) + DBUG_RETURN(0); + + char* db = thd->db ? thd->db : table_list->db; + char* table_name = table_list->name; + char key[MAX_DBKEY_LENGTH]; + uint key_length; + key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; + + pthread_mutex_lock(&LOCK_open); + if(open_unireg_entry(table, db, table_name, table_name) || + !(table->table_cache_key =memdup_root(&table->mem_root,(char*) key, + key_length))) + { + pthread_mutex_unlock(&LOCK_open); + DBUG_RETURN(0); + } + + table->key_length=key_length; + table->version=refresh_version; + table->flush_version=flush_version; + if (!key_cache_inited) + ha_key_cache(); + table->in_use = thd; + check_unused(); + pthread_mutex_unlock(&LOCK_open); + table->tablenr=thd->current_tablenr++; + table->used_fields=0; + table->const_table=0; + table->outer_join=table->null_row=table->maybe_null=0; + table->status=STATUS_NO_RECORD; + table->keys_in_use_for_query=table->used_keys= table->keys_in_use; + DBUG_RETURN(table); +} + /****************************************************************************** ** open a table diff --git a/sql/sql_table.cc b/sql/sql_table.cc index fa309a85bc5..19973ffd77b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -755,24 +755,32 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) { char* backup_dir = thd->lex.backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - int backup_dir_len = strlen(backup_dir); char* table_name = table->name; - int table_name_len = strlen(table_name); char* db = thd->db ? thd->db : table->db; - if(backup_dir_len + table_name_len + 4 >= FN_REFLEN) + if(!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64)) return -1; // protect buffer overflow - memcpy(src_path, backup_dir, backup_dir_len); - char* p = src_path + backup_dir_len; - *p++ = '/'; - memcpy(p, table_name, table_name_len); - p += table_name_len; - *p = 0; sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name); - if(my_copy(fn_format(src_path, src_path, "", reg_ext, 4), - fn_format(dst_path, dst_path, "", reg_ext, 4), + int lock_retcode; + pthread_mutex_lock(&LOCK_open); + if((lock_retcode = lock_table_name(thd, table)) < 0) + { + pthread_mutex_unlock(&LOCK_open); + return -1; + } + + if(lock_retcode && wait_for_locked_table_names(thd, table)) + { + pthread_mutex_unlock(&LOCK_open); + return -1; + } + pthread_mutex_unlock(&LOCK_open); + + if(my_copy(src_path, + fn_format(dst_path, dst_path,"", + reg_ext, 4), MYF(MY_WME))) { return send_check_errmsg(thd, table, "restore", @@ -840,7 +848,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, // now we should be able to open the partially restored table // to finish the restore in the handler later on - table->table = open_ltable(thd, table, lock_type); + table->table = reopen_name_locked_table(thd, table); } if (!table->table)