List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:December 28 2010 7:37am
Subject:bzr commit into mysql-trunk-bugfixing branch (alfranio.correia:3471) WL#5599
View as plain text  
#At file:///home/acorreia/workspace.oracle/repository.mysql/bzrwork/bug-proposal/mysql-trunk-bugfixing/ based on revid:tor.didriksen@stripped

 3471 Alfranio Correia	2010-12-28
      Reorganized and backported the basis for WL#5599.

    modified:
      sql/CMakeLists.txt
      sql/rpl_info.cc
      sql/rpl_info.h
      sql/rpl_info_factory.cc
      sql/rpl_info_factory.h
      sql/rpl_info_file.cc
      sql/rpl_info_file.h
      sql/rpl_info_handler.h
      sql/rpl_info_table.cc
      sql/rpl_info_table.h
      sql/rpl_info_table_access.cc
      sql/rpl_info_table_access.h
      sql/rpl_mi.cc
      sql/rpl_mi.h
      sql/rpl_rli.cc
      sql/rpl_rli.h
      sql/rpl_slave.cc
      sql/sys_vars.cc
=== modified file 'sql/CMakeLists.txt'
--- a/sql/CMakeLists.txt	2010-12-17 09:41:21 +0000
+++ b/sql/CMakeLists.txt	2010-12-28 07:37:37 +0000
@@ -108,7 +108,7 @@ ADD_DEPENDENCIES(master GenError)
 SET (SLAVE_SOURCE rpl_slave.cc rpl_reporting.cc rpl_mi.cc rpl_rli.cc
 		  rpl_info_handler.cc rpl_info_file.cc rpl_info_table.cc
 		  rpl_info_values.cc rpl_info.cc rpl_info_factory.cc
-		  rpl_info_table_access.cc server_ids.h)
+		  rpl_info_table_access.cc server_ids.h rpl_info_dummy.cc)
 ADD_LIBRARY(slave ${SLAVE_SOURCE})
 ADD_DEPENDENCIES(slave GenError)
 ADD_LIBRARY(sqlgunitlib

=== modified file 'sql/rpl_info.cc'
--- a/sql/rpl_info.cc	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_info.cc	2010-12-28 07:37:37 +0000
@@ -35,8 +35,8 @@ Rpl_info::Rpl_info(const char* type
   key_info_stop_cond(param_key_info_stop_cond),
 #endif
   info_thd(0), inited(0), abort_slave(0),
-  slave_running(0), slave_run_id(0),
-  handler(0)
+  slave_running(0), slave_run_id(0), uidx(0),
+  nidx(0), handler(0)
 {
 #ifdef HAVE_PSI_INTERFACE
   mysql_mutex_init(*key_info_run_lock,
@@ -65,6 +65,9 @@ Rpl_info::~Rpl_info()
   mysql_cond_destroy(&start_cond);
   mysql_cond_destroy(&stop_cond);
 
+  if (uidx)
+    delete []uidx;
+
   if (handler)
     delete handler;
 

=== modified file 'sql/rpl_info.h'
--- a/sql/rpl_info.h	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_info.h	2010-12-28 07:37:37 +0000
@@ -53,6 +53,17 @@ public:
   int events_until_exit;
 #endif
 
+  /**
+    Array of values that uniquely identifies an entry in the repository.
+  */
+  ulong *uidx;
+
+  /**
+    Number of entries in the array that uniquely identifies an entry in
+    the repository.
+  */
+  uint nidx;
+
   Rpl_info(const char* type
 #ifdef HAVE_PSI_INTERFACE
            ,PSI_mutex_key *param_key_info_run_lock,
@@ -66,12 +77,12 @@ public:
 
   int check_info()
   {
-    return (handler->check_info());
+    return (handler->check_info(uidx, nidx));
   }
 
   int remove_info()
   {
-    return (handler->remove_info());
+    return (handler->remove_info(uidx, nidx));
   }
 
   bool is_transactional()
@@ -86,13 +97,25 @@ public:
 
   bool copy_info(Rpl_info_handler *from, Rpl_info_handler *to)
   {
-    if (read_info(from) || write_info(to, TRUE))
+    if (read_info(from) || write_info(to))
       return(TRUE);
 
     return(FALSE);
   }
 
   /**
+    Sets the array that uniquely identifies an entry in the repository.
+
+    @param[in] param_uidx an arry of values
+    @param[in] param_nidx number of entries in the array
+  */
+  void set_idx_info(ulong *param_uidx, uint param_nidx)
+  {
+    uidx= param_uidx;
+    nidx= param_nidx;
+  }
+
+  /**
     Sets the persistency component/handler.
 
     @param[in] hanlder Pointer to the handler.
@@ -100,11 +123,14 @@ public:
   void set_rpl_info_handler(Rpl_info_handler * handler);
 
 protected:
+  /**
+    Pointer to a handler, i.e. repository.
+  */
   Rpl_info_handler *handler;
 
 private:
   virtual bool read_info(Rpl_info_handler *from)= 0;
-  virtual bool write_info(Rpl_info_handler *to, bool force)= 0;
+  virtual bool write_info(Rpl_info_handler *to)= 0;
 
   Rpl_info& operator=(const Rpl_info& info);
   Rpl_info(const Rpl_info& info);

=== modified file 'sql/rpl_info_factory.cc'
--- a/sql/rpl_info_factory.cc	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_info_factory.cc	2010-12-28 07:37:37 +0000
@@ -18,12 +18,9 @@
 #include "rpl_slave.h"
 #include "rpl_info_factory.h"
 
-/*
-  We need to replace these definitions by an option that states the
-  engine one wants to use in the master info repository.
-*/
 #define master_info_engine NULL
 #define relay_log_info_engine NULL
+#define NUMBER_OF_FIELDS_TO_IDENTIFY_MI_RLI 1
 
 /**
   Creates both a Master info and a Relay log info repository whose types are
@@ -42,7 +39,7 @@
 bool Rpl_info_factory::create(uint mi_option, Master_info **mi,
                               uint rli_option, Relay_log_info **rli)
 {
-  DBUG_ENTER("Rpl_info_factory::Rpl_info_factory");
+  DBUG_ENTER("Rpl_info_factory::create");
 
   if (!((*mi)= Rpl_info_factory::create_mi(mi_option)))
     DBUG_RETURN(TRUE);
@@ -82,10 +79,11 @@ Master_info *Rpl_info_factory::create_mi
   Master_info* mi= NULL;
   Rpl_info_file*  mi_file= NULL;
   Rpl_info_table*  mi_table= NULL;
+  ulong *key_info_idx= NULL;
   const char *msg= "Failed to allocate memory for the master info "
                    "structure";
 
-  DBUG_ENTER("Rpl_info_factory::Rpl_info_factory");
+  DBUG_ENTER("Rpl_info_factory::create_mi");
 
   if (!(mi= new Master_info(
 #ifdef HAVE_PSI_INTERFACE
@@ -98,29 +96,51 @@ Master_info *Rpl_info_factory::create_mi
                            )))
     goto err;
 
-  /*
-    Now we instantiate all info repos and later decide which one to take,
-    but not without first checking if there is already existing data for
-    a repo different from the one that is being requested.
-  */
-  if (!(mi_file= new Rpl_info_file(mi->get_number_info_mi_fields(),
-                                   master_info_file)))
-    goto err;
-
-  if (!(mi_table= new Rpl_info_table(mi->get_number_info_mi_fields() + 1,
-                                     MI_FIELD_ID, MI_SCHEMA, MI_TABLE)))
-    goto err;
+  if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_MI_RLI]))
+     goto err;
+  key_info_idx[0]= server_id;
+  mi->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_MI_RLI);
 
   DBUG_ASSERT(mi_option == MI_REPOSITORY_FILE ||
-              mi_option == MI_REPOSITORY_TABLE);
+              mi_option == MI_REPOSITORY_TABLE ||
+              mi_option == MI_REPOSITORY_DUMMY);
+
+  if (mi_option == MI_REPOSITORY_FILE ||
+      mi_option == MI_REPOSITORY_TABLE)
+  {
+    /*
+      Now we instantiate all info repos and later decide which one to take,
+      but not without first checking if there is already existing data for
+      a repo different from the one that is being requested.
+    */
+    if (!(mi_file= new Rpl_info_file(mi->get_number_info_mi_fields(),
+                                   master_info_file)))
+      goto err;
 
-  if (decide_repository(mi, &mi_table, &mi_file,
+    if (!(mi_table= new Rpl_info_table(mi->get_number_info_mi_fields() + 1,
+                                     MI_SCHEMA, MI_TABLE)))
+      goto err;
+
+    /*
+      In a multi-master envinroment, we need to make sure that both master
+      info and relay log info are prepared to handle events from all
+      masters. In such case, we need to execute the code below for each
+      master. /Alfranio
+    */
+    if (decide_repository(mi, &mi_table, &mi_file,
                         mi_option == MI_REPOSITORY_TABLE, &msg))
-    goto err;
+      goto err;
+
+    if ((mi_option == MI_REPOSITORY_TABLE) &&
+         change_engine(static_cast<Rpl_info_table *>(mi_table),
+                       master_info_engine, &msg))
+      goto err;
+
+    DBUG_RETURN(mi);
+  }
 
-  if ((mi_option == MI_REPOSITORY_TABLE) &&
-       change_engine(static_cast<Rpl_info_table *>(mi_table),
-                     master_info_engine, &msg))
+  if (Rpl_info_factory::create_info_dummy(mi,
+                                          mi->get_number_info_mi_fields()))
     goto err;
 
   DBUG_RETURN(mi);
@@ -128,6 +148,11 @@ Master_info *Rpl_info_factory::create_mi
 err:
   if (mi_file) delete mi_file;
   if (mi_table) delete mi_table;
+  if (key_info_idx)
+  {
+    delete []key_info_idx;
+    mi->set_idx_info(NULL, 0);
+  }
   if (mi)
   {
     /*
@@ -162,6 +187,7 @@ Relay_log_info *Rpl_info_factory::create
   Relay_log_info *rli= NULL;
   Rpl_info_file* rli_file= NULL;
   Rpl_info_table* rli_table= NULL;
+  ulong *key_info_idx= NULL;
   const char *msg= "Failed to allocate memory for the relay log info "
                    "structure";
 
@@ -178,29 +204,51 @@ Relay_log_info *Rpl_info_factory::create
                                )))
     goto err;
 
-  /*
-    Now we instantiate all info repos and later decide which one to take,
-    but not without first checking if there is already existing data for
-    a repo different from the one that is being requested.
-  */
-  if (!(rli_file= new Rpl_info_file(rli->get_number_info_rli_fields(),
-                                    relay_log_info_file)))
-    goto err;
-
-  if (!(rli_table= new Rpl_info_table(rli->get_number_info_rli_fields() + 1,
-                                      RLI_FIELD_ID, RLI_SCHEMA, RLI_TABLE)))
-    goto err;
+  if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_MI_RLI]))
+     goto err;
+  key_info_idx[0]= server_id;
+  rli->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_MI_RLI);
 
   DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE ||
