summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorguilhem@mysql.com <>2003-09-11 23:17:28 +0200
committerguilhem@mysql.com <>2003-09-11 23:17:28 +0200
commit59663fc661891a375f59a87d17ed9545175975be (patch)
tree17368ba287e00c5ee8a4b28a65a34bbf5fb4e4f5 /sql
parent99490870e6fbc26208d044d712e28b1095f0aada (diff)
downloadmariadb-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.cc14
-rw-r--r--sql/slave.cc45
-rw-r--r--sql/slave.h4
-rw-r--r--sql/sql_parse.cc7
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);
}