mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
Merge work:/home/bk/mysql
into mysql.sashanet.com:/home/sasha/src/bk/mysql
This commit is contained in:
commit
96b2e90852
5 changed files with 128 additions and 13 deletions
|
@ -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);
|
||||
|
|
|
@ -921,7 +921,7 @@ static void safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi)
|
|||
mi->port, 0, 0))
|
||||
{
|
||||
sql_print_error(
|
||||
"Slave thread: error connecting to slave:%s, retry in %d sec",
|
||||
"Slave thread: error connecting to master:%s, retry in %d sec",
|
||||
mc_mysql_error(mysql), mi->connect_retry);
|
||||
safe_sleep(thd, mi->connect_retry);
|
||||
}
|
||||
|
|
|
@ -841,6 +841,49 @@ 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=0;
|
||||
table->flush_version=0;
|
||||
if (!key_cache_inited)
|
||||
ha_key_cache();
|
||||
table->in_use = thd;
|
||||
check_unused();
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
table->next = thd->open_tables;
|
||||
thd->open_tables = table;
|
||||
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)
|
||||
|
|
63
tests/restore-lock.smack
Executable file
63
tests/restore-lock.smack
Executable file
|
@ -0,0 +1,63 @@
|
|||
#! /usr/local/bin/mysql-super-smack
|
||||
|
||||
query "select"
|
||||
{
|
||||
type "select";
|
||||
query "select count(*) from w";
|
||||
has_result_set "y";
|
||||
parsed "n";
|
||||
}
|
||||
|
||||
query "restore"
|
||||
{
|
||||
type "restore";
|
||||
query "restore table w from '/tmp'";
|
||||
has_result_set "y";
|
||||
parsed "n";
|
||||
}
|
||||
|
||||
query "drop"
|
||||
{
|
||||
type "drop";
|
||||
query "drop table if exists w";
|
||||
has_result_set "n";
|
||||
parsed "n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
client "restorer"
|
||||
{
|
||||
user "root";
|
||||
pass "";
|
||||
host "localhost";
|
||||
db "test";
|
||||
query_barrel "1 drop 1 restore";
|
||||
}
|
||||
|
||||
client "selector"
|
||||
{
|
||||
user "root";
|
||||
pass "";
|
||||
host "localhost";
|
||||
db "test";
|
||||
query_barrel "-3 1 select";
|
||||
}
|
||||
|
||||
main
|
||||
{
|
||||
selector.init();
|
||||
restorer.init();
|
||||
selector.create_threads(1);
|
||||
restorer.create_threads(1);
|
||||
selector.set_num_rounds(1);
|
||||
restorer.set_num_rounds(1);
|
||||
selector.connect();
|
||||
restorer.connect();
|
||||
restorer.unload_query_barrel();
|
||||
selector.unload_query_barrel();
|
||||
restorer.collect_threads();
|
||||
selector.collect_threads();
|
||||
selector.disconnect();
|
||||
restorer.disconnect();
|
||||
}
|
Loading…
Reference in a new issue