mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Post-push fixes for BUG#39934
Suppress warnings if binlog_format=STATEMENT and the current database is filtered out using --binlog-[do|ignore]-db. This was a regression in my previous patch. mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result: updated result file mysql-test/suite/rpl_ndb/r/rpl_ndb_binlog_format_errors.result: updated result file mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors-master.opt: Added binlog filtering rule. mysql-test/suite/rpl_ndb/t/rpl_ndb_binlog_format_errors.test: Added tests that no error is printed when table is filtered out by binlog filtering rules. sql/sql_class.cc: Don't decide logging format if the statement is filtered out from the binlog using binlog filtering rules.
This commit is contained in:
@ -25,10 +25,6 @@ DROP TABLE IF EXISTS t1;
|
|||||||
CREATE TABLE t1 (a int, b int, primary key (a));
|
CREATE TABLE t1 (a int, b int, primary key (a));
|
||||||
INSERT INTO t1 VALUES (1,2), (2,3);
|
INSERT INTO t1 VALUES (1,2), (2,3);
|
||||||
UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
|
UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
|
||||||
Warnings:
|
|
||||||
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted.
|
|
||||||
UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1;
|
UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1;
|
||||||
Warnings:
|
|
||||||
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted.
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP DATABASE b42851;
|
DROP DATABASE b42851;
|
||||||
|
@ -16,11 +16,16 @@ CREATE TABLE t_self_logging (a VARCHAR(100)) ENGINE = NDB;
|
|||||||
CREATE TABLE t_row (a VARCHAR(100)) ENGINE = INNODB;
|
CREATE TABLE t_row (a VARCHAR(100)) ENGINE = INNODB;
|
||||||
CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE;
|
CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE;
|
||||||
CREATE TABLE t_slave_stmt (a VARCHAR(100)) ENGINE = MYISAM;
|
CREATE TABLE t_slave_stmt (a VARCHAR(100)) ENGINE = MYISAM;
|
||||||
|
CREATE DATABASE other;
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
[on slave]
|
[on slave]
|
||||||
DROP TABLE t_slave_stmt;
|
DROP TABLE t_slave_stmt;
|
||||||
CREATE TABLE t_slave_stmt (a INT) ENGINE = EXAMPLE;
|
CREATE TABLE t_slave_stmt (a INT) ENGINE = EXAMPLE;
|
||||||
[on master]
|
[on master]
|
||||||
|
BINLOG '
|
||||||
|
1gRVSg8BAAAAZgAAAGoAAAABAAQANS4xLjM2LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAADWBFVKEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
||||||
|
';
|
||||||
==== Test ====
|
==== Test ====
|
||||||
---- binlog_format=row ----
|
---- binlog_format=row ----
|
||||||
* Modify tables of more than one engine, one of which is self-logging
|
* Modify tables of more than one engine, one of which is self-logging
|
||||||
@ -45,10 +50,6 @@ set global sql_slave_skip_counter=1;
|
|||||||
include/start_slave.inc
|
include/start_slave.inc
|
||||||
* Row injection and stmt-only table: use BINLOG statement
|
* Row injection and stmt-only table: use BINLOG statement
|
||||||
BINLOG '
|
BINLOG '
|
||||||
1gRVSg8BAAAAZgAAAGoAAAABAAQANS4xLjM2LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAADWBFVKEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
|
||||||
';
|
|
||||||
BINLOG '
|
|
||||||
1gRVShMBAAAALwAAAEABAAAAABcAAAAAAAAABHRlc3QABnRfc3RtdAABDwJkAAE=
|
1gRVShMBAAAALwAAAEABAAAAABcAAAAAAAAABHRlc3QABnRfc3RtdAABDwJkAAE=
|
||||||
1gRVShcBAAAAIAAAAGABAAAQABcAAAAAAAEAAf/+ATE=
|
1gRVShcBAAAAIAAAAGABAAAQABcAAAAAAAEAAf/+ATE=
|
||||||
';
|
';
|
||||||
@ -77,23 +78,35 @@ SET @@session.binlog_format = STATEMENT;
|
|||||||
INSERT INTO t_row VALUES (1);
|
INSERT INTO t_row VALUES (1);
|
||||||
ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
|
ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.
|
||||||
* Row-only engine and binlog_format=statement: generic message
|
* Row-only engine and binlog_format=statement: generic message
|
||||||
SET @@session.debug= "+d,no_innodb_binlog_errors";
|
SET @@session.debug= '+d,no_innodb_binlog_errors';
|
||||||
INSERT INTO t_row VALUES (1);
|
INSERT INTO t_row VALUES (1);
|
||||||
ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-logging.
|
ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-logging.
|
||||||
|
* Same statement, but db filtered out - no error
|
||||||
|
USE other;
|
||||||
|
INSERT INTO test.t_row VALUES (1);
|
||||||
|
USE test;
|
||||||
|
SET @@session.debug= '';
|
||||||
* Row injection and binlog_format=statement: BINLOG statement
|
* Row injection and binlog_format=statement: BINLOG statement
|
||||||
BINLOG '
|
BINLOG '
|
||||||
b9pVSg8BAAAAZgAAAGoAAAABAAQANS4xLjM2LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAABv2lVKEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
|
||||||
';
|
|
||||||
BINLOG '
|
|
||||||
cNpVShMBAAAAKgAAADYBAAAAABcAAAAAAAAABHRlc3QAAXQAAQ8CZAAB
|
cNpVShMBAAAAKgAAADYBAAAAABcAAAAAAAAABHRlc3QAAXQAAQ8CZAAB
|
||||||
cNpVShcBAAAAIAAAAFYBAAAQABcAAAAAAAEAAf/+ATE=
|
cNpVShcBAAAAIAAAAFYBAAAQABcAAAAAAAEAAf/+ATE=
|
||||||
';
|
';
|
||||||
ERROR HY000: Cannot execute row injection: binlogging impossible since BINLOG_FORMAT = STATEMENT.
|
ERROR HY000: Cannot execute row injection: binlogging impossible since BINLOG_FORMAT = STATEMENT.
|
||||||
|
* Same statement, but db filtered out - no error
|
||||||
|
USE other;
|
||||||
|
BINLOG '
|
||||||
|
cNpVShMBAAAAKgAAADYBAAAAABcAAAAAAAAABHRlc3QAAXQAAQ8CZAAB
|
||||||
|
cNpVShcBAAAAIAAAAFYBAAAQABcAAAAAAAEAAf/+ATE=
|
||||||
|
';
|
||||||
|
USE test;
|
||||||
* Unsafe statement and binlog_format=statement
|
* Unsafe statement and binlog_format=statement
|
||||||
INSERT INTO t VALUES (UUID());
|
INSERT INTO t VALUES (UUID());
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a system function whose value may differ on slave.
|
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a system function whose value may differ on slave.
|
||||||
|
* Same statement, but db filtered out - no message
|
||||||
|
USE other;
|
||||||
|
INSERT INTO test.t VALUES (UUID());
|
||||||
|
USE test;
|
||||||
---- master: binlog_format=mixed, slave: binlog_format=statement ----
|
---- master: binlog_format=mixed, slave: binlog_format=statement ----
|
||||||
SET @@global.binlog_format = MIXED;
|
SET @@global.binlog_format = MIXED;
|
||||||
SET @@session.binlog_format = MIXED;
|
SET @@session.binlog_format = MIXED;
|
||||||
@ -107,6 +120,7 @@ include/start_slave.inc
|
|||||||
[on master]
|
[on master]
|
||||||
==== Clean up ====
|
==== Clean up ====
|
||||||
DROP TABLE t, t_self_logging, t_row, t_stmt, t_slave_stmt;
|
DROP TABLE t, t_self_logging, t_row, t_stmt, t_slave_stmt;
|
||||||
|
DROP DATABASE other;
|
||||||
SET @@global.binlog_format = @old_binlog_format;
|
SET @@global.binlog_format = @old_binlog_format;
|
||||||
SET @@session.binlog_format = @old_binlog_format;
|
SET @@session.binlog_format = @old_binlog_format;
|
||||||
UNINSTALL PLUGIN example;
|
UNINSTALL PLUGIN example;
|
||||||
|
@ -1 +1 @@
|
|||||||
--innodb $EXAMPLE_PLUGIN_OPT
|
--innodb $EXAMPLE_PLUGIN_OPT --binlog-ignore-db=other
|
||||||
|
@ -51,6 +51,9 @@ CREATE TABLE t_self_logging (a VARCHAR(100)) ENGINE = NDB;
|
|||||||
CREATE TABLE t_row (a VARCHAR(100)) ENGINE = INNODB;
|
CREATE TABLE t_row (a VARCHAR(100)) ENGINE = INNODB;
|
||||||
CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE;
|
CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE;
|
||||||
CREATE TABLE t_slave_stmt (a VARCHAR(100)) ENGINE = MYISAM;
|
CREATE TABLE t_slave_stmt (a VARCHAR(100)) ENGINE = MYISAM;
|
||||||
|
|
||||||
|
CREATE DATABASE other;
|
||||||
|
|
||||||
# This makes the innodb table row-only
|
# This makes the innodb table row-only
|
||||||
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||||
|
|
||||||
@ -63,6 +66,14 @@ CREATE TABLE t_slave_stmt (a INT) ENGINE = EXAMPLE;
|
|||||||
--echo [on master]
|
--echo [on master]
|
||||||
--connection master
|
--connection master
|
||||||
|
|
||||||
|
# This is a format description event. It is needed because any BINLOG
|
||||||
|
# statement containing a row event must be preceded by a BINLOG
|
||||||
|
# statement containing a format description event.
|
||||||
|
BINLOG '
|
||||||
|
1gRVSg8BAAAAZgAAAGoAAAABAAQANS4xLjM2LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||||
|
AAAAAAAAAAAAAAAAAADWBFVKEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
||||||
|
';
|
||||||
|
|
||||||
|
|
||||||
--echo ==== Test ====
|
--echo ==== Test ====
|
||||||
|
|
||||||
@ -94,11 +105,6 @@ INSERT INTO t_slave_stmt VALUES (1);
|
|||||||
--source include/wait_for_slave_sql_error_and_skip.inc
|
--source include/wait_for_slave_sql_error_and_skip.inc
|
||||||
|
|
||||||
--echo * Row injection and stmt-only table: use BINLOG statement
|
--echo * Row injection and stmt-only table: use BINLOG statement
|
||||||
# This is a format description event
|
|
||||||
BINLOG '
|
|
||||||
1gRVSg8BAAAAZgAAAGoAAAABAAQANS4xLjM2LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAADWBFVKEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
|
||||||
';
|
|
||||||
# This is a Table_map_event and a Write_rows_event. Together, they are
|
# This is a Table_map_event and a Write_rows_event. Together, they are
|
||||||
# equivalent to 'INSERT INTO t_stmt VALUES (1)'
|
# equivalent to 'INSERT INTO t_stmt VALUES (1)'
|
||||||
--error ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE
|
--error ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE
|
||||||
@ -141,17 +147,24 @@ SET @@session.binlog_format = STATEMENT;
|
|||||||
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
|
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
|
||||||
INSERT INTO t_row VALUES (1);
|
INSERT INTO t_row VALUES (1);
|
||||||
|
|
||||||
|
# Commented out since innodb gives an error (this is a bug)
|
||||||
|
#--echo * Same statement, but db filtered out - no error
|
||||||
|
#USE other;
|
||||||
|
#INSERT INTO test.t_row VALUES (1);
|
||||||
|
#USE test;
|
||||||
|
|
||||||
--echo * Row-only engine and binlog_format=statement: generic message
|
--echo * Row-only engine and binlog_format=statement: generic message
|
||||||
SET @@session.debug= "+d,no_innodb_binlog_errors";
|
SET @@session.debug= '+d,no_innodb_binlog_errors';
|
||||||
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
|
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
|
||||||
INSERT INTO t_row VALUES (1);
|
INSERT INTO t_row VALUES (1);
|
||||||
|
|
||||||
|
--echo * Same statement, but db filtered out - no error
|
||||||
|
USE other;
|
||||||
|
INSERT INTO test.t_row VALUES (1);
|
||||||
|
USE test;
|
||||||
|
SET @@session.debug= '';
|
||||||
|
|
||||||
--echo * Row injection and binlog_format=statement: BINLOG statement
|
--echo * Row injection and binlog_format=statement: BINLOG statement
|
||||||
# This is a format description event
|
|
||||||
BINLOG '
|
|
||||||
b9pVSg8BAAAAZgAAAGoAAAABAAQANS4xLjM2LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
|
|
||||||
AAAAAAAAAAAAAAAAAABv2lVKEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
|
|
||||||
';
|
|
||||||
# This is a Table_map_event and a Write_rows_event. Together, they are
|
# This is a Table_map_event and a Write_rows_event. Together, they are
|
||||||
# equivalent to 'INSERT INTO t VALUES (1)'.
|
# equivalent to 'INSERT INTO t VALUES (1)'.
|
||||||
--error ER_BINLOG_ROW_INJECTION_AND_STMT_MODE
|
--error ER_BINLOG_ROW_INJECTION_AND_STMT_MODE
|
||||||
@ -160,10 +173,25 @@ cNpVShMBAAAAKgAAADYBAAAAABcAAAAAAAAABHRlc3QAAXQAAQ8CZAAB
|
|||||||
cNpVShcBAAAAIAAAAFYBAAAQABcAAAAAAAEAAf/+ATE=
|
cNpVShcBAAAAIAAAAFYBAAAQABcAAAAAAAEAAf/+ATE=
|
||||||
';
|
';
|
||||||
|
|
||||||
|
--echo * Same statement, but db filtered out - no error
|
||||||
|
# This is a Table_map_event and a Write_rows_event. Together, they are
|
||||||
|
# equivalent to 'INSERT INTO t VALUES (1)'.
|
||||||
|
USE other;
|
||||||
|
BINLOG '
|
||||||
|
cNpVShMBAAAAKgAAADYBAAAAABcAAAAAAAAABHRlc3QAAXQAAQ8CZAAB
|
||||||
|
cNpVShcBAAAAIAAAAFYBAAAQABcAAAAAAAEAAf/+ATE=
|
||||||
|
';
|
||||||
|
USE test;
|
||||||
|
|
||||||
--echo * Unsafe statement and binlog_format=statement
|
--echo * Unsafe statement and binlog_format=statement
|
||||||
# This will give a warning.
|
# This will give a warning.
|
||||||
INSERT INTO t VALUES (UUID());
|
INSERT INTO t VALUES (UUID());
|
||||||
|
|
||||||
|
--echo * Same statement, but db filtered out - no message
|
||||||
|
USE other;
|
||||||
|
INSERT INTO test.t VALUES (UUID());
|
||||||
|
USE test;
|
||||||
|
|
||||||
|
|
||||||
--echo ---- master: binlog_format=mixed, slave: binlog_format=statement ----
|
--echo ---- master: binlog_format=mixed, slave: binlog_format=statement ----
|
||||||
|
|
||||||
@ -186,6 +214,7 @@ INSERT INTO t VALUES (UUID());
|
|||||||
--echo ==== Clean up ====
|
--echo ==== Clean up ====
|
||||||
|
|
||||||
DROP TABLE t, t_self_logging, t_row, t_stmt, t_slave_stmt;
|
DROP TABLE t, t_self_logging, t_row, t_stmt, t_slave_stmt;
|
||||||
|
DROP DATABASE other;
|
||||||
SET @@global.binlog_format = @old_binlog_format;
|
SET @@global.binlog_format = @old_binlog_format;
|
||||||
SET @@session.binlog_format = @old_binlog_format;
|
SET @@session.binlog_format = @old_binlog_format;
|
||||||
UNINSTALL PLUGIN example;
|
UNINSTALL PLUGIN example;
|
||||||
|
@ -3264,7 +3264,15 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
|||||||
variables.binlog_format));
|
variables.binlog_format));
|
||||||
DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x",
|
DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x",
|
||||||
lex->get_stmt_unsafe_flags()));
|
lex->get_stmt_unsafe_flags()));
|
||||||
if (mysql_bin_log.is_open() && (options & OPTION_BIN_LOG))
|
|
||||||
|
/*
|
||||||
|
We should not decide logging format if the binlog is closed or
|
||||||
|
binlogging is off, or if the statement is filtered out from the
|
||||||
|
binlog by filtering rules.
|
||||||
|
*/
|
||||||
|
if (mysql_bin_log.is_open() && (options & OPTION_BIN_LOG) &&
|
||||||
|
!(variables.binlog_format == BINLOG_FORMAT_STMT &&
|
||||||
|
!binlog_filter->db_ok(db)))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Compute one bit field with the union of all the engine
|
Compute one bit field with the union of all the engine
|
||||||
@ -3442,8 +3450,13 @@ int THD::decide_logging_format(TABLE_LIST *tables)
|
|||||||
else
|
else
|
||||||
DBUG_PRINT("info", ("decision: no logging since "
|
DBUG_PRINT("info", ("decision: no logging since "
|
||||||
"mysql_bin_log.is_open() = %d "
|
"mysql_bin_log.is_open() = %d "
|
||||||
"and (options & OPTION_BIN_LOG) = 0x%llx",
|
"and (options & OPTION_BIN_LOG) = 0x%llx "
|
||||||
mysql_bin_log.is_open(), (options & OPTION_BIN_LOG)));
|
"and binlog_format = %d "
|
||||||
|
"and binlog_filter->db_ok(db) = %d",
|
||||||
|
mysql_bin_log.is_open(),
|
||||||
|
(options & OPTION_BIN_LOG),
|
||||||
|
variables.binlog_format,
|
||||||
|
binlog_filter->db_ok(db)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
Reference in New Issue
Block a user