summaryrefslogtreecommitdiff
path: root/sql/log_event.cc
diff options
context:
space:
mode:
authorunknown <guilhem@mysql.com>2003-08-20 23:24:45 +0200
committerunknown <guilhem@mysql.com>2003-08-20 23:24:45 +0200
commit1542fffb345693565a32f9a2e6a1eba980aeaaf2 (patch)
tree6d56c107522f2e75c11380e6351b948e3ce70832 /sql/log_event.cc
parentd43a347db179f4601465debc3bfd3cfbb87d1528 (diff)
downloadmariadb-git-1542fffb345693565a32f9a2e6a1eba980aeaaf2.tar.gz
First commit for fixing BUG#1100
"LOAD DATA INFILE is badly filtered by binlog-*-db rules". There will probably be a second final one to merge Dmitri's changes to rpl_log.result and mine. 2 new tests: rpl_loaddata_rule_m : test of logging of LOAD DATA INFILE when the master has binlog-*-db rules, rpl_loaddata_rule_s : test of logging of LOAD DATA INFILE when the slave has binlog-*-db rules and --log-slave-updates. mysql-test/r/rpl_loaddata.result: Test that logging of LOAD DATA INFILE is done on the slave mysql-test/t/rpl_loaddata.test: Test that logging of LOAD DATA is done on the slave sql/log.cc: debug info sql/log_event.cc: * Append_block, Exec_load and Delete_file now have a member 'db' like Create_file. This member is filled by mysql_load(). It is used for filtering by binlog-*-db rules, that's all. It's not written to the binlog, and so can't be read from the binlog. In other words, that's temporary info which is stored in the event and lost when it is written and deleted. * Better error messages in Append_block et al. events. * The slave now logs (log-slave-updates) the Create_file et al. events in mysql_load() (they are not directly copied from the events in the relay log, because this prevented filtering by binlog-*-db rules). Before, mysql_load() in the slave did no logging, now it does the logging, as in any regular thread. sql/log_event.h: New member 'db' for Append_block et al. events. sql/slave.cc: Removed useless code. Why was it useless: - CREATE_FILE_EVENT is not defined in 3.23. It appeared in 4.0. - in queue_old_event(), which is called only if the master is 3.23, we had a case CREATE_FILE_EVENT: so this case can be removed. - this case was the only caller of process_io_create_file() so this function can be removed. sql/sql_load.cc: Pass the db to events, so that they can be well filtered. sql/sql_repl.cc: Pass the db to events so that they can be well filtered.
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r--sql/log_event.cc69
1 files changed, 34 insertions, 35 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 2a1669737f8..407da85c38a 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1606,11 +1606,12 @@ void Create_file_log_event::pack_info(String* packet)
#endif
#ifndef MYSQL_CLIENT
-Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg,
+Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg,
+ char* block_arg,
uint block_len_arg,
bool using_trans)
:Log_event(thd_arg,0, using_trans), block(block_arg),
- block_len(block_len_arg), file_id(thd_arg->file_id)
+ block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
{
}
#endif
@@ -1654,8 +1655,9 @@ void Append_block_log_event::pack_info(String* packet)
net_store_data(packet, buf1);
}
-Delete_file_log_event::Delete_file_log_event(THD* thd_arg, bool using_trans)
- :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id)
+Delete_file_log_event::Delete_file_log_event(THD* thd_arg, const char* db_arg,
+ bool using_trans)
+ :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
{
}
#endif
@@ -1700,8 +1702,9 @@ void Delete_file_log_event::pack_info(String* packet)
#ifndef MYSQL_CLIENT
-Execute_load_log_event::Execute_load_log_event(THD* thd_arg, bool using_trans)
- :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id)
+Execute_load_log_event::Execute_load_log_event(THD* thd_arg, const char* db_arg,
+ bool using_trans)
+ :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
{
}
#endif
@@ -1905,7 +1908,19 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
DBUG_ASSERT(thd->query == 0);
thd->query = 0; // Should not be needed
thd->query_error = 0;
-
+
+ /*
+ We test replicate_*_db rules. Note that we have already prepared the file to
+ load, even if we are going to ignore and delete it now. So it is possible
+ that we did a lot of disk writes for nothing. In other words, a big LOAD
+ DATA INFILE on the master will still consume a lot of space on the slave
+ (space in the relay log + space of temp files: twice the space of the file
+ to load...) even if it will finally be ignored.
+ TODO: fix this; this can be done by testing rules in
+ Create_file_log_event::exec_event() and then discarding Append_block and
+ al. Another way is do the filtering in the I/O thread (more efficient: no
+ disk writes at all).
+ */
if (db_ok(thd->db, replicate_do_db, replicate_ignore_db))
{
thd->set_time((time_t)when);
@@ -2210,7 +2225,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
goto err;
}
@@ -2221,7 +2236,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
if (write_base(&file))
{
strmov(p, ".info"); // to have it right in the error message
- slave_print_error(rli,my_errno, "Could not write to file '%s'", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not write to file '%s'", fname_buf);
goto err;
}
end_io_cache(&file);
@@ -2231,16 +2246,14 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC,
MYF(MY_WME))) < 0)
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
goto err;
}
if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
{
- slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf);
+ slave_print_error(rli,my_errno, "Error in Create_file event: write to '%s' failed", fname_buf);
goto err;
}
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
error=0; // Everything is ok
err:
@@ -2259,8 +2272,6 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
(void) my_delete(fname, MYF(MY_WME));
memcpy(p, ".info", 6);
(void) my_delete(fname, MYF(MY_WME));
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
return Log_event::exec_event(rli);
}
@@ -2274,16 +2285,14 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
memcpy(p, ".data", 6);
if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0)
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname);
+ slave_print_error(rli,my_errno, "Error in Append_block event: could not open file '%s'", fname);
goto err;
}
if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
{
- slave_print_error(rli,my_errno, "Write to '%s' failed", fname);
+ slave_print_error(rli,my_errno, "Error in Append_block event: write to '%s' failed", fname);
goto err;
}
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
error=0;
err:
@@ -2298,7 +2307,6 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
char *p= slave_load_file_stem(fname, file_id, server_id);
int fd;
int error = 1;
- ulong save_options;
IO_CACHE file;
Load_log_event* lev = 0;
@@ -2307,7 +2315,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
- slave_print_error(rli,my_errno, "Could not open file '%s'", fname);
+ slave_print_error(rli,my_errno, "Error in Exec_load event: could not open file '%s'", fname);
goto err;
}
if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
@@ -2315,21 +2323,16 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
(bool)0)) ||
lev->get_type_code() != NEW_LOAD_EVENT)
{
- slave_print_error(rli,0, "File '%s' appears corrupted", fname);
+ slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname);
goto err;
}
- /*
- We want to disable binary logging in slave thread because we need the file
- events to appear in the same order as they do on the master relative to
- other events, so that we can preserve ascending order of log sequence
- numbers - needed to handle failover .
- */
- save_options = thd->options;
- thd->options &= ~ (ulong) (OPTION_BIN_LOG);
+
lev->thd = thd;
/*
lev->exec_event should use rli only for errors
- i.e. should not advance rli's position
+ i.e. should not advance rli's position.
+ lev->exec_event is the place where the table is loaded (it calls
+ mysql_load()).
*/
if (lev->exec_event(0,rli,1))
{
@@ -2350,15 +2353,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
tmp, fname);
my_free(tmp,MYF(0));
}
- thd->options= save_options;
goto err;
}
- thd->options = save_options;
(void) my_delete(fname, MYF(MY_WME));
memcpy(p, ".data", 6);
(void) my_delete(fname, MYF(MY_WME));
- if (mysql_bin_log.is_open())
- mysql_bin_log.write(this);
error = 0;
err: