List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:November 17 2010 8:46am
Subject:bzr commit into mysql-next-mr-bugfixing branch (zhenxing.he:3329) WL#5675
View as plain text  
#At file:///media/sdb2/hezx/work/mysql/bzr/rap/next-mr-bugfixing/ based on revid:zhenxing.he@stripped

 3329 He Zhenxing	2010-11-17
      WL#5675 Replication librarification: Move to separate directory
              and define basic interfaces
      
      This is a preview patch for the WL.

    modified:
      client/mysqlbinlog.cc
      libmysqld/CMakeLists.txt
      sql/CMakeLists.txt
      sql/ha_ndbcluster_binlog.cc
      sql/handler.cc
      sql/mysqld.cc
      sql/mysqld.h
      sql/replication.h
      sql/rpl/binlog.cc
      sql/rpl/binlog.h
      sql/rpl/log_event.cc
      sql/rpl/log_event.h
      sql/rpl/rpl_filter.cc
      sql/rpl/rpl_filter.h
      sql/rpl/rpl_master.cc
      sql/rpl/rpl_master.h
      sql/rpl/rpl_rli.cc
      sql/rpl/rpl_rli.h
      sql/rpl/rpl_slave.cc
      sql/rpl/rpl_slave.h
      sql/rpl/sql_binlog.cc
      sql/sp.cc
      sql/sql_acl.cc
      sql/sql_base.cc
      sql/sql_class.h
      sql/sql_delete.cc
      sql/sql_insert.cc
      sql/sql_lex.cc
      sql/sql_lex.h
      sql/sql_parse.cc
      sql/sql_reload.cc
      sql/sql_table.cc
      sql/sql_update.cc
      sql/sql_view.cc
      sql/sql_yacc.yy
      sql/sys_vars.cc
=== modified file 'client/mysqlbinlog.cc'
--- a/client/mysqlbinlog.cc	2010-09-01 02:51:08 +0000
+++ b/client/mysqlbinlog.cc	2010-11-17 08:46:17 +0000
@@ -50,7 +50,7 @@ ulong server_id = 0;
 ulong bytes_sent = 0L, bytes_received = 0L;
 ulong mysqld_net_retry_count = 10L;
 ulong open_files_limit;
-ulong opt_binlog_rows_event_max_size;
+//ulong opt_binlog_rows_event_max_size;
 uint test_flags = 0; 
 static uint opt_protocol= 0;
 static FILE *result_file;

=== modified file 'libmysqld/CMakeLists.txt'
--- a/libmysqld/CMakeLists.txt	2010-10-25 10:01:24 +0000
+++ b/libmysqld/CMakeLists.txt	2010-11-17 08:46:17 +0000
@@ -86,7 +86,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc l
            ../sql/sql_alter.cc ../sql/sql_partition_admin.cc
            ../sql/event_parse_data.cc
            ../sql/sql_signal.cc ../sql/rpl/rpl_handler.cc
-	       ../sql/rpl/rpl_utility.cc ../sql/rpl/binlog.cc
+	   ../sql/rpl/rpl_utility.cc ../sql/rpl/binlog.cc
+	   ../sql/rpl/rpl_lex.cc
            ../sql/sys_vars.cc
            ${CMAKE_BINARY_DIR}/sql/sql_builtin.cc
            ../sql/mdl.cc ../sql/transaction.cc ../sql/sql_bootstrap.cc

=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt	2010-10-25 10:01:24 +0000
+++ b/sql/CMakeLists.txt	2010-11-17 08:46:17 +0000
@@ -78,6 +78,7 @@ SET (SQL_SOURCE
                datadict.cc sql_reload.cc
                sql_partition_admin.cc
                sql_admin.cc sql_alter.cc
+	       rpl/rpl_lex.cc
                ${GEN_SOURCES}
                ${MYSYS_LIBWRAP_SOURCE})
 

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-09-01 22:59:33 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2010-11-17 08:46:17 +0000
@@ -1867,10 +1867,10 @@ static void ndb_binlog_query(THD *thd, C
     thd->server_id= schema->any_value;
   thd->db= schema->db;
   int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
-  thd->binlog_query(THD::STMT_QUERY_TYPE, schema->query,
-                    schema->query_length, FALSE, TRUE,
-                    schema->name[0] == 0 || thd->db[0] == 0,
-                    errcode);
+  binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE, schema->query,
+                      schema->query_length, FALSE, TRUE,
+                      schema->name[0] == 0 || thd->db[0] == 0,
+                      errcode);
   thd->server_id= thd_server_id_save;
   thd->db= thd_db_save;
 }

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2010-09-01 02:51:08 +0000
+++ b/sql/handler.cc	2010-11-17 08:46:17 +0000
@@ -68,8 +68,6 @@ st_plugin_int *hton2plugin[MAX_HA];
 
 static handlerton *installed_htons[128];
 
-#define BITMAP_STACKBUF_SIZE (128/8)
-
 KEY_CREATE_INFO default_key_create_info=
   { HA_KEY_ALG_UNDEF, 0, {NullS, 0}, {NullS, 0} };
 
@@ -5523,178 +5521,6 @@ bool ha_show_status(THD *thd, handlerton
   return result;
 }
 
-/*
-  Function to check if the conditions for row-based binlogging is
-  correct for the table.
-
-  A row in the given table should be replicated if:
-  - Row-based replication is enabled in the current thread
-  - The binlog is enabled
-  - It is not a temporary table
-  - The binary log is open
-  - The database the table resides in shall be binlogged (binlog_*_db rules)
-  - table is not mysql.event
-*/
-
-static bool check_table_binlog_row_based(THD *thd, TABLE *table)
-{
-  if (table->s->cached_row_logging_check == -1)
-  {
-    int const check(table->s->tmp_table == NO_TMP_TABLE &&
-                    binlog_filter->db_ok(table->s->db.str));
-    table->s->cached_row_logging_check= check;
-  }
-
-  DBUG_ASSERT(table->s->cached_row_logging_check == 0 ||
-              table->s->cached_row_logging_check == 1);
-
-  return (thd->is_current_stmt_binlog_format_row() &&
-          table->s->cached_row_logging_check &&
-          (thd->variables.option_bits & OPTION_BIN_LOG) &&
-          mysql_bin_log.is_open());
-}
-
-
-/** @brief
-   Write table maps for all (manually or automatically) locked tables
-   to the binary log.
-
-   SYNOPSIS
-     write_locked_table_maps()
-       thd     Pointer to THD structure
-
-   DESCRIPTION
-       This function will generate and write table maps for all tables
-       that are locked by the thread 'thd'.
-
-   RETURN VALUE
-       0   All OK
-       1   Failed to write all table maps
-
-   SEE ALSO
-       THD::lock
-*/
-
-static int write_locked_table_maps(THD *thd)
-{
-  DBUG_ENTER("write_locked_table_maps");
-  DBUG_PRINT("enter", ("thd: 0x%lx  thd->lock: 0x%lx "
-                       "thd->extra_lock: 0x%lx",
-                       (long) thd, (long) thd->lock, (long) thd->extra_lock));
-
-  DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", thd->get_binlog_table_maps()));
-
-  if (thd->get_binlog_table_maps() == 0)
-  {
-    MYSQL_LOCK *locks[2];
-    locks[0]= thd->extra_lock;
-    locks[1]= thd->lock;
-    for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
-    {
-      MYSQL_LOCK const *const lock= locks[i];
-      if (lock == NULL)
-        continue;
-
-      bool need_binlog_rows_query= thd->variables.binlog_rows_query_log_events;
-      TABLE **const end_ptr= lock->table + lock->table_count;
-      for (TABLE **table_ptr= lock->table ; 
-           table_ptr != end_ptr ;
-           ++table_ptr)
-      {
-        TABLE *const table= *table_ptr;
-        DBUG_PRINT("info", ("Checking table %s", table->s->table_name.str));
-        if (table->current_lock == F_WRLCK &&
-            check_table_binlog_row_based(thd, table))
-        {
-          /*
-            We need to have a transactional behavior for SQLCOM_CREATE_TABLE
-            (e.g. CREATE TABLE... SELECT * FROM TABLE) in order to keep a
-            compatible behavior with the STMT based replication even when
-            the table is not transactional. In other words, if the operation
-            fails while executing the insert phase nothing is written to the
-            binlog.
-
-            Note that at this point, we check the type of a set of tables to
-            create the table map events. In the function binlog_log_row(),
-            which calls the current function, we check the type of the table
-            of the current row.
-          */
-          bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
-                                table->file->has_transactions();
-          int const error= thd->binlog_write_table_map(table, has_trans,
-                                                       need_binlog_rows_query);
-          /* Binlog Rows_query log event once for one statement which updates
-             two or more tables.*/
-          if (need_binlog_rows_query)
-            need_binlog_rows_query= FALSE;
-          /*
-            If an error occurs, it is the responsibility of the caller to
-            roll back the transaction.
-          */
-          if (unlikely(error))
-            DBUG_RETURN(1);
-        }
-      }
-    }
-  }
-  DBUG_RETURN(0);
-}
-
-
-typedef bool Log_func(THD*, TABLE*, bool, MY_BITMAP*,
-                      uint, const uchar*, const uchar*);
-
-static int binlog_log_row(TABLE* table,
-                          const uchar *before_record,
-                          const uchar *after_record,
-                          Log_func *log_func)
-{
-  if (table->no_replicate)
-    return 0;
-  bool error= 0;
-  THD *const thd= table->in_use;
-
-  if (check_table_binlog_row_based(thd, table))
-  {
-    MY_BITMAP cols;
-    /* Potential buffer on the stack for the bitmap */
-    uint32 bitbuf[BITMAP_STACKBUF_SIZE/sizeof(uint32)];
-    uint n_fields= table->s->fields;
-    my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
-
-    /*
-      If there are no table maps written to the binary log, this is
-      the first row handled in this statement. In that case, we need
-      to write table maps for all locked tables to the binary log.
-    */
-    if (likely(!(error= bitmap_init(&cols,
-                                    use_bitbuf ? bitbuf : NULL,
-                                    (n_fields + 7) & ~7UL,
-                                    FALSE))))
-    {
-      bitmap_set_all(&cols);
-      if (likely(!(error= write_locked_table_maps(thd))))
-      {
-        /*
-          We need to have a transactional behavior for SQLCOM_CREATE_TABLE
-          (i.e. CREATE TABLE... SELECT * FROM TABLE) in order to keep a
-          compatible behavior with the STMT based replication even when
-          the table is not transactional. In other words, if the operation
-          fails while executing the insert phase nothing is written to the
-          binlog.
-        */
-        bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
-                             table->file->has_transactions();
-        error= (*log_func)(thd, table, has_trans, &cols, table->s->fields,
-                           before_record, after_record);
-      }
-      if (!use_bitbuf)
-        bitmap_free(&cols);
-    }
-  }
-  return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
-}
-
 int handler::ha_external_lock(THD *thd, int lock_type)
 {
   MYSQL_TABLE_WAIT_VARIABLES(locker, state) /* no ';' */
@@ -5796,7 +5622,6 @@ int handler::ha_reset()
 int handler::ha_write_row(uchar *buf)
 {
   int error;
-  Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
   MYSQL_TABLE_WAIT_VARIABLES(locker, state) /* no ';' */
 
   DBUG_ENTER("handler::ha_write_row");
@@ -5813,7 +5638,7 @@ int handler::ha_write_row(uchar *buf)
   if (unlikely(error))
     DBUG_RETURN(error);
 
-  if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
+  if (unlikely(error= binlog.write_row(table, buf)))
     DBUG_RETURN(error); /* purecov: inspected */
   DBUG_RETURN(0);
 }
@@ -5822,7 +5647,6 @@ int handler::ha_write_row(uchar *buf)
 int handler::ha_update_row(const uchar *old_data, uchar *new_data)
 {
   int error;
-  Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
   MYSQL_TABLE_WAIT_VARIABLES(locker, state) /* no ';' */
 
   /*
@@ -5843,7 +5667,7 @@ int handler::ha_update_row(const uchar *
   MYSQL_UPDATE_ROW_DONE(error);
   if (unlikely(error))
     return error;
-  if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func)))
+  if (unlikely(error= binlog.update_row(table, old_data, new_data)))
     return error;
   return 0;
 }
@@ -5851,7 +5675,6 @@ int handler::ha_update_row(const uchar *
 int handler::ha_delete_row(const uchar *buf)
 {
   int error;
-  Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
   MYSQL_TABLE_WAIT_VARIABLES(locker, state) /* no ';' */
 
   MYSQL_DELETE_ROW_START(table_share->db.str, table_share->table_name.str);
@@ -5866,7 +5689,7 @@ int handler::ha_delete_row(const uchar *
   MYSQL_DELETE_ROW_DONE(error);
   if (unlikely(error))
     return error;
-  if (unlikely(error= binlog_log_row(table, buf, 0, log_func)))
+  if (unlikely(error= binlog.delete_row(table, buf)))
     return error;
   return 0;
 }

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2010-10-13 23:16:09 +0000
+++ b/sql/mysqld.cc	2010-11-17 08:46:17 +0000
@@ -53,7 +53,6 @@
 #include <m_ctype.h>
 #include <my_dir.h>
 #include <my_bit.h>
-#include "rpl_slave.h"
 #include "rpl_master.h"
 #include "rpl_mi.h"
 #include "rpl_filter.h"
@@ -437,7 +436,6 @@ volatile bool mqh_used = 0;
 my_bool opt_noacl;
 my_bool sp_automatic_privileges= 1;
 
-ulong opt_binlog_rows_event_max_size;
 const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
 #ifdef HAVE_INITGROUPS
 static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
@@ -1109,7 +1107,7 @@ static void close_connections(void)
   mysql_mutex_unlock(&LOCK_thread_count); // For unlink from list
 
   Events::deinit();
-  end_slave();
+  rpl_slave.end();
 
   if (thread_count)
     sleep(2);					// Give threads time to die
@@ -1471,7 +1469,7 @@ void clean_up(bool print_message)
   bitmap_free(&temp_pool);
   free_max_user_conn();
 #ifdef HAVE_REPLICATION
-  end_slave_list();
+  rpl_master.end();
 #endif
   delete binlog_filter;
   delete rpl_filter;
@@ -3506,18 +3504,11 @@ You should consider changing lower_case_
 			&my_charset_utf8_tolower_ci :
 			&my_charset_bin);
 
-  /*
-    Build do_table and ignore_table rules to hush
-    after the resetting of table_alias_charset
-  */
-  if (rpl_filter->build_do_table_hash() ||
-      rpl_filter->build_ignore_table_hash())
-  {
-    sql_print_error("An error occurred while building do_table"
-                    "and ignore_table rules to hush.");
+#ifdef HAVE_REPLICATION
+  if (rpl_filter->table_alias_charset_changed())
     return 1;
-  }
-
+#endif
+  
   return 0;
 }
 
@@ -3888,7 +3879,7 @@ static int init_server_components()
   setup_fpu();
   init_thr_lock();
 #ifdef HAVE_REPLICATION
-  init_slave_list();
+  rpl_master.init();
 #endif
 
   /* Setup logs */
@@ -4689,16 +4680,11 @@ int mysqld_main(int argc, char **argv)
   check_binlog_cache_size(NULL);
 
   binlog_unsafe_map_init();
+  
   /*
     init_slave() must be called after the thread keys are created.
-    Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
-    places) assume that active_mi != 0, so let's fail if it's 0 (out of
-    memory); a message has already been printed.
   */
-  if (init_slave() && !active_mi)
-  {
-    unireg_abort(1);
-  }
+  rpl_slave.init();
 
 #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
   initialize_performance_schema_acl(opt_bootstrap);
@@ -5856,16 +5842,6 @@ struct my_option my_long_options[]=
   {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
    "Tells the master that updates to the given database should not be logged to the binary log.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-  {"binlog-row-event-max-size", 0,
-   "The maximum size of a row-based binary log event in bytes. Rows will be "
-   "grouped into events smaller than this size if possible. "
-   "The value has to be a multiple of 256.",
-   &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
-   0, GET_ULONG, REQUIRED_ARG,
-   /* def_value */ 1024, /* min_value */  256, /* max_value */ ULONG_MAX, 
-   /* sub_size */     0, /* block_size */ 256, 
-   /* app_type */ 0
-  },
 #ifndef DISABLE_GRANT_OPTIONS
   {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
    GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},

=== modified file 'sql/mysqld.h'
--- a/sql/mysqld.h	2010-09-01 13:06:14 +0000
+++ b/sql/mysqld.h	2010-11-17 08:46:17 +0000
@@ -148,6 +148,7 @@ extern char pidfile_name[FN_REFLEN], sys
 extern char default_logfile_name[FN_REFLEN];
 extern char log_error_file[FN_REFLEN], *opt_tc_log_file;
 /*Move UUID_LENGTH from item_strfunc.h*/
+#define HAVE_SERVER_UUID 1
 #define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
 extern char server_uuid[UUID_LENGTH+1];
 extern const char *server_uuid_ptr;
@@ -178,7 +179,6 @@ extern ulong max_prepared_stmt_count, pr
 extern ulong binlog_cache_size, open_files_limit;
 extern ulonglong max_binlog_cache_size;
 extern ulong max_binlog_size, max_relay_log_size;
-extern ulong opt_binlog_rows_event_max_size;
 extern ulong thread_cache_size;
 extern ulong back_log;
 extern char language[FN_REFLEN];

=== modified file 'sql/replication.h'
--- a/sql/replication.h	2010-07-02 02:58:51 +0000
+++ b/sql/replication.h	2010-11-17 08:46:17 +0000
@@ -20,9 +20,7 @@
 
 typedef struct st_mysql MYSQL;
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+C_MODE_START
 
 /**
    Transaction observer flags.
@@ -438,28 +436,6 @@ int register_binlog_relay_io_observer(Bi
 int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p);
 
 /**
-   Connect to master
-
-   This function can only used in the slave I/O thread context, and
-   will use the same master information to do the connection.
-
-   @code
-   MYSQL *mysql = mysql_init(NULL);
-   if (rpl_connect_master(mysql))
-   {
-     // do stuff with the connection
-   }
-   mysql_close(mysql); // close the connection
-   @endcode
-   
-   @param mysql address of MYSQL structure to use, pass NULL will
-   create a new one
-
-   @return address of MYSQL structure on success, NULL on failure
-*/
-MYSQL *rpl_connect_master(MYSQL *mysql);
-
-/**
    Set thread entering a condition
 
    This function should be called before putting a thread to wait for
@@ -544,9 +520,6 @@ int get_user_var_str(const char *name,
                      char *value, unsigned long len,
                      unsigned int precision, int *null_value);
 
-  
 
-#ifdef __cplusplus
-}
-#endif
+C_MODE_END
 #endif /* REPLICATION_H */

=== modified file 'sql/rpl/binlog.cc'
--- a/sql/rpl/binlog.cc	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/binlog.cc	2010-11-17 08:46:17 +0000
@@ -17,6 +17,7 @@
 #include "my_global.h"
 #include "log.h"
 #include "binlog.h"
+#include "binlog_priv.h"
 #include "log_event.h"
 #include "rpl_filter.h"
 #include "rpl_rli.h"
@@ -26,6 +27,7 @@
 #define MY_OFF_T_UNDEF (~(my_off_t)0UL)
 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 
+Binlog binlog;
 handlerton *binlog_hton;
 
 MYSQL_BIN_LOG mysql_bin_log(&sync_binlog_period);
@@ -1067,7 +1069,7 @@ bool stmt_has_updated_non_trans_table(co
   @retval FALSE success
   @retval TRUE failure
 */
-bool purge_master_logs(THD* thd, const char* to_log)
+int Binlog::purge_binary_logs(THD* thd, const char* to_log)
 {
   char search_file_name[FN_REFLEN];
   if (!mysql_bin_log.is_open())
@@ -1094,7 +1096,7 @@ bool purge_master_logs(THD* thd, const c
   @retval FALSE success
   @retval TRUE failure
 */
-bool purge_master_logs_before_date(THD* thd, time_t purge_time)
+int Binlog::purge_binary_logs_before(THD* thd, time_t purge_time)
 {
   if (!mysql_bin_log.is_open())
   {
@@ -1393,11 +1395,11 @@ err:
   @retval FALSE success
   @retval TRUE failure
 */
-bool mysql_show_binlog_events(THD* thd)
+int Binlog::show_binlog_events(THD* thd)
 {
   Protocol *protocol= thd->protocol;
   List<Item> field_list;
-  DBUG_ENTER("mysql_show_binlog_events");
+  DBUG_ENTER("Binlog::show_binlog_events");
 
   DBUG_ASSERT(thd->lex->sql_command == SQLCOM_SHOW_BINLOG_EVENTS);
 
@@ -1413,7 +1415,7 @@ bool mysql_show_binlog_events(THD* thd)
   */
   ha_binlog_wait(thd);
   
-  DBUG_RETURN(show_binlog_events(thd, &mysql_bin_log));
+  DBUG_RETURN(::show_binlog_events(thd, &mysql_bin_log));
 }
 
 #endif /* HAVE_REPLICATION */
@@ -4881,26 +4883,6 @@ int THD::binlog_flush_pending_rows_event
 }
 
 
-#if !defined(DBUG_OFF) && !defined(_lint)
-static const char *
-show_query_type(THD::enum_binlog_query_type qtype)
-{
-  switch (qtype) {
-  case THD::ROW_QUERY_TYPE:
-    return "ROW";
-  case THD::STMT_QUERY_TYPE:
-    return "STMT";
-  case THD::QUERY_TYPE_COUNT:
-  default:
-    DBUG_ASSERT(0 <= qtype && qtype < THD::QUERY_TYPE_COUNT);
-  }
-  static char buf[64];
-  sprintf(buf, "UNKNOWN#%d", qtype);
-  return buf;
-}
-#endif
-
-
 /**
   Auxiliary method used by @c binlog_query() to raise warnings.
 
@@ -4946,6 +4928,113 @@ void THD::issue_unsafe_warnings()
 }
 
 
+#endif /* !defined(MYSQL_CLIENT) */
+
+#ifdef INNODB_COMPATIBILITY_HOOKS
+/**
+  Get the file name of the MySQL binlog.
+  @return the name of the binlog file
+*/
+extern "C"
+const char* mysql_bin_log_file_name(void)
+{
+  return mysql_bin_log.get_log_fname();
+}
+/**
+  Get the current position of the MySQL binlog.
+  @return byte offset from the beginning of the binlog
+*/
+extern "C"
+ulonglong mysql_bin_log_file_pos(void)
+{
+  return (ulonglong) mysql_bin_log.get_log_file()->pos_in_file;
+}
+#endif /* INNODB_COMPATIBILITY_HOOKS */
+
+
+static MYSQL_SYSVAR_ULONG(row_event_max_size, opt_binlog_rows_event_max_size,
+       PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+       "The maximum size of a row-based binary log event in bytes. Rows will be "
+       "grouped into events smaller than this size if possible. "
+       "The value has to be a multiple of 256.",
+       NULL,
+       NULL,
+       1024, 256, ULONG_MAX, 256);
+
+static MYSQL_THDVAR_BOOL(rows_query_log_events,
+       PLUGIN_VAR_OPCMDARG,
+      "Allow writing of Rows_query_log events into binary log.",
+       NULL,                                    /* check */
+       NULL,                                    /* update */ 
+       FALSE);                                  /* default */
+
+static struct st_mysql_sys_var* binlog_system_vars[]= {
+  MYSQL_SYSVAR(row_event_max_size),
+  MYSQL_SYSVAR(rows_query_log_events),
+  NULL,
+};
+
+struct st_mysql_storage_engine binlog_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+
+mysql_declare_plugin(binlog)
+{
+  MYSQL_STORAGE_ENGINE_PLUGIN,
+  &binlog_storage_engine,
+  "binlog",
+  "MySQL AB",
+  "This is a pseudo storage engine to represent the binlog in a transaction",
+  PLUGIN_LICENSE_GPL,
+  binlog_init, /* Plugin Init */
+  NULL, /* Plugin Deinit */
+  0x0100 /* 1.0 */,
+  NULL,                       /* status variables                */
+  binlog_system_vars,         /* system variables                */
+  NULL                        /* config options                  */
+}
+mysql_declare_plugin_end;
+
+bool thd_binlog_rows_query_log_events(THD *thd)
+{
+  return THDVAR(thd, rows_query_log_events);
+}
+
+void set_binlog_rows_query_log_events(THD *thd, bool val)
+{
+  THDVAR(thd, rows_query_log_events)= val;
+}
+
+/*
+  Function to check if the conditions for row-based binlogging is
+  correct for the table.
+
+  A row in the given table should be replicated if:
+  - Row-based replication is enabled in the current thread
+  - The binlog is enabled
+  - It is not a temporary table
+  - The binary log is open
+  - The database the table resides in shall be binlogged (binlog_*_db rules)
+  - table is not mysql.event
+*/
+
+static bool check_table_binlog_row_based(THD *thd, TABLE *table)
+{
+  if (table->s->cached_row_logging_check == -1)
+  {
+    int const check(table->s->tmp_table == NO_TMP_TABLE &&
+                    binlog_filter->db_ok(table->s->db.str));
+    table->s->cached_row_logging_check= check;
+  }
+
+  DBUG_ASSERT(table->s->cached_row_logging_check == 0 ||
+              table->s->cached_row_logging_check == 1);
+
+  return (thd->is_current_stmt_binlog_format_row() &&
+          table->s->cached_row_logging_check &&
+          (thd->variables.option_bits & OPTION_BIN_LOG) &&
+          mysql_bin_log.is_open());
+}
+
 /**
   Log the current query.
 
@@ -4971,14 +5060,15 @@ void THD::issue_unsafe_warnings()
   @retval nonzero If there is a failure when writing the query (e.g.,
   write failure), then the error code is returned.
 */
-int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
-                      ulong query_len, bool is_trans, bool direct, 
-                      bool suppress_use, int errcode)
+int Binlog::binlog_query(THD* thd,
+                         enum_binlog_query_type qtype, char const *query,
+                         ulong query_len, bool is_trans, bool direct, 
+                         bool suppress_use, int errcode)
 {
-  DBUG_ENTER("THD::binlog_query");
+  DBUG_ENTER("Binlog::binlog_query");
   DBUG_PRINT("enter", ("qtype: %s  query: '%s'",
-                       show_query_type(qtype), query_arg));
-  DBUG_ASSERT(query_arg && mysql_bin_log.is_open());
+                       show_query_type(qtype), query));
+  DBUG_ASSERT(query && mysql_bin_log.is_open());
 
   /*
     If we are not in prelocked mode, mysql_unlock_tables() will be
@@ -4989,8 +5079,8 @@ int THD::binlog_query(THD::enum_binlog_q
     If we are in prelocked mode, the flushing will be done inside the
     top-most close_thread_tables().
   */
-  if (this->locked_tables_mode <= LTM_LOCK_TABLES)
-    if (int error= binlog_flush_pending_rows_event(TRUE, is_trans))
+  if (thd->locked_tables_mode <= LTM_LOCK_TABLES)
+    if (int error= thd->binlog_flush_pending_rows_event(TRUE, is_trans))
       DBUG_RETURN(error);
 
   /*
@@ -5006,7 +5096,7 @@ int THD::binlog_query(THD::enum_binlog_q
     2 - sp_head::execute_function which prints out warnings for calls
     involving functions.
 
-    3 - THD::binlog_query (here) which prints warning for top level
+    3 - Binlog::binlog_query (here) which prints warning for top level
     statements not covered by the two cases above: i.e., if not insided a
     procedure and a function.
  
@@ -5015,9 +5105,9 @@ int THD::binlog_query(THD::enum_binlog_q
     the execution is inside a function, or generaly speaking, when
     the variables.option_bits & OPTION_BIN_LOG is false.
   */
-  if ((variables.option_bits & OPTION_BIN_LOG) &&
-      spcont == NULL && !binlog_evt_union.do_union)
-    issue_unsafe_warnings();
+  if ((thd->variables.option_bits & OPTION_BIN_LOG) &&
+      thd->spcont == NULL && !thd->binlog_evt_union.do_union)
+    thd->issue_unsafe_warnings();
 
   switch (qtype) {
     /*
@@ -5027,11 +5117,11 @@ int THD::binlog_query(THD::enum_binlog_q
       statement has already been logged in row format and hence shall
       not be logged again.
     */
-  case THD::ROW_QUERY_TYPE:
+  case ROW_QUERY_TYPE:
     DBUG_PRINT("debug",
                ("is_current_stmt_binlog_format_row: %d",
-                is_current_stmt_binlog_format_row()));
-    if (is_current_stmt_binlog_format_row())
+                thd->is_current_stmt_binlog_format_row()));
+    if (thd->is_current_stmt_binlog_format_row())
       DBUG_RETURN(0);
     /* Fall through */
 
@@ -5045,13 +5135,13 @@ int THD::binlog_query(THD::enum_binlog_q
       STMT_QUERY_TYPE and current_stmt_binlog_format is row.  Fix those
       places and add assert to ensure correct behavior. /Sven
     */
-  case THD::STMT_QUERY_TYPE:
+  case STMT_QUERY_TYPE:
     /*
       The MYSQL_LOG::write() function will set the STMT_END_F flag and
       flush the pending rows event if necessary.
     */
     {
-      Query_log_event qinfo(this, query_arg, query_len, is_trans, direct,
+      Query_log_event qinfo(thd, query, query_len, is_trans, direct,
                             suppress_use, errcode);
       /*
         Binlog table maps will be irrelevant after a Query_log_event
@@ -5060,58 +5150,284 @@ int THD::binlog_query(THD::enum_binlog_q
         table maps were written.
        */
       int error= mysql_bin_log.write(&qinfo);
-      binlog_table_maps= 0;
+      thd->binlog_table_maps= 0;
       DBUG_RETURN(error);
     }
     break;
 
-  case THD::QUERY_TYPE_COUNT:
+  case QUERY_TYPE_COUNT:
   default:
     DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
   }
   DBUG_RETURN(0);
 }
 
-#endif /* !defined(MYSQL_CLIENT) */
-
-#ifdef INNODB_COMPATIBILITY_HOOKS
 /**
-  Get the file name of the MySQL binlog.
-  @return the name of the binlog file
+  Execute a SHOW BINARY LOGS statement.
+
+  @param thd Pointer to THD object for the client thread executing the
+  statement.
+
+  @retval FALSE success
+  @retval TRUE failure
 */
-extern "C"
-const char* mysql_bin_log_file_name(void)
+int Binlog::show_binary_logs(THD* thd)
 {
-  return mysql_bin_log.get_log_fname();
+  IO_CACHE *index_file;
+  LOG_INFO cur;
+  File file;
+  char fname[FN_REFLEN];
+  List<Item> field_list;
+  uint length;
+  int cur_dir_len;
+  Protocol *protocol= thd->protocol;
+  DBUG_ENTER("show_binlogs");
+
+  if (!mysql_bin_log.is_open())
+  {
+    my_message(ER_NO_BINARY_LOGGING, ER(ER_NO_BINARY_LOGGING), MYF(0));
+    DBUG_RETURN(TRUE);
+  }
+
+  field_list.push_back(new Item_empty_string("Log_name", 255));
+  field_list.push_back(new Item_return_int("File_size", 20,
+                                           MYSQL_TYPE_LONGLONG));
+  if (protocol->send_result_set_metadata(&field_list,
+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+    DBUG_RETURN(TRUE);
+  
+  mysql_mutex_lock(mysql_bin_log.get_log_lock());
+  mysql_bin_log.lock_index();
+  index_file=mysql_bin_log.get_index_file();
+  
+  mysql_bin_log.raw_get_current_log(&cur); // dont take mutex
+  mysql_mutex_unlock(mysql_bin_log.get_log_lock()); // lockdep, OK
+  
+  cur_dir_len= dirname_length(cur.log_file_name);
+
+  reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0);
+
+  /* The file ends with EOF or empty line */
+  while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1)
+  {
+    int dir_len;
+    ulonglong file_length= 0;                   // Length if open fails
+    fname[--length] = '\0';                     // remove the newline
+
+    protocol->prepare_for_resend();
+    dir_len= dirname_length(fname);
+    length-= dir_len;
+    protocol->store(fname + dir_len, length, &my_charset_bin);
+
+    if (!(strncmp(fname+dir_len, cur.log_file_name+cur_dir_len, length)))
+      file_length= cur.pos;  /* The active log, use the active position */
+    else
+    {
+      /* this is an old log, open it and find the size */
+      if ((file= mysql_file_open(key_file_binlog,
+                                 fname, O_RDONLY | O_SHARE | O_BINARY,
+                                 MYF(0))) >= 0)
+      {
+        file_length= (ulonglong) mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0));
+        mysql_file_close(file, MYF(0));
+      }
+    }
+    protocol->store(file_length);
+    if (protocol->write())
+      goto err;
+  }
+  mysql_bin_log.unlock_index();
+  my_eof(thd);
+  DBUG_RETURN(FALSE);
+
+err:
+  mysql_bin_log.unlock_index();
+  DBUG_RETURN(TRUE);
 }
-/**
-  Get the current position of the MySQL binlog.
-  @return byte offset from the beginning of the binlog
+
+#define BITMAP_STACKBUF_SIZE (128/8)
+
+int Binlog::log_row(TABLE* table,
+                    const uchar *before_record,
+                    const uchar *after_record,
+                    Log_func *log_func)
+{
+  if (table->no_replicate)
+    return 0;
+  bool error= 0;
+  THD *const thd= table->in_use;
+
+  if (check_table_binlog_row_based(thd, table))
+  {
+    MY_BITMAP cols;
+    /* Potential buffer on the stack for the bitmap */
+    uint32 bitbuf[BITMAP_STACKBUF_SIZE/sizeof(uint32)];
+    uint n_fields= table->s->fields;
+    my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
+
+    /*
+      If there are no table maps written to the binary log, this is
+      the first row handled in this statement. In that case, we need
+      to write table maps for all locked tables to the binary log.
+    */
+    if (likely(!(error= bitmap_init(&cols,
+                                    use_bitbuf ? bitbuf : NULL,
+                                    (n_fields + 7) & ~7UL,
+                                    FALSE))))
+    {
+      bitmap_set_all(&cols);
+      if (likely(!(error= binlog.write_locked_table_maps(thd))))
+      {
+        /*
+          We need to have a transactional behavior for SQLCOM_CREATE_TABLE
+          (i.e. CREATE TABLE... SELECT * FROM TABLE) in order to keep a
+          compatible behavior with the STMT based replication even when
+          the table is not transactional. In other words, if the operation
+          fails while executing the insert phase nothing is written to the
+          binlog.
+        */
+        bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
+                             table->file->has_transactions();
+        error= (*log_func)(thd, table, has_trans, &cols, table->s->fields,
+                           before_record, after_record);
+      }
+      if (!use_bitbuf)
+        bitmap_free(&cols);
+    }
+  }
+  return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
+}
+
+/** @brief
+   Write table maps for all (manually or automatically) locked tables
+   to the binary log.
+
+   SYNOPSIS
+     write_locked_table_maps()
+       thd     Pointer to THD structure
+
+   DESCRIPTION
+       This function will generate and write table maps for all tables
+       that are locked by the thread 'thd'.
+
+   RETURN VALUE
+       0   All OK
+       1   Failed to write all table maps
+
+   SEE ALSO
+       THD::lock
 */
-extern "C"
-ulonglong mysql_bin_log_file_pos(void)
+
+int Binlog::write_locked_table_maps(THD *thd)
 {
-  return (ulonglong) mysql_bin_log.get_log_file()->pos_in_file;
+  DBUG_ENTER("write_locked_table_maps");
+  DBUG_PRINT("enter", ("thd: 0x%lx  thd->lock: 0x%lx "
+                       "thd->extra_lock: 0x%lx",
+                       (long) thd, (long) thd->lock, (long) thd->extra_lock));
+
+  DBUG_PRINT("debug", ("get_binlog_table_maps(): %d", thd->get_binlog_table_maps()));
+
+  if (thd->get_binlog_table_maps() == 0)
+  {
+    MYSQL_LOCK *locks[2];
+    locks[0]= thd->extra_lock;
+    locks[1]= thd->lock;
+    for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
+    {
+      MYSQL_LOCK const *const lock= locks[i];
+      if (lock == NULL)
+        continue;
+
+      bool need_binlog_rows_query= thd_binlog_rows_query_log_events(thd);
+      TABLE **const end_ptr= lock->table + lock->table_count;
+      for (TABLE **table_ptr= lock->table ; 
+           table_ptr != end_ptr ;
+           ++table_ptr)
+      {
+        TABLE *const table= *table_ptr;
+        DBUG_PRINT("info", ("Checking table %s", table->s->table_name.str));
+        if (table->current_lock == F_WRLCK &&
+            check_table_binlog_row_based(thd, table))
+        {
+          /*
+            We need to have a transactional behavior for SQLCOM_CREATE_TABLE
+            (e.g. CREATE TABLE... SELECT * FROM TABLE) in order to keep a
+            compatible behavior with the STMT based replication even when
+            the table is not transactional. In other words, if the operation
+            fails while executing the insert phase nothing is written to the
+            binlog.
+
+            Note that at this point, we check the type of a set of tables to
+            create the table map events. In the function binlog_log_row(),
+            which calls the current function, we check the type of the table
+            of the current row.
+          */
+          bool const has_trans= thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
+                                table->file->has_transactions();
+          int const error= thd->binlog_write_table_map(table, has_trans,
+                                                       need_binlog_rows_query);
+          /* Binlog Rows_query log event once for one statement which updates
+             two or more tables.*/
+          if (need_binlog_rows_query)
+            need_binlog_rows_query= FALSE;
+          /*
+            If an error occurs, it is the responsibility of the caller to
+            roll back the transaction.
+          */
+          if (unlikely(error))
+            DBUG_RETURN(1);
+        }
+      }
+    }
+  }
+  DBUG_RETURN(0);
 }
-#endif /* INNODB_COMPATIBILITY_HOOKS */
 
+int Binlog::get_delayed_row_data(THD *thd, TABLE* table,
+                                 void **row_binlog_data, LEX_STRING* query, bool log_on)
+{
+  Delayed_row_binlog_data *row_data= new Delayed_row_binlog_data;
+  if (!row_data)
+    return 1;
+  row_data->binlog_rows_query_log_events= thd_binlog_rows_query_log_events(thd);
+  *row_binlog_data= row_data;
+  return 0;
+}
 
-struct st_mysql_storage_engine binlog_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION };
+int Binlog::before_handle_delayed_row(THD* thd, TABLE* table,
+                                      void* row_binlog_data,
+                                      LEX_STRING* query,
+                                      bool log_query)
+{
+  if (log_query)
+  {
+    if (thd->is_current_stmt_binlog_format_row())
+    {
+      /* Flush rows of previous statement*/
+      if (thd->binlog_flush_pending_rows_event(TRUE, FALSE))
+        return 1;
+      /* Set query for Rows_query_log event in RBR*/
+      thd->set_query(query->str, query->length);
+      set_binlog_rows_query_log_events(thd,
+                                       ((Delayed_row_binlog_data*)row_binlog_data)->binlog_rows_query_log_events);
+    }
+  }
+  return 0;
+}
 
-mysql_declare_plugin(binlog)
+int Binlog::after_handle_delayed_row(THD* thd,
+                                     TABLE* table,
+                                     void* row_binlog_data,
+                                     LEX_STRING* query,
+                                     bool log_query)
 {
-  MYSQL_STORAGE_ENGINE_PLUGIN,
-  &binlog_storage_engine,
-  "binlog",
-  "MySQL AB",
-  "This is a pseudo storage engine to represent the binlog in a transaction",
-  PLUGIN_LICENSE_GPL,
-  binlog_init, /* Plugin Init */
-  NULL, /* Plugin Deinit */
-  0x0100 /* 1.0 */,
-  NULL,                       /* status variables                */
-  NULL,                       /* system variables                */
-  NULL                        /* config options                  */
+  delete (Delayed_row_binlog_data*)row_binlog_data;
+  return 0;
+}
+
+int Binlog::flush_binary_log(THD* thd)
+{
+  if (mysql_bin_log.is_open())
+    mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+  return 0;
 }
-mysql_declare_plugin_end;

=== modified file 'sql/rpl/binlog.h'
--- a/sql/rpl/binlog.h	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/binlog.h	2010-11-17 08:46:17 +0000
@@ -246,21 +246,110 @@ typedef struct st_load_file_info
 
 extern MYSQL_PLUGIN_IMPORT MYSQL_BIN_LOG mysql_bin_log;
 
-bool trans_has_updated_trans_table(const THD* thd);
-bool stmt_has_updated_trans_table(const THD *thd);
-bool use_trans_cache(const THD* thd, bool is_transactional);
-bool ending_trans(THD* thd, const bool all);
-bool ending_single_stmt_trans(THD* thd, const bool all);
-bool trans_has_updated_non_trans_table(const THD* thd);
-bool stmt_has_updated_non_trans_table(const THD* thd);
-
 int log_loaded_block(IO_CACHE* file);
-File open_binlog(IO_CACHE *log, const char *log_file_name,
-                 const char **errmsg);
-int check_binlog_magic(IO_CACHE* log, const char** errmsg);
-bool purge_master_logs(THD* thd, const char* to_log);
-bool purge_master_logs_before_date(THD* thd, time_t purge_time);
-bool show_binlog_events(THD *thd, MYSQL_BIN_LOG *binary_log);
 void check_binlog_cache_size(THD *thd);
 
+bool thd_binlog_rows_query_log_events(THD *thd);
+void set_binlog_rows_query_log_events(THD *thd, bool val);
+
+class Delayed_row_binlog_data {
+public:
+  bool binlog_rows_query_log_events;
+};
+
+typedef bool Log_func(THD*, TABLE*, bool, MY_BITMAP*,
+                      uint, const uchar*, const uchar*);
+
+class Binlog {
+public:
+  enum enum_binlog_query_type {
+    /* The query can be logged in row format or in statement format. */
+    ROW_QUERY_TYPE,
+    
+    /* The query has to be logged in statement format. */
+    STMT_QUERY_TYPE,
+    
+    QUERY_TYPE_COUNT
+  };
+
+public:
+  int init()
+  {
+    mysql_bin_log.init_pthread_objects();
+    return 0;
+  }
+  void end()
+  {
+    mysql_bin_log.cleanup();
+  }
+  bool is_open()
+  {
+    return mysql_bin_log.is_open();
+  }
+  int flush_binary_log(THD* thd);
+  int show_binary_logs(THD* thd);
+  int show_binlog_events(THD* thd);
+  int purge_binary_logs(THD* thd, const char* to_log);
+  int purge_binary_logs_before(THD* thd, time_t before_time);
+  int write_event(Log_event* event)
+  {
+    return mysql_bin_log.write(event);
+  }
+  int binlog_query(THD* thd,
+                   enum_binlog_query_type qtype, char const *query,
+                   ulong query_len, bool is_trans, bool direct, 
+                   bool suppress_use, int errcode);
+  int write_row(TABLE* table, const uchar* record)
+  {
+    Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
+    return log_row(table, 0, record, log_func);
+  }
+  int update_row(TABLE* table, const uchar* before_record,
+                 const uchar* after_record)
+  {
+    Log_func *log_func= Update_rows_log_event::binlog_row_logging_function;
+    return log_row(table, before_record, after_record, log_func);
+  }
+  int delete_row(TABLE* table, const uchar* record)
+  {
+    Log_func *log_func= Delete_rows_log_event::binlog_row_logging_function;
+    return log_row(table, record, 0, log_func);
+  }
+  int get_delayed_row_data(THD* thd, TABLE* table,
+                           void** row_binlog_data,
+                           LEX_STRING* query, bool log_on);
+  int before_handle_delayed_row(THD* thd, TABLE* table,
+                                void* row_binlog_data,
+                                LEX_STRING* query, bool log_query);
+  int after_handle_delayed_row(THD* thd, TABLE* table,
+                               void* row_binlog_data,
+                               LEX_STRING* query, bool log_query);
+
+private:
+#if !defined(DBUG_OFF) && !defined(_lint)
+  const char* show_query_type(enum_binlog_query_type qtype)
+  {
+    switch (qtype) {
+    case ROW_QUERY_TYPE:
+      return "ROW";
+    case STMT_QUERY_TYPE:
+      return "STMT";
+    case QUERY_TYPE_COUNT:
+    default:
+      DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
+    }
+    static char buf[64];
+    sprintf(buf, "UNKNOWN#%d", qtype);
+    return buf;
+  }
+#endif
+  int write_locked_table_maps(THD* thd);
+  int log_row(TABLE* table,
+              const uchar* before_record,
+              const uchar* after_record,
+              Log_func* log_func);
+};
+
+extern MYSQL_PLUGIN_IMPORT Binlog binlog;
+
 #endif /* BINLOG_H_INCLUDED */

=== modified file 'sql/rpl/log_event.cc'
--- a/sql/rpl/log_event.cc	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/log_event.cc	2010-11-17 08:46:17 +0000
@@ -55,6 +55,7 @@
 
 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 
+ulong opt_binlog_rows_event_max_size;
 
 /*
   Size of buffer for printing a double in format %.<PREC>g

=== modified file 'sql/rpl/log_event.h'
--- a/sql/rpl/log_event.h	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/log_event.h	2010-11-17 08:46:17 +0000
@@ -49,6 +49,8 @@
 #include "sql_class.h"                          /* THD */
 #endif
 
+extern ulong opt_binlog_rows_event_max_size;
+
 /* Forward declarations */
 class String;
 

=== modified file 'sql/rpl/rpl_filter.cc'
--- a/sql/rpl/rpl_filter.cc	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_filter.cc	2010-11-17 08:46:17 +0000
@@ -18,14 +18,16 @@
 #include "rpl_filter.h"
 #include "hash.h"                               // my_hash_free
 #include "table.h"                              // TABLE_LIST
+#include "log.h"                                // sql_print_error
 
 #define TABLE_RULE_HASH_SIZE   16
 #define TABLE_RULE_ARR_SIZE   16
 
 Rpl_filter::Rpl_filter() : 
-  table_rules_on(0), do_table_array_inited(0), ignore_table_array_inited(0),
-  wild_do_table_inited(0), wild_ignore_table_inited(0),
-  do_table_hash_inited(0), ignore_table_hash_inited(0)
+  table_rules_on(0),
+  do_table_hash_inited(0), ignore_table_hash_inited(0),
+  do_table_array_inited(0), ignore_table_array_inited(0),
+  wild_do_table_inited(0), wild_ignore_table_inited(0)
 {
   do_db.empty();
   ignore_db.empty();
@@ -686,3 +688,19 @@ Rpl_filter::get_ignore_db()
 {
   return &ignore_db;
 }
+
+int Rpl_filter::table_alias_charset_changed()
+{
+  /*
+    Build do_table and ignore_table rules to hush
+    after the resetting of table_alias_charset
+  */
+  if (rpl_filter->build_do_table_hash() ||
+      rpl_filter->build_ignore_table_hash())
+  {
+    sql_print_error("An error occurred while building do_table"
+                    "and ignore_table rules to hush.");
+    return 1;
+  }
+  return 0;
+}

=== modified file 'sql/rpl/rpl_filter.h'
--- a/sql/rpl/rpl_filter.h	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_filter.h	2010-11-17 08:46:17 +0000
@@ -58,7 +58,11 @@ public:
   int build_do_table_hash();
   int build_ignore_table_hash();
 
+  int add_do_table(const char* table_spec)
+  { return add_do_table_array(table_spec); }
   int add_do_table_array(const char* table_spec);
+  int add_ignore_table(const char* table_spec)
+  { return add_ignore_table_array(table_spec); }
   int add_ignore_table_array(const char* table_spec);
 
   int add_wild_do_table(const char* table_spec);
@@ -82,6 +86,8 @@ public:
   I_List<i_string>* get_do_db();
   I_List<i_string>* get_ignore_db();
 
+  int table_alias_charset_changed();
+
 private:
   bool table_rules_on;
 

=== modified file 'sql/rpl/rpl_master.cc'
--- a/sql/rpl/rpl_master.cc	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_master.cc	2010-11-17 08:46:17 +0000
@@ -16,16 +16,40 @@
 
 #include "sql_priv.h"
 #include "unireg.h"
-#include "sql_parse.h"                          // check_access
 #ifdef HAVE_REPLICATION
 
-#include "sql_acl.h"                            // SUPER_ACL
 #include "log_event.h"
+#include "binlog_priv.h"
 #include "rpl_filter.h"
 #include <my_dir.h>
 #include "rpl_handler.h"
 #include "rpl_master.h"
 
+typedef struct st_slave_info
+{
+  uint32 server_id;
+  uint32 rpl_recovery_rank, master_id;
+  char host[HOSTNAME_LENGTH+1];
+  char user[USERNAME_LENGTH+1];
+  char password[MAX_PASSWORD_LENGTH+1];
+  uint16 port;
+  THD* thd;
+} SLAVE_INFO;
+
+static void init_slave_list();
+static void end_slave_list();
+static void unregister_slave(THD* thd, bool only_mine, bool need_mutex);
+
+#if HAVE_SERVER_UUID
+static String *get_slave_uuid(THD *thd, String *value);
+static void kill_zombie_dump_threads(String *slave_uuid);
+#else
+static void kill_zombie_dump_threads(uint32 slave_server_id);
+#endif
+
+static void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
+
+
 int max_binlog_dump_events = 0; // unlimited
 my_bool opt_sporadic_binlog_dump_fail = 0;
 
@@ -83,7 +107,7 @@ static void init_all_slave_list_mutexes(
 }
 #endif /* HAVE_PSI_INTERFACE */
 
-void init_slave_list()
+static void init_slave_list()
 {
 #ifdef HAVE_PSI_INTERFACE
   init_all_slave_list_mutexes();
@@ -95,7 +119,7 @@ void init_slave_list()
   mysql_mutex_init(key_LOCK_slave_list, &LOCK_slave_list, MY_MUTEX_INIT_FAST);
 }
 
-void end_slave_list()
+static void end_slave_list()
 {
   /* No protection by a mutex needed as we are only called at shutdown */
   if (my_hash_inited(&slave_list))
@@ -114,15 +138,13 @@ void end_slave_list()
     1	Error.   Error message sent to client
 */
 
-int register_slave(THD* thd, uchar* packet, uint packet_length)
+int Rpl_master::register_slave(THD* thd, char* packet, uint packet_length)
 {
   int res;
   SLAVE_INFO *si;
-  uchar *p= packet, *p_end= packet + packet_length;
+  char *p= packet, *p_end= packet + packet_length;
   const char *errmsg= "Wrong parameters to function register_slave";
 
-  if (check_access(thd, REPL_SLAVE_ACL, any_db, NULL, NULL, 0, 0))
-    return 1;
   if (!(si = (SLAVE_INFO*)my_malloc(sizeof(SLAVE_INFO), MYF(MY_WME))))
     goto err2;
 
@@ -159,7 +181,7 @@ err2:
   return 1;
 }
 
-void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
+static void unregister_slave(THD* thd, bool only_mine, bool need_mutex)
 {
   if (thd->server_id)
   {
@@ -187,7 +209,7 @@ void unregister_slave(THD* thd, bool onl
   @retval FALSE success
   @retval TRUE failure
 */
-bool show_slave_hosts(THD* thd)
+int Rpl_master::show_slave_hosts(THD* thd)
 {
   List<Item> field_list;
   Protocol *protocol= thd->protocol;
@@ -204,8 +226,9 @@ bool show_slave_hosts(THD* thd)
   field_list.push_back(new Item_return_int("Port", 7, MYSQL_TYPE_LONG));
   field_list.push_back(new Item_return_int("Master_id", 10,
 					   MYSQL_TYPE_LONG));
+#if HAVE_SERVER_UUID
   field_list.push_back(new Item_empty_string("Slave_UUID", UUID_LENGTH));
-
+#endif
   if (protocol->send_result_set_metadata(&field_list,
                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
     DBUG_RETURN(TRUE);
@@ -226,10 +249,12 @@ bool show_slave_hosts(THD* thd)
     protocol->store((uint32) si->port);
     protocol->store((uint32) si->master_id);
 
+#if HAVE_SERVER_UUID
     /* get slave's UUID */
     String slave_uuid;
     if (get_slave_uuid(si->thd, &slave_uuid))
       protocol->store(slave_uuid.c_ptr_safe(), &my_charset_bin);
+#endif
     if (protocol->write())
     {
       mysql_mutex_unlock(&LOCK_slave_list);
@@ -491,11 +516,12 @@ static int send_heartbeat_event(NET* net
   DBUG_RETURN(0);
 }
 
+
 /*
   TODO: Clean up loop to only have one call to send_file()
 */
 
-void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
+static void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos,
 		       ushort flags)
 {
   LOG_INFO linfo;
@@ -1118,7 +1144,7 @@ String *get_slave_uuid(THD *thd, String 
 
 */
 
-
+#if HAVE_SERVER_UUID
 void kill_zombie_dump_threads(String *slave_uuid)
 {
   if (slave_uuid->length() == 0)
@@ -1155,6 +1181,36 @@ void kill_zombie_dump_threads(String *sl
   }
 }
 
+#else /* HAVE_SERVER_UUID */
+
+void kill_zombie_dump_threads(uint32 slave_server_id)
+{
+  mysql_mutex_lock(&LOCK_thread_count);
+  I_List_iterator<THD> it(threads);
+  THD *tmp;
+
+  while ((tmp=it++))
+  {
+    if (tmp->command == COM_BINLOG_DUMP &&
+       tmp->server_id == slave_server_id)
+    {
+      mysql_mutex_lock(&tmp->LOCK_thd_data);    // Lock from delete
+      break;
+    }
+  }
+  mysql_mutex_unlock(&LOCK_thread_count);
+  if (tmp)
+  {
+    /*
+      Here we do not call kill_one_thread() as
+      it will be slow because it will iterate through the list
+      again. We just to do kill the thread ourselves.
+    */
+    tmp->awake(THD::KILL_QUERY);
+    mysql_mutex_unlock(&tmp->LOCK_thd_data);
+  }
+}
+#endif /* HAVE_SERVER_UUID */
 
 /**
   Execute a RESET MASTER statement.
@@ -1165,7 +1221,7 @@ void kill_zombie_dump_threads(String *sl
   @retval 0 success
   @retval 1 error
 */
-int reset_master(THD* thd)
+int Rpl_master::reset_master(THD* thd)
 {
   if (!mysql_bin_log.is_open())
   {
@@ -1180,23 +1236,6 @@ int reset_master(THD* thd)
   return 0;
 }
 
-int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
-		   const char* log_file_name2, ulonglong log_pos2)
-{
-  int res;
-  size_t log_file_name1_len=  strlen(log_file_name1);
-  size_t log_file_name2_len=  strlen(log_file_name2);
-
-  //  We assume that both log names match up to '.'
-  if (log_file_name1_len == log_file_name2_len)
-  {
-    if ((res= strcmp(log_file_name1, log_file_name2)))
-      return res;
-    return (log_pos1 < log_pos2) ? -1 : (log_pos1 == log_pos2) ? 0 : 1;
-  }
-  return ((log_file_name1_len < log_file_name2_len) ? -1 : 1);
-}
-
 
 /**
   Execute a SHOW MASTER STATUS statement.
@@ -1239,88 +1278,55 @@ bool show_binlog_info(THD* thd)
   DBUG_RETURN(FALSE);
 }
 
-
-/**
-  Execute a SHOW BINARY LOGS statement.
-
-  @param thd Pointer to THD object for the client thread executing the
-  statement.
-
-  @retval FALSE success
-  @retval TRUE failure
-*/
-bool show_binlogs(THD* thd)
+int Rpl_master::init()
 {
-  IO_CACHE *index_file;
-  LOG_INFO cur;
-  File file;
-  char fname[FN_REFLEN];
-  List<Item> field_list;
-  uint length;
-  int cur_dir_len;
-  Protocol *protocol= thd->protocol;
-  DBUG_ENTER("show_binlogs");
+  init_slave_list();
+  return 0;
+}
 
-  if (!mysql_bin_log.is_open())
-  {
-    my_message(ER_NO_BINARY_LOGGING, ER(ER_NO_BINARY_LOGGING), MYF(0));
-    DBUG_RETURN(TRUE);
-  }
+void Rpl_master::end()
+{
+  end_slave_list();
+}
 
-  field_list.push_back(new Item_empty_string("Log_name", 255));
-  field_list.push_back(new Item_return_int("File_size", 20,
-                                           MYSQL_TYPE_LONGLONG));
-  if (protocol->send_result_set_metadata(&field_list,
-                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-    DBUG_RETURN(TRUE);
-  
-  mysql_mutex_lock(mysql_bin_log.get_log_lock());
-  mysql_bin_log.lock_index();
-  index_file=mysql_bin_log.get_index_file();
-  
-  mysql_bin_log.raw_get_current_log(&cur); // dont take mutex
-  mysql_mutex_unlock(mysql_bin_log.get_log_lock()); // lockdep, OK
-  
-  cur_dir_len= dirname_length(cur.log_file_name);
-
-  reinit_io_cache(index_file, READ_CACHE, (my_off_t) 0, 0, 0);
-
-  /* The file ends with EOF or empty line */
-  while ((length=my_b_gets(index_file, fname, sizeof(fname))) > 1)
-  {
-    int dir_len;
-    ulonglong file_length= 0;                   // Length if open fails
-    fname[--length] = '\0';                     // remove the newline
+int Rpl_master::binlog_dump(THD* thd, char* packet, uint packet_length)
+{
+  ulong pos;
+  ushort flags;
+#if HAVE_SERVER_UUID
+  String slave_uuid;
+#else
+  uint32 slave_server_id;
+#endif
 
-    protocol->prepare_for_resend();
-    dir_len= dirname_length(fname);
-    length-= dir_len;
-    protocol->store(fname + dir_len, length, &my_charset_bin);
+  /* TODO: The following has to be changed to an 8 byte integer */
+  pos = uint4korr(packet);
+  flags = uint2korr(packet + 4);
+
+#if HAVE_SERVER_UUID
+  thd->server_id= uint4korr(packet+6);
+  get_slave_uuid(thd, &slave_uuid);
+  kill_zombie_dump_threads(&slave_uuid);
+#else
+  thd->server_id=0; /* avoid suicide */
+  if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
+    kill_zombie_dump_threads(slave_server_id);
+  thd->server_id = slave_server_id;
+#endif
 
-    if (!(strncmp(fname+dir_len, cur.log_file_name+cur_dir_len, length)))
-      file_length= cur.pos;  /* The active log, use the active position */
-    else
-    {
-      /* this is an old log, open it and find the size */
-      if ((file= mysql_file_open(key_file_binlog,
-                                 fname, O_RDONLY | O_SHARE | O_BINARY,
-                                 MYF(0))) >= 0)
-      {
-        file_length= (ulonglong) mysql_file_seek(file, 0L, MY_SEEK_END, MYF(0));
-        mysql_file_close(file, MYF(0));
-      }
-    }
-    protocol->store(file_length);
-    if (protocol->write())
-      goto err;
-  }
-  mysql_bin_log.unlock_index();
-  my_eof(thd);
-  DBUG_RETURN(FALSE);
+  general_log_print(thd, COM_BINLOG_DUMP, "Log: '%s'  Pos: %ld", packet+10,
+                    (long) pos);
+  mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
+  unregister_slave(thd,1,1);
+  /*  fake COM_QUIT -- if we get here, the thread needs to terminate */
+  return 1;
+}
 
-err:
-  mysql_bin_log.unlock_index();
-  DBUG_RETURN(TRUE);
+int Rpl_master::show_master_status(THD* thd)
+{
+  return show_binlog_info(thd);
 }
 
+Rpl_master rpl_master;
+
 #endif /* HAVE_REPLICATION */

=== modified file 'sql/rpl/rpl_master.h'
--- a/sql/rpl/rpl_master.h	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_master.h	2010-11-17 08:46:17 +0000
@@ -16,32 +16,12 @@
 
 
 #define RPL_MASTER_H_INCLUDED
+
+#include "rpl.h"
+
 extern bool server_id_supplied;
 extern int max_binlog_dump_events;
 extern my_bool opt_sporadic_binlog_dump_fail;
 extern my_bool opt_show_slave_auth_info;
 
-typedef struct st_slave_info
-{
-  uint32 server_id;
-  uint32 rpl_recovery_rank, master_id;
-  char host[HOSTNAME_LENGTH+1];
-  char user[USERNAME_LENGTH+1];
-  char password[MAX_PASSWORD_LENGTH+1];
-  uint16 port;
-  THD* thd;
-} SLAVE_INFO;
-
-void init_slave_list();
-void end_slave_list();
-int register_slave(THD* thd, uchar* packet, uint packet_length);
-void unregister_slave(THD* thd, bool only_mine, bool need_mutex);
-bool show_slave_hosts(THD* thd);
-
-String *get_slave_uuid(THD *thd, String *value);
-bool mysql_show_binlog_events(THD* thd);
-bool show_binlogs(THD* thd);
-void kill_zombie_dump_threads(String *slave_uuid);
-void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
-int reset_master(THD* thd);
 #endif /* RPL_MASTER_H_INCLUDED */

=== modified file 'sql/rpl/rpl_rli.cc'
--- a/sql/rpl/rpl_rli.cc	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_rli.cc	2010-11-17 08:46:17 +0000
@@ -1347,32 +1347,5 @@ void Relay_log_info::slave_close_thread_
     thd->mdl_context.release_transactional_locks();
   clear_tables_to_lock();
 }
-/**
-  Execute a SHOW RELAYLOG EVENTS statement.
-
-  @param thd Pointer to THD object for the client thread executing the
-  statement.
-
-  @retval FALSE success
-  @retval TRUE failure
-*/
-bool mysql_show_relaylog_events(THD* thd)
-{
-  Protocol *protocol= thd->protocol;
-  List<Item> field_list;
-  DBUG_ENTER("mysql_show_relaylog_events");
-
-  DBUG_ASSERT(thd->lex->sql_command == SQLCOM_SHOW_RELAYLOG_EVENTS);
-
-  Log_event::init_show_field_list(&field_list);
-  if (protocol->send_result_set_metadata(&field_list,
-                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-    DBUG_RETURN(TRUE);
-
-  if (!active_mi)
-    DBUG_RETURN(TRUE);
-  
-  DBUG_RETURN(show_binlog_events(thd, &active_mi->rli.relay_log));
-}
 
 #endif

=== modified file 'sql/rpl/rpl_rli.h'
--- a/sql/rpl/rpl_rli.h	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_rli.h	2010-11-17 08:46:17 +0000
@@ -21,6 +21,7 @@
 #include "rpl_utility.h"
 #include "log.h"                         /* LOG_INFO */
 #include "binlog.h"                      /* MYSQL_BIN_LOG */
+#include "binlog_priv.h"
 #include "sql_class.h"                   /* THD */
 
 struct RPL_TABLE_LIST;

=== modified file 'sql/rpl/rpl_slave.cc'
--- a/sql/rpl/rpl_slave.cc	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_slave.cc	2010-11-17 08:46:17 +0000
@@ -153,7 +153,9 @@ static int connect_to_master(THD* thd, M
 static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
                       void* thread_killed_arg);
 static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi);
+#if HAVE_SERVER_UUID
 static int get_master_uuid(MYSQL *mysql, Master_info *mi);
+#endif
 int io_thread_init_commands(MYSQL *mysql, Master_info *mi);
 static Log_event* next_event(Relay_log_info* rli);
 static int queue_event(Master_info* mi,const char* buf,ulong event_len);
@@ -1187,6 +1189,7 @@ bool is_network_error(uint errorno)
   return FALSE;   
 }
 
+#if HAVE_SERVER_UUID
 /**
   Set user variables after connecting to the master.
 
@@ -1311,6 +1314,7 @@ static int get_master_uuid(MYSQL *mysql,
     mysql_free_result(master_res);
   return ret;
 }
+#endif /* HAVE_SERVER_UUID */
 
 /*
   Note that we rely on the master's version (3.23, 4.0.14 etc) instead of
@@ -1937,7 +1941,9 @@ bool show_master_info(THD* thd, Master_i
                                              FN_REFLEN));
   field_list.push_back(new Item_return_int("Master_Server_Id", sizeof(ulong),
                                            MYSQL_TYPE_LONG));
+#if HAVE_SERVER_UUID
   field_list.push_back(new Item_empty_string("Master_UUID", UUID_LENGTH));
+#endif
   field_list.push_back(new Item_empty_string("Master_Info_File",
                                              sizeof(mi->info_file_name)));
   field_list.push_back(new Item_return_int("SQL_Delay", 10, MYSQL_TYPE_LONG));
@@ -2112,7 +2118,9 @@ bool show_master_info(THD* thd, Master_i
     }
     // Master_Server_id
     protocol->store((uint32) mi->master_id);
+#if HAVE_SERVER_UUID
     protocol->store(mi->master_uuid, &my_charset_bin);
+#endif
     // Master_Info_File
     protocol->store(mi->info_file_name, &my_charset_bin);
     // SQL_Delay
@@ -2810,7 +2818,7 @@ static int exec_relay_log_event(THD* thd
     */
     if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
     {
-      if (thd->variables.binlog_rows_query_log_events)
+      if (thd_binlog_rows_query_log_events(thd))
         handle_rows_query_log_event(ev, rli);
 
       DBUG_PRINT("info", ("Deleting the event after it has been executed"));
@@ -3125,10 +3133,12 @@ connected:
   thd->slave_net = &mysql->net;
   thd_proc_info(thd, "Checking master version");
   ret= get_master_version_and_clock(mysql, mi);
+#if HAVE_SERVER_UUID
   if (!ret)
     ret= get_master_uuid(mysql, mi);
   if (!ret)
     io_thread_init_commands(mysql, mi);
+#endif
 
   if (ret == 1)
     /* Fatal error */
@@ -4599,71 +4609,6 @@ static int safe_reconnect(THD* thd, MYSQ
 }
 
 
-MYSQL *rpl_connect_master(MYSQL *mysql)
-{
-  THD *thd= current_thd;
-  Master_info *mi= my_pthread_getspecific_ptr(Master_info*, RPL_MASTER_INFO);
-  if (!mi)
-  {
-    sql_print_error("'rpl_connect_master' must be called in slave I/O thread context.");
-    return NULL;
-  }
-
-  bool allocated= false;
-  
-  if (!mysql)
-  {
-    if(!(mysql= mysql_init(NULL)))
-    {
-      sql_print_error("rpl_connect_master: failed in mysql_init()");
-      return NULL;
-    }
-    allocated= true;
-  }
-
-  /*
-    XXX: copied from connect_to_master, this function should not
-    change the slave status, so we cannot use connect_to_master
-    directly
-    
-    TODO: make this part a seperate function to eliminate duplication
-  */
-  mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *) &slave_net_timeout);
-  mysql_options(mysql, MYSQL_OPT_READ_TIMEOUT, (char *) &slave_net_timeout);
-
-#ifdef HAVE_OPENSSL
-  if (mi->ssl)
-  {
-    mysql_ssl_set(mysql,
-                  mi->ssl_key[0]?mi->ssl_key:0,
-                  mi->ssl_cert[0]?mi->ssl_cert:0,
-                  mi->ssl_ca[0]?mi->ssl_ca:0,
-                  mi->ssl_capath[0]?mi->ssl_capath:0,
-                  mi->ssl_cipher[0]?mi->ssl_cipher:0);
-    mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
-                  &mi->ssl_verify_server_cert);
-  }
-#endif
-
-  mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset_info->csname);
-  /* This one is not strictly needed but we have it here for completeness */
-  mysql_options(mysql, MYSQL_SET_CHARSET_DIR, (char *) charsets_dir);
-
-  if (io_slave_killed(thd, mi)
-      || !mysql_real_connect(mysql, mi->host, mi->user, mi->password, 0,
-                             mi->port, 0, 0))
-  {
-    if (!io_slave_killed(thd, mi))
-      sql_print_error("rpl_connect_master: error connecting to master: %s (server_error: %d)",
-                      mysql_error(mysql), mysql_errno(mysql));
-    
-    if (allocated)
-      mysql_close(mysql);                       // this will free the object
-    return NULL;
-  }
-  return mysql;
-}
-
 /**
   Store the file and position where the slave's SQL thread are in the
   relay log.
@@ -5324,8 +5269,6 @@ int start_slave(THD* thd , Master_info* 
   int thread_mask;
   DBUG_ENTER("start_slave");
 
-  if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
-    DBUG_RETURN(1);
   lock_slave_threads(mi);  // this allows us to cleanly read slave_running
   // Get a mask of _stopped_ threads
   init_thread_mask(&thread_mask,mi,1 /* inverse */);
@@ -5464,8 +5407,6 @@ int stop_slave(THD* thd, Master_info* mi
   if (!thd)
     thd = current_thd;
 
-  if (check_access(thd, SUPER_ACL, any_db, NULL, NULL, 0, 0))
-    DBUG_RETURN(1);
   thd_proc_info(thd, "Killing slave");
   int thread_mask;
   lock_slave_threads(mi);
@@ -5665,7 +5606,9 @@ bool change_master(THD* thd, Master_info
   if ((lex_mi->host && strcmp(lex_mi->host, mi->host)) ||
       (lex_mi->port && lex_mi->port != mi->port))
   {
+#if HAVE_SERVER_UUID
     mi->master_uuid[0]= 0;
+#endif
     mi->master_id= 0;
   }
 
@@ -5896,6 +5839,137 @@ err:
   DBUG_RETURN(ret);
 }
 
+int Rpl_slave::change_master(THD* thd)
+{
+  int res= 0;
+  mysql_mutex_lock(&LOCK_active_mi);
+  res = ::change_master(thd,active_mi);
+  mysql_mutex_unlock(&LOCK_active_mi);
+  return res;
+}
+
+int Rpl_slave::start_slave(THD*thd)
+{
+  mysql_mutex_lock(&LOCK_active_mi);
+  ::start_slave(thd,active_mi,1 /* net report*/);
+  mysql_mutex_unlock(&LOCK_active_mi);
+  return 0;
+}
+
+int Rpl_slave::stop_slave(THD* thd)
+{
+  /*
+    If the client thread has locked tables, a deadlock is possible.
+    Assume that
+    - the client thread does LOCK TABLE t READ.
+    - then the master updates t.
+    - then the SQL slave thread wants to update t,
+      so it waits for the client thread because t is locked by it.
+    - then the client thread does SLAVE STOP.
+      SLAVE STOP waits for the SQL slave thread to terminate its
+      update t, which waits for the client thread because t is locked by it.
+    To prevent that, refuse SLAVE STOP if the
+    client thread has locked tables
+  */
+  if (thd->locked_tables_mode ||
+      thd->in_active_multi_stmt_transaction() || thd->global_read_lock.is_acquired())
+  {
+    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
+               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
+    return 1;
+  }
+  mysql_mutex_lock(&LOCK_active_mi);
+  int res= ::stop_slave(thd,active_mi,1/* net report*/);
+  mysql_mutex_unlock(&LOCK_active_mi);
+  return res;
+}
+
+int Rpl_slave::show_slave_status(THD* thd)
+{
+  int res= 0;
+  mysql_mutex_lock(&LOCK_active_mi);
+  if (active_mi != NULL)
+  {
+    res = show_master_info(thd, active_mi);
+  }
+  else
+  {
+    push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                 WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
+    my_ok(thd);
+  }
+  mysql_mutex_unlock(&LOCK_active_mi);
+  return res;
+}
+
+int Rpl_slave::flush_relay_log(THD* thd)
+{
+  int res= 0;
+  mysql_mutex_lock(&LOCK_active_mi);
+  rotate_relay_log(active_mi);
+  mysql_mutex_unlock(&LOCK_active_mi);
+  return res;
+}
+
+int Rpl_slave::reset_slave(THD* thd)
+{
+  int res= 0;
+  mysql_mutex_lock(&LOCK_active_mi);
+  res= ::reset_slave(thd, active_mi);
+  mysql_mutex_unlock(&LOCK_active_mi);
+  return res;
+}
+
+/**
+  Execute a SHOW RELAYLOG EVENTS statement.
+
+  @param thd Pointer to THD object for the client thread executing the
+  statement.
+
+  @retval FALSE success
+  @retval TRUE failure
+*/
+int Rpl_slave::show_relay_log_events(THD* thd)
+{
+  Protocol *protocol= thd->protocol;
+  List<Item> field_list;
+  DBUG_ENTER("mysql_show_relaylog_events");
+
+  DBUG_ASSERT(thd->lex->sql_command == SQLCOM_SHOW_RELAYLOG_EVENTS);
+
+  Log_event::init_show_field_list(&field_list);
+  if (protocol->send_result_set_metadata(&field_list,
+                            Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+    DBUG_RETURN(TRUE);
+
+  if (!active_mi)
+    DBUG_RETURN(TRUE);
+  
+  DBUG_RETURN(show_binlog_events(thd, &active_mi->rli.relay_log));
+}
+
+int Rpl_slave::init()
+{
+  /*
+    init_slave() must be called after the thread keys are created.
+    Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
+    places) assume that active_mi != 0, so let's fail if it's 0 (out of
+    memory); a message has already been printed.
+  */
+  if (init_slave() && !active_mi)
+  {
+    unireg_abort(1);
+  }
+  return 0;
+}
+
+void Rpl_slave::end()
+{
+  end_slave();
+}
+
+Rpl_slave rpl_slave;
+
 /**
   @} (end of group Replication)
 */

=== modified file 'sql/rpl/rpl_slave.h'
--- a/sql/rpl/rpl_slave.h	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/rpl_slave.h	2010-11-17 08:46:17 +0000
@@ -48,6 +48,7 @@
 #include "my_list.h"
 #include "rpl_filter.h"
 #include "rpl_tblmap.h"
+#include "rpl.h"
 
 #define SLAVE_NET_TIMEOUT  3600
 
@@ -159,8 +160,6 @@ extern ulonglong relay_log_space_limit;
 int start_slave(THD* thd, Master_info* mi, bool net_report);
 int stop_slave(THD* thd, Master_info* mi, bool net_report);
 bool change_master(THD* thd, Master_info* mi);
-int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1,
-		   const char* log_file_name2, ulonglong log_pos2);
 int reset_slave(THD *thd, Master_info* mi);
 int init_slave();
 int init_recovery(Master_info* mi, const char** errmsg);

=== modified file 'sql/rpl/sql_binlog.cc'
--- a/sql/rpl/sql_binlog.cc	2010-10-25 10:01:24 +0000
+++ b/sql/rpl/sql_binlog.cc	2010-11-17 08:46:17 +0000
@@ -273,7 +273,7 @@ void mysql_client_binlog_statement(THD* 
       */
       if (ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
       {
-        if (thd->variables.binlog_rows_query_log_events)
+        if (thd_binlog_rows_query_log_events(thd))
           handle_rows_query_log_event(ev, rli);
         if (ev->get_type_code() != ROWS_QUERY_LOG_EVENT)
         {

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2010-09-28 15:17:29 +0000
+++ b/sql/sp.cc	2010-11-17 08:46:17 +0000
@@ -1150,9 +1150,9 @@ sp_create_routine(THD *thd, int type, sp
       /* restore sql_mode when binloging */
       thd->variables.sql_mode= saved_mode;
       /* Such a statement can always go directly to binlog, no trans cache */
-      if (thd->binlog_query(THD::STMT_QUERY_TYPE,
-                            log_query.c_ptr(), log_query.length(),
-                            FALSE, FALSE, FALSE, 0))
+      if (binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                              log_query.c_ptr(), log_query.length(),
+                              FALSE, FALSE, FALSE, 0))
         ret= SP_INTERNAL_ERROR;
       thd->variables.sql_mode= 0;
     }

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2010-08-12 00:26:10 +0000
+++ b/sql/sql_acl.cc	2010-11-17 08:46:17 +0000
@@ -1654,8 +1654,8 @@ bool change_password(THD *thd, const cha
                           acl_user->host.hostname ? acl_user->host.hostname : "",
                           new_password);
     thd->clear_error();
-    result= thd->binlog_query(THD::STMT_QUERY_TYPE, buff, query_length,
-                              FALSE, FALSE, FALSE, 0);
+    result= binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE, buff, query_length,
+                                FALSE, FALSE, FALSE, 0);
   }
 end:
   close_mysql_tables(thd);

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2010-09-28 15:17:29 +0000
+++ b/sql/sql_base.cc	2010-11-17 08:46:17 +0000
@@ -3753,9 +3753,9 @@ static bool open_table_entry_fini(THD *t
         end = strxmov(strmov(query, "DELETE FROM `"),
                       share->db.str,"`.`",share->table_name.str,"`", NullS);
         int errcode= query_error_code(thd, TRUE);
-        if (thd->binlog_query(THD::STMT_QUERY_TYPE,
-                              query, (ulong)(end-query),
-                              FALSE, FALSE, FALSE, errcode))
+        if (binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                                query, (ulong)(end-query),
+                                FALSE, FALSE, FALSE, errcode))
         {
           my_free(query);
           return TRUE;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-09-28 15:17:29 +0000
+++ b/sql/sql_class.h	2010-11-17 08:46:17 +0000
@@ -475,7 +475,6 @@ typedef struct system_variables
   Time_zone *time_zone;
 
   my_bool sysdate_is_now;
-  my_bool binlog_rows_query_log_events;
 
   double long_query_time_double;
 
@@ -1618,12 +1617,12 @@ private:
   */
   uint32 binlog_unsafe_warning_flags;
 
+public:
   /*
     Number of outstanding table maps, i.e., table maps in the
     transaction cache.
   */
   uint binlog_table_maps;
-public:
   void issue_unsafe_warnings();
 
   uint get_binlog_table_maps() const {
@@ -2165,23 +2164,6 @@ public:
 #endif
   void awake(THD::killed_state state_to_set);
 
-#ifndef MYSQL_CLIENT
-  enum enum_binlog_query_type {
-    /* The query can be logged in row format or in statement format. */
-    ROW_QUERY_TYPE,
-    
-    /* The query has to be logged in statement format. */
-    STMT_QUERY_TYPE,
-    
-    QUERY_TYPE_COUNT
-  };
-  
-  int binlog_query(enum_binlog_query_type qtype,
-                   char const *query, ulong query_len, bool is_trans,
-                   bool direct, bool suppress_use,
-                   int errcode);
-#endif
-
   /*
     For enter_cond() / exit_cond() to work the mutex must be got before
     enter_cond(); this mutex is then released by exit_cond().

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2010-08-12 00:26:10 +0000
+++ b/sql/sql_delete.cc	2010-11-17 08:46:17 +0000
@@ -65,7 +65,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   uint usable_index= MAX_KEY;
   SELECT_LEX   *select_lex= &thd->lex->select_lex;
   THD::killed_state killed_status= THD::NOT_KILLED;
-  THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
+  Binlog::enum_binlog_query_type query_type= Binlog::ROW_QUERY_TYPE;
   DBUG_ENTER("mysql_delete");
 
   if (open_and_lock_tables(thd, table_list, TRUE, 0))
@@ -151,7 +151,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
         If delete_all_rows() is used, it is not possible to log the
         query in row format, so we have to log it in statement format.
       */
-      query_type= THD::STMT_QUERY_TYPE;
+      query_type= Binlog::STMT_QUERY_TYPE;
       error= -1;
       deleted= maybe_deleted;
       goto cleanup;
@@ -392,10 +392,10 @@ cleanup:
         statement-based; otherwise, 'ha_delete_row()' was used to
         delete specific rows which we might log row-based.
       */
-      int log_result= thd->binlog_query(query_type,
-                                        thd->query(), thd->query_length(),
-                                        transactional_table, FALSE, FALSE,
-                                        errcode);
+      int log_result= binlog.binlog_query(thd, query_type,
+                                          thd->query(), thd->query_length(),
+                                          transactional_table, FALSE, FALSE,
+                                          errcode);
 
       if (log_result)
       {
@@ -815,9 +815,9 @@ void multi_delete::abort_result_set()
     {
       int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
       /* possible error of writing binary log is ignored deliberately */
-      (void) thd->binlog_query(THD::ROW_QUERY_TYPE,
-                               thd->query(), thd->query_length(),
-                               transactional_tables, FALSE, FALSE, errcode);
+      (void) binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
+                                 thd->query(), thd->query_length(),
+                                 transactional_tables, FALSE, FALSE, errcode);
     }
   }
   DBUG_VOID_RETURN;
@@ -991,9 +991,9 @@ bool multi_delete::send_eof()
         thd->clear_error();
       else
         errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
-      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
-                            thd->query(), thd->query_length(),
-                            transactional_tables, FALSE, FALSE, errcode) &&
+      if (binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
+                              thd->query(), thd->query_length(),
+                              transactional_tables, FALSE, FALSE, errcode) &&
           !normal_tables)
       {
 	local_error=1;  // Log write failed: roll back the SQL statement

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2010-10-15 05:30:43 +0000
+++ b/sql/sql_insert.cc	2010-11-17 08:46:17 +0000
@@ -1036,16 +1036,16 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
 
             error= 1;
           }
-          else if (thd->binlog_query(THD::ROW_QUERY_TYPE,
-                                     log_query.c_ptr(), log_query.length(),
-                                     transactional_table, FALSE, FALSE,
-                                     errcode))
+          else if (binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
+                                       log_query.c_ptr(), log_query.length(),
+                                       transactional_table, FALSE, FALSE,
+                                       errcode))
             error= 1;
         }
-        else if (thd->binlog_query(THD::ROW_QUERY_TYPE,
-			           thd->query(), thd->query_length(),
-			           transactional_table, FALSE, FALSE,
-                                   errcode))
+        else if (binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
+                                     thd->query(), thd->query_length(),
+                                     transactional_table, FALSE, FALSE,
+                                     errcode))
 	  error= 1;
       }
     }
@@ -1838,7 +1838,7 @@ public:
   time_t start_time;
   ulong sql_mode;
   bool auto_increment_field_not_null;
-  bool query_start_used, ignore, log_query, binlog_rows_query_log_events;
+  bool query_start_used, ignore, log_query;
   bool stmt_depends_on_first_successful_insert_id_in_prev_stmt;
   ulonglong first_successful_insert_id_in_prev_stmt;
   ulonglong forced_insert_id;
@@ -1847,11 +1847,11 @@ public:
   timestamp_auto_set_type timestamp_field_type;
   LEX_STRING query;
   Time_zone *time_zone;
+  void* binlog_data;
 
   delayed_row(LEX_STRING const query_arg, enum_duplicates dup_arg,
               bool ignore_arg, bool log_query_arg)
     : record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg),
-      binlog_rows_query_log_events(FALSE),
       forced_insert_id(0), query(query_arg), time_zone(0)
     {}
   ~delayed_row()
@@ -2418,7 +2418,6 @@ int write_delayed(THD *thd, TABLE *table
   row->auto_increment_offset=    thd->variables.auto_increment_offset;
   row->sql_mode=                 thd->variables.sql_mode;
   row->auto_increment_field_not_null= table->auto_increment_field_not_null;
-  row->binlog_rows_query_log_events= thd->variables.binlog_rows_query_log_events;
 
   /* Copy the next forced auto increment value, if any. */
   if ((forced_auto_inc= thd->auto_inc_intervals_forced.get_next()))
@@ -2428,6 +2427,10 @@ int write_delayed(THD *thd, TABLE *table
                            (ulong) row->forced_insert_id));
   }
 
+  if(binlog.get_delayed_row_data(thd, table,
+                                 &row->binlog_data, &query, log_on))
+    goto err;
+
   di->rows.push_back(row);
   di->stacked_inserts++;
   di->status=1;
@@ -2856,18 +2859,11 @@ bool Delayed_insert::handle_inserts(void
     DBUG_PRINT("delayed", ("query: '%s'  length: %lu", row->query.str ?
                            row->query.str : "[NULL]",
                            (ulong) row->query.length));
+    if (binlog.before_handle_delayed_row(&thd, table, row->binlog_data,
+                                         &row->query, log_query))
+      goto err;
     if (log_query)
     {
-      if (thd.is_current_stmt_binlog_format_row())
-      {
-        /* Flush rows of previous statement*/
-        if (thd.binlog_flush_pending_rows_event(TRUE, FALSE))
-          goto err;
-        /* Set query for Rows_query_log event in RBR*/
-        thd.set_query(row->query.str, row->query.length);
-        thd.variables.binlog_rows_query_log_events= row->binlog_rows_query_log_events;
-      }
-
       /*
         This is the first value of an INSERT statement.
         It is the right place to clear a forced insert_id.
@@ -2935,6 +2931,10 @@ bool Delayed_insert::handle_inserts(void
       table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
     }
 
+    if (binlog.after_handle_delayed_row(&thd, table, row->binlog_data,
+                                        &row->query, log_query))
+      goto err;
+    
     if (log_query && mysql_bin_log.is_open() &&
         !thd.is_current_stmt_binlog_format_row())
     {
@@ -2956,9 +2956,9 @@ bool Delayed_insert::handle_inserts(void
         In SBR, only the query which has one single value
         will be binlogged here.
       */
-      if (thd.binlog_query(THD::STMT_QUERY_TYPE,
-                           row->query.str, row->query.length,
-                           FALSE, FALSE, FALSE, errcode))
+      if (binlog.binlog_query(&thd, Binlog::STMT_QUERY_TYPE,
+                              row->query.str, row->query.length,
+                              FALSE, FALSE, FALSE, errcode))
         goto err;
 
       thd.time_zone_used = backup_time_zone_used;
@@ -3495,7 +3495,7 @@ bool select_insert::send_eof()
       thd->clear_error();
     else
       errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
-    if (thd->binlog_query(THD::ROW_QUERY_TYPE,
+    if (binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
                       thd->query(), thd->query_length(),
                       trans_table, FALSE, FALSE, errcode))
     {
@@ -3575,9 +3575,9 @@ void select_insert::abort_result_set() {
         {
           int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
           /* error of writing binary log is ignored */
-          (void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
-                                   thd->query_length(),
-                                   transactional_table, FALSE, FALSE, errcode);
+          (void) binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE, thd->query(),
+                                     thd->query_length(),
+                                     transactional_table, FALSE, FALSE, errcode);
         }
 	if (changed)
 	  query_cache_invalidate3(thd, table, 1);
@@ -3954,12 +3954,12 @@ select_create::binlog_show_create_table(
   if (mysql_bin_log.is_open())
   {
     int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
-    result= thd->binlog_query(THD::STMT_QUERY_TYPE,
-                              query.ptr(), query.length(),
-                              /* is_trans */ TRUE,
-                              /* direct */ FALSE,
-                              /* suppress_use */ FALSE,
-                              errcode);
+    result= binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                                query.ptr(), query.length(),
+                                /* is_trans */ TRUE,
+                                /* direct */ FALSE,
+                                /* suppress_use */ FALSE,
+                                errcode);
   }
   return result;
 }

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2010-08-20 03:51:38 +0000
+++ b/sql/sql_lex.cc	2010-11-17 08:46:17 +0000
@@ -3158,15 +3158,6 @@ bool LEX::is_partition_management() cons
 }
 
 
-/**
-  Set all fields to their "unspecified" value.
-*/
-void st_lex_master_info::set_unspecified()
-{
-  bzero((char*) this, sizeof(*this));
-  sql_delay= -1;
-}
-
 #ifdef MYSQL_SERVER
 uint binlog_unsafe_map[256];
 

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2010-09-01 13:16:07 +0000
+++ b/sql/sql_lex.h	2010-11-17 08:46:17 +0000
@@ -123,6 +123,7 @@ struct sys_var_with_base
 #endif
 
 #include "sql_cmd.h"
+#include "rpl_lex.h"
 
 // describe/explain types
 #define DESCRIBE_NONE		0 // Not explain query
@@ -195,38 +196,6 @@ typedef struct st_lex_server_options
 } LEX_SERVER_OPTIONS;
 
 
-/**
-  Structure to hold parameters for CHANGE MASTER or START/STOP SLAVE
-  or SHOW NEW MASTER.
-
-  Remark: this should not be confused with Master_info (and perhaps
-  would better be renamed to st_lex_replication_info).  Some fields,
-  e.g., delay, are saved in Relay_log_info, not in Master_info.
-*/
-typedef struct st_lex_master_info
-{
-  char *host, *user, *password, *log_file_name;
-  uint port, connect_retry;
-  float heartbeat_period;
-  int sql_delay;
-  ulonglong pos;
-  ulong server_id, retry_count;
-  /*
-    Enum is used for making it possible to detect if the user
-    changed variable or if it should be left at old value
-   */
-  enum {LEX_MI_UNCHANGED= 0, LEX_MI_DISABLE, LEX_MI_ENABLE}
-    ssl, ssl_verify_server_cert, heartbeat_opt, repl_ignore_server_ids_opt, 
-    retry_count_opt;
-  char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher;
-  char *relay_log_name;
-  ulong relay_log_pos;
-  DYNAMIC_ARRAY repl_ignore_server_ids;
-
-  void set_unspecified();
-} LEX_MASTER_INFO;
-
-
 enum sub_select_type
 {
   UNSPECIFIED_TYPE,UNION_TYPE, INTERSECT_TYPE,

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-09-30 07:47:11 +0000
+++ b/sql/sql_parse.cc	2010-11-17 08:46:17 +0000
@@ -996,7 +996,9 @@ bool dispatch_command(enum enum_server_c
 #ifdef HAVE_REPLICATION
   case COM_REGISTER_SLAVE:
   {
-    if (!register_slave(thd, (uchar*)packet, packet_length))
+    if (check_global_access(thd, REPL_SLAVE_ACL))
+      break;
+    if (!rpl_master.register_slave(thd, packet, packet_length))
       my_ok(thd);
     break;
   }
@@ -1318,29 +1320,11 @@ bool dispatch_command(enum enum_server_c
 #ifndef EMBEDDED_LIBRARY
   case COM_BINLOG_DUMP:
     {
-      ulong pos;
-      ushort flags;
-      String slave_uuid;
-
       status_var_increment(thd->status_var.com_other);
       thd->enable_slow_log= opt_log_slow_admin_statements;
       if (check_global_access(thd, REPL_SLAVE_ACL))
 	break;
-
-      /* TODO: The following has to be changed to an 8 byte integer */
-      pos = uint4korr(packet);
-      flags = uint2korr(packet + 4);
-      thd->server_id= uint4korr(packet+6);
-
-      get_slave_uuid(thd, &slave_uuid);
-      kill_zombie_dump_threads(&slave_uuid);
-
-      general_log_print(thd, command, "Log: '%s'  Pos: %ld", packet+10,
-                      (long) pos);
-      mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
-      unregister_slave(thd,1,1);
-      /*  fake COM_QUIT -- if we get here, the thread needs to terminate */
-      error = TRUE;
+      error = rpl_master.binlog_dump(thd, packet, packet_length);
       break;
     }
 #endif
@@ -2239,7 +2223,7 @@ case SQLCOM_PREPARE:
     if (check_global_access(thd, SUPER_ACL))
       goto error;
     /* PURGE MASTER LOGS TO 'file' */
-    res = purge_master_logs(thd, lex->to_log);
+    res = binlog.purge_binary_logs(thd, lex->to_log);
     break;
   }
   case SQLCOM_PURGE_BEFORE:
@@ -2262,7 +2246,7 @@ case SQLCOM_PREPARE:
       value of constant
     */
     it->quick_fix_field();
-    res = purge_master_logs_before_date(thd, (ulong)it->val_int());
+    res = binlog.purge_binary_logs_before(thd, (ulong)it->val_int());
     break;
   }
 #endif
@@ -2308,21 +2292,21 @@ case SQLCOM_PREPARE:
   {
     if (check_global_access(thd, REPL_SLAVE_ACL))
       goto error;
-    res = show_slave_hosts(thd);
+    res = rpl_master.show_slave_hosts(thd);
     break;
   }
   case SQLCOM_SHOW_RELAYLOG_EVENTS:
   {
     if (check_global_access(thd, REPL_SLAVE_ACL))
       goto error;
-    res = mysql_show_relaylog_events(thd);
+    res = rpl_slave.show_relay_log_events(thd);
     break;
   }
   case SQLCOM_SHOW_BINLOG_EVENTS:
   {
     if (check_global_access(thd, REPL_SLAVE_ACL))
       goto error;
-    res = mysql_show_binlog_events(thd);
+    res = binlog.show_binlog_events(thd);
     break;
   }
 #endif
@@ -2354,9 +2338,7 @@ case SQLCOM_PREPARE:
   {
     if (check_global_access(thd, SUPER_ACL))
       goto error;
-    mysql_mutex_lock(&LOCK_active_mi);
-    res = change_master(thd,active_mi);
-    mysql_mutex_unlock(&LOCK_active_mi);
+    res = rpl_slave.change_master(thd);
     break;
   }
   case SQLCOM_SHOW_SLAVE_STAT:
@@ -2364,18 +2346,7 @@ case SQLCOM_PREPARE:
     /* Accept one of two privileges */
     if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
       goto error;
-    mysql_mutex_lock(&LOCK_active_mi);
-    if (active_mi != NULL)
-    {
-      res = show_master_info(thd, active_mi);
-    }
-    else
-    {
-      push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                   WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
-      my_ok(thd);
-    }
-    mysql_mutex_unlock(&LOCK_active_mi);
+    res = rpl_slave.show_slave_status(thd);
     break;
   }
   case SQLCOM_SHOW_MASTER_STAT:
@@ -2383,7 +2354,7 @@ case SQLCOM_PREPARE:
     /* Accept one of two privileges */
     if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
       goto error;
-    res = show_binlog_info(thd);
+    res = rpl_master.show_master_status(thd);
     break;
   }
 
@@ -2667,36 +2638,18 @@ end_with_restore_list:
 #ifdef HAVE_REPLICATION
   case SQLCOM_SLAVE_START:
   {
-    mysql_mutex_lock(&LOCK_active_mi);
-    start_slave(thd,active_mi,1 /* net report*/);
-    mysql_mutex_unlock(&LOCK_active_mi);
+    if (check_global_access(thd, SUPER_ACL))
+      goto error;
+    if (rpl_slave.start_slave(thd))
+      goto error;
     break;
   }
   case SQLCOM_SLAVE_STOP:
-  /*
-    If the client thread has locked tables, a deadlock is possible.
-    Assume that
-    - the client thread does LOCK TABLE t READ.
-    - then the master updates t.
-    - then the SQL slave thread wants to update t,
-      so it waits for the client thread because t is locked by it.
-    - then the client thread does SLAVE STOP.
-      SLAVE STOP waits for the SQL slave thread to terminate its
-      update t, which waits for the client thread because t is locked by it.
-    To prevent that, refuse SLAVE STOP if the
-    client thread has locked tables
-  */
-  if (thd->locked_tables_mode ||
-      thd->in_active_multi_stmt_transaction() || thd->global_read_lock.is_acquired())
-  {
-    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-    goto error;
-  }
   {
-    mysql_mutex_lock(&LOCK_active_mi);
-    stop_slave(thd,active_mi,1/* net report*/);
-    mysql_mutex_unlock(&LOCK_active_mi);
+    if (check_global_access(thd, SUPER_ACL))
+      goto error;
+    if (rpl_slave.stop_slave(thd))
+      goto error;
     break;
   }
 #endif /* HAVE_REPLICATION */
@@ -2745,7 +2698,7 @@ end_with_restore_list:
     {
       if (check_global_access(thd, SUPER_ACL))
 	goto error;
-      res = show_binlogs(thd);
+      res = binlog.show_binary_logs(thd);
       break;
     }
 #endif

=== modified file 'sql/sql_reload.cc'
--- a/sql/sql_reload.cc	2010-08-20 08:48:59 +0000
+++ b/sql/sql_reload.cc	2010-11-17 08:46:17 +0000
@@ -23,8 +23,9 @@
 #include "sql_base.h"    // close_cached_tables
 #include "sql_db.h"      // my_dbopt_cleanup
 #include "hostname.h"    // hostname_cache_refresh
+#include "binlog.h"
+#include "replication.h"
 #include "rpl_master.h"  // reset_master, reset_slave
-#include "rpl_rli.h"     // rotate_relay_log
 #include "debug_sync.h"
 
 
@@ -136,15 +137,14 @@ bool reload_acl_and_cache(THD *thd, unsi
       than it would help them)
     */
     tmp_write_to_binlog= 0;
-    if (mysql_bin_log.is_open())
-      mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+    if (binlog.flush_binary_log(thd))
+      result= 1;
   }
   if (options & REFRESH_RELAY_LOG)
   {
 #ifdef HAVE_REPLICATION
-    mysql_mutex_lock(&LOCK_active_mi);
-    rotate_relay_log(active_mi);
-    mysql_mutex_unlock(&LOCK_active_mi);
+    if (rpl_slave.flush_relay_log(thd))
+      result= 1;
 #endif
   }
 #ifdef HAVE_QUERY_CACHE
@@ -250,7 +250,7 @@ bool reload_acl_and_cache(THD *thd, unsi
   {
     DBUG_ASSERT(thd);
     tmp_write_to_binlog= 0;
-    if (reset_master(thd))
+    if (rpl_master.reset_master(thd))
     {
       result=1;
     }
@@ -267,10 +267,8 @@ bool reload_acl_and_cache(THD *thd, unsi
  if (options & REFRESH_SLAVE)
  {
    tmp_write_to_binlog= 0;
-   mysql_mutex_lock(&LOCK_active_mi);
-   if (reset_slave(thd, active_mi))
+   if (rpl_slave.reset_slave(thd))
      result=1;
-   mysql_mutex_unlock(&LOCK_active_mi);
  }
 #endif
  if (options & REFRESH_USER_RESOURCES)

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2010-09-28 15:17:29 +0000
+++ b/sql/sql_table.cc	2010-11-17 08:46:17 +0000
@@ -1992,9 +1992,9 @@ int write_bin_log(THD *thd, bool clear_e
       thd->clear_error();
     else
       errcode= query_error_code(thd, TRUE);
-    error= thd->binlog_query(THD::STMT_QUERY_TYPE,
-                             query, query_length, is_trans, FALSE, FALSE,
-                             errcode);
+    error= binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                               query, query_length, is_trans, FALSE, FALSE,
+                               errcode);
   }
   return error;
 }
@@ -2471,20 +2471,20 @@ err:
           /* Chop of the last comma */
           built_non_trans_tmp_query.chop();
           built_non_trans_tmp_query.append(" /* generated by server */");
-          error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
-                                     built_non_trans_tmp_query.ptr(),
-                                     built_non_trans_tmp_query.length(),
-                                     FALSE, FALSE, FALSE, 0);
+          error |= binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                                       built_non_trans_tmp_query.ptr(),
+                                       built_non_trans_tmp_query.length(),
+                                       FALSE, FALSE, FALSE, 0);
       }
       if (trans_tmp_table_deleted)
       {
           /* Chop of the last comma */
           built_trans_tmp_query.chop();
           built_trans_tmp_query.append(" /* generated by server */");
-          error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
-                                     built_trans_tmp_query.ptr(),
-                                     built_trans_tmp_query.length(),
-                                     TRUE, FALSE, FALSE, 0);
+          error |= binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                                       built_trans_tmp_query.ptr(),
+                                       built_trans_tmp_query.length(),
+                                       TRUE, FALSE, FALSE, 0);
       }
       if (non_tmp_table_deleted)
       {
@@ -2493,11 +2493,11 @@ err:
           built_query.append(" /* generated by server */");
           int error_code = (non_tmp_error ?
             (foreign_key_error ? ER_ROW_IS_REFERENCED : ER_BAD_TABLE_ERROR) : 0);
-          error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
-                                     built_query.ptr(),
-                                     built_query.length(),
-                                     TRUE, FALSE, FALSE,
-                                     error_code);
+          error |= binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                                       built_query.ptr(),
+                                       built_query.length(),
+                                       TRUE, FALSE, FALSE,
+                                       error_code);
       }
     }
   }

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2010-08-16 06:58:42 +0000
+++ b/sql/sql_update.cc	2010-11-17 08:46:17 +0000
@@ -826,9 +826,9 @@ int mysql_update(THD *thd,
       else
         errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
 
-      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
-                            thd->query(), thd->query_length(),
-                            transactional_table, FALSE, FALSE, errcode))
+      if (binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
+                              thd->query(), thd->query_length(),
+                              transactional_table, FALSE, FALSE, errcode))
       {
         error=1;				// Rollback update
       }
@@ -1838,9 +1838,9 @@ void multi_update::abort_result_set()
       */
       int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
       /* the error of binary logging is ignored */
-      (void)thd->binlog_query(THD::ROW_QUERY_TYPE,
-                        thd->query(), thd->query_length(),
-                        transactional_tables, FALSE, FALSE, errcode);
+      (void)binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
+                                thd->query(), thd->query_length(),
+                                transactional_tables, FALSE, FALSE, errcode);
     }
     thd->transaction.all.modified_non_trans_table= TRUE;
   }
@@ -2071,9 +2071,9 @@ bool multi_update::send_eof()
         thd->clear_error();
       else
         errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
-      if (thd->binlog_query(THD::ROW_QUERY_TYPE,
-                            thd->query(), thd->query_length(),
-                            transactional_tables, FALSE, FALSE, errcode))
+      if (binlog.binlog_query(thd, Binlog::ROW_QUERY_TYPE,
+                              thd->query(), thd->query_length(),
+                              transactional_tables, FALSE, FALSE, errcode))
       {
 	local_error= 1;				// Rollback update
       }

=== modified file 'sql/sql_view.cc'
--- a/sql/sql_view.cc	2010-08-30 06:38:09 +0000
+++ b/sql/sql_view.cc	2010-11-17 08:46:17 +0000
@@ -696,8 +696,8 @@ bool mysql_create_view(THD *thd, TABLE_L
     buff.append(views->source.str, views->source.length);
 
     int errcode= query_error_code(thd, TRUE);
-    if (thd->binlog_query(THD::STMT_QUERY_TYPE,
-                          buff.ptr(), buff.length(), FALSE, FALSE, FALSE, errcode))
+    if (binlog.binlog_query(thd, Binlog::STMT_QUERY_TYPE,
+                            buff.ptr(), buff.length(), FALSE, FALSE, FALSE, errcode))
       res= TRUE;
   }
 

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2010-09-01 13:16:07 +0000
+++ b/sql/sql_yacc.yy	2010-11-17 08:46:17 +0000
@@ -1891,107 +1891,79 @@ master_defs:
 master_def:
           MASTER_HOST_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.host = $3.str;
