List:Commits« Previous MessageNext Message »
From:Patrick Galbraith Date:September 15 2007 3:17pm
Subject:bk commit into 5.2 tree (patg:1.2599) BUG#8368
View as plain text  
Below is the list of changes that have just been committed into a local
5.2 repository of patg. When patg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-09-15 09:17:39-04:00, patg@stripped +4 -0
  BUG #8368
  
  "mysqldump needs --slave-data option"
  
  Added this option, named as "--dump-slave". The purpose of this option is to be
  able to produce a dump from a slave used for making backups of the master. Originally,
  dumping from the main master was fine, but as more data accumulated, the dump process
  would take over 30 minutes, locking up the master database hence website for 30 minutes.
  A slave dedicated to producing backups was the answer, but I needed a dump that could be

  used to restore a slave instantly and in order to do that, it has to have three things 
  contained in the dump:
  
  1. "STOP SLAVE;" at the beginning
  2. "CHANGE MASTER TO ...<the master - info from 'show slave status'>"
  3. "START SLAVE;" at the end
  
  These options in this changeset contain this.
  
  --stop-slave adds "STOP SLAVE" to the beginning of the dump and "STOP SLAVE" 
  to the end of the dump.
  
  --include-host gives the user the option to have the host explicitely added
  to the "CHANGE MASTER TO ..." line.
  
  --dump-slave adds the "CHANGE MASTER ..." to the dump representing not the slave's
  master binlog info, but the slave's master's info from "SHOW SLAVE STATUS" 

  client/client_priv.h@stripped, 2007-09-15 09:17:27-04:00, patg@stripped +1 -1
    BUG #8368
    
    mysqldump needs --slave-data option
    
    Added OPT_SLAVE_DATA to client_priv.h

  client/mysqldump.c@stripped, 2007-09-15 09:17:29-04:00, patg@stripped +187 -1
    BUG #8368
    
    mysqldump needs --slave-data option
    
    * Added --dump-slave option (name per Brian)
    * Added --stop-slave to print "STOP SLAVE;" into the dump
    * Added --include-host option to include "MASTER_HOST=..." and "MASTER_PORT=..."
      to the dump since unlike --master-data, the host can't be assumed to be
      the local host
    * Added do_start_slave and do_stop_slave to stop the slave sql thread upon
      start of the dump process, and to start the slave sql upon finish of dump process -
      to keep the log information frozen during this time.
    * Added do_show_slave_status for obtaining slave information needed to compose "CHANGE
MASTER ..."
      output to the master of this slave.
    * Added necessary long options and defines required for new options

  mysql-test/r/rpl_mysqldump_slave.result@stripped, 2007-09-15 09:17:30-04:00, patg@stripped
+13 -0
    New BitKeeper file ``mysql-test/r/rpl_mysqldump_slave.result''

  mysql-test/r/rpl_mysqldump_slave.result@stripped, 2007-09-15 09:17:30-04:00, patg@stripped
+0 -0

  mysql-test/t/rpl_mysqldump_slave.test@stripped, 2007-09-14 20:47:28-04:00, patg@stripped
+23 -0
    BitKeeper file /Users/patg/mysql-build/mysql-5.2/mysql-test/t/rpl_mysqldump_slave.test

  mysql-test/t/rpl_mysqldump_slave.test@stripped, 2007-09-14 20:47:28-04:00, patg@stripped
+0 -0

diff -Nrup a/client/client_priv.h b/client/client_priv.h
--- a/client/client_priv.h	2007-08-03 21:44:45 -04:00
+++ b/client/client_priv.h	2007-09-15 09:17:27 -04:00
@@ -80,5 +80,5 @@ enum options_client
   OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID,
   OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT,
   OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE,
-  OPT_WRITE_BINLOG, OPT_MAX_CLIENT_OPTION
+  OPT_WRITE_BINLOG, OPT_MAX_CLIENT_OPTION, OPT_SLAVE_DATA
 };
diff -Nrup a/client/mysqldump.c b/client/mysqldump.c
--- a/client/mysqldump.c	2007-08-28 20:41:31 -04:00
+++ b/client/mysqldump.c	2007-09-15 09:17:29 -04:00
@@ -98,6 +98,7 @@ static my_bool  verbose= 0, opt_no_creat
                 opt_complete_insert= 0, opt_drop_database= 0,
                 opt_replace_into= 0,
                 opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1,
+                opt_stop_slave=0, opt_include_host=0,
                 opt_events= 0,
                 opt_alltspcs=0, opt_notspcs= 0;
 static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0;
@@ -116,7 +117,9 @@ static char compatible_mode_normal_str[2
 static ulong opt_compatible_mode= 0;
 #define MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL 1
 #define MYSQL_OPT_MASTER_DATA_COMMENTED_SQL 2
-static uint opt_mysql_port= 0, opt_master_data;
+#define MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL 1
+#define MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL 2
+static uint     opt_mysql_port= 0, opt_master_data, opt_slave_data;
 static uint my_end_arg;
 static char * opt_mysql_unix_port=0;
 static int   first_error=0;
@@ -265,6 +268,19 @@ static struct my_option my_long_options[
   {"events", 'E', "Dump events.",
      (uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL,
      NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"dump-slave", OPT_SLAVE_DATA,
+   "This causes the binary log position and filename of the master that the "
+   "slave being dumped is ready from to be appended to the dumped data"
+   "output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
+   " to 2, that command will be prefixed with a comment symbol. "
+   "This option will turn --lock-all-tables on, unless "
+   "--single-transaction is specified too (in which case a "
+   "global read lock is only taken a short time at the beginning of the dump "
+   "- don't forget to read about --single-transaction below). In all cases "
+   "any action on logs will happen at the exact moment of the dump."
+   "Option automatically turns --lock-tables off.",
+   (uchar**) &opt_slave_data, (uchar**) &opt_slave_data, 0,
+   GET_UINT, OPT_ARG, 0, 0, MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL, 0, 0, 0},
   {"extended-insert", 'e',
    "Allows utilization of the new, much faster INSERT syntax.",
    (uchar**) &extended_insert, (uchar**) &extended_insert, 0, GET_BOOL, NO_ARG,
@@ -430,6 +446,14 @@ static struct my_option my_long_options[
   {"socket", 'S', "Socket file to use for connection.",
    (uchar**) &opt_mysql_unix_port, (uchar**) &opt_mysql_unix_port, 0, GET_STR,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"stop-slave", 'e',
+   "Adds 'STOP SLAVE' prior to 'CHANGE MASTER' and 'START SLAVE' to bottom of dump.",
+   (uchar**) &opt_stop_slave, (uchar**) &opt_stop_slave, 0, GET_BOOL, NO_ARG,
+   0, 0, 0, 0, 0, 0},
+  {"include-host", 'e',
+   "Adds 'MASTER_HOST=<host>, MASTER_PORT=<port>' to 'CHANGE MASTER TO..' in
dump produced with --dump-slave.",
+   (uchar**) &opt_include_host, (uchar**) &opt_include_host, 0, GET_BOOL, NO_ARG,
+   0, 0, 0, 0, 0, 0},
 #include <sslopt-longopts.h>
   {"tab",'T',
    "Creates tab separated textfile for each table to given path. (creates .sql and .txt
files). NOTE: This only works if mysqldump is run on the same machine as the mysqld
daemon.",
@@ -746,6 +770,10 @@ get_one_option(int optid, const struct m
     if (!argument) /* work like in old versions */
       opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL;
     break;
+  case (int) OPT_SLAVE_DATA:
+    if (!argument) /* work like in old versions */
+      opt_slave_data= MYSQL_OPT_SLAVE_DATA_EFFECTIVE_SQL;
+    break;
   case (int) OPT_OPTIMIZE:
     extended_insert= opt_drop= opt_lock= quick= create_options=
       opt_disable_keys= lock_tables= opt_set_charset= 1;
@@ -878,6 +906,14 @@ static int get_options(int *argc, char *
     return(EX_USAGE);
   }
 
+  /* We don't delete master logs if slave data option */
+  if (opt_slave_data)
+  {
+    opt_lock_all_tables= !opt_single_transaction;
+    opt_master_data= 0;
+    opt_delete_master_logs= 0;
+  }
+
   /* Ensure consistency of the set of binlog & locking options */
   if (opt_delete_master_logs && !opt_master_data)
     opt_master_data= MYSQL_OPT_MASTER_DATA_COMMENTED_SQL;
@@ -888,7 +924,10 @@ static int get_options(int *argc, char *
     return(EX_USAGE);
   }
   if (opt_master_data)
+  {
     opt_lock_all_tables= !opt_single_transaction;
+    opt_slave_data= 0;
+  }
   if (opt_single_transaction || opt_lock_all_tables)
     lock_tables= 0;
   if (enclosed && opt_enclosed)
@@ -4288,6 +4327,137 @@ static int do_show_master_status(MYSQL *
   return 0;
 }
 
+static int do_stop_slave_sql(MYSQL *mysql_con)
+{
+  MYSQL_RES *slave;
+  /* We need to check if the slave sql is running in the first place */
+  if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+    return(1);
+  else
+  {
+    MYSQL_ROW row= mysql_fetch_row(slave);
+    if (row && row[11])
+    {
+      /* if SLAVE SQL is not running, we don't stop it */
+      if (!strcmp(row[11],"No"))
+      {
+        mysql_free_result(slave);
+        /* Silently assume that they don't have the slave running */
+        return(0);
+      }
+    }
+  }
+  mysql_free_result(slave);
+
+  /* now, stop slave if running */
+  if (mysql_query_with_error_report(mysql_con, 0, "STOP SLAVE SQL_THREAD"))
+  {
+    return(1);
+  }
+  return(0);
+}
+
+static int add_stop_slave(void)
+{
+  if (opt_comments)
+    fprintf(md_result_file,
+                "\n--\n-- stop slave statement to make a recovery dump)\n--\n\n");
+      fprintf(md_result_file, "STOP SLAVE;\n");
+      return(0);
+}
+
+static int add_start_slave(void)
+{
+  if (opt_comments)
+    fprintf(md_result_file,
+                "\n--\n-- start slave statement to make a recovery dump)\n--\n\n");
+      fprintf(md_result_file, "START SLAVE;\n");
+      return(0);
+}
+
+static int do_show_slave_status(MYSQL *mysql_con)
+{
+  MYSQL_RES *slave;
+  const char *comment_prefix=
+    (opt_slave_data == MYSQL_OPT_SLAVE_DATA_COMMENTED_SQL) ? "-- " : "";
+  if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+  {
+    if (!ignore_errors)
+    {
+      /* SHOW SLAVE STATUS reports nothing and --force is not enabled */
+      my_printf_error(0, "Error: Slave not set up",
+                      MYF(0));
+    }
+    mysql_free_result(slave);
+    return 1;
+  }
+  else
+  {
+    MYSQL_ROW row= mysql_fetch_row(slave);
+    if (row && row[9] && row[21])
+    {
+      /* SHOW MASTER STATUS reports file and position */
+      if (opt_comments)
+        fprintf(md_result_file,
+                "\n--\n-- Position to start replication or point-in-time "
+                "recovery from (the master of this slave)\n--\n\n");
+
+      fprintf(md_result_file, "%sCHANGE MASTER TO ", comment_prefix);
+
+      if (opt_include_host)
+      {
+        if (row[1] && strcmp(row[1],""))
+        {
+          fprintf(md_result_file, "MASTER_HOST='%s', ", row[1]);
+        }
+        if (row[3] && strcmp(row[3],""))
+        {
+          fprintf(md_result_file, "MASTER_PORT='%s', ", row[3]);
+        }
+      }
+      fprintf(md_result_file,
+              "MASTER_LOG_FILE='%s', MASTER_LOG_POS=%s;\n", row[9], row[21]);
+
+      check_io(md_result_file);
+    }
+    mysql_free_result(slave);
+  }
+  return 0;
+}
+
+static int do_start_slave_sql(MYSQL *mysql_con)
+{
+  MYSQL_RES *slave;
+  /* We need to check if the slave sql is stopped in the first place */
+  if (mysql_query_with_error_report(mysql_con, &slave, "SHOW SLAVE STATUS"))
+    return(1);
+  else
+  {
+    MYSQL_ROW row= mysql_fetch_row(slave);
+    if (row && row[11])
+    {
+      /* if SLAVE SQL is not running, we don't start it */
+      if (!strcmp(row[11],"Yes"))
+      {
+        mysql_free_result(slave);
+        /* Silently assume that they don't have the slave running */
+        return(0);
+      }
+    }
+  }
+  mysql_free_result(slave);
+
+  /* now, start slave if stopped */
+  if (mysql_query_with_error_report(mysql_con, 0, "START SLAVE"))
+  {
+    my_printf_error(0, "Error: Unable to start slave",
+                    MYF(0));
+    return 1;
+  }
+  return(0);
+}
+
+
 
 static int do_flush_tables_read_lock(MYSQL *mysql_con)
 {
@@ -4933,6 +5103,9 @@ int main(int argc, char **argv)
   if (!path)
     write_header(md_result_file, *argv);
 
+  if (opt_slave_data && do_stop_slave_sql(mysql))
+    goto err;
+
   if ((opt_lock_all_tables || opt_master_data) &&
       do_flush_tables_read_lock(mysql))
     goto err;
@@ -4951,8 +5124,13 @@ int main(int argc, char **argv)
       goto err;
     flush_logs= 0; /* not anymore; that would not be sensible */
   }
+  /* Add 'STOP SLAVE to beginning of dump */
+  if (opt_stop_slave && add_stop_slave())
+    goto err;
   if (opt_master_data && do_show_master_status(mysql))
     goto err;
+  if (opt_slave_data && do_show_slave_status(mysql))
+    goto err;
   if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit!
*/
     goto err;
 
@@ -4979,6 +5157,14 @@ int main(int argc, char **argv)
       dump_tablespaces_for_databases(argv);
     dump_databases(argv);
   }
+
+  /* if --dump-slave , start the slave sql thread */
+  if (opt_slave_data && do_start_slave_sql(mysql))
+    goto err;
+
+  /* add 'START SLAVE' to end of dump */
+  if (opt_stop_slave && add_start_slave())
+    goto err;
 
   /* ensure dumped data flushed */
   if (md_result_file && fflush(md_result_file))
diff -Nrup a/mysql-test/r/rpl_mysqldump_slave.result
b/mysql-test/r/rpl_mysqldump_slave.result
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/r/rpl_mysqldump_slave.result	2007-09-15 09:17:30 -04:00
@@ -0,0 +1,13 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+#
+# New --dump-slave, --stop-slave, --start-slave functionality 
+#
+grant all privileges on *.* to root@locahost;
+use test;
+STOP SLAVE;
+START SLAVE;
diff -Nrup a/mysql-test/t/rpl_mysqldump_slave.test b/mysql-test/t/rpl_mysqldump_slave.test
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/mysql-test/t/rpl_mysqldump_slave.test	2007-09-14 20:47:28 -04:00
@@ -0,0 +1,23 @@
+source include/master-slave.inc;
+
+--echo #
+--echo # New --dump-slave, --stop-slave, --start-slave functionality 
+--echo #
+connection master;
+grant all privileges on *.* to root@locahost;
+use test;
+
+connection slave;
+
+# Execute mysqldump with --dump-slave
+--exec $MYSQL_DUMP_SLAVE --compact --dump-slave test > dump.txt
+
+# Execute mysqldump with --dump-slave and --stop-slave 
+--exec $MYSQL_DUMP_SLAVE --compact --dump-slave --stop-slave test >> dump.txt
+
+# Execute mysqldump with --dump-slave ,--stop-slave and --include-host
+--exec $MYSQL_DUMP_SLAVE --compact --dump-slave --stop-slave --include-host test >>
dump.txt
+
+# Execute mysqldump with --master-data and --stop-slave 
+--exec $MYSQL_DUMP --compact --master-data --stop-slave test >> dump.txt
+
Thread
bk commit into 5.2 tree (patg:1.2599) BUG#8368Patrick Galbraith15 Sep