Below is the list of changes that have just been committed into a local
5.1 repository of mats. When mats does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-01-18 09:46:42+01:00, mats@romeo.(none) +11 -0
Merge romeo.(none):/home/bkroot/mysql-5.1-new-rpl
into romeo.(none):/home/bk/b23171-mysql-5.1-new-rpl
MERGE: 1.2303.45.19
mysql-test/r/rpl_row_tabledefs_2myisam.result@stripped, 2007-01-18 09:24:20+01:00,
mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.6.2.1
mysql-test/r/rpl_row_tabledefs_3innodb.result@stripped, 2007-01-18 09:24:20+01:00,
mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.3.2.1
sql/log.cc@stripped, 2007-01-18 09:24:20+01:00, mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.237.6.3
sql/log_event.cc@stripped, 2007-01-18 09:46:36+01:00, mats@romeo.(none) +0 -6
Manual merge
MERGE: 1.246.2.6
sql/log_event.h@stripped, 2007-01-18 09:24:21+01:00, mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.136.1.9
sql/rpl_rli.cc@stripped, 2007-01-18 09:24:21+01:00, mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.2.1.2
sql/rpl_rli.h@stripped, 2007-01-18 09:24:21+01:00, mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.7.1.1
sql/rpl_utility.cc@stripped, 2007-01-18 09:24:21+01:00, mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.3.1.3
sql/rpl_utility.h@stripped, 2007-01-18 09:24:21+01:00, mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.2.1.2
sql/slave.cc@stripped, 2007-01-18 09:46:36+01:00, mats@romeo.(none) +1 -2
Manual merge
MERGE: 1.293.1.9
sql/slave.h@stripped, 2007-01-18 09:24:22+01:00, mats@romeo.(none) +0 -0
Auto merged
MERGE: 1.102.1.1
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: mats
# Host: romeo.(none)
# Root: /home/bk/b23171-mysql-5.1-new-rpl/RESYNC
--- 1.253/sql/log.cc 2007-01-18 09:46:51 +01:00
+++ 1.254/sql/log.cc 2007-01-18 09:46:51 +01:00
@@ -1544,7 +1544,7 @@
do nothing.
just pretend we can do 2pc, so that MySQL won't
switch to 1pc.
- real work will be done in MYSQL_BIN_LOG::log()
+ real work will be done in TC_LOG_BINLOG::log()
*/
return 0;
}
@@ -1558,9 +1558,15 @@
IO_CACHE *trans_log= &trx_data->trans_log;
DBUG_ASSERT(mysql_bin_log.is_open());
- if (all && trx_data->empty())
+ /*
+ The condition here has to be identical to the one inside
+ binlog_end_trans(), guarding the write of the transaction cache to
+ the binary log.
+ */
+ if ((all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) &&
+ trx_data->empty())
{
- // we're here because trans_log was flushed in MYSQL_BIN_LOG::log()
+ // we're here because trans_log was flushed in TC_LOG_BINLOG::log()
trx_data->reset();
DBUG_RETURN(0);
}
@@ -2513,7 +2519,7 @@
/*
Set 'created' to 0, so that in next relay logs this event does not
trigger cleaning actions on the slave in
- Format_description_log_event::exec_event().
+ Format_description_log_event::apply_event_impl().
*/
description_event_for_queue->created= 0;
/* Don't set log_pos in event header */
@@ -3219,8 +3225,10 @@
{
tc_log_page_waits++;
pthread_mutex_lock(&LOCK_prep_xids);
- while (prepared_xids)
+ while (prepared_xids) {
+ DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
pthread_cond_wait(&COND_prep_xids, &LOCK_prep_xids);
+ }
pthread_mutex_unlock(&LOCK_prep_xids);
}
@@ -5066,8 +5074,10 @@
{
pthread_mutex_lock(&LOCK_prep_xids);
DBUG_ASSERT(prepared_xids > 0);
- if (--prepared_xids == 0)
+ if (--prepared_xids == 0) {
+ DBUG_PRINT("info", ("prepared_xids=%lu", prepared_xids));
pthread_cond_signal(&COND_prep_xids);
+ }
pthread_mutex_unlock(&LOCK_prep_xids);
rotate_and_purge(0); // as ::write() did not rotate
}
--- 1.262/sql/log_event.cc 2007-01-18 09:46:51 +01:00
+++ 1.263/sql/log_event.cc 2007-01-18 09:46:51 +01:00
@@ -88,9 +88,10 @@
operator&()
DESCRIPTION
- Function to return a pointer to the internal, so that the object
- can be treated as a IO_CACHE and used with the my_b_* IO_CACHE
- functions
+
+ Function to return a pointer to the internal cache, so that the
+ object can be treated as a IO_CACHE and used with the my_b_*
+ IO_CACHE functions
RETURN VALUE
A pointer to the internal IO_CACHE.
@@ -545,25 +546,19 @@
#ifndef MYSQL_CLIENT
#ifdef HAVE_REPLICATION
-/*
- Log_event::exec_event()
-*/
-
-int Log_event::exec_event(struct st_relay_log_info* rli)
+int Log_event::do_update_pos(RELAY_LOG_INFO *rli)
{
- DBUG_ENTER("Log_event::exec_event");
-
/*
- rli is null when (as far as I (Guilhem) know)
- the caller is
- Load_log_event::exec_event *and* that one is called from
- Execute_load_log_event::exec_event.
- In this case, we don't do anything here ;
- Execute_load_log_event::exec_event will call Log_event::exec_event
- again later with the proper rli.
- Strictly speaking, if we were sure that rli is null
- only in the case discussed above, 'if (rli)' is useless here.
- But as we are not 100% sure, keep it for now.
+ rli is null when (as far as I (Guilhem) know) the caller is
+ Load_log_event::do_apply_event *and* that one is called from
+ Execute_load_log_event::do_apply_event. In this case, we don't
+ do anything here ; Execute_load_log_event::do_apply_event will
+ call Log_event::do_apply_event again later with the proper rli.
+ Strictly speaking, if we were sure that rli is null only in the
+ case discussed above, 'if (rli)' is useless here. But as we are
+ not 100% sure, keep it for now.
+
+ Matz: I don't think we will need this check with this refactoring.
*/
if (rli)
{
@@ -598,18 +593,31 @@
{
rli->inc_group_relay_log_pos(log_pos);
flush_relay_log_info(rli);
- /*
- Note that Rotate_log_event::exec_event() does not call this
- function, so there is no chance that a fake rotate event resets
- last_master_timestamp.
- Note that we update without mutex (probably ok - except in some very
- rare cases, only consequence is that value may take some time to
- display in Seconds_Behind_Master - not critical).
+ /*
+ Note that Rotate_log_event::do_apply_event() does not call
+ this function, so there is no chance that a fake rotate event
+ resets last_master_timestamp. Note that we update without
+ mutex (probably ok - except in some very rare cases, only
+ consequence is that value may take some time to display in
+ Seconds_Behind_Master - not critical).
*/
rli->last_master_timestamp= when;
}
}
- DBUG_RETURN(0);
+
+ return 0; // Cannot fail currently
+}
+
+
+Log_event::enum_skip_reason
+Log_event::shall_skip(RELAY_LOG_INFO *rli)
+{
+ if (this->server_id == ::server_id && !replicate_same_server_id)
+ return EVENT_SKIP_SAME_SID;
+ else if (rli->slave_skip_counter > 0)
+ return EVENT_SKIP_COUNT;
+ else
+ return EVENT_NOT_SKIPPED;
}
@@ -756,7 +764,7 @@
ulong data_len;
int result=0;
char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
- DBUG_ENTER("read_log_event");
+ DBUG_ENTER("Log_event::read_log_event");
if (log_lock)
pthread_mutex_lock(log_lock);
@@ -831,7 +839,7 @@
const Format_description_log_event
*description_event)
#endif
{
- DBUG_ENTER("Log_event::read_log_event(IO_CACHE *, Format_description_log_event *");
+ DBUG_ENTER("Log_event::read_log_event");
DBUG_ASSERT(description_event != 0);
char head[LOG_EVENT_MINIMAL_HEADER_LEN];
/*
@@ -1869,27 +1877,28 @@
/*
- Query_log_event::exec_event()
+ Query_log_event::do_apply_event()
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Query_log_event::exec_event(struct st_relay_log_info* rli)
+int Query_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
- return exec_event(rli, query, q_len);
+ return do_apply_event(rli, query, q_len);
}
-int Query_log_event::exec_event(struct st_relay_log_info* rli,
- const char *query_arg, uint32 q_len_arg)
+int Query_log_event::do_apply_event(RELAY_LOG_INFO const *rli,
+ const char *query_arg, uint32 q_len_arg)
{
LEX_STRING new_db;
int expected_error,actual_error= 0;
/*
- Colleagues: please never free(thd->catalog) in MySQL. This would lead to
- bugs as here thd->catalog is a part of an alloced block, not an entire
- alloced block (see Query_log_event::exec_event()). Same for thd->db.
- Thank you.
+ Colleagues: please never free(thd->catalog) in MySQL. This would
+ lead to bugs as here thd->catalog is a part of an alloced block,
+ not an entire alloced block (see
+ Query_log_event::do_apply_event()). Same for thd->db. Thank
+ you.
*/
thd->catalog= catalog_len ? (char *) catalog : (char *)"";
new_db.length= db_len;
@@ -1908,11 +1917,11 @@
END of the current log event (COMMIT). We save it in rli so that InnoDB can
access it.
*/
- rli->future_group_master_log_pos= log_pos;
+ const_cast<RELAY_LOG_INFO*>(rli)->future_group_master_log_pos= log_pos;
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
- clear_all_errors(thd, rli);
- rli->clear_tables_to_lock();
+ clear_all_errors(thd, const_cast<RELAY_LOG_INFO*>(rli));
+ const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
/*
Note: We do not need to execute reset_one_shot_variables() if this
@@ -1921,8 +1930,8 @@
its companion query. If the SET is ignored because of
db_ok(), the companion query will also be ignored, and if
the companion query is ignored in the db_ok() test of
- ::exec_event(), then the companion SET also have so we
- don't need to reset_one_shot_variables().
+ ::do_apply_event(), then the companion SET also have so
+ we don't need to reset_one_shot_variables().
*/
if (rpl_filter->db_ok(thd->db))
{
@@ -2024,7 +2033,7 @@
to check/fix it.
*/
if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
- clear_all_errors(thd, rli); /* Can ignore query */
+ clear_all_errors(thd, const_cast<RELAY_LOG_INFO*>(rli)); /* Can ignore
query */
else
{
slave_print_msg(ERROR_LEVEL, rli, expected_error,
@@ -2075,7 +2084,7 @@
ignored_error_code(actual_error))
{
DBUG_PRINT("info",("error ignored"));
- clear_all_errors(thd, rli);
+ clear_all_errors(thd, const_cast<RELAY_LOG_INFO*>(rli));
}
/*
Other cases: mostly we expected no error and get one.
@@ -2142,16 +2151,26 @@
thd->first_successful_insert_id_in_prev_stmt= 0;
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
+ return thd->query_error;
+}
+
+int Query_log_event::do_update_pos(RELAY_LOG_INFO *rli)
+{
/*
- If there was an error we stop. Otherwise we increment positions. Note that
- we will not increment group* positions if we are just after a SET
- ONE_SHOT, because SET ONE_SHOT should not be separated from its following
- updating query.
- */
- return (thd->query_error ? thd->query_error :
- (thd->one_shot_set ? (rli->inc_event_relay_log_pos(),0) :
- Log_event::exec_event(rli)));
+ Note that we will not increment group* positions if we are just
+ after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
+ from its following updating query.
+ */
+ if (thd->one_shot_set)
+ {
+ rli->inc_event_relay_log_pos();
+ return 0;
+ }
+ else
+ return Log_event::do_update_pos(rli);
}
+
+
#endif
@@ -2278,7 +2297,7 @@
/*
- Start_log_event_v3::exec_event()
+ Start_log_event_v3::do_apply_event()
The master started
@@ -2297,9 +2316,9 @@
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Start_log_event_v3::exec_event(struct st_relay_log_info* rli)
+int Start_log_event_v3::do_apply_event(RELAY_LOG_INFO const *rli)
{
- DBUG_ENTER("Start_log_event_v3::exec_event");
+ DBUG_ENTER("Start_log_event_v3::do_apply_event");
switch (binlog_version)
{
case 3:
@@ -2341,7 +2360,7 @@
/* this case is impossible */
DBUG_RETURN(1);
}
- DBUG_RETURN(Log_event::exec_event(rli));
+ DBUG_RETURN(0);
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -2528,24 +2547,10 @@
}
#endif
-/*
- SYNOPSIS
- Format_description_log_event::exec_event()
-
- IMPLEMENTATION
- Save the information which describes the binlog's format, to be able to
- read all coming events.
- Call Start_log_event_v3::exec_event().
-*/
-
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
+int Format_description_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
- DBUG_ENTER("Format_description_log_event::exec_event");
-
- /* save the information describing this binlog */
- delete rli->relay_log.description_event_for_exec;
- rli->relay_log.description_event_for_exec= this;
+ DBUG_ENTER("Format_description_log_event::do_apply_event");
#ifdef USING_TRANSACTIONS
/*
@@ -2567,14 +2572,36 @@
"or ROLLBACK in relay log). A probable cause is that "
"the master died while writing the transaction to "
"its binary log, thus rolled back too.");
- rli->cleanup_context(thd, 1);
+ const_cast<RELAY_LOG_INFO*>(rli)->cleanup_context(thd, 1);
}
#endif
/*
- If this event comes from ourselves, there is no cleaning task to perform,
- we don't call Start_log_event_v3::exec_event() (this was just to update the
- log's description event).
+ If this event comes from ourselves, there is no cleaning task to
+ perform, we don't call Start_log_event_v3::do_apply_event()
+ (this was just to update the log's description event).
*/
+ if (server_id != (uint32) ::server_id)
+ {
+ /*
+ If the event was not requested by the slave i.e. the master sent
+ it while the slave asked for a position >4, the event will make
+ rli->group_master_log_pos advance. Say that the slave asked for
+ position 1000, and the Format_desc event's end is 96. Then in
+ the beginning of replication rli->group_master_log_pos will be
+ 0, then 96, then jump to first really asked event (which is
+ >96). So this is ok.
+ */
+ DBUG_RETURN(Start_log_event_v3::do_apply_event(rli));
+ }
+ DBUG_RETURN(0);
+}
+
+int Format_description_log_event::do_update_pos(RELAY_LOG_INFO *rli)
+{
+ /* save the information describing this binlog */
+ delete rli->relay_log.description_event_for_exec;
+ rli->relay_log.description_event_for_exec= this;
+
if (server_id == (uint32) ::server_id)
{
/*
@@ -2591,19 +2618,20 @@
the Intvar_log_event respectively.
*/
rli->inc_event_relay_log_pos();
- DBUG_RETURN(0);
+ return 0;
+ }
+ else
+ {
+ return Log_event::do_update_pos(rli);
}
+}
- /*
- If the event was not requested by the slave i.e. the master sent it while
- the slave asked for a position >4, the event will make
- rli->group_master_log_pos advance. Say that the slave asked for position
- 1000, and the Format_desc event's end is 96. Then in the beginning of
- replication rli->group_master_log_pos will be 0, then 96, then jump to
- first really asked event (which is >96). So this is ok.
- */
- DBUG_RETURN(Start_log_event_v3::exec_event(rli));
+Log_event::enum_skip_reason
+Format_description_log_event::shall_skip(RELAY_LOG_INFO *rli)
+{
+ return Log_event::EVENT_NOT_SKIPPED;
}
+
#endif
/**************************************************************************
@@ -3086,30 +3114,32 @@
Does the data loading job when executing a LOAD DATA on the slave
SYNOPSIS
- Load_log_event::exec_event
- net
- rli
- use_rli_only_for_errors - if set to 1, rli is provided to
- Load_log_event::exec_event only for this
- function to have RPL_LOG_NAME and
- rli->last_slave_error, both being used by
- error reports. rli's position advancing
- is skipped (done by the caller which is
- Execute_load_log_event::exec_event).
- - if set to 0, rli is provided for full use,
- i.e. for error reports and position
- advancing.
+ Load_log_event::do_apply_event
+ net
+ rli
+ use_rli_only_for_errors - if set to 1, rli is provided to
+ Load_log_event::do_apply_event
+ only for this function to have
+ RPL_LOG_NAME and
+ rli->last_slave_error, both being
+ used by error reports. rli's
+ position advancing is skipped (done
+ by the caller which is
+ Execute_load_log_event::do_apply_event).
+ - if set to 0, rli is provided for
+ full use, i.e. for error reports and
+ position advancing.
DESCRIPTION
Does the data loading job when executing a LOAD DATA on the slave
-
+
RETURN VALUE
- 0 Success
+ 0 Success
1 Failure
*/
-int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
- bool use_rli_only_for_errors)
+int Load_log_event::do_apply_event(NET* net, RELAY_LOG_INFO const *rli,
+ bool use_rli_only_for_errors)
{
LEX_STRING new_db;
new_db.length= db_len;
@@ -3118,9 +3148,9 @@
DBUG_ASSERT(thd->query == 0);
thd->query_length= 0; // Should not be needed
thd->query_error= 0;
- clear_all_errors(thd, rli);
+ clear_all_errors(thd, const_cast<RELAY_LOG_INFO*>(rli));
- /* see Query_log_event::exec_event() and BUG#13360 */
+ /* see Query_log_event::do_apply_event() and BUG#13360 */
DBUG_ASSERT(!rli->m_table_map.count());
/*
Usually mysql_init_query() is called by mysql_parse(), but we need it here
@@ -3129,22 +3159,26 @@
mysql_init_query(thd, 0, 0);
if (!use_rli_only_for_errors)
{
- /* Saved for InnoDB, see comment in Query_log_event::exec_event() */
- rli->future_group_master_log_pos= log_pos;
+ /*
+ Saved for InnoDB, see comment in
+ Query_log_event::do_apply_event()
+ */
+ const_cast<RELAY_LOG_INFO*>(rli)->future_group_master_log_pos= log_pos;
DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
}
/*
- 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).
+ 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::do_apply_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).
Note: We do not need to execute reset_one_shot_variables() if this
@@ -3153,8 +3187,8 @@
its companion query. If the SET is ignored because of
db_ok(), the companion query will also be ignored, and if
the companion query is ignored in the db_ok() test of
- ::exec_event(), then the companion SET also have so we
- don't need to reset_one_shot_variables().
+ ::do_apply_event(), then the companion SET also have so
+ we don't need to reset_one_shot_variables().
*/
if (rpl_filter->db_ok(thd->db))
{
@@ -3350,7 +3384,7 @@
return 1;
}
- return ( use_rli_only_for_errors ? 0 : Log_event::exec_event(rli) );
+ return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
}
#endif
@@ -3463,8 +3497,18 @@
}
#endif
+/**
+ Helper function to detect if the event is inside a group.
+ */
+static bool is_in_group(THD *const thd, RELAY_LOG_INFO *const rli)
+{
+ return (thd->options & OPTION_BEGIN) != 0 ||
+ (rli->last_event_start_time > 0);
+}
+
+
/*
- Rotate_log_event::exec_event()
+ Rotate_log_event::do_apply_event()
Got a rotate log event from the master
@@ -3481,34 +3525,43 @@
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Rotate_log_event::exec_event(struct st_relay_log_info* rli)
+int Rotate_log_event::do_update_pos(RELAY_LOG_INFO *rli)
{
- DBUG_ENTER("Rotate_log_event::exec_event");
+ DBUG_ENTER("Rotate_log_event::do_update_pos");
+#ifndef DBUG_OFF
+ char buf[32];
+#endif
+
+ DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu", this->server_id,
::server_id));
+ DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
+ DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
pthread_mutex_lock(&rli->data_lock);
rli->event_relay_log_pos= my_b_tell(rli->cur_log);
/*
- If we are in a transaction: the only normal case is when the I/O thread was
- copying a big transaction, then it was stopped and restarted: we have this
- in the relay log:
+ If we are in a transaction or in a group: the only normal case is
+ when the I/O thread was copying a big transaction, then it was
+ stopped and restarted: we have this in the relay log:
+
BEGIN
...
ROTATE (a fake one)
...
COMMIT or ROLLBACK
- In that case, we don't want to touch the coordinates which correspond to
- the beginning of the transaction.
- Starting from 5.0.0, there also are some rotates from the slave itself, in
- the relay log.
+
+ In that case, we don't want to touch the coordinates which
+ correspond to the beginning of the transaction. Starting from
+ 5.0.0, there also are some rotates from the slave itself, in the
+ relay log.
*/
- if (!(thd->options & OPTION_BEGIN))
+ if (!is_in_group(thd, rli))
{
memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
rli->notify_group_master_log_name_update();
rli->group_master_log_pos= pos;
rli->group_relay_log_pos= rli->event_relay_log_pos;
- DBUG_PRINT("info", ("group_master_log_name: '%s' "
- "group_master_log_pos: %lu",
+ DBUG_PRINT("info", ("new group_master_log_name: '%s' "
+ "new group_master_log_pos: %lu",
rli->group_master_log_name,
(ulong) rli->group_master_log_pos));
/*
@@ -3527,8 +3580,28 @@
pthread_mutex_unlock(&rli->data_lock);
pthread_cond_broadcast(&rli->data_cond);
flush_relay_log_info(rli);
+
DBUG_RETURN(0);
}
+
+
+Log_event::enum_skip_reason
+Rotate_log_event::shall_skip(RELAY_LOG_INFO *rli)
+{
+
+ enum_skip_reason reason= Log_event::shall_skip(rli);
+
+ switch (reason) {
+ case Log_event::EVENT_NOT_SKIPPED:
+ case Log_event::EVENT_SKIP_COUNT:
+ return Log_event::EVENT_NOT_SKIPPED;
+
+ case Log_event::EVENT_SKIP_SAME_SID:
+ return Log_event::EVENT_SKIP_SAME_SID;
+ }
+ DBUG_ASSERT(0);
+}
+
#endif
@@ -3635,11 +3708,11 @@
/*
- Intvar_log_event::exec_event()
+ Intvar_log_event::do_apply_event()
*/
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
-int Intvar_log_event::exec_event(struct st_relay_log_info* rli)
+int Intvar_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
switch (type) {
case LAST_INSERT_ID_EVENT:
@@ -3650,9 +3723,34 @@
thd->force_one_auto_inc_interval(val);
break;
}
+ return 0;
+}
+
+int Intvar_log_event::do_update_pos(RELAY_LOG_INFO *rli)
+{
rli->inc_event_relay_log_pos();
return 0;
}
+
+
+Log_event::enum_skip_reason
+Intvar_log_event::shall_skip(RELAY_LOG_INFO *rli)
+{
+ /*
+ It is a common error to set the slave skip counter to 1 instead
+ of 2 when recovering from an insert which used a auto increment,
+ rand, or user var. Therefore, if the slave skip counter is 1,
+ we just say that this event should be skipped because of the
+ slave skip count, but we do not change the value of the slave
+ skip counter since it will be decreased by the following insert
+ event.
+ */
+ if (rli->slave_skip_counter == 1)
+ return Log_event::EVENT_SKIP_COUNT;
+ else
+ return Log_event::shall_skip(rli);
+}
+
#endif
@@ -3715,13 +3813,38 @@
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Rand_log_event::exec_event(struct st_relay_log_info* rli)
+int Rand_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
thd->rand.seed1= (ulong) seed1;
thd->rand.seed2= (ulong) seed2;
+ return 0;
+}
+
+int Rand_log_event::do_update_pos(RELAY_LOG_INFO *rli)
+{
rli->inc_event_relay_log_pos();
return 0;
}
+
+
+Log_event::enum_skip_reason
+Rand_log_event::shall_skip(RELAY_LOG_INFO *rli)
+{
+ /*
+ It is a common error to set the slave skip counter to 1 instead
+ of 2 when recovering from an insert which used a auto increment,
+ rand, or user var. Therefore, if the slave skip counter is 1,
+ we just say that this event should be skipped because of the
+ slave skip count, but we do not change the value of the slave
+ skip counter since it will be decreased by the following insert
+ event.
+ */
+ if (rli->slave_skip_counter == 1)
+ return Log_event::EVENT_SKIP_COUNT;
+ else
+ return Log_event::shall_skip(rli);
+}
+
#endif /* !MYSQL_CLIENT */
@@ -3788,12 +3911,12 @@
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Xid_log_event::exec_event(struct st_relay_log_info* rli)
+int Xid_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
/* For a slave Xid_log_event is COMMIT */
general_log_print(thd, COM_QUERY,
"COMMIT /* implicit, from Xid_log_event */");
- return end_trans(thd, COMMIT) || Log_event::exec_event(rli);
+ return end_trans(thd, COMMIT);
}
#endif /* !MYSQL_CLIENT */
@@ -4071,11 +4194,11 @@
/*
- User_var_log_event::exec_event()
+ User_var_log_event::do_apply_event()
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int User_var_log_event::exec_event(struct st_relay_log_info* rli)
+int User_var_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
Item *it= 0;
CHARSET_INFO *charset;
@@ -4137,9 +4260,32 @@
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
free_root(thd->mem_root,0);
+ return 0;
+}
+
+int User_var_log_event::do_update_pos(RELAY_LOG_INFO *rli)
+{
rli->inc_event_relay_log_pos();
return 0;
}
+
+Log_event::enum_skip_reason
+User_var_log_event::shall_skip(RELAY_LOG_INFO *rli)
+ {
+ /*
+ It is a common error to set the slave skip counter to 1 instead
+ of 2 when recovering from an insert which used a auto increment,
+ rand, or user var. Therefore, if the slave skip counter is 1,
+ we just say that this event should be skipped because of the
+ slave skip count, but we do not change the value of the slave
+ skip counter since it will be decreased by the following insert
+ event.
+ */
+ if (rli->slave_skip_counter == 1)
+ return Log_event::EVENT_SKIP_COUNT;
+ else
+ return Log_event::shall_skip(rli);
+ }
#endif /* !MYSQL_CLIENT */
@@ -4179,7 +4325,7 @@
#ifndef MYSQL_CLIENT
Slave_log_event::Slave_log_event(THD* thd_arg,
- struct st_relay_log_info* rli)
+ RELAY_LOG_INFO* rli)
:Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
{
DBUG_ENTER("Slave_log_event");
@@ -4289,11 +4435,11 @@
#ifndef MYSQL_CLIENT
-int Slave_log_event::exec_event(struct st_relay_log_info* rli)
+int Slave_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
if (mysql_bin_log.is_open())
mysql_bin_log.write(this);
- return Log_event::exec_event(rli);
+ return 0;
}
#endif /* !MYSQL_CLIENT */
@@ -4322,21 +4468,21 @@
/*
- Stop_log_event::exec_event()
+ Stop_log_event::do_apply_event()
- The master stopped.
- We used to clean up all temporary tables but this is useless as, as the
- master has shut down properly, it has written all DROP TEMPORARY TABLE
- (prepared statements' deletion is TODO only when we binlog prep stmts).
- We used to clean up slave_load_tmpdir, but this is useless as it has been
- cleared at the end of LOAD DATA INFILE.
- So we have nothing to do here.
- The place were we must do this cleaning is in Start_log_event_v3::exec_event(),
- not here. Because if we come here, the master was sane.
+ The master stopped. We used to clean up all temporary tables but
+ this is useless as, as the master has shut down properly, it has
+ written all DROP TEMPORARY TABLE (prepared statements' deletion is
+ TODO only when we binlog prep stmts). We used to clean up
+ slave_load_tmpdir, but this is useless as it has been cleared at the
+ end of LOAD DATA INFILE. So we have nothing to do here. The place
+ were we must do this cleaning is in
+ Start_log_event_v3::do_apply_event(), not here. Because if we come
+ here, the master was sane.
*/
#ifndef MYSQL_CLIENT
-int Stop_log_event::exec_event(struct st_relay_log_info* rli)
+int Stop_log_event::do_update_pos(RELAY_LOG_INFO *rli)
{
/*
We do not want to update master_log pos because we get a rotate event
@@ -4354,6 +4500,7 @@
}
return 0;
}
+
#endif /* !MYSQL_CLIENT */
#endif /* HAVE_REPLICATION */
@@ -4544,11 +4691,11 @@
/*
- Create_file_log_event::exec_event()
+ Create_file_log_event::do_apply_event()
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
+int Create_file_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
char proc_info[17+FN_REFLEN+10], *fname_buf;
char *ext;
@@ -4610,7 +4757,7 @@
if (fd >= 0)
my_close(fd, MYF(0));
thd->proc_info= 0;
- return error ? 1 : Log_event::exec_event(rli);
+ return error == 0;
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -4718,15 +4865,15 @@
}
/*
- Append_block_log_event::exec_event()
+ Append_block_log_event::do_apply_event()
*/
-int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
+int Append_block_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
char proc_info[17+FN_REFLEN+10], *fname= proc_info+17;
int fd;
int error = 1;
- DBUG_ENTER("Append_block_log_event::exec_event");
+ DBUG_ENTER("Append_block_log_event::do_apply_event");
fname= strmov(proc_info, "Making temp file ");
slave_load_file_stem(fname, file_id, server_id, ".data");
@@ -4765,7 +4912,7 @@
if (fd >= 0)
my_close(fd, MYF(0));
thd->proc_info= 0;
- DBUG_RETURN(error ? error : Log_event::exec_event(rli));
+ DBUG_RETURN(error);
}
#endif
@@ -4849,18 +4996,18 @@
#endif
/*
- Delete_file_log_event::exec_event()
+ Delete_file_log_event::do_apply_event()
*/
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
-int Delete_file_log_event::exec_event(struct st_relay_log_info* rli)
+int Delete_file_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
char fname[FN_REFLEN+10];
char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
(void) my_delete(fname, MYF(MY_WME));
strmov(ext, ".info");
(void) my_delete(fname, MYF(MY_WME));
- return Log_event::exec_event(rli);
+ return 0;
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -4946,10 +5093,10 @@
/*
- Execute_load_log_event::exec_event()
+ Execute_load_log_event::do_apply_event()
*/
-int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
+int Execute_load_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
char fname[FN_REFLEN+10];
char *ext;
@@ -4980,14 +5127,15 @@
lev->thd = thd;
/*
- lev->exec_event should use rli only for errors
- i.e. should not advance rli's position.
- lev->exec_event is the place where the table is loaded (it calls
- mysql_load()).
+ lev->do_apply_event should use rli only for errors i.e. should
+ not advance rli's position.
+
+ lev->do_apply_event is the place where the table is loaded (it
+ calls mysql_load()).
*/
- rli->future_group_master_log_pos= log_pos;
- if (lev->exec_event(0,rli,1))
+ const_cast<RELAY_LOG_INFO*>(rli)->future_group_master_log_pos= log_pos;
+ if (lev->do_apply_event(0,rli,1))
{
/*
We want to indicate the name of the file that could not be loaded
@@ -5030,7 +5178,7 @@
my_close(fd, MYF(0));
end_io_cache(&file);
}
- return error ? error : Log_event::exec_event(rli);
+ return error;
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -5198,7 +5346,7 @@
int
-Execute_load_query_log_event::exec_event(struct st_relay_log_info* rli)
+Execute_load_query_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
char *p;
char *buf;
@@ -5235,7 +5383,7 @@
p= strmake(p, STRING_WITH_LEN(" INTO"));
p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
- error= Query_log_event::exec_event(rli, buf, p-buf);
+ error= Query_log_event::do_apply_event(rli, buf, p-buf);
/* Forging file name for deletion in same buffer */
*fname_end= 0;
@@ -5556,7 +5704,7 @@
the master does not have a default value (and isn't nullable)
*/
static int
-unpack_row(RELAY_LOG_INFO *rli,
+unpack_row(RELAY_LOG_INFO const *rli,
TABLE *table, uint const colcnt,
char const *row, MY_BITMAP const *cols,
char const **row_end, ulong *master_reclength,
@@ -5662,17 +5810,17 @@
DBUG_RETURN(error);
}
-int Rows_log_event::exec_event(st_relay_log_info *rli)
+int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
- DBUG_ENTER("Rows_log_event::exec_event(st_relay_log_info*)");
+ DBUG_ENTER("Rows_log_event::do_apply_event(st_relay_log_info*)");
int error= 0;
char const *row_start= (char const *)m_rows_buf;
/*
- If m_table_id == ~0UL, then we have a dummy event that does
- not contain any data. In that case, we just remove all tables in
- the tables_to_lock list, close the thread tables, step the relay
- log position, and return with success.
+ If m_table_id == ~0UL, then we have a dummy event that does not
+ contain any data. In that case, we just remove all tables in the
+ tables_to_lock list, close the thread tables, and return with
+ success. The relay log position will be stepped in
*/
if (m_table_id == ~0UL)
{
@@ -5682,16 +5830,16 @@
*/
DBUG_ASSERT(get_flags(STMT_END_F));
- rli->clear_tables_to_lock();
+ const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
close_thread_tables(thd);
thd->clear_error();
- rli->inc_event_relay_log_pos();
DBUG_RETURN(0);
}
/*
'thd' has been set by exec_relay_log_event(), just before calling
- exec_event(). We still check here to prevent future coding errors.
+ do_apply_event(). We still check here to prevent future coding
+ errors.
*/
DBUG_ASSERT(rli->sql_thd == thd);
@@ -5707,8 +5855,9 @@
/*
lock_tables() reads the contents of thd->lex, so they must be
- initialized. Contrary to in Table_map_log_event::exec_event() we don't
- call mysql_init_query() as that may reset the binlog format.
+ initialized. Contrary to in
+ Table_map_log_event::do_apply_event() we don't call
+ mysql_init_query() as that may reset the binlog format.
*/
lex_start(thd, NULL, 0);
@@ -5720,7 +5869,7 @@
slave_print_msg(ERROR_LEVEL, rli, error,
"Error in %s event: when locking tables",
get_type_str());
- rli->clear_tables_to_lock();
+ const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
DBUG_RETURN(error);
}
@@ -5738,10 +5887,12 @@
need to add code to assert that is the case.
*/
thd->binlog_flush_pending_rows_event(false);
- close_tables_for_reopen(thd, &rli->tables_to_lock);
+ close_tables_for_reopen(thd,
&const_cast<RELAY_LOG_INFO*>(rli)->tables_to_lock);
- if ((error= open_tables(thd, &rli->tables_to_lock,
- &rli->tables_to_lock_count, 0)))
+ if ((error= open_tables(thd,
+
&const_cast<RELAY_LOG_INFO*>(rli)->tables_to_lock,
+
&const_cast<RELAY_LOG_INFO*>(rli)->tables_to_lock_count,
+ 0)))
{
if (thd->query_error || thd->is_fatal_error)
{
@@ -5756,7 +5907,7 @@
"unexpected success or fatal error"));
thd->query_error= 1;
}
- rli->clear_tables_to_lock();
+ const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
DBUG_RETURN(error);
}
}
@@ -5770,24 +5921,24 @@
TABLE_LIST *ptr;
for (ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
{
- rli->m_table_map.set_table(ptr->table_id, ptr->table);
+ const_cast<RELAY_LOG_INFO*>(rli)->m_table_map.set_table(ptr->table_id,
ptr->table);
}
#ifdef HAVE_QUERY_CACHE
query_cache.invalidate_locked_for_write(rli->tables_to_lock);
#endif
- rli->clear_tables_to_lock();
+ const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
}
DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count ==
0);
- TABLE* table= rli->m_table_map.get_table(m_table_id);
+ TABLE* table=
const_cast<RELAY_LOG_INFO*>(rli)->m_table_map.get_table(m_table_id);
if (table)
{
/*
table == NULL means that this table should not be replicated
- (this was set up by Table_map_log_event::exec_event() which
- tested replicate-* rules).
+ (this was set up by Table_map_log_event::do_apply_event()
+ which tested replicate-* rules).
*/
/*
@@ -5844,9 +5995,9 @@
break;
default:
- slave_print_msg(ERROR_LEVEL, rli, error,
+ slave_print_msg(ERROR_LEVEL, rli, thd->net.last_errno,
"Error in %s event: row application failed",
- get_type_str());
+ get_type_str(), error);
thd->query_error= 1;
break;
}
@@ -5854,7 +6005,7 @@
row_start= row_end;
}
DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event",
- rli->abort_slave=1;);
+ const_cast<RELAY_LOG_INFO*>(rli)->abort_slave= 1;);
error= do_after_row_operations(table, error);
if (!cache_stmt)
{
@@ -5865,11 +6016,12 @@
if (error)
{ /* error has occured during the transaction */
- slave_print_msg(ERROR_LEVEL, rli, error,
+ slave_print_msg(ERROR_LEVEL, rli, thd->net.last_errno,
"Error in %s event: error during transaction execution "
"on table %s.%s",
get_type_str(), table->s->db.str,
table->s->table_name.str);
+
/*
If one day we honour --skip-slave-errors in row-based replication, and
the error should be skipped, then we would clear mappings, rollback,
@@ -5882,7 +6034,7 @@
rollback at the caller along with sbr.
*/
thd->reset_current_stmt_binlog_row_based();
- rli->cleanup_context(thd, 0); /* rollback at caller in step with sbr */
+ const_cast<RELAY_LOG_INFO*>(rli)->cleanup_context(thd, error);
thd->query_error= 1;
DBUG_RETURN(error);
}
@@ -5926,8 +6078,7 @@
*/
thd->reset_current_stmt_binlog_row_based();
- rli->cleanup_context(thd, 0);
- rli->transaction_end(thd);
+ const_cast<RELAY_LOG_INFO*>(rli)->cleanup_context(thd, 0);
if (error == 0)
{
@@ -5940,7 +6091,6 @@
do not become visible. We still prefer to wipe them out.
*/
thd->clear_error();
- error= Log_event::exec_event(rli);
}
else
slave_print_msg(ERROR_LEVEL, rli, error,
@@ -5967,17 +6117,17 @@
wait (reached end of last relay log and nothing gets appended
there), we timeout after one minute, and notify DBA about the
problem. When WL#2975 is implemented, just remove the member
- st_relay_log_info::unsafe_to_stop_at and all its occurences.
+ st_relay_log_info::last_event_start_time and all its occurences.
*/
- rli->unsafe_to_stop_at= time(0);
+ const_cast<RELAY_LOG_INFO*>(rli)->last_event_start_time= time(0);
}
DBUG_ASSERT(error == 0);
thd->clear_error();
- rli->inc_event_relay_log_pos();
-
+
DBUG_RETURN(0);
}
+
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
#ifndef MYSQL_CLIENT
@@ -6157,15 +6307,15 @@
const char *const vpart= buf + common_header_len + post_header_len;
/* Extract the length of the various parts from the buffer */
- byte const* const ptr_dblen= (byte const*)vpart + 0;
+ byte const *const ptr_dblen= (byte const*)vpart + 0;
m_dblen= *(uchar*) ptr_dblen;
/* Length of database name + counter + terminating null */
- byte const* const ptr_tbllen= ptr_dblen + m_dblen + 2;
+ byte const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
m_tbllen= *(uchar*) ptr_tbllen;
/* Length of table name + counter + terminating null */
- byte const* const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
+ byte const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
m_colcnt= net_field_length(&ptr_after_colcnt);
@@ -6210,9 +6360,9 @@
*/
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
-int Table_map_log_event::exec_event(st_relay_log_info *rli)
+int Table_map_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
{
- DBUG_ENTER("Table_map_log_event::exec_event(st_relay_log_info*)");
+ DBUG_ENTER("Table_map_log_event::do_apply_event(st_relay_log_info*)");
DBUG_ASSERT(rli->sql_thd == thd);
@@ -6316,29 +6466,24 @@
locked by linking the table into the list of tables to lock.
*/
table_list->next_global= table_list->next_local= rli->tables_to_lock;
- rli->tables_to_lock= table_list;
- rli->tables_to_lock_count++;
+ const_cast<RELAY_LOG_INFO*>(rli)->tables_to_lock= table_list;
+ const_cast<RELAY_LOG_INFO*>(rli)->tables_to_lock_count++;
/* 'memory' is freed in clear_tables_to_lock */
}
- /*
- We explicitly do not call Log_event::exec_event() here since we do not
- want the relay log position to be flushed to disk. The flushing will be
- done by the last Rows_log_event that either ends a statement (outside a
- transaction) or a transaction.
-
- A table map event can *never* end a transaction or a statement, so we
- just step the relay log position.
- */
-
- if (likely(!error))
- rli->inc_event_relay_log_pos();
DBUG_RETURN(error);
err:
my_free((gptr) memory, MYF(MY_WME));
DBUG_RETURN(error);
}
+
+int Table_map_log_event::do_update_pos(RELAY_LOG_INFO *rli)
+{
+ rli->inc_event_relay_log_pos();
+ return 0;
+}
+
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
#ifndef MYSQL_CLIENT
@@ -6503,7 +6648,7 @@
return error;
}
-int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
+int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli,
TABLE *table,
char const *const row_start,
char const **const row_end)
@@ -6644,6 +6789,32 @@
return 0; // All OK
}
+/**
+ Check if an error is a duplicate key error.
+
+ This function is used to check if an error code is one of the
+ duplicate key error, i.e., and error code for which it is sensible
+ to do a <code>get_dup_key()</code> to retrieve the duplicate key.
+
+ @param errcode The error code to check.
+
+ @return <code>true</code> if the error code is such that
+ <code>get_dup_key()</code> will return true,
<code>false</code>
+ otherwise.
+ */
+bool
+is_duplicate_key_error(int errcode)
+{
+ switch (errcode)
+ {
+ case HA_ERR_FOUND_DUPP_KEY:
+ case HA_ERR_FOUND_DUPP_UNIQUE:
+ return true;
+ }
+ return false;
+}
+
+
/*
Replace the provided record in the database.
@@ -6678,15 +6849,15 @@
while ((error= table->file->ha_write_row(table->record[0])))
{
- if (error == HA_ERR_LOCK_DEADLOCK || error == HA_ERR_LOCK_WAIT_TIMEOUT)
+ if (!is_duplicate_key_error(error))
{
- table->file->print_error(error, MYF(0)); /* to check at exec_relay_log_event
*/
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
if ((keynum= table->file->get_dup_key(error)) < 0)
{
/* We failed to retrieve the duplicate key */
- DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY);
+ DBUG_RETURN(error);
}
/*
@@ -6703,7 +6874,10 @@
{
error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
if (error)
+ {
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
+ }
}
else
{
@@ -6720,12 +6894,15 @@
}
key_copy((byte*)key.get(), table->record[0], table->key_info + keynum, 0);
- error= table->file->index_read_idx(table->record[1], keynum,
+ error= table->file->index_read_idx(table->record[1], keynum,
(const byte*)key.get(),
table->key_info[keynum].key_length,
HA_READ_KEY_EXACT);
if (error)
+ {
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
+ }
}
/*
@@ -6758,15 +6935,21 @@
{
error=table->file->ha_update_row(table->record[1],
table->record[0]);
+ if (error)
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
else
{
if ((error= table->file->ha_delete_row(table->record[1])))
+ {
+ table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
+ }
/* Will retry ha_write_row() with the offending row removed. */
}
}
+
DBUG_RETURN(error);
}
@@ -7105,7 +7288,7 @@
return error;
}
-int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
+int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli,
TABLE *table,
char const *const row_start,
char const **const row_end)
@@ -7240,7 +7423,7 @@
return error;
}
-int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli,
+int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO const *rli,
TABLE *table,
char const *const row_start,
char const **const row_end)
--- 1.138/sql/log_event.h 2007-01-18 09:46:51 +01:00
+++ 1.139/sql/log_event.h 2007-01-18 09:46:51 +01:00
@@ -1,9 +1,8 @@
-/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+/* Copyright (C) 2000-2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -200,8 +199,26 @@
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
#define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN +
EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
-/*
- Event header offsets;
+/*
+ Max number of possible extra bytes in a replication event compared to a
+ packet (i.e. a query) sent from client to master;
+ First, an auxiliary log_event status vars estimation:
+*/
+#define MAX_SIZE_LOG_EVENT_STATUS (4 /* flags2 */ + \
+ 8 /* sql mode */ + \
+ 1 + 1 + 255 /* catalog */ + \
+ 4 /* autoinc */ + \
+ 6 /* charset */ + \
+ MAX_TIME_ZONE_NAME_LENGTH)
+#define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \
+ LOG_EVENT_HEADER_LEN + /* write_header */ \
+ QUERY_HEADER_LEN + /* write_data */ \
+ EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN + /*write_post_header_for_derived */ \
+ MAX_SIZE_LOG_EVENT_STATUS + /* status */ \
+ NAME_LEN + 1)
+
+/*
+ Event header offsets;
these point to places inside the fixed header.
*/
@@ -253,6 +270,8 @@
*/
#define Q_CATALOG_NZ_CODE 6
+#define Q_LC_TIME_NAMES_CODE 7
+
/* Intvar event post-header */
#define I_TYPE_OFFSET 0
@@ -405,12 +424,18 @@
either, as the manual says (because a too big in-memory temp table is
automatically written to disk).
*/
-#define OPTIONS_WRITTEN_TO_BIN_LOG (OPTION_AUTO_IS_NULL | \
-OPTION_NO_FOREIGN_KEY_CHECKS | OPTION_RELAXED_UNIQUE_CHECKS)
+#define OPTIONS_WRITTEN_TO_BIN_LOG \
+ (OPTION_AUTO_IS_NULL | OPTION_NO_FOREIGN_KEY_CHECKS | \
+ OPTION_RELAXED_UNIQUE_CHECKS | OPTION_NOT_AUTOCOMMIT)
+
+/* Shouldn't be defined before */
+#define EXPECTED_OPTIONS \
+ ((ULL(1) << 14) | (ULL(1) << 26) | (ULL(1) << 27) | (ULL(1) <<
19))
-#if OPTIONS_WRITTEN_TO_BIN_LOG != ((1L << 14) | (1L << 26) | (1L <<
27))
+#if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS
#error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values!
#endif
+#undef EXPECTED_OPTIONS /* You shouldn't use this one */
enum Log_event_type
{
@@ -508,9 +533,11 @@
bool charset_inited;
char charset[6]; // 3 variables, each of them storable in 2 bytes
char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
+ uint lc_time_names_number;
st_print_event_info()
:flags2_inited(0), sql_mode_inited(0),
- auto_increment_increment(1),auto_increment_offset(1), charset_inited(0)
+ auto_increment_increment(1),auto_increment_offset(1), charset_inited(0),
+ lc_time_names_number(0)
{
/*
Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
@@ -520,6 +547,7 @@
bzero(db, sizeof(db));
bzero(charset, sizeof(charset));
bzero(time_zone_str, sizeof(time_zone_str));
+ strcpy(delimiter, ";");
uint const flags = MYF(MY_WME | MY_NABP);
init_io_cache(&head_cache, -1, 0, WRITE_CACHE, 0L, FALSE, flags);
init_io_cache(&body_cache, -1, 0, WRITE_CACHE, 0L, FALSE, flags);
@@ -536,6 +564,7 @@
bool base64_output;
my_off_t hexdump_from;
uint8 common_header_len;
+ char delimiter[16];
/*
These two caches are used by the row-based replication events to
@@ -566,6 +595,13 @@
/*
+ The following type definition is to be used whenever data is placed
+ and manipulated in a common buffer. Use this typedef for buffers
+ that contain data containing binary and character data.
+ */
+ typedef unsigned char Byte;
+
+ /*
The offset in the log where this event originally appeared (it is
preserved in relay logs, making SHOW SLAVE STATUS able to print
coordinates of the event in the master's binlog). Note: when a
@@ -884,7 +920,7 @@
class Query_log_event: public Log_event
{
protected:
- char* data_buf;
+ Log_event::Byte* data_buf;
public:
const char* query;
const char* catalog;
@@ -955,6 +991,7 @@
char charset[6];
uint time_zone_len; /* 0 means uninited */
const char *time_zone_str;
+ uint lc_time_names_number; /* 0 means en_US */
#ifndef MYSQL_CLIENT
@@ -1019,6 +1056,8 @@
bool write(IO_CACHE* file) { return(false); };
virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
+#else
+ Muted_query_log_event() {}
#endif
};
@@ -1910,8 +1949,6 @@
#endif
char *str_to_hex(char *to, const char *from, uint len);
-#ifdef HAVE_ROW_BASED_REPLICATION
-
/*****************************************************************************
Table map log event class
@@ -2245,7 +2282,7 @@
Write_rows_log_event(const char *buf, uint event_len,
const Format_description_log_event *description_event);
#endif
-#if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION)
+#if !defined(MYSQL_CLIENT)
static bool binlog_row_logging_function(THD *thd, TABLE *table,
bool is_transactional,
MY_BITMAP *cols,
@@ -2310,7 +2347,7 @@
const Format_description_log_event *description_event);
#endif
-#if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION)
+#if !defined(MYSQL_CLIENT)
static bool binlog_row_logging_function(THD *thd, TABLE *table,
bool is_transactional,
MY_BITMAP *cols,
@@ -2380,7 +2417,7 @@
Delete_rows_log_event(const char *buf, uint event_len,
const Format_description_log_event *description_event);
#endif
-#if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION)
+#if !defined(MYSQL_CLIENT)
static bool binlog_row_logging_function(THD *thd, TABLE *table,
bool is_transactional,
MY_BITMAP *cols,
@@ -2413,7 +2450,5 @@
virtual int do_exec_row(TABLE *table);
#endif
};
-
-#endif /* HAVE_ROW_BASED_REPLICATION */
#endif /* _log_event_h */
--- 1.295/sql/slave.cc 2007-01-18 09:46:51 +01:00
+++ 1.296/sql/slave.cc 2007-01-18 09:46:51 +01:00
@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -33,6 +32,7 @@
int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
+#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
#define MAX_SLAVE_RETRY_PAUSE 5
bool use_slave_mask = 0;
@@ -913,7 +913,7 @@
TABLE_LIST tables;
int error= 1;
handler *file;
- ulong save_options;
+ ulonglong save_options;
NET *net= &mysql->net;
DBUG_ENTER("create_table_from_dump");
@@ -1369,9 +1369,21 @@
void set_slave_thread_options(THD* thd)
{
DBUG_ENTER("set_slave_thread_options");
-
- thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) |
- OPTION_AUTO_IS_NULL;
+ /*
+ It's nonsense to constrain the slave threads with max_join_size; if a
+ query succeeded on master, we HAVE to execute it. So set
+ OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
+ (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
+ SELECT examining more than 4 billion rows would still fail (yes, because
+ when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
+ only for client threads.
+ */
+ ulonglong options= thd->options | OPTION_BIG_SELECTS;
+ if (opt_log_slave_updates)
+ options|= OPTION_BIN_LOG;
+ else
+ options&= ~OPTION_BIN_LOG;
+ thd->options= options;
thd->variables.completion_type= 0;
DBUG_VOID_RETURN;
}
@@ -1409,20 +1421,16 @@
SYSTEM_THREAD_SLAVE_SQL : SYSTEM_THREAD_SLAVE_IO;
thd->security_ctx->skip_grants();
my_net_init(&thd->net, 0);
+/*
+ Adding MAX_LOG_EVENT_HEADER_LEN to the max_allowed_packet on all
+ slave threads, since a replication event can become this much larger
+ than the corresponding packet (query) sent from client to master.
+*/
+ thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet
+ + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
thd->net.read_timeout = slave_net_timeout;
thd->slave_thread = 1;
set_slave_thread_options(thd);
- /*
- It's nonsense to constrain the slave threads with max_join_size; if a
- query succeeded on master, we HAVE to execute it. So set
- OPTION_BIG_SELECTS. Setting max_join_size to HA_POS_ERROR is not enough
- (and it's not needed if we have OPTION_BIG_SELECTS) because an INSERT
- SELECT examining more than 4 billion rows would still fail (yes, because
- when max_join_size is 4G, OPTION_BIG_SELECTS is automatically set, but
- only for client threads.
- */
- thd->options = ((opt_log_slave_updates) ? OPTION_BIN_LOG:0) |
- OPTION_AUTO_IS_NULL | OPTION_BIG_SELECTS;
thd->client_capabilities = CLIENT_LOCAL_FILES;
thd->real_id=pthread_self();
pthread_mutex_lock(&LOCK_thread_count);
@@ -1608,7 +1616,7 @@
DBUG_RETURN(packet_error);
}
- DBUG_PRINT("info",( "len=%u, net->read_pos[4] = %d\n",
+ DBUG_PRINT("exit", ("len: %lu net->read_pos[4]: %d",
len, mysql->net.read_pos[4]));
DBUG_RETURN(len - 1);
}
@@ -1752,6 +1760,9 @@
if (!ev->when)
ev->when = time(NULL);
ev->thd = thd; // because up to this point, ev->thd == 0
+ DBUG_PRINT("info", ("thd->options={ %s%s}",
+ FLAGSTR(thd->options, OPTION_NOT_AUTOCOMMIT),
+ FLAGSTR(thd->options, OPTION_BEGIN)));
exec_res= ev->exec_event(rli);
DBUG_PRINT("info", ("exec_event result = %d", exec_res));
@@ -1904,11 +1915,19 @@
thd->proc_info = "Connecting to master";
// we can get killed during safe_connect
if (!safe_connect(thd, mysql, mi))
- sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',\
- replication started in log '%s' at position %s", mi->user,
- mi->host, mi->port,
- IO_RPL_LOG_NAME,
- llstr(mi->master_log_pos,llbuff));
+ {
+ sql_print_information("Slave I/O thread: connected to master '%s@%s:%d',"
+ "replication started in log '%s' at position %s",
+ mi->user, mi->host, mi->port,
+ IO_RPL_LOG_NAME,
+ llstr(mi->master_log_pos,llbuff));
+ /*
+ Adding MAX_LOG_EVENT_HEADER_LEN to the max_packet_size on the I/O
+ thread, since a replication event can become this much larger than
+ the corresponding packet (query) sent from client to master.
+ */
+ mysql->net.max_packet_size= thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER;
+ }
else
{
sql_print_information("Slave I/O thread killed while connecting to master");
@@ -2554,7 +2573,7 @@
/* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
mi->master_log_pos= rev->pos;
- DBUG_PRINT("info", ("master_log_pos: '%s' %d",
+ DBUG_PRINT("info", ("master_log_pos: '%s' %lu",
mi->master_log_name, (ulong) mi->master_log_pos));
#ifndef DBUG_OFF
/*
@@ -2672,7 +2691,7 @@
int error = process_io_create_file(mi,(Create_file_log_event*)ev);
delete ev;
mi->master_log_pos += inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
pthread_mutex_unlock(&mi->data_lock);
my_free((char*)tmp_buf, MYF(0));
DBUG_RETURN(error);
@@ -2699,7 +2718,7 @@
}
delete ev;
mi->master_log_pos+= inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
pthread_mutex_unlock(&mi->data_lock);
DBUG_RETURN(0);
}
@@ -2755,7 +2774,7 @@
delete ev;
mi->master_log_pos+= inc_pos;
err:
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
pthread_mutex_unlock(&mi->data_lock);
DBUG_RETURN(0);
}
@@ -2928,7 +2947,8 @@
rli->ign_master_log_pos_end= mi->master_log_pos;
}
rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
- DBUG_PRINT("info", ("master_log_pos: %d, event originating from the same server,
ignored", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu, event originating from the same server,
ignored",
+ (ulong) mi->master_log_pos));
}
else
{
@@ -2936,7 +2956,7 @@
if (likely(!(rli->relay_log.appendv(buf,event_len,0))))
{
mi->master_log_pos+= inc_pos;
- DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos));
+ DBUG_PRINT("info", ("master_log_pos: %lu", (ulong) mi->master_log_pos));
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
}
else
@@ -3057,8 +3077,8 @@
{
last_errno=mysql_errno(mysql);
suppress_warnings= 0;
- sql_print_error("Slave I/O thread: error %s to master \
-'%s@%s:%d': \
+ sql_print_error("Slave I/O thread: error %s to master "
+ "'%s@%s:%d': \
Error: '%s' errno: %d retry-time: %d retries: %lu",
(reconnect ? "reconnecting" : "connecting"),
mi->user, mi->host, mi->port,
--- 1.4/sql/rpl_rli.cc 2007-01-18 09:46:51 +01:00
+++ 1.5/sql/rpl_rli.cc 2007-01-18 09:46:51 +01:00
@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -402,7 +401,7 @@
bool look_for_description_event)
{
DBUG_ENTER("init_relay_log_pos");
- DBUG_PRINT("info", ("pos=%lu", pos));
+ DBUG_PRINT("info", ("pos: %lu", (ulong) pos));
*errmsg=0;
pthread_mutex_t *log_lock=rli->relay_log.get_log_lock();
@@ -855,7 +854,7 @@
Don't ask for disk deletion. For now, anyway they will be deleted when
slave restarts, but it is a better intention to not delete them.
*/
- DBUG_PRINT("info", ("table: %p", table));
+ DBUG_PRINT("info", ("table: 0x%lx", (long) table));
close_temporary(table, 1, 0);
}
save_temporary_tables= 0;
--- 1.8/mysql-test/r/rpl_row_tabledefs_2myisam.result 2007-01-18 09:46:51 +01:00
+++ 1.9/mysql-test/r/rpl_row_tabledefs_2myisam.result 2007-01-18 09:46:51 +01:00
@@ -121,7 +121,7 @@
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
-Last_Errno 1364
+Last_Errno 1105
Last_Error Error in Write_rows event: error during transaction execution on table
test.t1_nodef
Skip_Counter 0
Exec_Master_Log_Pos #
--- 1.9/sql/rpl_rli.h 2007-01-18 09:46:51 +01:00
+++ 1.10/sql/rpl_rli.h 2007-01-18 09:46:51 +01:00
@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
--- 1.5/mysql-test/r/rpl_row_tabledefs_3innodb.result 2007-01-18 09:46:51 +01:00
+++ 1.6/mysql-test/r/rpl_row_tabledefs_3innodb.result 2007-01-18 09:46:51 +01:00
@@ -121,7 +121,7 @@
Replicate_Ignore_Table
Replicate_Wild_Do_Table
Replicate_Wild_Ignore_Table
-Last_Errno 1364
+Last_Errno 1105
Last_Error Error in Write_rows event: error during transaction execution on table
test.t1_nodef
Skip_Counter 0
Exec_Master_Log_Pos #
--- 1.4/sql/rpl_utility.cc 2007-01-18 09:46:51 +01:00
+++ 1.5/sql/rpl_utility.cc 2007-01-18 09:46:51 +01:00
@@ -1,9 +1,8 @@
-/* Copyright 2006 MySQL AB. All rights reserved.
+/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -12,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "rpl_utility.h"
@@ -25,7 +24,7 @@
switch (field_type) {
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL:
- length= ~0UL;
+ length= ~(uint32) 0;
break;
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_TINY:
@@ -71,7 +70,7 @@
break;
break;
case MYSQL_TYPE_BIT:
- length= ~0UL;
+ length= ~(uint32) 0;
break;
default:
/* This case should never be chosen */
@@ -85,7 +84,7 @@
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_VARCHAR:
- length= ~0UL; // NYI
+ length= ~(uint32) 0; // NYI
break;
case MYSQL_TYPE_TINY_BLOB:
@@ -93,7 +92,7 @@
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY:
- length= ~0UL; // NYI
+ length= ~(uint32) 0; // NYI
break;
}
@@ -132,7 +131,8 @@
slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF,
"Table width mismatch - "
"received %u columns, %s.%s has %u columns",
- size(), tsh->db.str, tsh->table_name.str, tsh->fields);
+ (uint) size(), tsh->db.str, tsh->table_name.str,
+ tsh->fields);
}
for (uint col= 0 ; col < cols_to_check ; ++col)
--- 1.3/sql/rpl_utility.h 2007-01-18 09:46:51 +01:00
+++ 1.4/sql/rpl_utility.h 2007-01-18 09:46:51 +01:00
@@ -1,9 +1,8 @@
-/* Copyright 2006 MySQL AB. All rights reserved.
+/* Copyright (C) 2006 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -12,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifndef RPL_UTILITY_H
#define RPL_UTILITY_H
--- 1.103/sql/slave.h 2007-01-18 09:46:51 +01:00
+++ 1.104/sql/slave.h 2007-01-18 09:46:51 +01:00
@@ -2,8 +2,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
| Thread |
|---|
| • bk commit into 5.1 tree (mats:1.2405) | Mats Kindahl | 18 Jan |