3745 Frazer Clement 2012-03-09
Bug#54854 Can't find good position for replication break between DDL statements
Commit of mysql-trunk patches for PB2 test-build
modified:
sql/binlog.cc
sql/binlog.h
sql/log.h
sql/log_event.h
sql/rpl_injector.cc
sql/rpl_injector.h
sql/sql_class.cc
sql/sql_class.h
3744 Jorgen Loland 2012-03-09
Bug#13810145: FIX WARNINGS BY FORTIFY
@ sql/opt_range.cc
Fix Fortify warning
modified:
sql/opt_range.cc
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc 2012-03-06 14:29:42 +0000
+++ b/sql/binlog.cc 2012-03-09 15:24:52 +0000
@@ -4160,6 +4160,19 @@ MYSQL_BIN_LOG::remove_pending_rows_event
}
/*
+ Updates thd's position-of-next-event variables
+ after a *real* write a file.
+ */
+void MYSQL_BIN_LOG::update_thd_next_event_pos(THD* thd)
+{
+ if (likely(thd != NULL))
+ {
+ thd->set_next_event_pos(log_file_name,
+ my_b_tell(&log_file));
+ }
+}
+
+/*
Moves the last bunch of rows from the pending Rows event to a cache (either
transactional cache if is_transaction is @c true, or the non-transactional
cache otherwise. Sets a new pending event.
@@ -4924,12 +4937,14 @@ bool MYSQL_BIN_LOG::write_cache(THD *thd
mysql_mutex_lock(&LOCK_prep_xids);
prepared_xids++;
mysql_mutex_unlock(&LOCK_prep_xids);
+ update_thd_next_event_pos(thd);
mysql_mutex_unlock(&LOCK_log);
}
else
{
if (rotate(false, &check_purge))
goto err;
+ update_thd_next_event_pos(thd);
mysql_mutex_unlock(&LOCK_log);
if (check_purge)
purge();
=== modified file 'sql/binlog.h'
--- a/sql/binlog.h 2012-01-26 10:53:34 +0000
+++ b/sql/binlog.h 2012-03-09 15:24:52 +0000
@@ -213,6 +213,7 @@ public:
int recover(IO_CACHE *log, Format_description_log_event *fdle);
#if !defined(MYSQL_CLIENT)
+ void update_thd_next_event_pos(THD *thd);
int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event,
bool is_transactional);
int remove_pending_rows_event(THD *thd, bool is_transactional);
=== modified file 'sql/log.h'
--- a/sql/log.h 2011-12-09 21:08:37 +0000
+++ b/sql/log.h 2012-03-09 15:24:52 +0000
@@ -19,6 +19,21 @@
#include "unireg.h" // REQUIRED: for other includes
#include "handler.h" /* my_xid */
+/**
+ the struct aggregates two paramenters that identify an event
+ uniquely in scope of communication of a particular master and slave couple.
+ I.e there can not be 2 events from the same staying connected master which
+ have the same coordinates.
+ @note
+ Such identifier is not yet unique generally as the event originating master
+ is resetable. Also the crashed master can be replaced with some other.
+*/
+typedef struct event_coordinates
+{
+ char * file_name; // binlog file name (directories stripped)
+ my_off_t pos; // event's position in the binlog file
+} LOG_POS_COORD;
+
/*
Transaction Coordinator log - a base abstract class
for two different implementations
=== modified file 'sql/log_event.h'
--- a/sql/log_event.h 2012-03-06 14:29:42 +0000
+++ b/sql/log_event.h 2012-03-09 15:24:52 +0000
@@ -812,21 +812,6 @@ typedef struct st_print_event_info
#endif
/**
- the struct aggregates two paramenters that identify an event
- uniquely in scope of communication of a particular master and slave couple.
- I.e there can not be 2 events from the same staying connected master which
- have the same coordinates.
- @note
- Such identifier is not yet unique generally as the event originating master
- is resetable. Also the crashed master can be replaced with some other.
-*/
-typedef struct event_coordinates
-{
- char * file_name; // binlog file name (directories stripped)
- my_off_t pos; // event's position in the binlog file
-} LOG_POS_COORD;
-
-/**
@class Log_event
This is the abstract base class for binary log events.
=== modified file 'sql/rpl_injector.cc'
--- a/sql/rpl_injector.cc 2012-03-06 14:29:42 +0000
+++ b/sql/rpl_injector.cc 2012-03-09 15:24:52 +0000
@@ -41,6 +41,28 @@ injector::transaction::transaction(MYSQL
m_start_pos.m_file_name= my_strdup(log_info.log_file_name, MYF(0));
m_start_pos.m_file_pos= log_info.pos;
+ if (unlikely(m_start_pos.m_file_name == NULL))
+ {
+ m_thd= NULL;
+ return;
+ }
+
+ /*
+ Next pos is unknown until after commit of the Binlog transaction
+ */
+ m_next_pos.m_file_name= 0;
+ m_next_pos.m_file_pos= 0;
+
+ /*
+ Ensure we don't pick up this thd's last written Binlog pos in
+ empty-transaction-commit cases.
+ This is not ideal, as it zaps this information for any other
+ usage (e.g. WL4047)
+ Potential improvement : save the 'old' next pos prior to
+ commit, and restore on error.
+ */
+ m_thd->clear_next_event_pos();
+
trans_begin(m_thd);
}
@@ -50,16 +72,18 @@ injector::transaction::~transaction()
return;
/* Needed since my_free expects a 'char*' (instead of 'void*'). */
- char* const the_memory= const_cast<char*>(m_start_pos.m_file_name);
+ char* const start_pos_memory= const_cast<char*>(m_start_pos.m_file_name);
- /*
- We set the first character to null just to give all the copies of the
- start position a (minimal) chance of seening that the memory is lost.
- All assuming the my_free does not step over the memory, of course.
- */
- *the_memory= '\0';
-
- my_free(the_memory);
+ if (start_pos_memory)
+ {
+ my_free(start_pos_memory);
+ }
+
+ char* const next_pos_memory= const_cast<char*>(m_next_pos.m_file_name);
+ if (next_pos_memory)
+ {
+ my_free(next_pos_memory);
+ }
}
/**
@@ -95,6 +119,22 @@ int injector::transaction::commit()
close_thread_tables(m_thd);
m_thd->mdl_context.release_transactional_locks();
}
+
+ /* Copy next position out into our next pos member */
+ if ((error == 0) &&
+ (m_thd->binlog_next_event_pos.file_name != NULL) &&
+ ((m_next_pos.m_file_name=
+ my_strdup(m_thd->binlog_next_event_pos.file_name, MYF(0))) != NULL))
+ {
+ m_next_pos.m_file_pos= m_thd->binlog_next_event_pos.pos;
+ }
+ else
+ {
+ /* Error, problem copying etc. */
+ m_next_pos.m_file_name= NULL;
+ m_next_pos.m_file_pos= 0;
+ }
+
DBUG_RETURN(error);
}
@@ -199,6 +239,10 @@ injector::transaction::binlog_pos inject
return m_start_pos;
}
+injector::transaction::binlog_pos injector::transaction::next_pos() const
+{
+ return m_next_pos;
+}
/*
injector - member definitions
=== modified file 'sql/rpl_injector.h'
--- a/sql/rpl_injector.h 2011-09-28 09:12:47 +0000
+++ b/sql/rpl_injector.h 2012-03-09 15:24:52 +0000
@@ -241,14 +241,30 @@ public:
/*
Get the position for the start of the transaction.
- Returns the position in the binary log of the first event in this
- transaction. If no event is yet written, the position where the event
- *will* be written is returned. This position is known, since a
- new_transaction() will lock the binary log and prevent any other
- writes to the binary log.
+ This is the current 'tail of Binlog' at the time the transaction
+ was started. The first event recorded by the transaction may
+ be at this, or some subsequent position. The first event recorded
+ by the transaction will not be before this position.
*/
binlog_pos start_pos() const;
+ /*
+ Get the next position after the end of the transaction
+
+ This call is only valid after a transaction has been committed.
+ It returns the next Binlog position after the committed transaction.
+ It is guaranteed that no other events will be recorded between the
+ COMMIT event of the Binlog transaction, and this position.
+ Note that this position may be in a different log file to the COMMIT
+ event.
+
+ If the commit had an error, or the transaction was empty and nothing
+ was binlogged then the next_pos will have a NULL file_name(), and
+ 0 file_pos().
+
+ */
+ binlog_pos next_pos() const;
+
private:
/* Only the injector may construct these object */
transaction(MYSQL_BIN_LOG *, THD *);
@@ -261,6 +277,13 @@ public:
o.m_start_pos= tmp;
}
+ /* std::swap(m_end_pos, o.m_end_pos); */
+ {
+ binlog_pos const tmp= m_next_pos;
+ m_next_pos= o.m_next_pos;
+ o.m_next_pos= tmp;
+ }
+
/* std::swap(m_thd, o.m_thd); */
{
THD* const tmp= m_thd;
@@ -333,6 +356,7 @@ public:
binlog_pos m_start_pos;
+ binlog_pos m_next_pos;
THD *m_thd;
};
=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc 2012-03-06 14:29:42 +0000
+++ b/sql/sql_class.cc 2012-03-09 15:24:52 +0000
@@ -930,6 +930,9 @@ THD::THD(bool enable_plugins)
m_binlog_invoker= FALSE;
memset(&invoker_user, 0, sizeof(invoker_user));
memset(&invoker_host, 0, sizeof(invoker_host));
+
+ binlog_next_event_pos.file_name= NULL;
+ binlog_next_event_pos.pos= 0;
}
@@ -1418,6 +1421,8 @@ THD::~THD()
if (m_enable_plugins)
plugin_thdvar_cleanup(this);
+ clear_next_event_pos();
+
DBUG_PRINT("info", ("freeing security context"));
main_security_ctx.destroy();
my_free(db);
@@ -4538,3 +4543,30 @@ void COPY_INFO::set_function_defaults(TA
}
DBUG_VOID_RETURN;
}
+
+void THD::set_next_event_pos(const char* _filename, ulonglong _pos)
+{
+ char*& filename= binlog_next_event_pos.file_name;
+ if (filename == NULL)
+ {
+ /* First time, allocate maximal buffer */
+ filename= (char*) my_malloc(FN_REFLEN+1, MYF(MY_WME));
+ if (filename == NULL) return;
+ }
+
+ assert(strlen(_filename) <= FN_REFLEN);
+ strcpy(filename, _filename);
+ filename[ FN_REFLEN ]= 0;
+
+ binlog_next_event_pos.pos= _pos;
+};
+
+void THD::clear_next_event_pos()
+{
+ if (binlog_next_event_pos.file_name != NULL)
+ {
+ my_free(binlog_next_event_pos.file_name);
+ }
+ binlog_next_event_pos.file_name= NULL;
+ binlog_next_event_pos.pos= 0;
+};
=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h 2012-03-06 14:29:42 +0000
+++ b/sql/sql_class.h 2012-03-09 15:24:52 +0000
@@ -2348,6 +2348,15 @@ public:
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
+ /*
+ Position of first event in Binlog
+ *after* last event written by this
+ thread.
+ */
+ event_coordinates binlog_next_event_pos;
+ void set_next_event_pos(const char* _filename, ulonglong _pos);
+ void clear_next_event_pos();
+
#ifndef MYSQL_CLIENT
int binlog_setup_trx_data();
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (frazer.clement:3744 to 3745) Bug#54854 | Frazer Clement | 12 Mar |