-              rli_option == RLI_REPOSITORY_TABLE);
+              rli_option == RLI_REPOSITORY_TABLE ||
+              rli_option == RLI_REPOSITORY_DUMMY);
 
-  if (decide_repository(rli, &rli_table, &rli_file,
-                        rli_option == RLI_REPOSITORY_TABLE, &msg))
-    goto err;
+  if (rli_option == RLI_REPOSITORY_FILE ||
+      rli_option == RLI_REPOSITORY_TABLE)
+  {
+    /*
+      Now we instantiate all info repos and later decide which one to take,
+      but not without first checking if there is already existing data for
+      a repo different from the one that is being requested.
+    */
+    if (!(rli_file= new Rpl_info_file(rli->get_number_info_rli_fields(),
+                                      relay_log_info_file)))
+      goto err;
+
+    if (!(rli_table= new Rpl_info_table(rli->get_number_info_rli_fields() + 1,
+                                        RLI_SCHEMA, RLI_TABLE)))
+      goto err;
 
-  if ((rli_option == RLI_REPOSITORY_TABLE) &&
-      change_engine(static_cast<Rpl_info_table *>(rli_table),
-                    relay_log_info_engine, &msg))
+    /*
+      In a multi-master envinroment, we need to make sure that both master
+      info and relay log info are prepared to handle events from all
+      masters. In such case, we need to execute the code below for each
+      master. /Alfranio
+    */
+    if (decide_repository(rli, &rli_table, &rli_file,
+                          rli_option == RLI_REPOSITORY_TABLE, &msg))
+      goto err;
+
+    if ((rli_option == RLI_REPOSITORY_TABLE) &&
+        change_engine(static_cast<Rpl_info_table *>(rli_table),
+                      relay_log_info_engine, &msg))
+      goto err;
+
+    DBUG_RETURN(rli);
+  }
+
+  if (Rpl_info_factory::create_info_dummy(rli,
+                                          rli->get_number_info_rli_fields()))
     goto err;
 
   DBUG_RETURN(rli);
@@ -208,6 +256,11 @@ Relay_log_info *Rpl_info_factory::create
 err:
   if (rli_file) delete rli_file;
   if (rli_table) delete rli_table;
