added reopen_name_locked_table()

changed RESTORE TABLE to use name lock
parent ce8f1b23
......@@ -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);
......
......@@ -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
......
......@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment