[Commits] e70fc842251: MDEV-17588 replicate-do filters cause errors when creating filtered-out tables on master with syntax unsupported on slave

sachin.setiya at mariadb.com sachin.setiya at mariadb.com
Tue May 7 09:46:13 EEST 2019


revision-id: e70fc842251b02849802ebf4b11d757961b7e2c8 (mariadb-10.1.38-114-ge70fc842251)
parent(s): 6c5e4c9bc0d9ac30f7ec7ee334630bacb58687ba
author: Sachin
committer: Sachin
timestamp: 2019-05-07 12:15:28 +0530
message:

MDEV-17588 replicate-do filters cause errors when creating filtered-out tables on master with syntax unsupported on slave

Delay throwing of error in parsing stage untill we know the result from rpl
filter.

---
 mysql-test/suite/rpl/r/rpl_mdev_17588.result    | 27 ++++++++++++++++++++++
 mysql-test/suite/rpl/t/rpl_mdev_17588-slave.opt |  1 +
 mysql-test/suite/rpl/t/rpl_mdev_17588.test      | 30 +++++++++++++++++++++++++
 sql/sql_lex.cc                                  |  5 +++++
 sql/sql_lex.h                                   | 17 ++++++++++++++
 sql/sql_parse.cc                                |  7 ++++++
 sql/sql_yacc.yy                                 | 18 ++++++++++++---
 7 files changed, 102 insertions(+), 3 deletions(-)

diff --git a/mysql-test/suite/rpl/r/rpl_mdev_17588.result b/mysql-test/suite/rpl/r/rpl_mdev_17588.result
new file mode 100644
index 00000000000..e1b017950c2
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_mdev_17588.result
@@ -0,0 +1,27 @@
+include/master-slave.inc
+[connection master]
+set sql_log_bin= 0;
+install soname 'ha_tokudb';
+set sql_log_bin= 1;
+set server_id=23;
+create table t1 (a int) engine=TokuDB;
+create table t2 (a int);
+create table t3 (a int) engine=TokuDB;
+include/wait_for_slave_sql_error.inc [errno=1286]
+show create table t1;
+ERROR 42S02: Table 'test.t1' doesn't exist
+show create table t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create table t3;
+ERROR 42S02: Table 'test.t3' doesn't exist
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+drop table t1, t2, t3;
+set sql_log_bin= 0;
+uninstall soname 'ha_tokudb';
+set sql_log_bin= 1;
+CALL mtr.add_suppression('Slave: Unknown storage engine .* Error_code: 1286');
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_mdev_17588-slave.opt b/mysql-test/suite/rpl/t/rpl_mdev_17588-slave.opt
new file mode 100644
index 00000000000..19497afd22a
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mdev_17588-slave.opt
@@ -0,0 +1 @@
+--replicate-do-table=test.t2 --replicate-do-table=test.t3 --sql-mode='NO_ENGINE_SUBSTITUTION'
diff --git a/mysql-test/suite/rpl/t/rpl_mdev_17588.test b/mysql-test/suite/rpl/t/rpl_mdev_17588.test
new file mode 100644
index 00000000000..ae65f07d2d5
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mdev_17588.test
@@ -0,0 +1,30 @@
+--source include/master-slave.inc
+
+--connection master
+set sql_log_bin= 0;
+install soname 'ha_tokudb';
+set sql_log_bin= 1;
+set server_id=23;
+
+create table t1 (a int) engine=TokuDB;
+create table t2 (a int);
+create table t3 (a int) engine=TokuDB;
+
+--connection slave
+let $slave_sql_errno= 1286;
+source include/wait_for_slave_sql_error.inc;
+--error ER_NO_SUCH_TABLE
+show create table t1;
+show create table t2;
+--error ER_NO_SUCH_TABLE
+show create table t3;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
+START SLAVE;
+--connection master
+drop table t1, t2, t3;
+set sql_log_bin= 0;
+uninstall soname 'ha_tokudb';
+set sql_log_bin= 1;
+--sync_slave_with_master
+CALL mtr.add_suppression('Slave: Unknown storage engine .* Error_code: 1286');
+--source include/rpl_end.inc
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index df868d0321f..e875fd4f52e 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -236,6 +236,11 @@ st_parsing_options::reset()
   allows_derived= TRUE;
 }
 
+void flags_func_1(flags_func_arg_struct *data)
+{
+  my_error(data->error, data->MyFlags, data->str1);
+  return;
+}
 
 /**
   Perform initialization of Lex_input_stream instance.
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 0142f812632..ead0b82b51b 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -215,6 +215,15 @@ typedef struct st_lex_server_options
   }
 } LEX_SERVER_OPTIONS;
 
+typedef struct
+{
+  uint error;
+  myf MyFlags;
+  char *str1;
+  char *str2;
+} flags_func_arg_struct;
+typedef void (*flags_func_ptr)(flags_func_arg_struct *);
+void flags_func_1(flags_func_arg_struct *data);
 
 /**
   Structure to hold parameters for CHANGE MASTER, START SLAVE, and STOP SLAVE.
@@ -240,6 +249,13 @@ struct LEX_MASTER_INFO
   ulong server_id;
   uint port, connect_retry;
   float heartbeat_period;
+  /* array for flags for error generated in parsing filtered transactions on slave */
+  bool flags[1]; // Currently only 1 should be increased in future.
+  /*
+    Corresponding function to be called when flag is turned on
+  */
+  flags_func_ptr flags_func[1];
+  flags_func_arg_struct flags_func_args[1];
   /*
     Enum is used for making it possible to detect if the user
     changed variable or if it should be left at old value
@@ -260,6 +276,7 @@ struct LEX_MASTER_INFO
                           sizeof(ulong), 0, 16, MYF(0));
     my_init_dynamic_array(&repl_ignore_domain_ids,
                           sizeof(ulong), 0, 16, MYF(0));
+    this->flags_func[0]= flags_func_1;
   }
   void reset(bool is_change_master)
   {
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6649c60f827..83b0f0a7de1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2656,6 +2656,13 @@ mysql_execute_command(THD *thd)
       /* we warn the slave SQL thread */
       my_message(ER_SLAVE_IGNORED_TABLE, ER_THD(thd, ER_SLAVE_IGNORED_TABLE),
                  MYF(0));
+      thd->lex->mi.flags[0]= false;
+      DBUG_RETURN(0);
+    }
+    if (thd->lex->mi.flags[0])
+    {
+      thd->lex->mi.flags_func[0](&thd->lex->mi.flags_func_args[0]);
+      thd->lex->mi.flags[0]= false;
       DBUG_RETURN(0);
     }
     /* 
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 5111f0690ab..c817ca441ca 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -2476,7 +2476,7 @@ create:
             LEX *lex= thd->lex;
             lex->current_select= &lex->select_lex; 
             if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
-                !lex->create_info.db_type)
+                !lex->create_info.db_type && !thd->lex->mi.flags[0])
             {
               lex->create_info.use_default_db_type(thd);
               push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
@@ -5791,9 +5791,21 @@ storage_engines:
             else
             {
               if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
-                my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str));
+              {
+                if (!thd->slave_thread)
+                  my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str));
+                else
+                {
+                  thd->lex->mi.flags[0]= true;
+                  thd->lex->mi.flags_func_args[0].error= ER_UNKNOWN_STORAGE_ENGINE;
+
+                  thd->lex->mi.flags_func_args[0].MyFlags= 0;
+                  thd->lex->mi.flags_func_args[0].str1= $1.str;
+                }
+              }
               $$= 0;
-              push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+              if (!thd->lex->mi.flags[0])
+                push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
                                   ER_UNKNOWN_STORAGE_ENGINE,
                                   ER_THD(thd, ER_UNKNOWN_STORAGE_ENGINE),
                                   $1.str);


More information about the commits mailing list