From c68e73b53fa2e1d6c60930f5f85f0ac52dabc825 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Mon, 17 Nov 2014 09:55:53 -0500 Subject: [PATCH] MDEV-6924 : Server crashed on CREATE TABLE ... SELECT Do not allow server to start if binlog_format is set to a format other than ROW. Also restrict the change of GLOBAL/SESSION binlog_format value at runtime. --- mysql-test/suite/galera/r/create.result | 23 +++++++++++ mysql-test/suite/galera/t/create.test | 26 +++++++++++++ mysql-test/suite/wsrep/r/binlog_format.result | 16 ++++++++ mysql-test/suite/wsrep/t/binlog_format.test | 13 +++++++ mysql-test/suite/wsrep/t/pool_of_threads.test | 1 + sql/mysqld.cc | 9 +++++ sql/sql_class.cc | 10 +++++ sql/sys_vars.cc | 38 +++++++++---------- 8 files changed, 116 insertions(+), 20 deletions(-) create mode 100644 mysql-test/suite/galera/r/create.result create mode 100644 mysql-test/suite/galera/t/create.test diff --git a/mysql-test/suite/galera/r/create.result b/mysql-test/suite/galera/r/create.result new file mode 100644 index 00000000000..4dffe96d719 --- /dev/null +++ b/mysql-test/suite/galera/r/create.result @@ -0,0 +1,23 @@ +# +# MDEV-6924 : Server crashed on CREATE TABLE ... SELECT +# +SET @wsrep_forced_binlog_format_saved=@@GLOBAL.wsrep_forced_binlog_format; +SET @@GLOBAL.wsrep_forced_binlog_format=STATEMENT; +SHOW VARIABLES LIKE '%log%bin%'; +Variable_name Value +log_bin OFF +log_bin_trust_function_creators ON +sql_log_bin ON +USE test; +CREATE TABLE t1(i INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +CREATE TEMPORARY TABLE `t1_temp` AS SELECT * FROM `t1` WHERE i = 1; +SELECT * FROM t1; +i +1 +SELECT * FROM t1_temp; +i +1 +DROP TABLE t1; +SET @@GLOBAL.wsrep_forced_binlog_format=@wsrep_forced_binlog_format_saved; +# End of tests diff --git a/mysql-test/suite/galera/t/create.test b/mysql-test/suite/galera/t/create.test new file mode 100644 index 00000000000..b56a841fb65 --- /dev/null +++ b/mysql-test/suite/galera/t/create.test @@ -0,0 +1,26 @@ +--source include/galera_cluster.inc +--source include/have_innodb.inc + +--echo # +--echo # MDEV-6924 : Server crashed on CREATE TABLE ... SELECT +--echo # + +SET @wsrep_forced_binlog_format_saved=@@GLOBAL.wsrep_forced_binlog_format; +SET @@GLOBAL.wsrep_forced_binlog_format=STATEMENT; + +# @@log_bin must be OFF +SHOW VARIABLES LIKE '%log%bin%'; + +USE test; +CREATE TABLE t1(i INT) ENGINE=INNODB; +INSERT INTO t1 VALUES(1); +CREATE TEMPORARY TABLE `t1_temp` AS SELECT * FROM `t1` WHERE i = 1; +SELECT * FROM t1; +SELECT * FROM t1_temp; + +# Cleanup +DROP TABLE t1; +SET @@GLOBAL.wsrep_forced_binlog_format=@wsrep_forced_binlog_format_saved; + +--echo # End of tests + diff --git a/mysql-test/suite/wsrep/r/binlog_format.result b/mysql-test/suite/wsrep/r/binlog_format.result index 5b8da51f829..2ce3d0b49c5 100644 --- a/mysql-test/suite/wsrep/r/binlog_format.result +++ b/mysql-test/suite/wsrep/r/binlog_format.result @@ -1,5 +1,6 @@ call mtr.add_suppression("WSREP: cannot get fake InnoDB transaction ID"); call mtr.add_suppression("WSREP: Could not open saved state file for reading:.*"); +call mtr.add_suppression("WSREP: MariaDB Galera does not support binlog format.*"); SHOW VARIABLES LIKE 'binlog_format'; Variable_name Value binlog_format ROW @@ -33,3 +34,18 @@ CREATE TABLE IF NOT EXISTS test.t3 AS SELECT * FROM information_schema.routines DROP TABLE IF EXISTS test.t1; DROP TABLE IF EXISTS test.t2; DROP TABLE IF EXISTS test.t3; +SET @@GLOBAL.binlog_format=STATEMENT; +ERROR 42000: Variable 'binlog_format' can't be set to the value of 'STATEMENT' +SHOW GLOBAL VARIABLES LIKE 'binlog_format'; +Variable_name Value +binlog_format ROW +SET @@GLOBAL.binlog_format=MIXED; +ERROR 42000: Variable 'binlog_format' can't be set to the value of 'MIXED' +SHOW GLOBAL VARIABLES LIKE 'binlog_format'; +Variable_name Value +binlog_format ROW +SET @@GLOBAL.binlog_format=ROW; +SHOW GLOBAL VARIABLES LIKE 'binlog_format'; +Variable_name Value +binlog_format ROW +# End of test. diff --git a/mysql-test/suite/wsrep/t/binlog_format.test b/mysql-test/suite/wsrep/t/binlog_format.test index d2035b28550..561e4d77ea9 100644 --- a/mysql-test/suite/wsrep/t/binlog_format.test +++ b/mysql-test/suite/wsrep/t/binlog_format.test @@ -5,6 +5,7 @@ # call mtr.add_suppression("WSREP: cannot get fake InnoDB transaction ID"); call mtr.add_suppression("WSREP: Could not open saved state file for reading:.*"); +call mtr.add_suppression("WSREP: MariaDB Galera does not support binlog format.*"); SHOW VARIABLES LIKE 'binlog_format'; -- error ER_WRONG_VALUE_FOR_VAR @@ -25,3 +26,15 @@ DROP TABLE IF EXISTS test.t1; DROP TABLE IF EXISTS test.t2; DROP TABLE IF EXISTS test.t3; +-- error ER_WRONG_VALUE_FOR_VAR +SET @@GLOBAL.binlog_format=STATEMENT; +SHOW GLOBAL VARIABLES LIKE 'binlog_format'; + +-- error ER_WRONG_VALUE_FOR_VAR +SET @@GLOBAL.binlog_format=MIXED; +SHOW GLOBAL VARIABLES LIKE 'binlog_format'; + +SET @@GLOBAL.binlog_format=ROW; +SHOW GLOBAL VARIABLES LIKE 'binlog_format'; + +--echo # End of test. diff --git a/mysql-test/suite/wsrep/t/pool_of_threads.test b/mysql-test/suite/wsrep/t/pool_of_threads.test index f4fffaf4f9a..dbf429e3f01 100644 --- a/mysql-test/suite/wsrep/t/pool_of_threads.test +++ b/mysql-test/suite/wsrep/t/pool_of_threads.test @@ -1,4 +1,5 @@ --source include/have_wsrep.inc +--source include/have_binlog_format_row.inc --echo --echo # diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6304b903737..63091da6133 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8746,6 +8746,15 @@ static int get_options(int *argc_ptr, char ***argv_ptr) global_system_variables.option_bits&= ~OPTION_BIG_SELECTS; #ifdef WITH_WSREP + if (!opt_bootstrap && WSREP_PROVIDER_EXISTS && + global_system_variables.binlog_format != BINLOG_FORMAT_ROW) { + + WSREP_ERROR ("Only binlog_format = 'ROW' is currently supported. " + "Configured value: '%s'. Please adjust your configuration.", + binlog_format_names[global_system_variables.binlog_format]); + return 1; + } + if (global_system_variables.wsrep_causal_reads) { WSREP_WARN("option --wsrep-casual-reads is deprecated"); if (!(global_system_variables.wsrep_sync_wait & diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 14821f0e027..c28966bcbcf 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5885,6 +5885,16 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg, The MYSQL_LOG::write() function will set the STMT_END_F flag and flush the pending rows event if necessary. */ +#ifdef WITH_WSREP + /* + Even though wsrep only supports ROW binary log format, a user can set + binlog format to STATEMENT (wsrep_forced_binlog_format). In which case + the control might reach here even when binary logging (--log-bin) is + not enabled. This is possible because wsrep patch partially enables + binary logging by setting wsrep_emulate_binlog. + */ + if (mysql_bin_log.is_open()) +#endif /* WITH_WSREP */ { Query_log_event qinfo(this, query_arg, query_len, is_trans, direct, suppress_use, errcode); diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 578d24a17e8..f55edd31320 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -280,6 +280,24 @@ static bool binlog_format_check(sys_var *self, THD *thd, set_var *var) if (check_has_super(self, thd, var)) return true; +#ifdef WITH_WSREP + /* + MariaDB Galera does not support STATEMENT or MIXED binlog format currently. + */ + if (WSREP(thd) && + var->save_result.ulonglong_value != BINLOG_FORMAT_ROW) + { + WSREP_ERROR("MariaDB Galera does not support binlog format: %s", + binlog_format_names[var->save_result.ulonglong_value]); + + // Also push a warning because error message is general. + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, + "MariaDB Galera does not support binlog format: %s", + binlog_format_names[var->save_result.ulonglong_value]); + return true; + } +#endif + if (var->type == OPT_GLOBAL) return false; @@ -308,26 +326,6 @@ static bool binlog_format_check(sys_var *self, THD *thd, set_var *var) ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT)) return true; -#ifdef WITH_WSREP - /* MariaDB Galera does not support STATEMENT or MIXED binlog - format currently */ - if (WSREP(thd) && - (var->save_result.ulonglong_value == BINLOG_FORMAT_STMT || - var->save_result.ulonglong_value == BINLOG_FORMAT_MIXED)) - { - WSREP_DEBUG("MariaDB Galera does not support binlog format : %s", - var->save_result.ulonglong_value == BINLOG_FORMAT_STMT ? - "STATEMENT" : "MIXED"); - /* Push also warning, because error message is general */ - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_UNKNOWN_ERROR, - "MariaDB Galera does not support binlog format: %s", - var->save_result.ulonglong_value == BINLOG_FORMAT_STMT ? - "STATEMENT" : "MIXED"); - return true; - } -#endif - return false; }