+            if (Lex->mi.set_host(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_USER_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.user = $3.str;
+            if (Lex->mi.set_user(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_PASSWORD_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.password = $3.str;
+            if (Lex->mi.set_password(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_PORT_SYM EQ ulong_num
           {
-            Lex->mi.port = $3;
+            if (Lex->mi.set_port(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
         | MASTER_CONNECT_RETRY_SYM EQ ulong_num
           {
-            Lex->mi.connect_retry = $3;
+            if (Lex->mi.set_connect_retry(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
         | MASTER_RETRY_COUNT_SYM EQ ulong_num
           {
-            Lex->mi.retry_count= $3;
-            Lex->mi.retry_count_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
+            if (Lex->mi.set_retry_count(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
         | MASTER_DELAY_SYM EQ ulong_num
           {
-            if ($3 > MASTER_DELAY_MAX)
-            {
-              my_error(ER_MASTER_DELAY_VALUE_OUT_OF_RANGE, MYF(0),
-                       $3, MASTER_DELAY_MAX);
-            }
-            else
-              Lex->mi.sql_delay = $3;
+	    if (Lex->mi.set_delay(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
         | MASTER_SSL_SYM EQ ulong_num
           {
-            Lex->mi.ssl= $3 ? 
-              LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
+            if (Lex->mi.set_ssl(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
         | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.ssl_ca= $3.str;
+            if (Lex->mi.set_ssl_ca(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.ssl_capath= $3.str;
+            if (Lex->mi.set_ssl_capath(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.ssl_cert= $3.str;
+            if (Lex->mi.set_ssl_cert(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.ssl_cipher= $3.str;
+            if (Lex->mi.set_ssl_cipher(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.ssl_key= $3.str;
+            if (Lex->mi.set_ssl_key(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_SSL_VERIFY_SERVER_CERT_SYM EQ ulong_num
           {
-            Lex->mi.ssl_verify_server_cert= $3 ?
-              LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
+            if (Lex->mi.set_ssl_verify_server_cert(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
 
         | MASTER_HEARTBEAT_PERIOD_SYM EQ NUM_literal
           {
-            Lex->mi.heartbeat_period= (float) $3->val_real();
-           if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD ||
-               Lex->mi.heartbeat_period < 0.0)
-           {
-             const char format[]= "%d seconds";
-             char buf[4*sizeof(SLAVE_MAX_HEARTBEAT_PERIOD) + sizeof(format)];
-             sprintf(buf, format, SLAVE_MAX_HEARTBEAT_PERIOD);
-             my_error(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE,
-                      MYF(0), " is negative or exceeds the maximum ", buf);
-              MYSQL_YYABORT;
-            }
-            if (Lex->mi.heartbeat_period > slave_net_timeout)
-            {
-              push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
-                                  ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE,
-                                  ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE),
-                                  " exceeds the value of `slave_net_timeout' sec.",
-                                  " A sensible value for the period should be"
-                                  " less than the timeout.");
-            }
-            if (Lex->mi.heartbeat_period < 0.001)
-            {
-              if (Lex->mi.heartbeat_period != 0.0)
-              {
-                push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_WARN,
-                                    ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE,
-                                    ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE),
-                                    " is less than 1 msec.",
-                                    " The period is reset to zero which means"
-                                    " no heartbeats will be sending");
-                Lex->mi.heartbeat_period= 0.0;
-              }
-              Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_DISABLE;
-            }
-            Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_ENABLE;
+	    if (Lex->mi.set_heartbeat_period(YYTHD, (float)$3->val_real()))
+	      MYSQL_YYABORT;
           }
         | IGNORE_SERVER_IDS_SYM EQ '(' ignore_server_id_list ')'
           {
@@ -2010,39 +1982,30 @@ ignore_server_id_list:
 ignore_server_id:
           ulong_num
           {
-            insert_dynamic(&Lex->mi.repl_ignore_server_ids, (uchar*) &($1));
+            if (Lex->mi.add_ignore_server_id(YYTHD, ($1)))
+	      MYSQL_YYABORT;
           }
 
 master_file_def:
           MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.log_file_name = $3.str;
+            if (Lex->mi.set_log_file(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | MASTER_LOG_POS_SYM EQ ulonglong_num
           {
-            Lex->mi.pos = $3;
-            /* 
-               If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it
-               instead of causing subsequent errors. 
-               We need to do it in this file, because only there we know that 
-               MASTER_LOG_POS has been explicitely specified. On the contrary
-               in change_master() (sql_repl.cc) we cannot distinguish between 0
-               (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified),
-               whereas we want to distinguish (specified 0 means "read the binlog
-               from 0" (4 in fact), unspecified means "don't change the position
-               (keep the preceding value)").
-            */
-            Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+            if (Lex->mi.set_log_pos(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
         | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
           {
-            Lex->mi.relay_log_name = $3.str;
+            if (Lex->mi.set_relay_log_file(YYTHD, $3.str))
+	      MYSQL_YYABORT;
           }
         | RELAY_LOG_POS_SYM EQ ulong_num
           {
-            Lex->mi.relay_log_pos = $3;
-            /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
-            Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+            if (Lex->mi.set_relay_log_pos(YYTHD, $3))
+	      MYSQL_YYABORT;
           }
         ;
 
@@ -6991,15 +6954,8 @@ slave_until:
         | UNTIL_SYM slave_until_opts
           {
             LEX *lex=Lex;
-            if (((lex->mi.log_file_name || lex->mi.pos) &&
-                (lex->mi.relay_log_name || lex->mi.relay_log_pos)) ||
-                !((lex->mi.log_file_name && lex->mi.pos) ||
-                  (lex->mi.relay_log_name && lex->mi.relay_log_pos)))
-            {
-               my_message(ER_BAD_SLAVE_UNTIL_COND,
-                          ER(ER_BAD_SLAVE_UNTIL_COND), MYF(0));
+	    if (lex->mi.check_slave_until_opts(YYTHD))
                MYSQL_YYABORT;
-            }
           }
         ;
 

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2010-09-28 15:17:29 +0000
+++ b/sql/sys_vars.cc	2010-11-17 08:46:17 +0000
@@ -384,11 +384,11 @@ static Sys_var_mybool Sys_binlog_direct(
        CMD_LINE(OPT_ARG), DEFAULT(FALSE),
        NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(binlog_direct_check));
 
-static Sys_var_mybool Sys_binlog_rows_query(
-       "binlog_rows_query_log_events",
-       "Allow writing of Rows_query_log events into binary log.",
-       SESSION_VAR(binlog_rows_query_log_events),
-       CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+// static Sys_var_mybool Sys_binlog_rows_query(
+//        "binlog_rows_query_log_events",
+//        "Allow writing of Rows_query_log events into binary log.",
+//        SESSION_VAR(binlog_rows_query_log_events),
+//        CMD_LINE(OPT_ARG), DEFAULT(FALSE));
 
 static Sys_var_ulong Sys_bulk_insert_buff_size(
        "bulk_insert_buffer_size", "Size of tree cache used in bulk "


Attachment: [text/bzr-bundle] bzr/zhenxing.he@sun.com-20101117084617-fx87ap5q716pp27b.bundle
Thread
bzr commit into mysql-next-mr-bugfixing branch (zhenxing.he:3329) WL#5675He Zhenxing17 Nov