diff options
author | guilhem@mysql.com <> | 2003-09-11 23:17:28 +0200 |
---|---|---|
committer | guilhem@mysql.com <> | 2003-09-11 23:17:28 +0200 |
commit | 59663fc661891a375f59a87d17ed9545175975be (patch) | |
tree | 17368ba287e00c5ee8a4b28a65a34bbf5fb4e4f5 /sql | |
parent | 99490870e6fbc26208d044d712e28b1095f0aada (diff) | |
download | mariadb-git-59663fc661891a375f59a87d17ed9545175975be.tar.gz |
* Fix for BUG#1248: "LOAD DATA FROM MASTER drops the slave's db unexpectedly".
Now LOAD DATA FROM MASTER does not drop the database, instead it only tries to
create it, and drops/creates table-by-table.
* replicate_wild_ignore_table='db1.%' is now considered as "ignore the 'db1'
database as a whole", as it already works for CREATE DATABASE and DROP DATABASE.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/repl_failsafe.cc | 14 | ||||
-rw-r--r-- | sql/slave.cc | 45 | ||||
-rw-r--r-- | sql/slave.h | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 7 |
4 files changed, 49 insertions, 21 deletions
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index dc3f3c87dde..8deb23e8586 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -717,7 +717,8 @@ static int fetch_db_tables(THD *thd, MYSQL *mysql, const char *db, if (!tables_ok(thd, &table)) continue; } - if ((error= fetch_master_table(thd, db, table_name, mi, mysql))) + /* download master's table and overwrite slave's table */ + if ((error= fetch_master_table(thd, db, table_name, mi, mysql, 1))) return error; } return 0; @@ -819,8 +820,11 @@ int load_master_data(THD* thd) char* db = row[0]; /* - Do not replicate databases excluded by rules - also skip mysql database - in most cases the user will + Do not replicate databases excluded by rules. We also test + replicate_wild_*_table rules (replicate_wild_ignore_table='db1.%' will + be considered as "ignore the 'db1' database as a whole, as it already + works for CREATE DATABASE and DROP DATABASE). + Also skip 'mysql' database - in most cases the user will mess up and not exclude mysql database with the rules when he actually means to - in this case, he is up for a surprise if his priv tables get dropped and downloaded from master @@ -830,14 +834,14 @@ int load_master_data(THD* thd) */ if (!db_ok(db, replicate_do_db, replicate_ignore_db) || + !db_ok_with_wild_table(db) || !strcmp(db,"mysql")) { *cur_table_res = 0; continue; } - if (mysql_rm_db(thd, db, 1,1) || - mysql_create_db(thd, db, 0, 1)) + if (mysql_create_db(thd, db, HA_LEX_CREATE_IF_NOT_EXISTS, 1)) { send_error(&thd->net, 0, 0); cleanup_mysql_results(db_res, cur_table_res - 1, table_res); diff --git a/sql/slave.cc b/sql/slave.cc index 1bc8dfc5b78..10d451a88bc 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -72,7 +72,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed, void* thread_killed_arg); static int request_table_dump(MYSQL* mysql, const char* db, const char* table); static int create_table_from_dump(THD* thd, NET* net, const char* db, - const char* table_name); + const char* table_name, bool overwrite); static int check_master_version(MYSQL* mysql, MASTER_INFO* mi); @@ -1033,12 +1033,22 @@ static int check_master_version(MYSQL* mysql, MASTER_INFO* mi) return 0; } +/* + Used by fetch_master_table (used by LOAD TABLE tblname FROM MASTER and LOAD + DATA FROM MASTER). Drops the table (if 'overwrite' is true) and recreates it + from the dump. Honours replication inclusion/exclusion rules. + + RETURN VALUES + 0 success + 1 error +*/ static int create_table_from_dump(THD* thd, NET* net, const char* db, - const char* table_name) + const char* table_name, bool overwrite) { ulong packet_len = my_net_read(net); // read create table statement char *query; + char* save_db; Vio* save_vio; HA_CHECK_OPT check_opt; TABLE_LIST tables; @@ -1078,13 +1088,24 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, thd->current_tablenr = 0; thd->query_error = 0; thd->net.no_send_ok = 1; + + bzero((char*) &tables,sizeof(tables)); + tables.db = (char*)db; + tables.alias= tables.real_name= (char*)table_name; + /* Drop the table if 'overwrite' is true */ + if (overwrite && mysql_rm_table(thd,&tables,1)) /* drop if exists */ + { + send_error(&thd->net); + sql_print_error("create_table_from_dump: failed to drop the table"); + goto err; + } - /* we do not want to log create table statement */ + /* Create the table. We do not want to log the "create table" statement */ save_options = thd->options; thd->options &= ~(ulong) (OPTION_BIN_LOG); thd->proc_info = "Creating table from master dump"; // save old db in case we are creating in a different database - char* save_db = thd->db; + save_db = thd->db; thd->db = (char*)db; mysql_parse(thd, thd->query, packet_len); // run create table thd->db = save_db; // leave things the way the were before @@ -1093,11 +1114,8 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, if (thd->query_error) goto err; // mysql_parse took care of the error send - bzero((char*) &tables,sizeof(tables)); - tables.db = (char*)db; - tables.alias= tables.real_name= (char*)table_name; - tables.lock_type = TL_WRITE; thd->proc_info = "Opening master dump table"; + tables.lock_type = TL_WRITE; if (!open_ltable(thd, &tables, TL_WRITE)) { send_error(&thd->net,0,0); // Send error from open_ltable @@ -1107,10 +1125,11 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, file = tables.table->file; thd->proc_info = "Reading master dump table data"; + /* Copy the data file */ if (file->net_read_dump(net)) { net_printf(&thd->net, ER_MASTER_NET_READ); - sql_print_error("create_table_from_dump::failed in\ + sql_print_error("create_table_from_dump: failed in\ handler::net_read_dump()"); goto err; } @@ -1125,6 +1144,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db, */ save_vio = thd->net.vio; thd->net.vio = 0; + /* Rebuild the index file from the copied data file (with REPAIR) */ error=file->repair(thd,&check_opt) != 0; thd->net.vio = save_vio; if (error) @@ -1137,7 +1157,7 @@ err: } int fetch_master_table(THD *thd, const char *db_name, const char *table_name, - MASTER_INFO *mi, MYSQL *mysql) + MASTER_INFO *mi, MYSQL *mysql, bool overwrite) { int error= 1; const char *errmsg=0; @@ -1169,9 +1189,10 @@ int fetch_master_table(THD *thd, const char *db_name, const char *table_name, errmsg= "Failed on table dump request"; goto err; } + if (create_table_from_dump(thd, &mysql->net, db_name, - table_name)) - goto err; // create_table_from_dump will have sent the error already + table_name, overwrite)) + goto err; // create_table_from_dump will have send_error already error = 0; err: diff --git a/sql/slave.h b/sql/slave.h index 67bf009763b..f61891acc91 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -384,9 +384,9 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock, int mysql_table_dump(THD* thd, const char* db, const char* tbl_name, int fd = -1); -/* retrieve non-exitent table from master */ +/* retrieve table from master and copy to slave*/ int fetch_master_table(THD* thd, const char* db_name, const char* table_name, - MASTER_INFO* mi, MYSQL* mysql); + MASTER_INFO* mi, MYSQL* mysql, bool overwrite); int show_master_info(THD* thd, MASTER_INFO* mi); int show_binlog_info(THD* thd); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4d010ac9a4b..0c4e3cad763 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1568,9 +1568,12 @@ mysql_execute_command(void) goto error; } LOCK_ACTIVE_MI; - // fetch_master_table will send the error to the client on failure + /* + fetch_master_table will send the error to the client on failure. + Give error if the table already exists. + */ if (!fetch_master_table(thd, tables->db, tables->real_name, - active_mi, 0)) + active_mi, 0, 0)) { send_ok(&thd->net); } |