+  if (key_info_idx)
+  {
+    delete []key_info_idx;
+    rli->set_idx_info(NULL, 0);
+  }
   if (rli) 
   {
     /*
@@ -258,7 +311,8 @@ err:
   @retval FALSE No error
   @retval TRUE  Failure
 */
-bool Rpl_info_factory::decide_repository(Rpl_info *info, Rpl_info_table **table,
+bool Rpl_info_factory::decide_repository(Rpl_info *info,
+                                         Rpl_info_table **table,
                                          Rpl_info_file **file, bool is_table,
                                          const char **msg)
 {
@@ -266,8 +320,8 @@ bool Rpl_info_factory::decide_repository
   DBUG_ENTER("Rpl_info_factory::decide_repository");
  
   bool error= TRUE;
-  bool is_t= !((*table)->check_info());
-  bool is_f= !((*file)->check_info());
+  bool is_t= !((*table)->check_info(info->uidx, info->nidx));
+  bool is_f= !((*file)->check_info(info->uidx, info->nidx));
 
   if (is_t && is_f)
   {
@@ -281,7 +335,8 @@ bool Rpl_info_factory::decide_repository
   {
     if (!is_t && is_f)
     {
-      if ((*table)->init_info() || (*file)->init_info())
+      if ((*table)->init_info(info->uidx, info->nidx) ||
+          (*file)->init_info(info->uidx, info->nidx))
       {
         *msg= "Error transfering information from a file to a table.";
         goto err;
@@ -289,8 +344,13 @@ bool Rpl_info_factory::decide_repository
       /*
         Transfer the information from the file to the table and delete the
         file, i.e. Update the table (T) and delete the file (F).
+    
+        This process is not atomic and if the server crashes before removing
+        the file, the user needs to manualy remove it.
       */
-      if (info->copy_info(*file, *table) || (*file)->remove_info())
+      if (info->copy_info(*file, *table) ||
+          (*table)->flush_info(info->uidx, info->nidx, TRUE)
+          || (*file)->remove_info(info->uidx, info->nidx))
       {
         *msg= "Error transfering information from a file to a table.";
         goto err;
@@ -305,7 +365,8 @@ bool Rpl_info_factory::decide_repository
   {
     if (is_t && !is_f)
     {
-      if ((*table)->init_info() || (*file)->init_info())
+      if ((*table)->init_info(info->uidx, info->nidx) ||
+          (*file)->init_info(info->uidx, info->nidx))
       {
         *msg= "Error transfering information from a file to a table.";
         goto err;
@@ -314,8 +375,15 @@ bool Rpl_info_factory::decide_repository
         Transfer the information from the table to the file and delete 
         entries in the table, i.e. Update the file (F) and delete the
         table (T).
+
+        This process is not atomic and if the server crashes before deleting
+        entry in the table, the user needs to manualy remove the file and
+        repeat the process. Note that we assuming here single master rep.
+        This process needs to be changed if there are multi-masters.
       */
-      if (info->copy_info(*table, *file) || (*table)->remove_info())
+      if (info->copy_info(*table, *file) ||
+          (*file)->flush_info(info->uidx, info->nidx, TRUE)
+          || (*table)->remove_info(info->uidx, info->nidx))
       {
         *msg= "Error transfering information from a table to a file.";
         goto err;
@@ -344,7 +412,7 @@ err:
 bool Rpl_info_factory::change_engine(Rpl_info_table *table, const char *engine,
                                      const char **msg)
 {
-  DBUG_ENTER("Rpl_info_factory::decide_engine");
+  DBUG_ENTER("Rpl_info_factory::change_engine");
 
   if (engine && table->change_engine(engine))
   {
@@ -354,3 +422,17 @@ bool Rpl_info_factory::change_engine(Rpl
 
   DBUG_RETURN(FALSE);
 }
+
+bool Rpl_info_factory::create_info_dummy(Rpl_info *rpl, uint nfields)
+{
+  DBUG_ENTER("Rpl_info_factory::create_info_dummy");
+
+  Rpl_info_dummy* rpl_dummy= NULL;
+
+  if (!(rpl_dummy= new Rpl_info_dummy(nfields)))
+    DBUG_RETURN(TRUE);
+
+  rpl->set_rpl_info_handler(rpl_dummy);
+
+  DBUG_RETURN(FALSE);
+}

=== modified file 'sql/rpl_info_factory.h'
--- a/sql/rpl_info_factory.h	2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_factory.h	2010-12-28 07:37:37 +0000
@@ -21,44 +21,47 @@
 #include "rpl_rli.h"
 #include "rpl_info_file.h"
 #include "rpl_info_table.h"
+#include "rpl_info_dummy.h"
 #include "rpl_info_handler.h"
 
 enum enum_mi_repository
 {
   MI_REPOSITORY_FILE= 0,
-  MI_REPOSITORY_TABLE= 1
+  MI_REPOSITORY_TABLE= 1,
+  MI_REPOSITORY_DUMMY= 2
 };
 extern ulong opt_mi_repository_id;
 
 enum enum_rli_repository
 {
   RLI_REPOSITORY_FILE= 0,
-  RLI_REPOSITORY_TABLE= 1
+  RLI_REPOSITORY_TABLE= 1,
+  RLI_REPOSITORY_DUMMY= 2
 };
 extern ulong opt_rli_repository_id;
 
-#define MI_FIELD_ID 0
-
 #define MI_SCHEMA "mysql"
 #define MI_TABLE  "slave_master_info"
 
-#define RLI_FIELD_ID 0
-
 #define RLI_SCHEMA "mysql"
 #define RLI_TABLE  "slave_relay_log_info"
 
 class Rpl_info_factory
 {
-  public:
+public:
 
   static bool create(uint mi_option, Master_info **mi,
                      uint rli_option, Relay_log_info **rli);
   static Master_info *create_mi(uint rli_option);
   static Relay_log_info *create_rli(uint rli_option, bool is_slave_recovery);
-  static bool decide_repository(Rpl_info *info, Rpl_info_table **table,
+
+private:
+  static bool decide_repository(Rpl_info *info,
+                                Rpl_info_table **table,
                                 Rpl_info_file **file, bool is_table,
                                 const char **msg);
   static bool change_engine(Rpl_info_table *table, const char *engine,
                             const char **msg);
+  static bool create_info_dummy(Rpl_info *rpl, uint nfields);
 };
 #endif

=== modified file 'sql/rpl_info_file.cc'
--- a/sql/rpl_info_file.cc	2010-10-29 09:07:21 +0000
+++ b/sql/rpl_info_file.cc	2010-12-28 07:37:37 +0000
@@ -39,7 +39,8 @@ Rpl_info_file::Rpl_info_file(const int n
   DBUG_VOID_RETURN;
 }
 
-int Rpl_info_file::do_init_info()
+int Rpl_info_file::do_init_info(const ulong *uidx __attribute__((unused)),
+                                const uint nidx __attribute__((unused)))
 {
   int error= 0;
 
@@ -47,7 +48,7 @@ int Rpl_info_file::do_init_info()
   DBUG_ENTER("Rpl_info_file::do_init_info");
 
   /* does info file exist ? */
-  if (do_check_info())
+  if (do_check_info(uidx, nidx))
   {
     /*
       If someone removed the file from underneath our feet, just close
@@ -106,26 +107,31 @@ file '%s')", info_fname);
   DBUG_RETURN(error);
 }
 
-int Rpl_info_file::do_prepare_info_for_read()
+int Rpl_info_file::do_prepare_info_for_read(const uint nidx
+                                            __attribute__((unused)))
 {
   cursor= 0;
   prv_error= FALSE;
   return (reinit_io_cache(&info_file, READ_CACHE, 0L, 0, 0));
 }
 
-int Rpl_info_file::do_prepare_info_for_write()
+int Rpl_info_file::do_prepare_info_for_write(const uint nidx
+                                             __attribute__((unused)))
 {
   cursor= 0;
   prv_error= FALSE;
   return (reinit_io_cache(&info_file, WRITE_CACHE, 0L, 0, 1));
 }
 
-int Rpl_info_file::do_check_info()
+int Rpl_info_file::do_check_info(const ulong *uidx __attribute__((unused)),
+                                 const uint nidx __attribute__((unused)))
 {
   return (access(info_fname,F_OK));
 }
 
-int Rpl_info_file::do_flush_info(const bool force)
+int Rpl_info_file::do_flush_info(const ulong *uidx,
+                                 const uint nidx,
+                                 const bool force)
 {
   int error= 0;
 
@@ -145,7 +151,8 @@ int Rpl_info_file::do_flush_info(const b
   DBUG_RETURN(error);
 }
 
-void Rpl_info_file::do_end_info()
+void Rpl_info_file::do_end_info(const ulong *uidx __attribute__((unused)),
+                                const uint nidx __attribute__((unused)))
 {
   DBUG_ENTER("Rpl_info_file::do_end_info");
 
@@ -159,7 +166,8 @@ void Rpl_info_file::do_end_info()
   DBUG_VOID_RETURN;
 }
 
-int Rpl_info_file::do_remove_info()
+int Rpl_info_file::do_remove_info(const ulong *uidx __attribute__((unused)),
+                                  const uint nidx __attribute__((unused)))
 {
   MY_STAT stat_area;
   int error= 0;
@@ -178,6 +186,12 @@ bool Rpl_info_file::do_set_info(const in
           FALSE : TRUE);
 }
 
+bool Rpl_info_file::do_set_info(const int pos, const uchar *value,
+                                const size_t size)
+{
+  return (my_b_write(&info_file, value, size));
+}
+
 bool Rpl_info_file::do_set_info(const int pos, const ulong value)
 {
   return (my_b_printf(&info_file, "%lu\n", value) > (size_t) 0 ?
@@ -235,6 +249,12 @@ bool Rpl_info_file::do_get_info(const in
                                 default_value));
 }
 
+bool Rpl_info_file::do_get_info(const int pos, uchar *value, const size_t size,
+                                const uchar *default_value)
+{
+  return(my_b_read(&info_file, value, size));
+}
+
 bool Rpl_info_file::do_get_info(const int pos, ulong *value,
                                 const ulong default_value)
 {

=== modified file 'sql/rpl_info_file.h'
--- a/sql/rpl_info_file.h	2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_file.h	2010-12-28 07:37:37 +0000
@@ -41,21 +41,26 @@ private:
   /* IO_CACHE of the info file - set only during init or end */
   IO_CACHE info_file;
 
-  int do_init_info();
-  int do_check_info();
-  void do_end_info();
-  int do_flush_info(const bool force);
-  int do_remove_info();
+  int do_init_info(const ulong *uidx, const uint nidx);
+  int do_check_info(const ulong *uidx, const uint nidx);
+  void do_end_info(const ulong *uidx, const uint nidx);
+  int do_flush_info(const ulong *uidx, const uint nidx,
+                    const bool force);
+  int do_remove_info(const ulong *uidx, const uint nidx);
 
-  int do_prepare_info_for_read();
-  int do_prepare_info_for_write();
+  int do_prepare_info_for_read(const uint nidx);
+  int do_prepare_info_for_write(const uint nidx);
   bool do_set_info(const int pos, const char *value);
+  bool do_set_info(const int pos, const uchar *value,
+                   const size_t size);
   bool do_set_info(const int pos, const int value);
   bool do_set_info(const int pos, const ulong value);
   bool do_set_info(const int pos, const float value);
   bool do_set_info(const int pos, const Server_ids *value);
   bool do_get_info(const int pos, char *value, const size_t size,
                    const char *default_value);
+  bool do_get_info(const int pos, uchar *value, const size_t size,
+                   const uchar *default_value);
   bool do_get_info(const int pos, int *value,
                    const int default_value);
   bool do_get_info(const int pos, ulong *value,

=== modified file 'sql/rpl_info_handler.h'
--- a/sql/rpl_info_handler.h	2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_handler.h	2010-12-28 07:37:37 +0000
@@ -30,26 +30,32 @@ public:
     After creating an object and assembling components, this method is
     used to initialize internal structures. Everything that does not
     depend on other components (e.g. mutexes) should be placed in the
-    object's constructor though. 
+    object's constructor though.
+
+    @param[in] uidx Array of fields that identifies an object
+    @param[in] nidx Number of fields in the array
 
     @retval FALSE success,
     @retval TRUE  otherwise error.
   */
-  int init_info()
+  int init_info(const ulong *uidx, const uint nidx)
   {
-    return do_init_info();
+    return do_init_info(uidx, nidx);
   }
 
   /**
     Checks if any necessary dependency is satisfied such as a
     file exists.
 
+    @param[in] uidx Array of fields that identifies an object
+    @param[in] nidx Number of fields in the array
+
     @retval FALSE success,
     @retval TRUE  otherwise error.
   */
-  int check_info()
+  int check_info(const ulong *uidx, const uint nidx)
   {
-    return do_check_info();
+    return do_check_info(uidx, nidx);
   }
 
   /**
@@ -65,36 +71,44 @@ public:
     system, it may happen that the changes will only end up in the
     operating system's cache and a crash may lead to inconsistencies.
 
+    @param[in] uidx  Array of fields that identifies an object
+    @param[in] nidx  Number of fields in the array
     @param[in] force Always sync the information.
 
     @retval FALSE No error
     @retval TRUE  Failure
   */
-  int flush_info(const bool force)
+  int flush_info(const ulong *uidx, const uint nidx, const bool force)
   {
-    return do_flush_info(force);
+    return do_flush_info(uidx, nidx, force);
   }
 
   /**
     Deletes any information in the repository.
 
+    @param[in] uidx Array of fields that identifies an object
+    @param[in] nidx Number of fields in the array
+
     @retval FALSE No error
     @retval TRUE  Failure
   */
-  int remove_info()
+  int remove_info(const ulong *uidx, const uint nidx)
   {
-    return do_remove_info();
+    return do_remove_info(uidx, nidx);
   }
 
   /**
     Closes access to the repository.
 
+    @param[in] uidx Array of fields that identifies an object
+    @param[in] nidx Number of fields in the array
+
     @retval FALSE No error
     @retval TRUE  Failure
   */
-  void end_info()
+  void end_info(const ulong *uidx, const uint nidx)
   {
-    do_end_info();
+    do_end_info(uidx, nidx);
   }
 
   /**
@@ -104,9 +118,9 @@ public:
     @retval FALSE No error
     @retval TRUE  Failure
   */
-  int prepare_info_for_read()
+  int prepare_info_for_read(const uint nidx)
   {
-    return (do_prepare_info_for_read());
+    return (do_prepare_info_for_read(nidx));
   }
 
   /**
@@ -116,9 +130,9 @@ public:
     @retval FALSE No error
     @retval TRUE  Failure
   */
-  int prepare_info_for_write()
+  int prepare_info_for_write(const uint nidx)
   {
-    return (do_prepare_info_for_write());
+    return (do_prepare_info_for_write(nidx));
   }
 
   /**
@@ -144,6 +158,18 @@ public:
     return(prv_error);
   }
 
+  template <class TypeHandler>
+  bool set_info(TypeHandler const value, const size_t size)
+  {
+    if (cursor >= ninfo || prv_error)
+      return TRUE;
+
+    if (!(prv_error= do_set_info(cursor, value, size)))
+      cursor++;
+
+    return(prv_error);
+  }
+
   /**
     Returns the value of a field.
     Any call must be done in the right order which
@@ -185,8 +211,9 @@ public:
     @retval FALSE No error
     @retval TRUE Failure
   */
-  bool get_info(char *value, const size_t size,
-                const char *default_value)
+  template <class TypeHandler>
+  bool get_info(TypeHandler value, const size_t size,
+                TypeHandler const default_value)
   {
     if (cursor >= ninfo || prv_error)
       return TRUE;
@@ -290,21 +317,28 @@ protected:
   uint sync_period;
 
 private:
-  virtual int do_init_info()= 0;
-  virtual int do_check_info()= 0;
-  virtual int do_flush_info(const bool force)= 0;
-  virtual int do_remove_info()= 0;
-  virtual void do_end_info()= 0;
-  virtual int do_prepare_info_for_read()= 0;
-  virtual int do_prepare_info_for_write()= 0;
+  virtual int do_init_info(const ulong *uidx, const uint nidx)= 0;
+  virtual int do_check_info(const ulong *uidx, const uint nidx)= 0;
+  virtual int do_flush_info(const ulong *uidx, const uint nidx,
+                            const bool force)= 0;
+  virtual int do_remove_info(const ulong *uidx, const uint nidx)= 0;
+  virtual void do_end_info(const ulong *uidx, const uint nidx)= 0;
+  virtual int do_prepare_info_for_read(const uint nidx)= 0;
+  virtual int do_prepare_info_for_write(const uint nidx)= 0;
 
   virtual bool do_set_info(const int pos, const char *value)= 0;
+  virtual bool do_set_info(const int pos, const uchar *value,
+                           const size_t size)= 0;
   virtual bool do_set_info(const int pos, const ulong value)= 0;
   virtual bool do_set_info(const int pos, const int value)= 0;
   virtual bool do_set_info(const int pos, const float value)= 0;
   virtual bool do_set_info(const int pos, const Server_ids *value)= 0;
-  virtual bool do_get_info(const int pos, char *value, const size_t size,
+  virtual bool do_get_info(const int pos, char *value,
+                           const size_t size,
                            const char *default_value)= 0;
+  virtual bool do_get_info(const int pos, uchar *value,
+                           const size_t size,
+                           const uchar *default_value)= 0;
   virtual bool do_get_info(const int pos, ulong *value,
                            const ulong default_value)= 0;
   virtual bool do_get_info(const int pos, int *value,

=== modified file 'sql/rpl_info_table.cc'
--- a/sql/rpl_info_table.cc	2010-12-03 00:15:40 +0000
+++ b/sql/rpl_info_table.cc	2010-12-28 07:37:37 +0000
@@ -15,12 +15,12 @@
 
 #include "rpl_info_table.h"
 #include "rpl_utility.h"
-#include "sql_parse.h"
+#include "sql_prepare.h"
 
-Rpl_info_table::Rpl_info_table(uint nparam, uint param_field_idx,
+Rpl_info_table::Rpl_info_table(uint nparam,
                                const char* param_schema,
                                const char *param_table)
-:Rpl_info_handler(nparam), field_idx(param_field_idx)
+:Rpl_info_handler(nparam)
 {
   str_schema.str= str_table.str= NULL;
   str_schema.length= str_table.length= 0;
@@ -65,7 +65,7 @@ Rpl_info_table::~Rpl_info_table()
     my_free(str_schema.str);
 }
 
-int Rpl_info_table::do_init_info()
+int Rpl_info_table::do_init_info(const ulong *uidx, const uint nidx)
 {
   int error= 1;
   enum enum_return_id res= FOUND_ID;
@@ -89,11 +89,10 @@ int Rpl_info_table::do_init_info()
     goto end;
 
   /*
-    Points the cursor at the row to be read where the master_id equals to
-    the server_id.
+    Points the cursor at the row to be read.
   */
-  if ((res= access->find_info_for_server_id(server_id, field_idx,
-                                            field_values, table)) == FOUND_ID)
+  if ((res= access->find_info(uidx, nidx, field_values,
+                              table)) == FOUND_ID)
   {
     /*
       Reads the information stored in the rpl_info table into a
@@ -116,7 +115,8 @@ end:
   DBUG_RETURN(error);
 }
 
-int Rpl_info_table::do_flush_info(const bool force)
+int Rpl_info_table::do_flush_info(const ulong *uidx, const uint nidx,
+                                  const bool force)
 {
   int error= 1;
   enum enum_return_id res= FOUND_ID;
@@ -145,12 +145,11 @@ int Rpl_info_table::do_flush_info(const
     goto end;
 
   /*
-    Points the cursor at the row to be read where the master_id
-    equals to the server_id. If the row is not found an error is
-    reported.
+    Points the cursor at the row to be read. If the row is not found
+    an error is reported.
   */
-  if ((res= access->find_info_for_server_id(server_id, field_idx,
-                                            field_values, table)) == NOT_FOUND_ID)
+  if ((res= access->find_info(uidx, nidx, field_values,
+                              table)) == NOT_FOUND_ID)
   {
     /*
       Prepares the information to be stored before calling ha_write_row.
@@ -214,7 +213,7 @@ end:
   DBUG_RETURN(error);
 }
 
-int Rpl_info_table::do_remove_info()
+int Rpl_info_table::do_remove_info(const ulong *uidx, const uint nidx)
 {
   int error= 1;
   enum enum_return_id res= FOUND_ID;
@@ -238,12 +237,11 @@ int Rpl_info_table::do_remove_info()
     goto end;
 
   /*
-    Points the cursor at the row to be deleted where the the master_id
-    equals to the server_id. If the row is not found, the execution
-    proceeds normally.
+    Points the cursor at the row to be deleted. If the row is not
+    found, the execution proceeds normally.
   */
-  if ((res= access->find_info_for_server_id(server_id, field_idx,
-                                            field_values, table)) == FOUND_ID)
+  if ((res= access->find_info(uidx, nidx, field_values,
+                              table)) == FOUND_ID)
   {
     /*
       Deletes a row in the rpl_info table.
@@ -266,7 +264,7 @@ end:
   DBUG_RETURN(error);
 }
 
-int Rpl_info_table::do_check_info()
+int Rpl_info_table::do_check_info(const ulong *uidx, const uint nidx)
 {
   int error= 1;
   TABLE *table= NULL;
@@ -288,12 +286,11 @@ int Rpl_info_table::do_check_info()
     goto end;
 
   /*
-    Points the cursor at the row to be deleted where the the master_id
-    equals to the server_id. If the row is not found, an error is
-    reported.
+    Points the cursor at the row to be cheked. If the row is not
+    found, the execution proceeds normally.
   */
-  if (access->find_info_for_server_id(server_id, field_idx,
-                                      field_values, table) != FOUND_ID)
+  if (access->find_info(uidx, nidx, field_values,
+                        table) != FOUND_ID)
   {
     /* 
        We cannot simply call my_error here because it does not
@@ -314,23 +311,23 @@ end:
   DBUG_RETURN(error);
 }
 
-void Rpl_info_table::do_end_info()
+void Rpl_info_table::do_end_info(const ulong *uidx, const uint nidx)
 {
 }
 
-int Rpl_info_table::do_prepare_info_for_read()
+int Rpl_info_table::do_prepare_info_for_read(const uint nidx)
 {
   if (!field_values)
     return TRUE;
 
-  cursor= 1;
+  cursor= nidx;
 
   return FALSE;
 }
 
-int Rpl_info_table::do_prepare_info_for_write()
+int Rpl_info_table::do_prepare_info_for_write(const uint nidx)
 {
-  return(do_prepare_info_for_read());
+  return(do_prepare_info_for_read(nidx));
 }
 
 bool Rpl_info_table::do_set_info(const int pos, const char *value)
@@ -339,6 +336,13 @@ bool Rpl_info_table::do_set_info(const i
                                         &my_charset_bin));
 }
 
+bool Rpl_info_table::do_set_info(const int pos, const uchar *value,
+                                 const size_t size)
+{
+  return (field_values->value[pos].copy((char *) value, size,
+                                        &my_charset_bin));
+}
+
 bool Rpl_info_table::do_set_info(const int pos, const ulong value)
 {
   return (field_values->value[pos].set_int(value, TRUE,
@@ -379,6 +383,15 @@ bool Rpl_info_table::do_get_info(const i
   return FALSE;
 }
 
+bool Rpl_info_table::do_get_info(const int pos, uchar *value, const size_t size,
+                                 const uchar *default_value __attribute__((unused)))
+{
+  if (field_values->value[pos].length() == size)
+    return (!memcpy((char *) value, (char *)
+            field_values->value[pos].c_ptr_safe(), size));
+  return TRUE;
+}
+
 bool Rpl_info_table::do_get_info(const int pos, ulong *value,
                                  const ulong default_value)
 {

=== modified file 'sql/rpl_info_table.h'
--- a/sql/rpl_info_table.h	2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_table.h	2010-12-28 07:37:37 +0000
@@ -22,7 +22,7 @@
 class Rpl_info_table : public Rpl_info_handler
 {
 public:
-  Rpl_info_table(uint nparam, uint param_field_id, const char* param_schema,
+  Rpl_info_table(uint nparam, const char* param_schema,
                  const char *param_table);
   virtual ~Rpl_info_table();
   /*
@@ -49,11 +49,6 @@ private:
   LEX_STRING str_table;
 
   /*
-    This property indentifies the id/position of the field that is
-    used as primary key.
-  */
-  uint field_idx;
-  /*
     This property represents a description of the repository.
     Speciffically, "schema"."table".
   */
@@ -65,21 +60,26 @@ private:
   */
   Rpl_info_table_access *access;
 
-  int do_init_info();
-  int do_check_info();
-  void do_end_info();
-  int do_flush_info(const bool force);
-  int do_remove_info();
+  int do_init_info(const ulong *uidx, const uint nidx);
+  int do_check_info(const ulong *uidx, const uint nidx);
+  void do_end_info(const ulong *uidx, const uint nidx);
+  int do_flush_info(const ulong *uidx, const uint nidx,
+                    const bool force);
+  int do_remove_info(const ulong *uidx, const uint nidx);
 
-  int do_prepare_info_for_read();
-  int do_prepare_info_for_write();
+  int do_prepare_info_for_read(const uint nidx);
+  int do_prepare_info_for_write(const uint nidx);
   bool do_set_info(const int pos, const char *value);
+  bool do_set_info(const int pos, const uchar *value,
+                   const size_t size);
   bool do_set_info(const int pos, const int value);
   bool do_set_info(const int pos, const ulong value);
   bool do_set_info(const int pos, const float value);
   bool do_set_info(const int pos, const Server_ids *value);
   bool do_get_info(const int pos, char *value, const size_t size,
                    const char *default_value);
+  bool do_get_info(const int pos, uchar *value, const size_t size,
+                   const uchar *default_value);
   bool do_get_info(const int pos, int *value,
                    const int default_value);
   bool do_get_info(const int pos, ulong *value,
@@ -94,5 +94,4 @@ private:
   Rpl_info_table& operator=(const Rpl_info_table& info);
   Rpl_info_table(const Rpl_info_table& info);
 };
-
 #endif /* RPL_INFO_TABLE_H */

=== modified file 'sql/rpl_info_table_access.cc'
--- a/sql/rpl_info_table_access.cc	2010-10-27 11:20:32 +0000
+++ b/sql/rpl_info_table_access.cc	2010-12-28 07:37:37 +0000
@@ -160,8 +160,8 @@ bool Rpl_info_table_access::close_table(
 
   In case search succeeded, the table cursor points to the found row.
 
-  @param[in]      server_id    Server id
-  @param[in]      idx          Index field
+  @param[in]      uidx         Array of fields in pk
+  @param[in]      nidx         Number of fields in pk
   @param[in,out]  field_values The sequence of values
   @param[in,out]  table        Table
 
@@ -170,34 +170,53 @@ bool Rpl_info_table_access::close_table(
     @retval NOT_FOUND The row was not found.
     @retval ERROR     There was a failure.
 */
-enum enum_return_id Rpl_info_table_access::find_info_for_server_id(ulong server_id,
-                                                                   uint idx,
-                                                                   Rpl_info_values *field_values,
-                                                                   TABLE *table)
+enum enum_return_id Rpl_info_table_access::find_info(const ulong *uidx,
+                                                     const uint nidx,
+                                                     Rpl_info_values *field_values,
+                                                     TABLE *table)
 {
   uchar key[MAX_KEY_LENGTH];
-  DBUG_ENTER("Rpl_info_table_access::find_info_for_server_id");
+  DBUG_ENTER("Rpl_info_table_access::find_info");
 
-  field_values->value[idx].set_int(server_id, TRUE, &my_charset_bin);
-
-  if (field_values->value[idx].length() > table->field[idx]->field_length)
+  /* 
+     There is a primary key which is the first key among the
+     set of keys and it is enabled.
+  */
+  if (!(table->s->primary_key == 0 &&
+      table->s->keys_in_use.is_set(table->s->primary_key) &&
+      table->key_info->key_parts == nidx))
     DBUG_RETURN(ERROR_ID);
 
-  table->field[idx]->store(field_values->value[idx].c_ptr_safe(),
-                           field_values->value[idx].length(),
-                           &my_charset_bin);
-
-  if (!(table->field[idx]->flags & PRI_KEY_FLAG) &&
-      table->s->keys_in_use.is_set(0))
-    DBUG_RETURN(ERROR_ID);
+  uint offset_idx= table->s->primary_key;
 
+  for (uint idx= 0; idx < nidx; idx++)
+  {
+    /*
+      Fields that are part of a primary key are contiguous in
+      table's definition. If we want to release this we need
+      to iterate through the keyinfo.
+    */
+    if (!(table->field[idx + offset_idx]->flags & PRI_KEY_FLAG))
+      DBUG_RETURN(ERROR_ID);
+
+    /*
+      The size of the field must be great to store data.
+    */
+    if (field_values->value[idx + offset_idx].length() >
+        table->field[idx + offset_idx]->field_length)
+      DBUG_RETURN(ERROR_ID);
+
+    field_values->value[idx + offset_idx].set_int(uidx[idx], TRUE, &my_charset_bin);
+
+    table->field[idx + offset_idx]->store(field_values->value[idx + offset_idx].c_ptr_safe(),
+                             field_values->value[idx + offset_idx].length(),
+                             &my_charset_bin);
+  }
   key_copy(key, table->record[0], table->key_info, table->key_info->key_length);
 
   if (table->file->ha_index_read_idx_map(table->record[0], 0, key, HA_WHOLE_KEY,
                                          HA_READ_KEY_EXACT))
-  {
     DBUG_RETURN(NOT_FOUND_ID);
-  }
 
   DBUG_RETURN(FOUND_ID);
 }
@@ -227,7 +246,7 @@ bool Rpl_info_table_access::load_info_va
   {
     fields[field_idx]->val_str(&str);
     field_values->value[field_idx].copy(str.c_ptr_safe(), str.length(),
-                                             &my_charset_bin);
+                                        &my_charset_bin);
     field_idx++;
   }
 
@@ -256,6 +275,7 @@ bool Rpl_info_table_access::store_info_v
   while (field_idx < max_num_field)
   {
     fields[field_idx]->set_notnull();
+
     if (fields[field_idx]->store(field_values->value[field_idx].c_ptr_safe(),
                                  field_values->value[field_idx].length(),
                                  &my_charset_bin))
@@ -288,6 +308,7 @@ THD *Rpl_info_table_access::create_thd()
     thd= new THD;
     thd->thread_stack= (char*) &thd;
     thd->store_globals();
+    thd->security_ctx->skip_grants();
   }
   else
     thd= current_thd;

=== modified file 'sql/rpl_info_table_access.h'
--- a/sql/rpl_info_table_access.h	2010-10-25 10:39:01 +0000
+++ b/sql/rpl_info_table_access.h	2010-12-28 07:37:37 +0000
@@ -36,8 +36,8 @@ public:
                   TABLE** table, Open_tables_backup* backup);
   bool close_table(THD* thd, TABLE* table, Open_tables_backup* backup,
                    bool error);
-  enum enum_return_id find_info_for_server_id(ulong server_id, uint idx, Rpl_info_values *,
-                                              TABLE *table);
+  enum enum_return_id find_info(const ulong *uidx, const uint nidx,
+                                Rpl_info_values *, TABLE *table);
   bool load_info_values(uint max_num_field, Field **fields,
                         Rpl_info_values *field_values);
   bool store_info_values(uint max_num_field, Field **fields,

=== modified file 'sql/rpl_mi.cc'
--- a/sql/rpl_mi.cc	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_mi.cc	2010-12-28 07:37:37 +0000
@@ -95,7 +95,8 @@ Master_info::Master_info(
    ssl(0), ssl_verify_server_cert(0),
    port(MYSQL_PORT), connect_retry(DEFAULT_CONNECT_RETRY),
    clock_diff_with_master(0), heartbeat_period(0),
-   received_heartbeats(0), last_heartbeat(0), master_id(0),
+   received_heartbeats(0), last_heartbeat(0),
+   ignore_server_ids(0), master_id(0),
    checksum_alg_before_fd(BINLOG_CHECKSUM_ALG_UNDEF),
    retry_count(master_retry_count)
 {
@@ -103,12 +104,12 @@ Master_info::Master_info(
   ssl_ca[0]= 0; ssl_capath[0]= 0; ssl_cert[0]= 0;
   ssl_cipher[0]= 0; ssl_key[0]= 0;
   master_uuid[0]= 0;
-  ignore_server_ids= new Server_ids();
 }
 
 Master_info::~Master_info()
 {
-  delete ignore_server_ids;
+  if (ignore_server_ids)
+    delete ignore_server_ids;
 }
 
 /**
@@ -179,7 +180,7 @@ void Master_info::end_info()
   if (!inited)
     DBUG_VOID_RETURN;
 
-  handler->end_info();
+  handler->end_info(uidx, nidx);
 
   inited = 0;
 
@@ -228,7 +229,10 @@ int Master_info::flush_info(bool force)
   */
   handler->set_sync_period(sync_masterinfo_period);
 
-  if (write_info(handler, force))
+  if (write_info(handler))
+    goto err;
+
+  if (handler->flush_info(uidx, nidx, force))
     goto err;
 
   DBUG_RETURN(0);
@@ -243,21 +247,25 @@ void Master_info::set_relay_log_info(Rel
   rli= info;
 }
 
+/**
+  The init_info() is used to either create or read information
+  from the repository, in order to initialize the Master_info.
+*/
 int Master_info::init_info()
 {
+  int necessary_to_configure= 0;
   DBUG_ENTER("Master_info::init_info");
 
   if (inited)
     DBUG_RETURN(0);
 
-  /*
-    The init_info() is used to either create or read information
-    from the repository, in order to initialize the Master_info.
-  */
+  if (!(ignore_server_ids= new Server_ids()))
+    goto err;
+
   mysql= 0; file_id= 1;
-  int necessary_to_configure= check_info();
+  necessary_to_configure= check_info();
   
-  if (handler->init_info())
+  if (handler->init_info(uidx, nidx))
     goto err;
 
   if (necessary_to_configure)
@@ -314,8 +322,9 @@ bool Master_info::read_info(Rpl_info_han
      is this.
   */
 
-  if (from->prepare_info_for_read() || 
-      from->get_info(master_log_name, sizeof(master_log_name), ""))
+  if (from->prepare_info_for_read(nidx) || 
+      from->get_info(master_log_name, (size_t) sizeof(master_log_name),
+                     (char *) ""))
     DBUG_RETURN(TRUE);
 
   lines= strtoul(master_log_name, &first_non_digit, 10);
@@ -324,20 +333,21 @@ bool Master_info::read_info(Rpl_info_han
       *first_non_digit=='\0' && lines >= LINES_IN_MASTER_INFO_WITH_SSL)
   {
     /* Seems to be new format => read master log name */
-    if (from->get_info(master_log_name,  sizeof(master_log_name), ""))
+    if (from->get_info(master_log_name, (size_t) sizeof(master_log_name),
+                       (char *) ""))
       DBUG_RETURN(TRUE);
   }
   else 
     lines= 7;
 
   if (from->get_info(&temp_master_log_pos,
-                        (ulong) BIN_LOG_HEADER_SIZE) ||
-      from->get_info(host, sizeof(host), 0) ||
-      from->get_info(user, sizeof(user), "test") ||
-      from->get_info(password, sizeof(password), 0) ||
+                     (ulong) BIN_LOG_HEADER_SIZE) ||
+      from->get_info(host, (size_t) sizeof(host), (char *) 0) ||
+      from->get_info(user, (size_t) sizeof(user), (char *) "test") ||
+      from->get_info(password, (size_t) sizeof(password), (char *) 0) ||
       from->get_info((int *) &port, (int) MYSQL_PORT) ||
       from->get_info((int *) &connect_retry,
-                        (int) DEFAULT_CONNECT_RETRY))
+                     (int) DEFAULT_CONNECT_RETRY))
       DBUG_RETURN(TRUE);
 
   /*
@@ -349,11 +359,11 @@ bool Master_info::read_info(Rpl_info_han
   if (lines >= LINES_IN_MASTER_INFO_WITH_SSL)
   {
     if (from->get_info(&temp_ssl, 0) ||
-        from->get_info(ssl_ca, sizeof(ssl_ca), 0) ||
-        from->get_info(ssl_capath, sizeof(ssl_capath), 0) ||
-        from->get_info(ssl_cert, sizeof(ssl_cert), 0) ||
-        from->get_info(ssl_cipher, sizeof(ssl_cipher), 0) ||
-        from->get_info(ssl_key, sizeof(ssl_key), 0))
+        from->get_info(ssl_ca, (size_t) sizeof(ssl_ca), (char *) 0) ||
+        from->get_info(ssl_capath, (size_t) sizeof(ssl_capath), (char *) 0) ||
+        from->get_info(ssl_cert, (size_t) sizeof(ssl_cert), (char *) 0) ||
+        from->get_info(ssl_cipher, (size_t) sizeof(ssl_cipher), (char *) 0) ||
+        from->get_info(ssl_key, (size_t) sizeof(ssl_key), (char *) 0))
       DBUG_RETURN(TRUE);
   }
 
@@ -382,7 +392,7 @@ bool Master_info::read_info(Rpl_info_han
   */
   if (lines >= LINE_FOR_MASTER_BIND)
   {
-    if (from->get_info(bind_addr, sizeof(bind_addr), ""))
+    if (from->get_info(bind_addr, (size_t) sizeof(bind_addr), (char *) ""))
       DBUG_RETURN(TRUE);
   }
 
@@ -399,7 +409,7 @@ bool Master_info::read_info(Rpl_info_han
   /* Starting from 5.5 the master_uuid may be in the repository. */
   if (lines >= LINE_FOR_MASTER_UUID)
   {
-    if (from->get_info(master_uuid, sizeof(master_uuid), 0))
+    if (from->get_info(master_uuid, (size_t) sizeof(master_uuid), (char *) 0))
       DBUG_RETURN(TRUE);
   }
 
@@ -414,6 +424,7 @@ bool Master_info::read_info(Rpl_info_han
   ssl= (my_bool) test(temp_ssl);
   ssl_verify_server_cert= (my_bool) test(temp_ssl_verify_server_cert);
   master_log_pos= (my_off_t) temp_master_log_pos;
+
 #ifndef HAVE_OPENSSL
   if (ssl)
     sql_print_warning("SSL information in the master info file "
@@ -424,7 +435,7 @@ bool Master_info::read_info(Rpl_info_han
   DBUG_RETURN(FALSE);
 }
 
-bool Master_info::write_info(Rpl_info_handler *to, bool force)
+bool Master_info::write_info(Rpl_info_handler *to)
 {
   DBUG_ENTER("Master_info::write_info");
 
@@ -436,10 +447,10 @@ bool Master_info::write_info(Rpl_info_ha
      of file we don't care about this garbage.
   */
 
-  if (to->prepare_info_for_write() ||
+  if (to->prepare_info_for_write(nidx) ||
       to->set_info((int) LINES_IN_MASTER_INFO) ||
       to->set_info(master_log_name) ||
-      to->set_info((ulong)master_log_pos) ||
+      to->set_info((ulong) master_log_pos) ||
       to->set_info(host) ||
       to->set_info(user) ||
       to->set_info(password) ||
@@ -451,7 +462,7 @@ bool Master_info::write_info(Rpl_info_ha
       to->set_info(ssl_cert) ||
       to->set_info(ssl_cipher) ||
       to->set_info(ssl_key) ||
-      to->set_info(ssl_verify_server_cert) ||
+      to->set_info((int) ssl_verify_server_cert) ||
       to->set_info(heartbeat_period) ||
       to->set_info(bind_addr) ||
       to->set_info(ignore_server_ids) ||
@@ -459,9 +470,6 @@ bool Master_info::write_info(Rpl_info_ha
       to->set_info(retry_count))
     DBUG_RETURN(TRUE);
 
-  if (to->flush_info(force))
-    DBUG_RETURN(TRUE);
-
   DBUG_RETURN(FALSE);
 }
 #endif /* HAVE_REPLICATION */

=== modified file 'sql/rpl_mi.h'
--- a/sql/rpl_mi.h	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_mi.h	2010-12-28 07:37:37 +0000
@@ -144,7 +144,7 @@ public:
 
 private:
   bool read_info(Rpl_info_handler *from);
-  bool write_info(Rpl_info_handler *to, bool force);
+  bool write_info(Rpl_info_handler *to);
 
   Master_info& operator=(const Master_info& info);
   Master_info(const Master_info& info);

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_rli.cc	2010-12-28 07:37:37 +0000
@@ -1183,7 +1183,7 @@ a file name for --relay-log-index option
     the handler->init_info().
   */
   int necessary_to_configure= check_info();
-  if ((error= handler->init_info()))
+  if ((error= handler->init_info(uidx, nidx)))
   {
     msg= "Error reading relay log configuration";
     error= 1;
@@ -1273,7 +1273,7 @@ void Relay_log_info::end_info()
   if (!inited)
     DBUG_VOID_RETURN;
 
-  handler->end_info();
+  handler->end_info(uidx, nidx);
 
   if (cur_log_fd >= 0)
   {
@@ -1378,7 +1378,10 @@ int Relay_log_info::flush_info(bool forc
   */
   handler->set_sync_period(sync_relayloginfo_period);
 
-  if (write_info(handler, force))
+  if (write_info(handler))
+    goto err;
+
+  if (handler->flush_info(uidx, nidx, force))
     goto err;
 
   DBUG_RETURN(0);
@@ -1441,8 +1444,9 @@ bool Relay_log_info::read_info(Rpl_info_
     it is line count and not binlog name (new format) it will be
     overwritten by the second row later.
   */
-  if (from->prepare_info_for_read() ||
-      from->get_info(group_relay_log_name, sizeof(group_relay_log_name), ""))
+  if (from->prepare_info_for_read(nidx) ||
+      from->get_info(group_relay_log_name, (size_t) sizeof(group_relay_log_name),
+                     (char *) ""))
     DBUG_RETURN(TRUE);
 
   lines= strtoul(group_relay_log_name, &first_non_digit, 10);
@@ -1451,23 +1455,24 @@ bool Relay_log_info::read_info(Rpl_info_
       *first_non_digit=='\0' && lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY)
   {
     /* Seems to be new format => read group relay log name */
-    if (from->get_info(group_relay_log_name,  sizeof(group_relay_log_name), ""))
+    if (from->get_info(group_relay_log_name, (size_t) sizeof(group_relay_log_name),
+                       (char *) ""))
       DBUG_RETURN(TRUE);
   }
   else
      DBUG_PRINT("info", ("relay_log_info file is in old format."));
 
   if (from->get_info((ulong *) &temp_group_relay_log_pos,
-                        (ulong) BIN_LOG_HEADER_SIZE) ||
+                     (ulong) BIN_LOG_HEADER_SIZE) ||
       from->get_info(group_master_log_name,
-                        sizeof(group_relay_log_name), "") ||
+                     (size_t) sizeof(group_relay_log_name), (char *) "") ||
       from->get_info((ulong *) &temp_group_master_log_pos,
-                        (ulong) 0))
+                     (ulong) 0))
     DBUG_RETURN(TRUE);
 
   if (lines >= LINES_IN_RELAY_LOG_INFO_WITH_DELAY)
   {
-    if (from->get_info((int *) &temp_sql_delay,(int) 0))
+    if (from->get_info((int *) &temp_sql_delay, (int) 0))
       DBUG_RETURN(TRUE);
   }
 
@@ -1478,7 +1483,7 @@ bool Relay_log_info::read_info(Rpl_info_
   DBUG_RETURN(FALSE);
 }
 
-bool Relay_log_info::write_info(Rpl_info_handler *to, bool force)
+bool Relay_log_info::write_info(Rpl_info_handler *to)
 {
   DBUG_ENTER("Relay_log_info::write_info");
 
@@ -1488,7 +1493,7 @@ bool Relay_log_info::write_info(Rpl_info
   */
   //DBUG_ASSERT(!belongs_to_client());
 
-  if (to->prepare_info_for_write() ||
+  if (to->prepare_info_for_write(nidx) ||
       to->set_info((int) LINES_IN_RELAY_LOG_INFO_WITH_DELAY) ||
       to->set_info(group_relay_log_name) ||
       to->set_info((ulong) group_relay_log_pos) ||
@@ -1497,8 +1502,5 @@ bool Relay_log_info::write_info(Rpl_info
       to->set_info((int) sql_delay))
     DBUG_RETURN(TRUE);
 
-  if (to->flush_info(force))
-    DBUG_RETURN(TRUE);
-
   DBUG_RETURN(FALSE);
 }

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2010-12-21 09:33:41 +0000
+++ b/sql/rpl_rli.h	2010-12-28 07:37:37 +0000
@@ -617,7 +617,7 @@ private:
   static const int LINES_IN_RELAY_LOG_INFO_WITH_DELAY= 5;
 
   bool read_info(Rpl_info_handler *from);
-  bool write_info(Rpl_info_handler *to, bool force);
+  bool write_info(Rpl_info_handler *to);
 
   Relay_log_info& operator=(const Relay_log_info& info);
   Relay_log_info(const Relay_log_info& info);

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2010-12-10 16:55:50 +0000
+++ b/sql/rpl_slave.cc	2010-12-28 07:37:37 +0000
@@ -404,6 +404,11 @@ int init_info(Master_info* mi, bool igno
     thread is being started and the relay log info if either the
     SLAVE_SQL thread is being started or was not initialized as it is
     required by the SLAVE_IO thread.
+
+    In a multi-master envinroment, we need to make sure that both master
+    info and relay log info are prepared to handle events from all
+    masters. In such case, we need to execute the code below for each
+    master. /Alfranio
   */
   necessary_to_configure= mi->check_info();
   if (!(ignore_if_no_info && necessary_to_configure))
@@ -432,8 +437,13 @@ void end_info(Master_info* mi)
   DBUG_ASSERT(mi != NULL && mi->rli != NULL);
 
   /*
-    The previous implementation was not acquiring locks.
-    We do the same here. However, this is quite strange.
+    The previous implementation was not acquiring locks.  We do the same here.
+    However, this is quite strange.
+
+    In a multi-master envinroment, we need to make sure that both master
+    info and relay log info are prepared to handle events from all
+    masters. In such case, we need to execute the code below for each
+    master. /Alfranio
   */
   mi->end_info();
   mi->rli->end_info();
@@ -460,6 +470,12 @@ int remove_info(Master_info* mi)
   mi->rli->clear_until_condition();
   mi->rli->clear_sql_delay();
 
+  /*
+    In a multi-master envinroment, we need to make sure that both master
+    info and relay log info are prepared to handle events from all
+    masters. In such case, we need to execute the code below for each
+    master. /Alfranio
+  */
   mi->end_info();
   mi->rli->end_info();
 
@@ -497,6 +513,12 @@ int flush_master_info(Master_info* mi, b
 
   mysql_mutex_lock(log_lock);
 
+  /*
+    In a multi-master envinroment, we need to make sure that both master
+    info and relay log info are prepared to handle events from all
+    masters. In such case, we need to execute the code below for each
+    master. /Alfranio
+  */
   int err=  (mi->rli->flush_current_log() ||  mi->flush_info(force));
 
   mysql_mutex_unlock(log_lock);
@@ -647,6 +669,11 @@ int terminate_slave_threads(Master_info*
 
     /*
       Flushes the master info regardles of the sync_master_info option.
+
+      In a multi-master envinroment, we need to make sure that both master
+      info and relay log info are prepared to handle events from all
+      masters. In such case, we need to execute the code below for each
+      master. /Alfranio
     */
     if (mi->flush_info(TRUE))
       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
@@ -679,6 +706,11 @@ int terminate_slave_threads(Master_info*
 
     /*
       Flushes the relay log info regardles of the sync_relay_log_info option.
+
+      In a multi-master envinroment, we need to make sure that both master
+      info and relay log info are prepared to handle events from all
+      masters. In such case, we need to execute the code below for each
+      master. /Alfranio
     */
     if (mi->rli->flush_info(TRUE))
       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
@@ -5253,6 +5285,12 @@ static Log_event* next_event(Relay_log_i
         }
         rli->set_event_relay_log_pos(BIN_LOG_HEADER_SIZE);
         rli->set_event_relay_log_name(rli->linfo.log_file_name);
+        /*
+          In a multi-master envinroment, we need to make sure that both master
+          info and relay log info are prepared to handle events from all
+          masters. In such case, we need to execute the code below for each
+          master. /Alfranio
+        */
         rli->flush_info();
       }
 
@@ -6116,6 +6154,11 @@ bool change_master(THD* thd, Master_info
     before START SLAVE, then old will remain in relay-log.info, and will be the
     in-memory value at restart (thus causing errors, as the old relay log does
     not exist anymore).
+
+    In a multi-master envinroment, we need to make sure that both master
+    info and relay log info are prepared to handle events from all
+    masters. In such case, we need to execute the code below for each
+    master. /Alfranio
   */
   ret= mi->rli->flush_info(TRUE);
   mysql_cond_broadcast(&mi->data_cond);

=== modified file 'sql/sys_vars.cc'
--- a/sql/sys_vars.cc	2010-12-20 13:26:51 +0000
+++ b/sql/sys_vars.cc	2010-12-28 07:37:37 +0000
@@ -433,7 +433,11 @@ static Sys_var_mybool Sys_binlog_direct(
 
 static const char *repository_names[]=
 {
-  "FILE", "TABLE", 0
+  "FILE", "TABLE",
+#ifndef DBUG_OFF
+  "DUMMY",
+#endif
+  0
 };
 
 ulong opt_mi_repository_id;


Attachment: [text/bzr-bundle] bzr/alfranio.correia@oracle.com-20101228073737-b1ofzjsk6ukklxgy.bundle
Thread
bzr commit into mysql-trunk-bugfixing branch (alfranio.correia:3471) WL#5599Alfranio Correia28 Dec