List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:November 30 2010 2:39pm
Subject:bzr commit into mysql-next-mr.crash-safe branch (andrei.elkin:3222) WL#5569
WL#5599
View as plain text  
#At file:///home/andrei/MySQL/BZR/2a-23May/WL/mysql-next-mr-wl5569/ based on revid:andrei.elkin@stripped

 3222 Andrei Elkin	2010-11-30 [merge]
      merging from from wl#5569 repo containing wl#5599 integration

    modified:
      sql/binlog.cc
      sql/log_event.cc
      sql/rpl_constants.h
      sql/rpl_info.cc
      sql/rpl_info.h
      sql/rpl_info_dummy.cc
      sql/rpl_info_dummy.h
      sql/rpl_info_factory.cc
      sql/rpl_info_factory.h
      sql/rpl_mi.cc
      sql/rpl_mi.h
      sql/rpl_rli.cc
      sql/rpl_rli.h
      sql/rpl_rli_pdb.cc
      sql/rpl_rli_pdb.h
      sql/rpl_slave.cc
=== modified file 'sql/binlog.cc'
--- a/sql/binlog.cc	2010-11-11 11:53:01 +0000
+++ b/sql/binlog.cc	2010-11-30 02:08:01 +0000
@@ -2140,8 +2140,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay
   }
 
   /* Store where we are in the new file for the execution thread */
-  /* Andrei needs to guarantee that there is no worker using the current relay log. */
-  rli->flush_info(key_info_idx, key_info_size, TRUE);
+  rli->flush_info(TRUE);
 
   DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_ABORT(););
 

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-11-30 14:02:15 +0000
+++ b/sql/log_event.cc	2010-11-30 14:39:40 +0000
@@ -2665,6 +2665,8 @@ int slave_worker_exec_job(Slave_worker *
   if (ev->starts_group())
   {
     w->curr_group_seen_begin= TRUE; // The current group is started with B-event
+    // ANDREI ----
+    // w->configure_position(rli);
   } 
   else
   {
@@ -2698,6 +2700,7 @@ int slave_worker_exec_job(Slave_worker *
   if (ev->ends_group() || !w->curr_group_seen_begin)
   {
     w->slave_worker_ends_group(ev->mts_group_cnt, error); /* last done sets post exec */
+    w->checkpoint(w->w_rli);
   }
 
   mysql_mutex_lock(&w->jobs_lock);
@@ -4209,8 +4212,7 @@ int Query_log_event::do_update_pos(Relay
   DBUG_EXECUTE_IF("crash_after_commit_and_update_pos",
        if (!strcmp("COMMIT", query))
        {
-         /* Alfranio needs to update the coordinator and workers. */
-         rli->flush_info(key_info_idx, key_info_size, TRUE);
+         rli->flush_info(TRUE);
          DBUG_ABORT();
        }
   );
@@ -5860,11 +5862,8 @@ int Rotate_log_event::do_update_pos(Rela
                         rli->get_group_master_log_name(),
                         (ulong) rli->get_group_master_log_pos()));
     mysql_mutex_unlock(&rli->data_lock);
-    /*
-       Andrei to investigate if it is necessary to guarantee that
-       this done in sequential mode.
-    */
-    rli->flush_info(key_info_idx, key_info_size, TRUE);
+    
+    rli->flush_info(TRUE);
     
     /*
       Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
@@ -6272,8 +6271,7 @@ int Xid_log_event::do_apply_event(Relay_
       rli_ptr->set_group_master_log_pos(log_pos);
     }
 
-    /* Alfranio needs to update the coordinator and workers. */ 
-    if ((error= rli_ptr->flush_info(key_info_idx, key_info_size, TRUE)))
+    if ((error= rli_ptr->flush_info(TRUE)))
       goto err;
   }
 
@@ -6944,11 +6942,7 @@ int Stop_log_event::do_update_pos(Relay_
   else
   {
     rli->inc_group_relay_log_pos(0);
-    /*
-       Andrei to investigate if it is necessary to guarantee that
-       this done in sequential mode.
-    */
-    rli->flush_info(key_info_idx, key_info_size, TRUE);
+    rli->flush_info(TRUE);
   }
   return 0;
 }

=== modified file 'sql/rpl_constants.h'
--- a/sql/rpl_constants.h	2010-11-11 11:53:01 +0000
+++ b/sql/rpl_constants.h	2010-11-30 02:08:01 +0000
@@ -15,14 +15,4 @@ enum Incident {
   INCIDENT_COUNT
 };
 
-#define NUMBER_OF_FIELDS_TO_IDENTIFY_MASTER 1
-#define NUMBER_OF_MASTERS 1
-/*
-  We assume here a single master and uses slave's id to identify
-  entries in a system table, if there is any. This code needs to
-  be changed when we start handling multi-master replication.
-*/
-extern ulong key_info_idx[];
-extern uint key_info_size;
-
 #endif /* RPL_CONSTANTS_H */

=== modified file 'sql/rpl_info.cc'
--- a/sql/rpl_info.cc	2010-11-23 09:03:37 +0000
+++ b/sql/rpl_info.cc	2010-11-30 02:08:01 +0000
@@ -17,20 +17,10 @@
 #include <sql_priv.h>
 #include "rpl_info.h"
 
-/*
-  We assume here a single master and uses slave's id to identify
-  entries in a system table, if there is any. This code needs to
-  be changed when we start handling multi-master replication.
-
-  Most likely, server_id is zero when key_info_idx is defined.
-  For that reason, it is reset in Rpl_info_factory.
-*/
-ulong key_info_idx[]= { server_id };
-uint key_info_size= NUMBER_OF_FIELDS_TO_IDENTIFY_MASTER;
-
 Rpl_info::Rpl_info(const char* type)
   : Slave_reporting_capability(type),
-  info_thd(0), inited(0), abort_slave(0),
+  info_thd(0), uidx(0), nidx(0),
+  inited(0), abort_slave(0),
   slave_running(0), slave_run_id(0),
   handler(0)
 {
@@ -39,6 +29,9 @@ Rpl_info::Rpl_info(const char* type)
 
 Rpl_info::~Rpl_info()
 {
+  if (uidx)
+    delete []uidx;
+
   if (handler)
     delete handler;
 }

=== modified file 'sql/rpl_info.h'
--- a/sql/rpl_info.h	2010-11-23 09:03:37 +0000
+++ b/sql/rpl_info.h	2010-11-30 02:08:01 +0000
@@ -27,6 +27,10 @@ class Rpl_info : public Slave_reporting_
 public:
   THD *info_thd;
 
+  ulong *uidx;
+
+  uint nidx;
+
   bool inited;
   volatile bool abort_slave;
   volatile uint slave_running;
@@ -35,12 +39,12 @@ public:
   Rpl_info(const char *type);
   virtual ~Rpl_info();
 
-  int check_info(const ulong *uidx, const uint nidx)
+  int check_info()
   {
     return (handler->check_info(uidx, nidx));
   }
 
-  int remove_info(const ulong *uidx, const uint nidx)
+  int remove_info()
   {
     return (handler->remove_info(uidx, nidx));
   }
@@ -50,6 +54,12 @@ public:
     return (handler->is_transactional());
   }
 
+  void set_idx_info(ulong *param_uidx, uint param_nidx)
+  {
+    uidx= param_uidx;
+    nidx= param_nidx;
+  }
+
   char *get_description_info()
   {
     return (handler->get_description_info());

=== modified file 'sql/rpl_info_dummy.cc'
--- a/sql/rpl_info_dummy.cc	2010-11-23 09:03:37 +0000
+++ b/sql/rpl_info_dummy.cc	2010-11-30 02:08:01 +0000
@@ -16,8 +16,8 @@
 #include <my_global.h>
 #include "rpl_info_dummy.h"
 
-Rpl_info_dummy::Rpl_info_dummy(bool param_abort)
-  :Rpl_info_handler(0),  abort(param_abort)
+Rpl_info_dummy::Rpl_info_dummy()
+  :Rpl_info_handler(0)
 {
 }
 

=== modified file 'sql/rpl_info_dummy.h'
--- a/sql/rpl_info_dummy.h	2010-11-23 09:03:37 +0000
+++ b/sql/rpl_info_dummy.h	2010-11-30 02:08:01 +0000
@@ -30,7 +30,7 @@
 class Rpl_info_dummy : public Rpl_info_handler
 {
 public:
-  Rpl_info_dummy(bool param_abort);
+  Rpl_info_dummy();
   virtual ~Rpl_info_dummy() { };
 
 private:
@@ -61,7 +61,7 @@ private:
   char* do_get_description_info();
   bool do_is_transactional();
 
-  bool abort;
+  static const bool abort= FALSE;
 
   Rpl_info_dummy& operator=(const Rpl_info_dummy& info);
   Rpl_info_dummy(const Rpl_info_dummy& info);

=== modified file 'sql/rpl_info_factory.cc'
--- a/sql/rpl_info_factory.cc	2010-11-23 09:03:37 +0000
+++ b/sql/rpl_info_factory.cc	2010-11-30 02:08:01 +0000
@@ -25,6 +25,10 @@
 #define master_info_engine NULL
 #define relay_log_info_engine NULL
 
+#define NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR 1
+#define NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER 2
+
+
 /**
   Creates both a Master info and a Relay log info repository whose types are
   defined as parameters.
@@ -82,6 +86,7 @@ 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";
 
@@ -91,35 +96,50 @@ Master_info *Rpl_info_factory::create_mi
       !(mi->registered_mutexes))
     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(),
+  if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR]))
+     goto err;
+  key_info_idx[0]= server_id;
+  mi->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR);
+
+  DBUG_ASSERT(mi_option == MI_REPOSITORY_FILE ||
+              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;
+      goto err;
 
-  if (!(mi_table= new Rpl_info_table(mi->get_number_info_mi_fields() + 1,
+    if (!(mi_table= new Rpl_info_table(mi->get_number_info_mi_fields() + 1,
                                      MI_SCHEMA, MI_TABLE)))
-    goto err;
-
-  DBUG_ASSERT(mi_option == MI_REPOSITORY_FILE ||
-              mi_option == MI_REPOSITORY_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 and correctly set the key_info_idx. /Alfranio
-  */
-  if (decide_repository(mi, key_info_idx, key_info_size, &mi_table, &mi_file,
+    /*
+      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 and correctly set the key_info_idx. /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))
+    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 (Rpl_info_factory::create_info_dummy(mi))
     goto err;
 
   DBUG_RETURN(mi);
@@ -127,6 +147,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)
   {
     /*
@@ -161,6 +186,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";
 
@@ -170,36 +196,50 @@ Relay_log_info *Rpl_info_factory::create
       !(rli->registered_mutexes))
     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_SCHEMA, RLI_TABLE)))
-    goto err;
+  if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR]))
+     goto err;
+  key_info_idx[0]= server_id;
+  rli->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_COORDINATOR);
 
   DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE ||
-              rli_option == RLI_REPOSITORY_TABLE);
+              rli_option == RLI_REPOSITORY_TABLE ||
+              rli_option == RLI_REPOSITORY_DUMMY);
 
-  /*
-    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 and correctly set the key_info_idx. /Alfranio
-  */
-  if (decide_repository(rli, key_info_idx, key_info_size,
-                        &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_option == RLI_REPOSITORY_TABLE) &&
-      change_engine(static_cast<Rpl_info_table *>(rli_table),
-                    relay_log_info_engine, &msg))
+    if (!(rli_table= new Rpl_info_table(rli->get_number_info_rli_fields() + 1,
+                                        RLI_SCHEMA, RLI_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 and correctly set the key_info_idx. /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))
     goto err;
 
   DBUG_RETURN(rli);
@@ -207,6 +247,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 +303,6 @@ err:
   @retval TRUE  Failure
 */
 bool Rpl_info_factory::decide_repository(Rpl_info *info,
-                                         ulong *uidx, uint nidx,
                                          Rpl_info_table **table,
                                          Rpl_info_file **file, bool is_table,
                                          const char **msg)
@@ -267,8 +311,8 @@ bool Rpl_info_factory::decide_repository
   DBUG_ENTER("Rpl_info_factory::decide_repository");
  
   bool error= TRUE;
-  bool is_t= !((*table)->check_info(uidx, nidx));
-  bool is_f= !((*file)->check_info(uidx, nidx));
+  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)
   {
@@ -282,7 +326,8 @@ bool Rpl_info_factory::decide_repository
   {
     if (!is_t && is_f)
     {
-      if ((*table)->init_info(uidx, nidx) || (*file)->init_info(uidx, nidx))
+      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;
@@ -294,8 +339,9 @@ bool Rpl_info_factory::decide_repository
         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) || (*table)->flush_info(uidx, nidx, TRUE)
-          || (*file)->remove_info(uidx, nidx))
+      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;
@@ -310,7 +356,8 @@ bool Rpl_info_factory::decide_repository
   {
     if (is_t && !is_f)
     {
-      if ((*table)->init_info(uidx, nidx) || (*file)->init_info(uidx, nidx))
+      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;
@@ -325,8 +372,9 @@ bool Rpl_info_factory::decide_repository
         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) || (*file)->flush_info(uidx, nidx, TRUE)
-          || (*table)->remove_info(uidx, nidx))
+      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;
@@ -355,7 +403,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))
   {
@@ -374,8 +422,8 @@ Slave_worker *Rpl_info_factory::create_w
   char info_name[FN_REFLEN];
   Rpl_info_file*  w_file= NULL;
   Rpl_info_table* w_table= NULL;
+  ulong *key_info_idx= NULL;
   Slave_worker *worker= NULL;
-  ulong idx[]= {server_id, worker_id};
   
   const char *msg= "Failed to allocate memory for the Slave worker info "
                    "structure";
@@ -390,7 +438,18 @@ Slave_worker *Rpl_info_factory::create_w
   if (!(worker= new Slave_worker(info_name)))
     goto err;
 
-  if (rli)
+  if (!(key_info_idx= new ulong[NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER]))
+     goto err;
+  key_info_idx[0]= server_id;
+  key_info_idx[1]= worker_id;
+  worker->set_idx_info(key_info_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER);
+
+  DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE ||
+              rli_option == RLI_REPOSITORY_TABLE ||
+              rli_option == RLI_REPOSITORY_DUMMY);
+
+  if (rli_option == RLI_REPOSITORY_FILE ||
+      rli_option == RLI_REPOSITORY_TABLE)
   {
     /*
       Now we instantiate all info repos and later decide which one to take,
@@ -405,15 +464,12 @@ Slave_worker *Rpl_info_factory::create_w
                                       WORKER_SCHEMA, WORKER_TABLE)))
       goto err;
 
-    DBUG_ASSERT(rli_option == RLI_REPOSITORY_FILE ||
-                rli_option == RLI_REPOSITORY_TABLE);
-
     /*
      Check if this is conceptually right and what happens in case of
      partial failures. Problems will not happen if we decide to use
      only TABLES as repositories. /Alfranio
     */
-    if (decide_repository(worker, idx, sizeof(idx), &w_table, &w_file,
+    if (decide_repository(worker, &w_table, &w_file,
                           rli_option == MI_REPOSITORY_TABLE, &msg))
       goto err;
 
@@ -421,13 +477,23 @@ Slave_worker *Rpl_info_factory::create_w
          change_engine(static_cast<Rpl_info_table *>(w_table),
                        relay_log_info_engine, &msg))
       goto err;
+
+    DBUG_RETURN(worker);
   }
 
+  if (Rpl_info_factory::create_info_dummy(rli))
+    goto err;
+
   DBUG_RETURN(worker);
 
 err:
   if (w_file) delete w_file;
   if (w_table) delete w_table;
+  if (key_info_idx)
+  {
+    delete []key_info_idx;
+    worker->set_idx_info(NULL, 0);
+  }
   if (worker)
   {
     /*
@@ -440,3 +506,17 @@ err:
   sql_print_error("%s", msg);
   DBUG_RETURN(NULL);
 }
+
+bool Rpl_info_factory::create_info_dummy(Rpl_info *rpl)
+{
+  DBUG_ENTER("Rpl_info_factory::create_info_dummy");
+
+  Rpl_info_dummy* rpl_dummy= NULL;
+
+  if (!(rpl_dummy= new Rpl_info_dummy()))
+    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-11-11 11:53:01 +0000
+++ b/sql/rpl_info_factory.h	2010-11-30 02:08:01 +0000
@@ -22,19 +22,22 @@
 #include "rpl_rli_pdb.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;
 
@@ -58,11 +61,11 @@ class Rpl_info_factory
   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,
-                                ulong *uidx, uint nidx,
                                 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);
 };
 #endif

=== modified file 'sql/rpl_mi.cc'
--- a/sql/rpl_mi.cc	2010-11-23 09:03:37 +0000
+++ b/sql/rpl_mi.cc	2010-11-30 02:08:01 +0000
@@ -156,7 +156,7 @@ void Master_info::init_master_log_pos()
   DBUG_VOID_RETURN;
 }
 
-void Master_info::end_info(ulong *uidx, uint nidx)
+void Master_info::end_info()
 {
   DBUG_ENTER("Master_info::end_info");
 
@@ -199,7 +199,7 @@ void Master_info::end_info(ulong *uidx, 
   @todo Change the log file information to a binary format to avoid
   calling longlong2str.
 */
-int Master_info::flush_info(ulong *uidx, uint nidx, bool force)
+int Master_info::flush_info(bool force)
 {
   DBUG_ENTER("Master_info::flush_info");
   DBUG_PRINT("enter",("master_pos: %lu", (ulong) master_log_pos));
@@ -230,7 +230,7 @@ void Master_info::set_relay_log_info(Rel
   rli= info;
 }
 
-int Master_info::init_info(ulong *uidx, uint nidx)
+int Master_info::init_info()
 {
   DBUG_ENTER("Master_info::init_info");
 
@@ -242,7 +242,7 @@ int Master_info::init_info(ulong *uidx, 
     from the repository, in order to initialize the Master_info.
   */
   mysql= 0; file_id= 1;
-  int necessary_to_configure= check_info(uidx, nidx);
+  int necessary_to_configure= check_info();
   
   if (handler->init_info(uidx, nidx))
     goto err;
@@ -256,7 +256,7 @@ int Master_info::init_info(ulong *uidx, 
     goto err;
 
 end:
-  if (flush_info(uidx, nidx, TRUE))
+  if (flush_info(TRUE))
     goto err;
 
   inited= 1;

=== modified file 'sql/rpl_mi.h'
--- a/sql/rpl_mi.h	2010-11-23 09:03:37 +0000
+++ b/sql/rpl_mi.h	2010-11-30 02:08:01 +0000
@@ -97,9 +97,9 @@ class Master_info : public Rpl_info_coor
   ulong retry_count;
   char master_uuid[UUID_LENGTH+1];
 
-  int init_info(ulong *uidx, uint nidx);
-  void end_info(ulong *uidx, uint nidx);
-  int flush_info(ulong *uidx, uint nidx, bool force= FALSE);
+  int init_info();
+  void end_info();
+  int flush_info(bool force= FALSE);
   void set_relay_log_info(Relay_log_info *info);
 
   bool shall_ignore_server_id(ulong s_id);

=== modified file 'sql/rpl_rli.cc'
--- a/sql/rpl_rli.cc	2010-11-30 14:02:15 +0000
+++ b/sql/rpl_rli.cc	2010-11-30 14:39:40 +0000
@@ -1016,17 +1016,7 @@ void Relay_log_info::stmt_done(my_off_t 
     /* Alfranio needs to update the coordinator and workers. */
     
     if ((w= get_current_worker()) == NULL)
-      flush_info(key_info_idx, key_info_size, is_transactional() ? TRUE : FALSE);
-    
-    // Andrei: tried testing the worker's method but got a segfault
-    // because in to->set_info(group_relay_log_name) the arg is NULL.
-
-    else
-    {
-      // ulong key_worker_idx[]= { server_id, w->id };
-      // w->flush_info(key_worker_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER,
-      //              is_transactional() ? TRUE : FALSE);
-    }
+      flush_info(is_transactional() ? TRUE : FALSE);
   }
 }
 
@@ -1150,7 +1140,7 @@ bool mysql_show_relaylog_events(THD* thd
 
 #endif
 
-int Relay_log_info::init_info(ulong *uidx, uint nidx)
+int Relay_log_info::init_info()
 {
   int error= 0;
   const char *msg= NULL;
@@ -1296,7 +1286,7 @@ a file name for --relay-log-index option
     will be values to be read. Please, do not move this call after
     the handler->init_info().
   */
-  int necessary_to_configure= check_info(uidx, nidx);
+  int necessary_to_configure= check_info();
   if ((error= handler->init_info(uidx, nidx)))
   {
     msg= "Error reading relay log configuration";
@@ -1356,7 +1346,7 @@ a file name for --relay-log-index option
 #endif
   }
 
-  if ((error= flush_info(uidx, nidx, TRUE)))
+  if ((error= flush_info(TRUE)))
   {
     msg= "Error reading relay log configuration";
     error= 1;
@@ -1380,7 +1370,7 @@ err:
   DBUG_RETURN(error);
 }
 
-void Relay_log_info::end_info(ulong *uidx, uint nidx)
+void Relay_log_info::end_info()
 {
   DBUG_ENTER("Relay_log_info::end_info");
 
@@ -1480,7 +1470,7 @@ void Relay_log_info::set_master_info(Mas
 
   @return 0 on success, 1 on error.
 */
-int Relay_log_info::flush_info(ulong *uidx, uint nidx, const bool force)
+int Relay_log_info::flush_info(const bool force)
 {
   DBUG_ENTER("Relay_log_info::flush_info");
 

=== modified file 'sql/rpl_rli.h'
--- a/sql/rpl_rli.h	2010-11-30 14:02:15 +0000
+++ b/sql/rpl_rli.h	2010-11-30 14:39:40 +0000
@@ -517,9 +517,9 @@ public:
 
   int count_relay_log_space();
 
-  int init_info(ulong *uidx, uint nidx);
-  void end_info(ulong *uidx, uint nidx);
-  int flush_info(ulong *uidx, uint nidx, bool force= FALSE);
+  int init_info();
+  void end_info();
+  int flush_info(bool force= FALSE);
   int flush_current_log();
   void set_master_info(Master_info *info);
 

=== modified file 'sql/rpl_rli_pdb.cc'
--- a/sql/rpl_rli_pdb.cc	2010-11-30 14:02:15 +0000
+++ b/sql/rpl_rli_pdb.cc	2010-11-30 14:39:40 +0000
@@ -28,7 +28,7 @@ Slave_worker::~Slave_worker() 
 
 }
 
-int Slave_worker::init_info(ulong *uidx, uint nidx)
+int Slave_worker::init_info()
 {
   DBUG_ENTER("Slave_worker::init_info");
 
@@ -39,7 +39,7 @@ int Slave_worker::init_info(ulong *uidx,
     The init_info() is used to either create or read information
     from the repository, in order to initialize the Slave_worker.
   */
-  int necessary_to_configure= check_info(uidx, nidx);
+  int necessary_to_configure= check_info();
 
   if (handler->init_info(uidx, nidx))
     goto err;
@@ -47,7 +47,7 @@ int Slave_worker::init_info(ulong *uidx,
   if (!necessary_to_configure && read_info(handler))
     goto err;
 
-  if (flush_info(uidx, nidx, TRUE))
+  if (flush_info(TRUE))
     goto err;
 
   inited= 1;
@@ -58,7 +58,7 @@ err:
   DBUG_RETURN(1);
 }
 
-void Slave_worker::end_info(ulong *uidx, uint nidx)
+void Slave_worker::end_info()
 {
   DBUG_ENTER("Slave_worker::end_info");
 
@@ -72,7 +72,7 @@ void Slave_worker::end_info(ulong *uidx,
   DBUG_VOID_RETURN;
 }
 
-int Slave_worker::flush_info(ulong *uidx, uint nidx, const bool force)
+int Slave_worker::flush_info(const bool force)
 {
   DBUG_ENTER("Slave_worker::flush_info");
 
@@ -153,6 +153,26 @@ size_t Slave_worker::get_number_worker_f
   return sizeof(info_slave_worker_fields)/sizeof(info_slave_worker_fields[0]);
 }
 
+bool Slave_worker::checkpoint(Relay_log_info *info)
+{
+  DBUG_ENTER("Relay_coordinator::checkpoint_worker");
+
+  bool error= FALSE;
+
+  group_relay_log_pos= info->get_group_relay_log_pos();
+  strmake(group_relay_log_name, info->get_group_relay_log_name(),
+          sizeof(group_relay_log_name)-1);
+
+  group_master_log_pos= info->get_group_master_log_pos();
+  strmake(group_master_log_name, info->get_group_master_log_name(),
+          sizeof(group_master_log_name)-1);
+
+  error= flush_info(TRUE);
+   
+  DBUG_RETURN(error);
+}
+
+
 static HASH mapping_db_to_worker;
 static bool inited_hash_workers= FALSE;
 

=== modified file 'sql/rpl_rli_pdb.h'
--- a/sql/rpl_rli_pdb.h	2010-11-30 14:02:15 +0000
+++ b/sql/rpl_rli_pdb.h	2010-11-30 14:39:40 +0000
@@ -210,14 +210,16 @@ public:
   char group_master_log_name[FN_REFLEN];
   ulonglong group_master_log_pos;
 
-  int init_info(ulong *uidx, uint nidx);
-  void end_info(ulong *uidx, uint nidx);
-  int flush_info(ulong *uidx, uint nidx, bool force= FALSE);
+  int init_info();
+  void end_info();
+  int flush_info(bool force= FALSE);
 
   size_t get_number_worker_fields();
 
   void slave_worker_ends_group(ulong, int);  // CGEP walk through to upd APH
 
+  bool checkpoint(Relay_log_info *rli);
+
 private:
   bool read_info(Rpl_info_handler *from);
   bool write_info(Rpl_info_handler *to);

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2010-11-30 14:02:15 +0000
+++ b/sql/rpl_slave.cc	2010-11-30 14:39:40 +0000
@@ -408,21 +408,21 @@ int init_info(Master_info* mi, bool igno
     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 and correctly set the key_info_idx.
+    master and correctly set the key_info_idx. /Alfranio
   */
-  necessary_to_configure= mi->check_info(key_info_idx, key_info_size);
+  necessary_to_configure= mi->check_info();
   if (!(ignore_if_no_info && necessary_to_configure))
   {
     if ((thread_mask & SLAVE_IO) != 0 &&
-        mi->init_info(key_info_idx, key_info_size))
+        mi->init_info())
       error= 1;
   }
 
-  necessary_to_configure= mi->rli->check_info(key_info_idx, key_info_size);
+  necessary_to_configure= mi->rli->check_info();
   if (!(ignore_if_no_info && necessary_to_configure))
   {
      if (((thread_mask & SLAVE_SQL) != 0 || !(mi->rli->inited))
-         && mi->rli->init_info(key_info_idx, key_info_size))
+         && mi->rli->init_info())
     error= 1;
   }
 
@@ -446,8 +446,8 @@ void end_info(Master_info* mi)
     masters. In such case, we need to execute the code below for each
     master and correctly set the key_info_idx. /Alfranio
   */
-  mi->end_info(key_info_idx, key_info_size);
-  mi->rli->end_info(key_info_idx, key_info_size);
+  mi->end_info();
+  mi->rli->end_info();
 
   DBUG_VOID_RETURN;
 }
@@ -477,11 +477,11 @@ int remove_info(Master_info* mi)
     masters. In such case, we need to execute the code below for each
     master and correctly set the key_info_idx. /Alfranio
   */
-  mi->end_info(key_info_idx, key_info_size);
-  mi->rli->end_info(key_info_idx, key_info_size);
+  mi->end_info();
+  mi->rli->end_info();
 
-  if (mi->remove_info(key_info_idx, key_info_size) ||
-      mi->rli->remove_info(key_info_idx, key_info_size))
+  if (mi->remove_info() ||
+      mi->rli->remove_info())
     error= 1;
 
   DBUG_RETURN(error);
@@ -522,7 +522,7 @@ int flush_master_info(Master_info* mi, b
     master and correctly set the key_info_idx. /Alfranio
   */
   int err=  (mi->rli->flush_current_log() ||
-             mi->flush_info(key_info_idx, key_info_size, force));
+             mi->flush_info(force));
 
   mysql_mutex_unlock(log_lock);
 
@@ -678,7 +678,7 @@ int terminate_slave_threads(Master_info*
       masters. In such case, we need to execute the code below for each
       master and correctly set the key_info_idx. /Alfranio
     */
-    if (mi->flush_info(key_info_idx, key_info_size, TRUE))
+    if (mi->flush_info(TRUE))
       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
 
     /*
@@ -714,7 +714,7 @@ int terminate_slave_threads(Master_info*
       masters. In such case, we need to execute the code below for each
       master and correctly set the key_info_idx. /Alfranio
     */
-    if (mi->rli->flush_info(key_info_idx, key_info_size, TRUE))
+    if (mi->rli->flush_info(TRUE))
       DBUG_RETURN(ER_ERROR_DURING_FLUSH_LOGS);
 
     mysql_mutex_unlock(log_lock);
@@ -3644,10 +3644,9 @@ int slave_start_single_worker(Relay_log_
   // fixme: experimenting to make Workers to run ev->update_pos(w->w_rli)
   // fixme: a real hack! part of Rpl_info_factory::create_rli(RLI_REPOSITORY_FILE, FALSE);
   w->w_rli= new Relay_log_info(FALSE);
-  Rpl_info_dummy *dummy_handler= new Rpl_info_dummy(TRUE);
+  Rpl_info_dummy *dummy_handler= new Rpl_info_dummy();
   w->w_rli->set_rpl_info_handler(dummy_handler);
-  ulong key_worker_idx[]= { server_id, w->id };
-  w->init_info(key_worker_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER);
+  w->init_info();
 
   w->relay_log_change_notified= FALSE; // the 1st group to contain relaylog name
 
@@ -3791,8 +3790,7 @@ void slave_stop_workers(Relay_log_info *
     Slave_worker *w;
     get_dynamic((DYNAMIC_ARRAY*)&rli->workers, (uchar*) &w, i);
 
-    ulong key_worker_idx[]= { server_id, w->id };
-    w->end_info(key_worker_idx, NUMBER_OF_FIELDS_TO_IDENTIFY_WORKER);
+    w->end_info();
 
     mysql_mutex_lock(&w->jobs_lock);
     while (w->jobs.len != rli->slave_pending_jobs_max + 1)
@@ -5378,7 +5376,7 @@ static Log_event* next_event(Relay_log_i
           We may update the worker here but this is not extremlly
           necessary. /Alfranio
         */
-        rli->flush_info(key_info_idx, key_info_size);
+        rli->flush_info();
       }
 
       /* Reset the relay-log-change-notified status of  Slave Workers */
@@ -6200,7 +6198,7 @@ bool change_master(THD* thd, Master_info
 
     Andrei needs to guarantee that this done in sequential mode.
   */
-  ret= mi->rli->flush_info(key_info_idx, key_info_size, TRUE);
+  ret= mi->rli->flush_info(TRUE);
   mysql_cond_broadcast(&mi->data_cond);
   mysql_mutex_unlock(&mi->rli->data_lock);
 


Attachment: [text/bzr-bundle] bzr/andrei.elkin@oracle.com-20101130143940-k9kypuuu6ysyau6w.bundle
Thread
bzr commit into mysql-next-mr.crash-safe branch (andrei.elkin:3222) WL#5569WL#5599Andrei Elkin30 Nov