[Commits] Rev 3452: MDEV-26: Global Transaction ID. in http://bazaar.launchpad.net/~maria-captains/maria/10.0

knielsen at knielsen-hq.org knielsen at knielsen-hq.org
Fri Feb 15 16:55:17 EET 2013


At http://bazaar.launchpad.net/~maria-captains/maria/10.0

------------------------------------------------------------
revno: 3452
revision-id: knielsen at knielsen-hq.org-20130215145517-a65cqml1tvt5vicm
parent: knielsen at knielsen-hq.org-20130215125448-p37uccfigtrf6lf1
committer: knielsen at knielsen-hq.org
branch nick: work-10.0-mdev26
timestamp: Fri 2013-02-15 15:55:17 +0100
message:
  MDEV-26: Global Transaction ID.
  
  Implement CHANGE MASTER TO ... MASTER_GTID_POS = "x-y-z,a-b-c".
=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2013-02-14 13:42:05 +0000
+++ b/sql/log_event.cc	2013-02-15 14:55:17 +0000
@@ -6065,13 +6065,12 @@ rpl_slave_state::init()
   inited= true;
 }
 
+
 void
-rpl_slave_state::deinit()
+rpl_slave_state::truncate_hash()
 {
   uint32 i;
 
-  if (!inited)
-    return;
   for (i= 0; i < hash.records; ++i)
   {
     element *e= (element *)my_hash_element(&hash, i);
@@ -6083,8 +6082,17 @@ rpl_slave_state::deinit()
       my_free(l);
       l= next;
     }
-    /* The element itself is freed by my_hash_free(). */
+    /* The element itself is freed by the hash element free function. */
   }
+  my_hash_reset(&hash);
+}
+
+void
+rpl_slave_state::deinit()
+{
+  if (!inited)
+    return;
+  truncate_hash();
   my_hash_free(&hash);
   mysql_mutex_destroy(&LOCK_slave_state);
 }
@@ -6137,6 +6145,42 @@ rpl_slave_state::get_element(uint32 doma
 
 #ifdef MYSQL_SERVER
 #ifdef HAVE_REPLICATION
+int
+rpl_slave_state::truncate_state_table(THD *thd)
+{
+  TABLE_LIST tlist;
+  int err= 0;
+  TABLE *table;
+
+  mysql_reset_thd_for_next_command(thd, 0);
+
+  tlist.init_one_table(STRING_WITH_LEN("mysql"),
+                       rpl_gtid_slave_state_table_name.str,
+                       rpl_gtid_slave_state_table_name.length,
+                       NULL, TL_WRITE);
+  if (!(err= open_and_lock_tables(thd, &tlist, FALSE, 0)))
+  {
+    table= tlist.table;
+    err= table->file->ha_truncate();
+
+    if (err)
+    {
+      ha_rollback_trans(thd, FALSE);
+      close_thread_tables(thd);
+      ha_rollback_trans(thd, TRUE);
+    }
+    else
+    {
+      ha_commit_trans(thd, FALSE);
+      close_thread_tables(thd);
+      ha_commit_trans(thd, TRUE);
+    }
+  }
+
+  return err;
+}
+
+
 /*
   Write a gtid to the replication slave state table.
 
@@ -6431,13 +6475,23 @@ gtid_parser_helper(char **ptr, char *end
   Update the slave replication state with the GTID position obtained from
   master when connecting with old-style (filename,offset) position.
 
+  If RESET is true then all existing entries are removed. Otherwise only
+  domain_ids mentioned in the STATE_FROM_MASTER are changed.
+
   Returns 0 if ok, non-zero if error.
 */
 int
-rpl_slave_state::load(THD *thd, char *state_from_master)
+rpl_slave_state::load(THD *thd, char *state_from_master, size_t len,
+                      bool reset)
 {
-  char *end= state_from_master + strlen(state_from_master);
+  char *end= state_from_master + len;
 
+  if (reset)
+  {
+    if (truncate_state_table(thd))
+      return 1;
+    truncate_hash();
+  }
   for (;;)
   {
     rpl_gtid gtid;
@@ -6452,6 +6506,7 @@ rpl_slave_state::load(THD *thd, char *st
       break;
     if (*state_from_master != ',')
       return 1;
+    ++state_from_master;
   }
   return 0;
 }

=== modified file 'sql/log_event.h'
--- a/sql/log_event.h	2013-02-14 13:42:05 +0000
+++ b/sql/log_event.h	2013-02-15 14:55:17 +0000
@@ -3003,13 +3003,15 @@ struct rpl_slave_state
 
   void init();
   void deinit();
+  void truncate_hash();
   ulong count() const { return hash.records; }
   int update(uint32 domain_id, uint32 server_id, uint64 sub_id, uint64 seq_no);
+  int truncate_state_table(THD *thd);
   int record_gtid(THD *thd, const rpl_gtid *gtid, uint64 sub_id,
                       bool in_transaction);
   uint64 next_subid(uint32 domain_id);
   int tostring(String *dest, rpl_gtid *extra_gtids, uint32 num_extra);
-  int load(THD *thd, char *state_from_master);
+  int load(THD *thd, char *state_from_master, size_t len, bool reset);
   bool is_empty();
 
   void lock() { DBUG_ASSERT(inited); mysql_mutex_lock(&LOCK_slave_state); }

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2012-10-02 22:44:54 +0000
+++ b/sql/share/errmsg-utf8.txt	2013-02-15 14:55:17 +0000
@@ -6598,3 +6598,7 @@ ER_SLAVE_STARTED
         eng "SLAVE '%.*s' started"
 ER_SLAVE_STOPPED
         eng "SLAVE '%.*s' stopped"
+ER_FAILED_GTID_STATE_INIT
+        eng "Failed initializing replication GTID state"
+ER_INCORRECT_GTID_STATE
+        eng "Could not parse GTID list for MASTER_GTID_POS"

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2013-02-15 12:54:48 +0000
+++ b/sql/slave.cc	2013-02-15 14:55:17 +0000
@@ -1862,7 +1862,8 @@ when it try to get the value of TIME_ZON
         (master_row= mysql_fetch_row(master_res)) &&
         (master_row[0] != NULL))
     {
-      rpl_global_gtid_slave_state.load(mi->io_thd, master_row[0]);
+      rpl_global_gtid_slave_state.load(mi->io_thd, master_row[0],
+                                       strlen(master_row[0]), false);
     }
     else if (check_io_slave_killed(mi->io_thd, mi, NULL))
       goto slave_killed_err;

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2013-01-22 14:18:36 +0000
+++ b/sql/sql_lex.h	2013-02-15 14:55:17 +0000
@@ -314,6 +314,8 @@ struct LEX_MASTER_INFO
     host= user= password= log_file_name= ssl_key= ssl_cert= ssl_ca=
       ssl_capath= ssl_cipher= relay_log_name= 0;
     pos= relay_log_pos= server_id= port= connect_retry= 0;
+    gtid_pos_str.str= NULL;
+    gtid_pos_str.length= 0;
     gtid_pos_auto= FALSE;
     heartbeat_period= 0;
     ssl= ssl_verify_server_cert= heartbeat_opt=

=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc	2013-02-13 12:36:46 +0000
+++ b/sql/sql_repl.cc	2013-02-15 14:55:17 +0000
@@ -2202,6 +2202,7 @@ bool change_master(THD* thd, Master_info
   char relay_log_info_file_tmp[FN_REFLEN];
   my_off_t saved_log_pos;
   LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
+  slave_connection_state tmp_slave_state;
   DBUG_ENTER("change_master");
 
   /* 
@@ -2231,6 +2232,27 @@ bool change_master(THD* thd, Master_info
     goto err;
   }
 
+  if (lex_mi->gtid_pos_str.str)
+  {
+    if (master_info_index->give_error_if_slave_running())
+    {
+      ret= TRUE;
+      goto err;
+    }
+    /*
+      First load it into a dummy object, to check for parse errors.
+      We do not want to wipe the previous state if there is an error
+      in the syntax of the new state!
+    */
+    if (tmp_slave_state.load(lex_mi->gtid_pos_str.str,
+                             lex_mi->gtid_pos_str.length))
+    {
+      my_error(ER_INCORRECT_GTID_STATE, MYF(0));
+      ret= TRUE;
+      goto err;
+    }
+  }
+
   thd_proc_info(thd, "Changing master");
 
   create_logfile_name_with_suffix(master_info_file_tmp,
@@ -2390,7 +2412,7 @@ bool change_master(THD* thd, Master_info
     mi->rli.group_relay_log_pos= mi->rli.event_relay_log_pos= lex_mi->relay_log_pos;
   }
 
-  if (lex_mi->gtid_pos_auto)
+  if (lex_mi->gtid_pos_auto || lex_mi->gtid_pos_str.str)
     mi->gtid_pos_auto= true;
   else if (lex_mi->gtid_pos_str.str ||
            lex_mi->log_file_name || lex_mi->pos ||
@@ -2427,6 +2449,18 @@ bool change_master(THD* thd, Master_info
      strmake(mi->master_log_name, mi->rli.group_master_log_name,
              sizeof(mi->master_log_name)-1);
   }
+
+  if (lex_mi->gtid_pos_str.str)
+  {
+    if (rpl_global_gtid_slave_state.load(thd, lex_mi->gtid_pos_str.str,
+                                         lex_mi->gtid_pos_str.length, true))
+    {
+      my_error(ER_FAILED_GTID_STATE_INIT, MYF(0));
+      ret= TRUE;
+      goto err;
+    }
+  }
+
   /*
     Relay log's IO_CACHE may not be inited, if rli->inited==0 (server was never
     a slave before).



More information about the commits mailing list