From 9c89b84d46e0645820acb9e3cc339af10c68cfb7 Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Fri, 18 Mar 2016 11:27:32 -0400 Subject: [PATCH] MDEV-9401: wsrep_forced_binlog_format with binlog causes crash Some statements are always replicated in STATEMENT binlog format. So upon their execution, the current binlog format is temporarily switched to STATEMENT even though the session's format is different. This state, stored in THD's current_stmt_binlog_format, was getting incorrectly masked by wsrep_forced_binlog_format, causing assertions and unintended generation of row events. Backported galera.galera_forced_binlog_format and added a test specific to this case. --- .../r/galera_forced_binlog_format.result | 40 +++++++++++++++++ .../t/galera_forced_binlog_format-master.opt | 1 + .../galera/t/galera_forced_binlog_format.test | 45 +++++++++++++++++++ sql/sql_class.h | 3 +- 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/galera/r/galera_forced_binlog_format.result create mode 100644 mysql-test/suite/galera/t/galera_forced_binlog_format-master.opt create mode 100644 mysql-test/suite/galera/t/galera_forced_binlog_format.test diff --git a/mysql-test/suite/galera/r/galera_forced_binlog_format.result b/mysql-test/suite/galera/r/galera_forced_binlog_format.result new file mode 100644 index 00000000000..f08aad8be1a --- /dev/null +++ b/mysql-test/suite/galera/r/galera_forced_binlog_format.result @@ -0,0 +1,40 @@ +RESET MASTER; +SET SESSION binlog_format = 'STATEMENT'; +Warnings: +Warning 1105 MariaDB Galera does not support binlog format: STATEMENT +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +SET SESSION binlog_format = 'MIXED'; +Warnings: +Warning 1105 MariaDB Galera does not support binlog format: MIXED +INSERT INTO t1 VALUES (2); +SHOW BINLOG EVENTS IN 'mysqld-bin.000001' FROM 245; +Log_name Pos Event_type Server_id End_log_pos Info +mysqld-bin.000001 Query 1 use `test`; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB +mysqld-bin.000001 Query 1 BEGIN +mysqld-bin.000001 Table_map 1 table_id: ### (test.t1) +mysqld-bin.000001 Write_rows 1 table_id: ### flags: STMT_END_F +mysqld-bin.000001 Xid 1 COMMIT /* xid=### */ +mysqld-bin.000001 Query 1 BEGIN +mysqld-bin.000001 Table_map 1 table_id: ### (test.t1) +mysqld-bin.000001 Write_rows 1 table_id: ### flags: STMT_END_F +mysqld-bin.000001 Xid 1 COMMIT /* xid=### */ +DROP TABLE t1; +# +# MDEV-9401: wsrep_forced_binlog_format with binlog causes crash +# +SET SESSION binlog_format = 'ROW'; +CREATE DATABASE testdb_9401; +USE testdb_9401; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +CREATE USER dummy@localhost; +GRANT ALL PRIVILEGES ON testdb_9401.t1 TO dummy@localhost; +FLUSH PRIVILEGES; +SHOW GRANTS FOR dummy@localhost; +Grants for dummy@localhost +GRANT USAGE ON *.* TO 'dummy'@'localhost' +GRANT ALL PRIVILEGES ON `testdb_9401`.`t1` TO 'dummy'@'localhost' +REVOKE ALL PRIVILEGES, GRANT OPTION FROM dummy@localhost; +DROP USER dummy@localhost; +DROP DATABASE testdb_9401; +# End of tests diff --git a/mysql-test/suite/galera/t/galera_forced_binlog_format-master.opt b/mysql-test/suite/galera/t/galera_forced_binlog_format-master.opt new file mode 100644 index 00000000000..8c58b59b45d --- /dev/null +++ b/mysql-test/suite/galera/t/galera_forced_binlog_format-master.opt @@ -0,0 +1 @@ +--log-bin --wsrep_forced_binlog_format=ROW diff --git a/mysql-test/suite/galera/t/galera_forced_binlog_format.test b/mysql-test/suite/galera/t/galera_forced_binlog_format.test new file mode 100644 index 00000000000..38e07526de1 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_forced_binlog_format.test @@ -0,0 +1,45 @@ +# +# Test that wsrep_forced_binlog_format=ROW indeed prevents the log to be switched to STATEMENT format on a per-connection basis +# + +--source include/have_log_bin.inc +--source include/have_innodb.inc +--source include/galera_cluster.inc + +--connection node_1 +RESET MASTER; + +SET SESSION binlog_format = 'STATEMENT'; + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); + +SET SESSION binlog_format = 'MIXED'; + +INSERT INTO t1 VALUES (2); + +--replace_regex /xid=[0-9]+/xid=###/ /table_id: [0-9]+/table_id: ###/ +--replace_column 2 5 +SHOW BINLOG EVENTS IN 'mysqld-bin.000001' FROM 245; + +DROP TABLE t1; + +--echo # +--echo # MDEV-9401: wsrep_forced_binlog_format with binlog causes crash +--echo # +SET SESSION binlog_format = 'ROW'; +CREATE DATABASE testdb_9401; +USE testdb_9401; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +CREATE USER dummy@localhost; +GRANT ALL PRIVILEGES ON testdb_9401.t1 TO dummy@localhost; +FLUSH PRIVILEGES; +SHOW GRANTS FOR dummy@localhost; +# Cleanup +REVOKE ALL PRIVILEGES, GRANT OPTION FROM dummy@localhost; +DROP USER dummy@localhost; +DROP DATABASE testdb_9401; + +--source include/galera_end.inc +--echo # End of tests + diff --git a/sql/sql_class.h b/sql/sql_class.h index 6c072fe513e..48f0776c340 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1824,8 +1824,7 @@ public: int is_current_stmt_binlog_format_row() const { DBUG_ASSERT(current_stmt_binlog_format == BINLOG_FORMAT_STMT || current_stmt_binlog_format == BINLOG_FORMAT_ROW); - return (WSREP_BINLOG_FORMAT((ulong)current_stmt_binlog_format) == - BINLOG_FORMAT_ROW); + return current_stmt_binlog_format == BINLOG_FORMAT_ROW; } private: