List:Commits« Previous MessageNext Message »
From:Martin Zaun Date:March 22 2012 7:02am
Subject:bzr push into mysql-trunk branch (martin.zaun:3821 to 3822)
View as plain text  
 3822 Martin Zaun	2012-03-21 [merge]
      merge to mysql-trunk

    added:
      mysql-test/suite/rpl/r/rpl_skip_ddl_errors_cli.result
      mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.cnf
      mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.test
    modified:
      sql/mysqld.cc
      sql/rpl_slave.cc
      sql/rpl_slave.h
 3821 Alfranio Correia	2012-03-21
      Post-push fix for BUG#13538891.
      
      rpl_alter_repository restarts mysql with different options and mtr
      uses the latest configuration to start servers on new tests. This
      behavior has made rpl_checksum_cache to run after rpl_alter_repository
      with replication system tables although its use has not been requested.
      
      Apart from running a replication test with unexpected configuration,
      the scenario should not have led to any problem. However, a bug in
      rpl_alter_repository was corrupting the replication system tables and
      leading to the failure of the rpl_checksum_cache.
      
      Specifically, rpl_alter_repository was dropping columns from some
      replication tables to inject faults and adding them back to fix the
      failures. Unfortunately, the procedure was changing the order of the
      columns making replication to fail.
      
      The problem was not noticeable before BUG#13538891 due to MyIsam's
      permissive behavior which does automatic conversions.
      
      To fix the problems, we have changed rpl_alter_repository as follows:
      
        . At the end of the test, the server is restarted with an empty
          configuration.
      
        . Only the last column of the table is dropped.

    modified:
      mysql-test/suite/rpl/r/rpl_alter_repository.result
      mysql-test/suite/rpl/t/rpl_alter_repository.test
=== added file 'mysql-test/suite/rpl/r/rpl_skip_ddl_errors_cli.result'
--- a/mysql-test/suite/rpl/r/rpl_skip_ddl_errors_cli.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_skip_ddl_errors_cli.result	2012-03-22 06:25:38 +0000
@@ -0,0 +1,5 @@
+Show the effect of the server command line option slave-skip-errors
+being passed the alias ignore_ddl_errors and a numeric error code
+SHOW VARIABLES LIKE 'slave_skip_errors';
+Variable_name	Value
+slave_skip_errors	1003,1007,1008,1050,1051,1054,1060,1061,1068,1091,1146

=== added file 'mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.cnf'
--- a/mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.cnf	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.cnf	2012-03-22 06:25:38 +0000
@@ -0,0 +1,7 @@
+!include include/default_mysqld.cnf
+
+[mysqld]
+# expect combined error codes
+slave-skip-errors=ddl_exist_errors,1003
+
+[mysqld.1.1]

=== added file 'mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.test'
--- a/mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_skip_ddl_errors_cli.test	2012-03-22 06:25:38 +0000
@@ -0,0 +1,3 @@
+--echo Show the effect of the server command line option slave-skip-errors
+--echo being passed the alias ignore_ddl_errors and a numeric error code
+SHOW VARIABLES LIKE 'slave_skip_errors';

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-03-20 15:09:23 +0000
+++ b/sql/mysqld.cc	2012-03-22 06:25:38 +0000
@@ -5071,6 +5071,10 @@ int mysqld_main(int argc, char **argv)
   check_binlog_stmt_cache_size(NULL);
 
   binlog_unsafe_map_init();
+
+  // Make @@slave_skip_errors show the nice human-readable value.
+  set_slave_skip_errors(&opt_slave_skip_errors);
+
   /*
     init_slave() must be called after the thread keys are created.
   */
@@ -8137,7 +8141,7 @@ static int get_options(int *argc_ptr, ch
 
 #ifdef HAVE_REPLICATION
   if (opt_slave_skip_errors)
-    init_slave_skip_errors(opt_slave_skip_errors);
+    add_slave_skip_errors(opt_slave_skip_errors);
 #endif
 
   if (global_system_variables.max_join_size == HA_POS_ERROR)

=== modified file 'sql/rpl_slave.cc'
--- a/sql/rpl_slave.cc	2012-03-16 10:29:55 +0000
+++ b/sql/rpl_slave.cc	2012-03-22 06:25:38 +0000
@@ -310,15 +310,6 @@ int init_slave()
   }
 
   /*
-    If --slave-skip-errors=... was not used, the string value for the
-    system variable has not been set up yet. Do it now.
-  */
-  if (!use_slave_mask)
-  {
-    print_slave_skip_errors();
-  }
-
-  /*
     This is the startup routine and as such we try to
     configure both the SLAVE_SQL and SLAVE_IO.
   */
@@ -611,9 +602,6 @@ static void print_slave_skip_errors(void
   DBUG_ASSERT(sizeof(slave_skip_error_names) > MIN_ROOM);
   DBUG_ASSERT(MAX_SLAVE_ERROR <= 999999); // 6 digits
 
-  /* Make @@slave_skip_errors show the nice human-readable value.  */
-  opt_slave_skip_errors= slave_skip_error_names;
-
   if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask))
   {
     /* purecov: begin tested */
@@ -655,21 +643,26 @@ static void print_slave_skip_errors(void
   DBUG_VOID_RETURN;
 }
 
-/*
-  Init function to set up array for errors that should be skipped for slave
-
-  SYNOPSIS
-    init_slave_skip_errors()
-    arg         List of errors numbers to skip, separated with ','
-
-  NOTES
-    Called from get_options() in mysqld.cc on start-up
+/**
+ Change arg to the string with the nice, human-readable skip error values.
+   @param slave_skip_errors_ptr
+          The pointer to be changed
 */
+void set_slave_skip_errors(char** slave_skip_errors_ptr)
+{
+  DBUG_ENTER("set_slave_skip_errors");
+  print_slave_skip_errors();
+  *slave_skip_errors_ptr= slave_skip_error_names;
+  DBUG_VOID_RETURN;
+}
 
-void init_slave_skip_errors(const char* arg)
+/**
+  Init function to set up array for errors that should be skipped for slave
+*/
+static void init_slave_skip_errors()
 {
-  const char *p;
   DBUG_ENTER("init_slave_skip_errors");
+  DBUG_ASSERT(!use_slave_mask); // not already initialized
 
   if (bitmap_init(&slave_error_mask,0,MAX_SLAVE_ERROR,0))
   {
@@ -677,14 +670,86 @@ void init_slave_skip_errors(const char* 
     exit(1);
   }
   use_slave_mask = 1;
-  for (;my_isspace(system_charset_info,*arg);++arg)
+  DBUG_VOID_RETURN;
+}
+
+static void add_slave_skip_errors(const uint* errors, uint n_errors)
+{
+  DBUG_ENTER("add_slave_skip_errors");
+  DBUG_ASSERT(errors);
+  DBUG_ASSERT(use_slave_mask);
+
+  for (uint i = 0; i < n_errors; i++)
+  {
+    const uint err_code = errors[i];
+    if (err_code < MAX_SLAVE_ERROR)
+       bitmap_set_bit(&slave_error_mask, err_code);
+  }
+  DBUG_VOID_RETURN;
+}
+
+/*
+  Add errors that should be skipped for slave
+
+  SYNOPSIS
+    add_slave_skip_errors()
+    arg         List of errors numbers to be added to skip, separated with ','
+
+  NOTES
+    Called from get_options() in mysqld.cc on start-up
+*/
+
+void add_slave_skip_errors(const char* arg)
+{
+  const char *p= NULL;
+  /*
+    ALL is only valid when nothing else is provided.
+  */
+  const uchar SKIP_ALL[]= "all";
+  size_t SIZE_SKIP_ALL= strlen((const char *) SKIP_ALL) + 1;
+  /*
+    IGNORE_DDL_ERRORS can be combined with other parameters
+    but must be the first one provided.
+  */
+  const uchar SKIP_DDL_ERRORS[]= "ddl_exist_errors";
+  size_t SIZE_SKIP_DDL_ERRORS= strlen((const char *) SKIP_DDL_ERRORS);
+  DBUG_ENTER("add_slave_skip_errors");
+
+  // initialize mask if not done yet
+  if (!use_slave_mask)
+    init_slave_skip_errors();
+
+  for (; my_isspace(system_charset_info,*arg); ++arg)
     /* empty */;
-  if (!my_strnncoll(system_charset_info,(uchar*)arg,4,(const uchar*)"all",4))
+  if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_ALL,
+                    SKIP_ALL, SIZE_SKIP_ALL))
   {
     bitmap_set_all(&slave_error_mask);
-    print_slave_skip_errors();
     DBUG_VOID_RETURN;
   }
+  if (!my_strnncoll(system_charset_info, (uchar*)arg, SIZE_SKIP_DDL_ERRORS,
+                    SKIP_DDL_ERRORS, SIZE_SKIP_DDL_ERRORS))
+  {
+    // DDL errors to be skipped for relaxed 'exist' handling
+    const uint ddl_errors[] = {
+      // error codes with create/add <schema object>
+      ER_DB_CREATE_EXISTS, ER_TABLE_EXISTS_ERROR, ER_DUP_KEYNAME,
+      ER_MULTIPLE_PRI_KEY,
+      // error codes with change/rename <schema object>
+      ER_BAD_FIELD_ERROR, ER_NO_SUCH_TABLE, ER_DUP_FIELDNAME,
+      // error codes with drop <schema object>
+      ER_DB_DROP_EXISTS, ER_BAD_TABLE_ERROR, ER_CANT_DROP_FIELD_OR_KEY
+    };
+
+    add_slave_skip_errors(ddl_errors,
+                          sizeof(ddl_errors)/sizeof(ddl_errors[0]));
+    /*
+      After processing the SKIP_DDL_ERRORS, the pointer is
+      increased to the position after the comma.
+    */
+    if (strlen(arg) > SIZE_SKIP_DDL_ERRORS + 1)
+      arg+= SIZE_SKIP_DDL_ERRORS + 1;
+  }
   for (p= arg ; *p; )
   {
     long err_code;
@@ -695,8 +760,6 @@ void init_slave_skip_errors(const char* 
     while (!my_isdigit(system_charset_info,*p) && *p)
       p++;
   }
-  /* Convert slave skip errors bitmap into a printable string. */
-  print_slave_skip_errors();
   DBUG_VOID_RETURN;
 }
 

=== modified file 'sql/rpl_slave.h'
--- a/sql/rpl_slave.h	2012-03-14 09:52:49 +0000
+++ b/sql/rpl_slave.h	2012-03-22 06:25:38 +0000
@@ -178,7 +178,8 @@ int init_info(Master_info* mi, bool igno
 void end_info(Master_info* mi);
 int remove_info(Master_info* mi);
 int flush_master_info(Master_info* mi, bool force);
-void init_slave_skip_errors(const char* arg);
+void add_slave_skip_errors(const char* arg);
+void set_slave_skip_errors(char** slave_skip_errors_ptr);
 int register_slave_on_master(MYSQL* mysql);
 int terminate_slave_threads(Master_info* mi, int thread_mask,
 			     bool skip_lock = 0);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (martin.zaun:3821 to 3822) Martin Zaun22 Mar