1
0
mirror of https://github.com/MariaDB/server.git synced 2025-10-24 07:13:33 +03:00

merged fixes for BUG#39934 to 5.1-rpl+3

Also renamed current_stmt_binlog_row_based to
current_stmt_binlog_format_row for consistency
This commit is contained in:
Sven Sandberg
2009-09-30 18:00:22 +02:00
123 changed files with 6016 additions and 6594 deletions

View File

@@ -14,12 +14,12 @@ SET BINLOG_FORMAT=STATEMENT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
UPDATE t1 SET b = 1*a WHERE a > 1;
ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-UNCOMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
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.
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
UPDATE t1 SET b = 2*a WHERE a > 2;
ERROR HY000: Binary logging not possible. Message: Transaction level 'READ-COMMITTED' in InnoDB is not safe for binlog mode 'STATEMENT'
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.
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

View File

@@ -42,7 +42,7 @@ INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
ERROR HY000: Binary logging not possible. Message: Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging
ERROR HY000: Cannot execute statement: binlogging impossible since more than one engine is involved and at least one engine is self-logging.
TRUNCATE t1m;
TRUNCATE t1b;
TRUNCATE t1n;
@@ -68,9 +68,9 @@ INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
ERROR HY000: Binary logging not possible. Message: Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging
ERROR HY000: Cannot execute statement: binlogging impossible since more than one engine is involved and at least one engine is self-logging.
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
ERROR HY000: Binary logging not possible. Message: Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging
ERROR HY000: Cannot execute statement: binlogging impossible since more than one engine is involved and at least one engine is self-logging.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
mysqld-bin.000001 # Query # # BEGIN

View File

@@ -12,7 +12,11 @@ master-bin.000001 # Query # # use `test`; insert delayed into t1 values (null)
master-bin.000001 # Query # # use `test`; insert delayed into t1 values (300)
master-bin.000001 # Query # # use `test`; FLUSH TABLES
insert delayed into t1 values (null),(null),(null),(null);
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses INSERT DELAYED. This is unsafe because the time when rows are inserted cannot be predicted.
insert delayed into t1 values (null),(null),(400),(null);
Warnings:
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses INSERT DELAYED. This is unsafe because the time when rows are inserted cannot be predicted.
select * from t1;
a
207

View File

@@ -11,7 +11,7 @@ prepare s from "insert into t1 select 100 limit ?";
set @a=100;
execute s using @a;
Warnings:
Note 1592 Statement may not be safe to log in statement format.
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.
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; create table t1 (a int)

View File

@@ -4,10 +4,10 @@ CREATE TABLE t1 (a int, b int, primary key (a));
INSERT INTO t1 VALUES (1,2), (2,3);
UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
Warnings:
Note 1592 Statement may not be safe to log in statement format.
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;
Warnings:
Note 1592 Statement may not be safe to log in statement format.
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;
### NOT filtered database => assertion: binlog disabled and warnings ARE NOT shown
SET SQL_LOG_BIN= 0;
@@ -38,11 +38,11 @@ CREATE TABLE t1 (a VARCHAR(36), b VARCHAR(10));
SET GLOBAL LOG_WARNINGS = 0;
INSERT INTO t1 VALUES(UUID(), 'Bug#46265');
Warnings:
Note 1592 Statement may not be safe to log in statement format.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a system function whose value may differ on slave.
SET GLOBAL LOG_WARNINGS = 1;
INSERT INTO t1 VALUES(UUID(), 'Bug#46265');
Warnings:
Note 1592 Statement may not be safe to log in statement format.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a system function whose value may differ on slave.
DROP TABLE t1;
SET GLOBAL log_warnings = @old_log_warnings;
# Count the number of times the "Unsafe" message was printed

File diff suppressed because it is too large Load Diff

View File

@@ -27,13 +27,13 @@ SET BINLOG_FORMAT=STATEMENT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
error ER_BINLOG_LOGGING_IMPOSSIBLE;
error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE;
UPDATE t1 SET b = 1*a WHERE a > 1;
COMMIT;
BEGIN;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
error ER_BINLOG_LOGGING_IMPOSSIBLE;
error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE;
UPDATE t1 SET b = 2*a WHERE a > 2;
COMMIT;

View File

@@ -60,7 +60,7 @@ let $wait_binlog_event= COMMIT;
source include/wait_for_binlog_event.inc;
UPDATE t1m, t1b SET m = 2, b = 3 WHERE n = c;
error ER_BINLOG_LOGGING_IMPOSSIBLE;
error ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE;
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
# Not possible to test this since NDB writes its own binlog, which
@@ -84,7 +84,7 @@ INSERT INTO t1m VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1b VALUES (1,1), (1,2), (2,1), (2,2);
INSERT INTO t1n VALUES (1,1), (1,2), (2,1), (2,2);
error ER_BINLOG_LOGGING_IMPOSSIBLE;
error ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE;
UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
# Not possible to test this since NDB writes its own binlog, which
@@ -93,7 +93,7 @@ UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
#UPDATE t1m, t1n SET m = 2, e = 3 WHERE n = f;
error ER_BINLOG_LOGGING_IMPOSSIBLE;
error ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE;
UPDATE t1n, t1b SET e = 2, b = 3 WHERE f = c;
source include/show_binlog_events.inc;

View File

@@ -0,0 +1 @@
$UDF_EXAMPLE_LIB_OPT

View File

@@ -1,34 +1,61 @@
# ==== Background ====
#
# Some statements may execute differently on master and slave when
# logged in statement format. Such statements are called unsafe.
# Unsafe statements include:
#
# - statements using @@variables (with a small number of exceptions;
# see below);
# - statements using certain functions, e.g., UUID();
# - statements using LIMIT;
# - INSERT DELAYED;
# - insert into two autoinc columns;
# - statements using UDF's.
# - statements reading from log tables in the mysql database.
#
# Note that statements that use stored functions, stored procedures,
# triggers, views, or prepared statements that invoke unsafe
# statements shall also be unsafe.
#
# Unsafeness of a statement shall have the following consequences:
#
# 1. If the binlogging is on and the unsafe statement is logged:
# - If binlog_format=STATEMENT, the statement shall give a warning.
# - If binlog_format=MIXED or binlog_format=ROW, the statement shall
# be logged in row format.
#
# 2. If binlogging is off or the statement is not logged (e.g. SELECT
# UUID()), no warning shall be issued and the statement shall not
# be logged.
#
# Moreover, when a sub-statement of a recursive construct (i.e.,
# stored function, stored procedure, trigger, view, or prepared
# statement) is unsafe and binlog_format=STATEMENT, then a warning
# shall be issued for every recursive construct. In effect, this
# creates a stack trace from the top-level statement to the unsafe
# statement.
#
#
# ==== Purpose ====
#
# Some statements can not be written to the binlog in a safe manner
# with statement-based replication, either because they rely on
# features that are local to the server they are replicated from
# (e.g., @@variables), or because they include nondeterministic
# queries (e.g., LIMIT), or because the time at which the query is
# executed cannot be determined (e.g., INSERT DELAYED). Such
# statements should be marked unsafe. All unsafe statements should
# give a warning.
# Yet the warning/error message isn't issued when SQL_LOG_BIN is turned off.
# This test verifies that a warning is generated when it should,
# according to the rules above.
#
# This test verifies that a warning is generated for statements that
# should be unsafe, when they are executed under statement mode
# logging.
#
# All variables should be unsafe, with some exceptions. Therefore,
# this test also verifies that the exceptions do *not* generare a
# All @@variables should be unsafe, with some exceptions. Therefore,
# this test also verifies that the exceptions do *not* generate a
# warning.
#
#
# ==== Method ====
#
# We try an INSERT DELAYED statement and verify that a warning is
# issued.
# 1. Each type of statements listed above is executed.
#
# We try to insert unsafe variables into a table in several ways:
# directly with an INSERT statement, from a stored procedure, from a
# stored function, from a trigger, from a prepared statement, and from
# a complicated nesting of triggers, functions, procedures, and
# prepared statements. In all cases, a warning should be issued.
# 2. Each unsafe statement is wrapped in each type of recursive
# construct (stored function, stored procedure, trigger, view, or
# prepared statement).
#
# 3. Each unsafe statement is wrapped in two levels of recursive
# constructs (function invoking trigger invoking UUID(), etc).
#
# We try to insert the variables that should not be unsafe into a
# table, and verify that *no* warning is issued.
@@ -38,7 +65,8 @@
# Execute a unsafe statement calling a trigger or stored function
# or neither when @@SQL_LOG_BIN is turned OFF,
# no warning/error is issued
#
#
# ==== Related bugs and worklogs ====
#
# WL#3339: Issue warnings when statement-based replication may fail
@@ -47,6 +75,9 @@
# BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed
# BUG#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0
# BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode)
# BUG#45825: INSERT DELAYED is not unsafe: logged in statement format
# BUG#45785: LIMIT in SP does not cause RBL if binlog_format=MIXED
#
#
# ==== Related test cases ====
#
@@ -57,192 +88,311 @@
# rpl.rpl_variables_stm tests the small subset of variables that
# actually can be replicated safely in statement mode.
#
#
# ==== Todo ====
#
# There are several other ways to create unsafe statements: see, e.g.,
# WL#3339, BUG#34768.
# rpl_ndb.rpl_ndb_binlog_format_errors tests all errors and warnings
# related to logging format (not just 'Unsafe statement binlogged in
# statement mode since BINLOG_FORMAT = STATEMENT').
source include/have_log_bin.inc;
source include/have_binlog_format_statement.inc;
--source include/have_udf.inc
--source include/have_log_bin.inc
--source include/have_binlog_format_statement.inc
--echo ==== Setup tables ====
--echo #### Setup tables ####
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a CHAR(40));
CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY);
CREATE TABLE trigger_table (a CHAR(7));
CREATE TABLE trigger_table2 (a INT);
CREATE TABLE t0 (a CHAR(100));
CREATE TABLE t1 (a CHAR(100));
CREATE TABLE t2 (a CHAR(100));
CREATE TABLE t3 (a CHAR(100));
CREATE TABLE ta0 (a CHAR(100));
CREATE TABLE ta1 (a CHAR(100));
CREATE TABLE ta2 (a CHAR(100));
CREATE TABLE ta3 (a CHAR(100));
CREATE TABLE autoinc_table (a INT PRIMARY KEY AUTO_INCREMENT);
CREATE TABLE data_table (a CHAR(100));
INSERT INTO data_table VALUES ('foo');
CREATE TABLE trigger_table_1 (a INT);
CREATE TABLE trigger_table_2 (a INT);
CREATE TABLE trigger_table_3 (a INT);
CREATE TABLE double_autoinc_table (a INT PRIMARY KEY AUTO_INCREMENT);
--echo ==== Non-deterministic statements ====
INSERT DELAYED INTO t1 VALUES (5);
--echo ==== Some variables that *should* be unsafe ====
--echo ---- Insert directly ----
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
--echo ---- Insert from stored procedure ----
DELIMITER |;
CREATE PROCEDURE proc()
--DELIMITER |
CREATE TRIGGER double_autoinc_trig
BEFORE INSERT ON double_autoinc_table FOR EACH ROW
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
DELIMITER ;|
CALL proc();
--echo ---- Insert from stored function ----
DELIMITER |;
CREATE FUNCTION func()
RETURNS INT
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
RETURN 0;
END|
DELIMITER ;|
SELECT func();
--echo ---- Insert from trigger ----
DELIMITER |;
CREATE TRIGGER trig
BEFORE INSERT ON trigger_table
FOR EACH ROW
BEGIN
INSERT INTO t1 VALUES (@@global.sync_binlog);
INSERT INTO t1 VALUES (@@session.insert_id);
INSERT INTO t1 VALUES (@@global.auto_increment_increment);
INSERT INTO t2 SELECT UUID();
INSERT INTO t2 VALUES (@@session.sql_mode);
INSERT INTO t2 VALUES (@@global.init_slave);
INSERT INTO t2 VALUES (@@hostname);
END|
DELIMITER ;|
INSERT INTO trigger_table VALUES ('bye.');
--echo ---- Insert from prepared statement ----
PREPARE p1 FROM 'INSERT INTO t1 VALUES (@@global.sync_binlog)';
PREPARE p2 FROM 'INSERT INTO t1 VALUES (@@session.insert_id)';
PREPARE p3 FROM 'INSERT INTO t1 VALUES (@@global.auto_increment_increment)';
PREPARE p4 FROM 'INSERT INTO t2 SELECT UUID()';
PREPARE p5 FROM 'INSERT INTO t2 VALUES (@@session.sql_mode)';
PREPARE p6 FROM 'INSERT INTO t2 VALUES (@@global.init_slave)';
PREPARE p7 FROM 'INSERT INTO t2 VALUES (@@hostname)';
EXECUTE p1; EXECUTE p2; EXECUTE p3; EXECUTE p4; EXECUTE p5;
EXECUTE p6; EXECUTE p7;
--echo ---- Insert from nested call of triggers / functions / procedures ----
DELIMITER |;
# proc1: cause trigger 'trig' above to be triggered.
CREATE PROCEDURE proc1()
INSERT INTO trigger_table VALUES ('ha!')|
# func2: call proc1 above.
CREATE FUNCTION func2()
RETURNS INT
BEGIN
CALL proc1();
RETURN 0;
INSERT INTO autoinc_table VALUES (NULL);
END|
# trig3: call func2 above
CREATE TRIGGER trig3
BEFORE INSERT ON trigger_table2
FOR EACH ROW
CREATE FUNCTION multi_unsafe_func() RETURNS INT
BEGIN
DECLARE tmp INT;
SELECT func2() INTO tmp;
INSERT INTO t0 VALUES(CONCAT(@@hostname, @@hostname));
INSERT INTO t0 VALUES(0);
INSERT INTO t0 VALUES(CONCAT(UUID(), @@hostname));
RETURN 1;
END|
--DELIMITER ;
# proc4: cause trig3 above to be triggered.
CREATE PROCEDURE proc4()
INSERT INTO trigger_table2 VALUES (1)|
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
--eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB"
# func5: call proc4 above.
CREATE FUNCTION func5()
RETURNS INT
BEGIN
CALL proc4;
RETURN 0;
END|
# In each iteration of this loop, we select one method to make the
# statement unsafe.
--let $unsafe_type= 0
while (`SELECT $unsafe_type < 9`) {
# prep6: call func5() above.
PREPARE prep6 FROM 'SELECT func5()'|
--echo
DELIMITER ;|
if (`SELECT $unsafe_type = 0`) {
--echo ==== Testing UUID() unsafeness ====
--let $desc_0= unsafe UUID() function
--let $stmt_sidef_0= INSERT INTO t0 VALUES (UUID())
--let $value_0= UUID()
--let $sel_sidef_0=
--let $sel_retval_0= SELECT UUID()
--let $CRC_ARG_expected_number_of_warnings= 1
}
# try a complicated call path to trigger 'trig'.
EXECUTE prep6;
if (`SELECT $unsafe_type = 1`) {
--echo ==== Testing @@hostname unsafeness ====
--let $desc_0= unsafe @@hostname variable
--let $stmt_sidef_0= INSERT INTO t0 VALUES (@@hostname)
--let $value_0= @@hostname
--let $sel_sidef_0=
# $sel_retval is going to be used in views. Views cannot execute
# statements that refer to @@variables. Hence, we set $set_retval
# to empty instead of SELECT @@hostname.
--let $sel_retval_0=
--let $CRC_ARG_expected_number_of_warnings= 1
}
if (`SELECT $unsafe_type = 2`) {
--echo ==== Testing SELECT...LIMIT unsafeness ====
--let $desc_0= unsafe SELECT...LIMIT statement
--let $stmt_sidef_0= INSERT INTO t0 SELECT * FROM data_table LIMIT 1
--let $value_0=
--let $sel_sidef_0=
--let $sel_retval_0= SELECT * FROM data_table LIMIT 1
--let $CRC_ARG_expected_number_of_warnings= 1
}
if (`SELECT $unsafe_type = 3`) {
--echo ==== Testing INSERT DELAYED unsafeness ====
--let $desc_0= unsafe INSERT DELAYED statement
--let $stmt_sidef_0= INSERT DELAYED INTO t0 VALUES (1), (2)
--let $value_0=
--let $sel_sidef_0=
--let $sel_retval_0=
--let $CRC_ARG_expected_number_of_warnings= 1
}
if (`SELECT $unsafe_type = 4`) {
--echo ==== Testing unsafeness of insert of two autoinc values ====
--let $desc_0= unsafe update of two autoinc columns
--let $stmt_sidef_0= INSERT INTO double_autoinc_table VALUES (NULL)
--let $value_0=
--let $sel_sidef_0=
--let $sel_retval_0=
# Note: we will expect 1 warning when BUG#45827 is fixed.
--let $CRC_ARG_expected_number_of_warnings= 0
}
if (`SELECT $unsafe_type = 5`) {
--echo ==== Testing unsafeness of UDF's ====
--let $desc_0= unsafe UDF
--let $stmt_sidef_0= INSERT INTO t0 VALUES (myfunc_int(10))
--let $value_0= myfunc_int(10)
--let $sel_sidef_0= SELECT myfunc_int(10)
--let $sel_retval_0=
--let $CRC_ARG_expected_number_of_warnings= 1
}
if (`SELECT $unsafe_type = 6`) {
--echo ==== Testing unsafeness of access to mysql.general_log ====
--let $desc_0= unsafe use of mysql.general_log
--let $stmt_sidef_0= INSERT INTO t0 SELECT COUNT(*) FROM mysql.general_log
--let $value_0=
--let $sel_sidef_0=
--let $sel_retval_0= SELECT COUNT(*) FROM mysql.general_log
--let $CRC_ARG_expected_number_of_warnings= 1
}
if (`SELECT $unsafe_type = 7`) {
--echo ==== Testing a statement that is unsafe in many ways ====
--let $desc_0= statement that is unsafe in many ways
# Concatenate three unsafe values, and then concatenate NULL to
# that so that the result is NULL and we instead use autoinc.
--let $stmt_sidef_0= INSERT DELAYED INTO double_autoinc_table SELECT CONCAT(UUID(), @@hostname, myfunc_int(), NULL) FROM mysql.general_log LIMIT 1
--let $value_0=
--let $sel_sidef_0=
--let $sel_retval_0=
# Note: we will expect 7 warnings when BUG#45827 is fixed.
--let $CRC_ARG_expected_number_of_warnings= 6
}
if (`SELECT $unsafe_type = 8`) {
--echo ==== Testing a statement that is unsafe several times ====
--let $desc_0= statement that is unsafe several times
--let $stmt_sidef_0= INSERT INTO ta0 VALUES (multi_unsafe_func())
--let $value_0=
--let $sel_sidef_0= SELECT multi_unsafe_func()
--let $sel_retval_0=
--let $CRC_ARG_expected_number_of_warnings= 2
}
# In each iteration of the following loop, we select one way to
# enclose the unsafe statement as a sub-statement of a recursive
# construct (i.e., a function, procedure, trigger, view, or prepared
# statement).
#
# In the last iteration, $call_type_1=7, we don't create a recursive
# construct. Instead, we just invoke the unsafe statement directly.
--let $call_type_1= 0
while (`SELECT $call_type_1 < 8`) {
#--echo debug: level 1, types $call_type_1 -> $unsafe_type
--let $CRC_ARG_level= 1
--let $CRC_ARG_type= $call_type_1
--let $CRC_ARG_stmt_sidef= $stmt_sidef_0
--let $CRC_ARG_value= $value_0
--let $CRC_ARG_sel_sidef= $sel_sidef_0
--let $CRC_ARG_sel_retval= $sel_retval_0
--let $CRC_ARG_desc= $desc_0
--source extra/rpl_tests/create_recursive_construct.inc
--let $stmt_sidef_1= $CRC_RET_stmt_sidef
--let $value_1= $CRC_RET_value
--let $sel_sidef_1= $CRC_RET_sel_sidef
--let $sel_retval_1= $CRC_RET_sel_retval
--let $is_toplevel_1= $CRC_RET_is_toplevel
--let $drop_1= $CRC_RET_drop
--let $desc_1= $CRC_RET_desc
# Some statements must be top-level statements, i.e., cannot be
# called as a sub-statement of any recursive construct. (One
# example is 'EXECUTE prepared_stmt'). When
# create_recursive_construct.inc creates a top-level statement, it
# sets $CRC_RET_is_toplevel=1.
if (!$is_toplevel_1) {
# In each iteration of this loop, we select one way to enclose
# the previous recursive construct in another recursive
# construct.
--let $call_type_2= 0
while (`SELECT $call_type_2 < 7`) {
#--echo debug: level 2, types $call_type_2 -> $call_type_1 -> $unsafe_type
--let $CRC_ARG_level= 2
--let $CRC_ARG_type= $call_type_2
--let $CRC_ARG_stmt_sidef= $stmt_sidef_1
--let $CRC_ARG_value= $value_1
--let $CRC_ARG_sel_sidef= $sel_sidef_1
--let $CRC_ARG_sel_retval= $sel_retval_1
--let $CRC_ARG_desc= $desc_1
--source extra/rpl_tests/create_recursive_construct.inc
--let $stmt_sidef_2= $CRC_RET_stmt_sidef
--let $value_2= $CRC_RET_value
--let $sel_sidef_2= $CRC_RET_sel_sidef
--let $sel_retval_2= $CRC_RET_sel_retval
--let $is_toplevel_2= $CRC_RET_is_toplevel
--let $drop_2= $CRC_RET_drop
--let $desc_2= $CRC_RET_desc
if (!$is_toplevel_2) {
# Conditioned out since it makes result file really big.
if (0) {
# In each iteration of this loop, we select one way to enclose
# the previous recursive construct in another recursive
# construct.
--let $call_type_3= 0
while (`SELECT $call_type_3 < 7`) {
#--echo debug: level 3, types $call_type_2 -> $call_type_2 -> $call_type_1 -> $unsafe_type
--let $CRC_ARG_level= 3
--let $CRC_ARG_type= $call_type_3
--let $CRC_ARG_stmt_sidef= $stmt_sidef_2
--let $CRC_ARG_value= $value_2
--let $CRC_ARG_sel_sidef= $sel_sidef_2
--let $CRC_ARG_sel_retval= $sel_retval_2
--let $CRC_ARG_desc= $desc_2
--source extra/rpl_tests/create_recursive_construct.inc
# Drop created object.
if (`SELECT '$drop_3' != ''`) {
--eval $drop_3
}
--inc $call_type_3
} # while (call_type_3)
} # if (0)
} # if (!is_toplevel_2)
# Drop created object.
if (`SELECT '$drop_2' != ''`) {
--eval $drop_2
}
--inc $call_type_2
} # while (call_type_2)
} # if (!is_toplevel_1)
# Drop created object.
if (`SELECT '$drop_1' != ''`) {
--eval $drop_1
}
--inc $call_type_1
} # while (call_type_1)
--inc $unsafe_type
} # while (unsafe_type)
DROP TRIGGER double_autoinc_trig;
DROP TABLE t0, t1, t2, t3, ta0, ta1, ta2, ta3,
autoinc_table, double_autoinc_table,
data_table,
trigger_table_1, trigger_table_2, trigger_table_3;
DROP FUNCTION myfunc_int;
DROP FUNCTION multi_unsafe_func;
--echo ==== Variables that should *not* be unsafe ====
--echo ==== Special system variables that should *not* be unsafe ====
CREATE TABLE t1 (a VARCHAR(1000));
CREATE TABLE autoinc_table (a INT PRIMARY KEY AUTO_INCREMENT);
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.foreign_key_checks);
INSERT INTO t1 VALUES (@@session.sql_auto_is_null);
INSERT INTO t1 VALUES (@@session.unique_checks);
INSERT INTO t1 VALUES (@@session.auto_increment_increment);
INSERT INTO t1 VALUES (@@session.auto_increment_offset);
INSERT INTO t2 VALUES (@@session.character_set_client);
INSERT INTO t2 VALUES (@@session.collation_connection);
INSERT INTO t2 VALUES (@@session.collation_server);
INSERT INTO t2 VALUES (@@session.time_zone);
INSERT INTO t2 VALUES (@@session.lc_time_names);
INSERT INTO t2 VALUES (@@session.collation_database);
INSERT INTO t2 VALUES (@@session.timestamp);
INSERT INTO t2 VALUES (@@session.last_insert_id);
INSERT INTO t1 VALUES (@@session.character_set_client);
INSERT INTO t1 VALUES (@@session.character_set_connection);
INSERT INTO t1 VALUES (@@session.character_set_database);
INSERT INTO t1 VALUES (@@session.character_set_server);
INSERT INTO t1 VALUES (@@session.collation_connection);
INSERT INTO t1 VALUES (@@session.collation_database);
INSERT INTO t1 VALUES (@@session.collation_server);
INSERT INTO t1 VALUES (@@session.foreign_key_checks);
INSERT INTO t1 VALUES (@@session.identity);
INSERT INTO t1 VALUES (@@session.last_insert_id);
INSERT INTO t1 VALUES (@@session.lc_time_names);
INSERT INTO t1 VALUES (@@session.pseudo_thread_id);
INSERT INTO t1 VALUES (@@session.sql_auto_is_null);
INSERT INTO t1 VALUES (@@session.timestamp);
INSERT INTO t1 VALUES (@@session.time_zone);
INSERT INTO t1 VALUES (@@session.unique_checks);
SET @my_var= 4711;
INSERT INTO t1 VALUES (@my_var);
# using insert_id implicitly should be ok.
SET insert_id=12;
INSERT INTO t3 VALUES (NULL);
SET insert_id= 12;
INSERT INTO autoinc_table VALUES (NULL);
# See set_var.cc for explanation.
--echo The following variables *should* give a warning, despite they are replicated.
INSERT INTO t1 VALUES (@@session.sql_mode);
INSERT INTO t1 VALUES (@@session.insert_id);
--echo ==== Clean up ====
DROP TABLE t1, autoinc_table;
DROP PROCEDURE proc;
DROP FUNCTION func;
DROP TRIGGER trig;
DROP PROCEDURE proc1;
DROP FUNCTION func2;
DROP TRIGGER trig3;
DROP PROCEDURE proc4;
DROP FUNCTION func5;
DROP PREPARE prep6;
DROP TABLE t1, t2, t3, trigger_table, trigger_table2;
#
# BUG#34768 - nondeterministic INSERT using LIMIT logged in stmt mode if
# binlog_format=mixed
@@ -388,4 +538,41 @@ DELETE FROM t1 LIMIT 1;
DROP TABLE t1, t2;
SET @@SESSION.SQL_MODE = @save_sql_mode;
#
# BUG#45825: INSERT DELAYED is not unsafe: logged in statement format
# BUG#45785: LIMIT in SP does not cause RBL if binlog_format=MIXED
#
SET @old_binlog_format = @@session.binlog_format;
SET binlog_format = MIXED;
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
INSERT INTO t2 VALUES (1), (2);
--DELIMITER |
CREATE PROCEDURE proc_insert_delayed ()
BEGIN
INSERT DELAYED INTO t1 VALUES (1), (2);
END|
CREATE FUNCTION func_limit ()
RETURNS INT
BEGIN
INSERT INTO t1 SELECT * FROM t2 LIMIT 1;
RETURN 1;
END|
--DELIMITER ;
RESET MASTER;
CALL proc_insert_delayed();
SELECT func_limit();
source include/show_binlog_events.inc;
SET @@session.binlog_format = @old_binlog_format;
DROP TABLE t1, t2;
DROP PROCEDURE proc_insert_delayed;
DROP FUNCTION func_limit;
--echo "End of tests"

View File

@@ -11,6 +11,17 @@ SET SESSION binlog_format = 'ROW';
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format ROW
@@session.binlog_format ROW
[on slave]
set @old_global_binlog_format= @@global.binlog_format;
set @old_session_binlog_format= @@session.binlog_format;
SET GLOBAL binlog_format = 'ROW';
SET SESSION binlog_format = 'ROW';
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format ROW
@@session.binlog_format ROW
include/stop_slave.inc
include/start_slave.inc
[on master]
DROP TABLE IF EXISTS t1, t2, t3;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
@@ -189,3 +200,6 @@ DROP TABLE t1, t2, t3;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP PROCEDURE IF EXISTS p3;
[on slave]
set @@global.binlog_format= @old_global_binlog_format;
set @@session.binlog_format= @old_session_binlog_format;

View File

@@ -11,6 +11,19 @@ set @old_session_binlog_format= @@session.binlog_format;
SET GLOBAL binlog_format = 'ROW';
SET SESSION binlog_format = 'ROW';
select @@global.binlog_format, @@session.binlog_format;
--echo [on slave]
connection slave;
set @old_global_binlog_format= @@global.binlog_format;
set @old_session_binlog_format= @@session.binlog_format;
SET GLOBAL binlog_format = 'ROW';
SET SESSION binlog_format = 'ROW';
select @@global.binlog_format, @@session.binlog_format;
# restart slave so that slave sql thread's binlog format is re-read
# from @@global.binlog_format
--source include/stop_slave.inc
--source include/start_slave.inc
--echo [on master]
connection master;
--disable_warnings
DROP TABLE IF EXISTS t1, t2, t3;
@@ -158,8 +171,9 @@ DROP TABLE t1, t2, t3;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
DROP PROCEDURE IF EXISTS p3;
save_master_pos;
connection slave;
sync_with_master;
--echo [on slave]
sync_slave_with_master;
set @@global.binlog_format= @old_global_binlog_format;
set @@session.binlog_format= @old_session_binlog_format;
# End of 5.1 tests

View File

@@ -6,96 +6,6 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
SET @old_event_scheduler = @@global.event_scheduler;
set global event_scheduler=1;
set binlog_format=row;
DROP EVENT IF EXISTS test.justonce;
drop table if exists t1,t2;
CREATE TABLE `t1` (
`id` INT(10) UNSIGNED NOT NULL,
`c` VARCHAR(50) NOT NULL,
`ts` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO t1 (id, c) VALUES (1, 'manually');
"Creating event test.justonce on the master"
CREATE EVENT test.justonce ON SCHEDULE EVERY 2 SECOND DO
INSERT IGNORE INTO t1 (id, c) VALUES (2, 'from justonce');
"Checking event is active on master"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator
test justonce ENABLED 1
"Checking event data on the master"
ONE
1
"Checking event data on the slave"
ZERO
0
"Checking event is inactive on slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'justonce';
db name status originator
test justonce SLAVESIDE_DISABLED 1
"Dropping event test.slave_once on the slave"
DROP EVENT IF EXISTS test.slave_once;
CREATE EVENT test.slave_once ON SCHEDULE EVERY 5 MINUTE STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (3, 'from slave_once');
"Checking event status on the slave for originator value = slave's server_id"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_once';
db name status originator
test slave_once ENABLED 2
"Dropping event test.slave_once on the slave"
DROP EVENT IF EXISTS test.slave_once;
"Dropping event test.justonce on the master"
DROP EVENT IF EXISTS test.justonce;
"Creating event test.er on the master"
CREATE EVENT test.er ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er');
"Checking event status on the master"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er ENABLED 1 INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er')
"Checking event status on the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er SLAVESIDE_DISABLED 1 INSERT IGNORE INTO t1(id, c) VALUES (4, 'from er')
"Altering event test.er on the master"
ALTER EVENT test.er ON SCHEDULE EVERY 5 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (5, 'from alter er');
"Checking event status on the master"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er ENABLED 1 INSERT IGNORE INTO t1(id, c) VALUES (5, 'from alter er')
"Checking event status on the slave"
SELECT db, name, status, originator, body FROM mysql.event WHERE db = 'test' AND name = 'er';
db name status originator body
test er SLAVESIDE_DISABLED 1 INSERT IGNORE INTO t1(id, c) VALUES (5, 'from alter er')
"Dropping event test.er on the master"
DROP EVENT test.er;
"Checking event status on the master"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
db name status originator
"Checking event status on the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test';
db name status originator
"Creating event test.slave_terminate on the slave"
CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND STARTS CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO
INSERT IGNORE INTO t1(id, c) VALUES (6, 'from slave_terminate');
"Checking event status on the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
db name status originator
test slave_terminate ENABLED 2
"Dropping event test.slave_terminate on the slave"
DROP EVENT test.slave_terminate;
"Creating event test.slave_terminate with DISABLE ON SLAVE on the slave"
CREATE EVENT test.slave_terminate ON SCHEDULE EVERY 3 SECOND DISABLE ON SLAVE DO
INSERT IGNORE INTO t1(c) VALUES (7, 'from slave_terminate');
"Checking event status on the slave"
SELECT db, name, status, originator FROM mysql.event WHERE db = 'test' AND name = 'slave_terminate';
db name status originator
test slave_terminate SLAVESIDE_DISABLED 2
"Dropping event test.slave_terminate on the slave"
DROP EVENT test.slave_terminate;
"Cleanup"
DROP TABLE t1;
set binlog_format=statement;
DROP EVENT IF EXISTS test.justonce;
drop table if exists t1,t2;
CREATE TABLE `t1` (

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -46,7 +46,6 @@ engine = INNODB;
insert into t1 set b=1;
insert into t2 set a=1, b=1;
set foreign_key_checks=0;
set @@session.binlog_format=row;
delete from t1;
must sync w/o a problem (could not with the buggy code)
select count(*) from t1 /* must be zero */;

View File

@@ -6,11 +6,12 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032");
call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452");
SET @old_slave_exec_mode= @@global.slave_exec_mode;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT);
INSERT INTO t1 VALUES (-1),(-2),(-3);
INSERT INTO t2 VALUES (-1),(-2),(-3);
SET @old_slave_exec_mode= @@global.slave_exec_mode;
SET @@global.slave_exec_mode= IDEMPOTENT;
DELETE FROM t1 WHERE a = -2;
DELETE FROM t2 WHERE a = -2;
DELETE FROM t1 WHERE a = -2;
@@ -72,158 +73,4 @@ a
Last_SQL_Error
0
DROP TABLE t1, t2;
select @@global.slave_exec_mode /* must be IDEMPOTENT */;
@@global.slave_exec_mode
IDEMPOTENT
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
select * from ti1 order by b /* must be (1),(2),(3) */;
b
1
2
3
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
a b
1 1
2 2
set @save_binlog_format= @@session.binlog_format;
set @@session.binlog_format= row;
delete from ti1 where b=1;
select * from ti1 order by b /* must be (2),(3) */;
b
2
3
select * from ti1 order by b /* must stays as were on master (1),(2),(3) */;
b
1
2
3
delete from ti1 where b=3;
insert into ti2 set a=3, b=3;
select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */;
a b
1 1
2 2
set global slave_exec_mode='IDEMPOTENT';
set global slave_exec_mode='STRICT';
set global slave_exec_mode='IDEMPOTENT,STRICT';
ERROR HY000: Ambiguous slave modes combination.
select @@global.slave_exec_mode /* must be STRICT */;
@@global.slave_exec_mode
STRICT
*** foreign keys errors as above now forces to stop
set foreign_key_checks=0;
drop table ti2, ti1;
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
select * from ti1 order by b /* must be (1),(2),(3) */;
b
1
2
3
*** conspire future problem
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
a b
1 1
2 2
delete from ti1 where b=1 /* offending delete event */;
select * from ti1 order by b /* must be (2),(3) */;
b
2
3
*** slave must stop (Trying to delete a referenced foreing key)
Last_SQL_Error
1451
select * from ti1 order by b /* must be (1),(2),(3) - not deleted */;
b
1
2
3
set foreign_key_checks= 0;
delete from ti2 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
*** conspire the following insert failure
*** conspire future problem
delete from ti1 where b=3;
insert into ti2 set a=3, b=3 /* offending write event */;
*** slave must stop (Trying to insert an invalid foreign key)
Last_SQL_Error
1452
select * from ti2 order by b /* must be (2,2) */;
a b
2 2
set foreign_key_checks= 0;
insert into ti1 set b=3;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
select * from ti2 order by b /* must be (2,2),(3,3) */;
a b
2 2
3 3
*** other errors
*** conspiring query
insert into ti1 set b=1;
insert into ti1 set b=1 /* offending write event */;
*** slave must stop (Trying to insert a dupliacte key)
Last_SQL_Error
1062
set foreign_key_checks= 0;
delete from ti1 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT);
INSERT INTO t1 VALUES (-1),(-2),(-3);
INSERT INTO t2 VALUES (-1),(-2),(-3);
DELETE FROM t1 WHERE a = -2;
DELETE FROM t2 WHERE a = -2;
DELETE FROM t1 WHERE a = -2;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
DELETE FROM t2 WHERE a = -2;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
UPDATE t1 SET a = 1 WHERE a = -1;
UPDATE t2 SET a = 1 WHERE a = -1;
UPDATE t1 SET a = 1 WHERE a = -1;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
UPDATE t2 SET a = 1 WHERE a = -1;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
SET @@global.slave_exec_mode= @old_slave_exec_mode;
set @@session.binlog_format= @save_binlog_format;
drop table t1,t2,ti2,ti1;
*** end of tests

View File

@@ -4,8 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
==== 0. Setting it all up ====
SET BINLOG_FORMAT=STATEMENT;
==== Initialize ====
**** On Master ****
CREATE TABLE t1 (a INT);
CREATE TABLE logtbl (sect INT, test INT, count INT);
@@ -16,106 +15,12 @@ INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
#### 1. Using statement mode ####
==== 1.1. Simple test ====
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,1,@a);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
a
1
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,2,@a);
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 3
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 3
==== 1.2. Stored procedure ====
==== Checking a procedure ====
**** On Master ****
CREATE PROCEDURE calc_and_log(sect INT, test INT) BEGIN
DECLARE cnt INT;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test,cnt);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test+1,cnt);
END $$
CALL calc_and_log(2,1);
a
1
a
7
CREATE PROCEDURE just_log(sect INT, test INT, found_rows INT) BEGIN
INSERT INTO logtbl VALUES (sect,test,found_rows);
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @found_rows;
CALL just_log(2,3,@found_rows);
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 183
2 3 183
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 183
2 3 183
==== 1.3. Stored functions ====
**** On Master ****
CREATE FUNCTION log_rows(sect INT, test INT, found_rows INT)
RETURNS INT
BEGIN
INSERT INTO logtbl VALUES(sect,test,found_rows);
RETURN found_rows;
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @found_rows;
SELECT log_rows(3,1,@found_rows), log_rows(3,2,@found_rows);
log_rows(3,1,@found_rows) log_rows(3,2,@found_rows)
183 183
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
sect test count
3 1 183
3 2 183
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
sect test count
3 1 183
3 2 183
==== 1.9. Cleanup ====
**** On Master ****
DELETE FROM logtbl;
DROP PROCEDURE just_log;
DROP PROCEDURE calc_and_log;
DROP FUNCTION log_rows;
**** Resetting master and slave ****
include/stop_slave.inc
RESET SLAVE;
RESET MASTER;
include/start_slave.inc
#### 2. Using mixed mode ####
==== 2.1. Checking a procedure ====
**** On Master ****
SET BINLOG_FORMAT=MIXED;
CREATE PROCEDURE just_log(sect INT, test INT) BEGIN
INSERT INTO logtbl VALUES (sect,test,FOUND_ROWS());
END $$
**** On Master 1 ****
SET BINLOG_FORMAT=MIXED;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
@@ -148,7 +53,7 @@ sect test count
1 2 183
1 3 3
1 4 183
==== 2.1. Checking a stored function ====
==== Checking a stored function ====
**** On Master ****
CREATE FUNCTION log_rows(sect INT, test INT)
RETURNS INT

View File

@@ -0,0 +1,71 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
CREATE SCHEMA IF NOT EXISTS mysqlslap;
USE mysqlslap;
select @@global.binlog_format;
@@global.binlog_format
MIXED
CREATE TABLE t1 (id INT primary key auto_increment, name VARCHAR(64));
FLUSH TABLE t1;
SELECT COUNT(*) FROM t1;
COUNT(*)
5000
use mysqlslap;
SELECT COUNT(*) FROM t1;
COUNT(*)
5000
truncate table t1;
insert delayed into t1 values(10, "my name");
insert delayed into t1 values(10, "is Bond"), (20, "James Bond");
flush table t1;
select * from t1;
id name
10 my name
20 James Bond
select * from t1;
id name
10 my name
20 James Bond
delete from t1 where id!=10;
insert delayed into t1 values(20, "is Bond"), (10, "James Bond");
flush table t1;
select * from t1;
id name
10 my name
20 is Bond
select * from t1;
id name
10 my name
20 is Bond
USE test;
DROP SCHEMA mysqlslap;
use test;
FLUSH LOGS;
FLUSH LOGS;
CREATE TABLE t1(a int, UNIQUE(a));
INSERT DELAYED IGNORE INTO t1 VALUES(1);
INSERT DELAYED IGNORE INTO t1 VALUES(1);
flush table t1;
show binlog events in 'master-bin.000002' LIMIT 2,2;
Log_name Pos Event_type Server_id End_log_pos Info
x x x x x BEGIN
x x x x x table_id: # (test.t1)
select * from t1;
a
1
On slave
show binlog events in 'slave-bin.000002' LIMIT 2,2;
Log_name Pos Event_type Server_id End_log_pos Info
x x x x x BEGIN
x x x x x table_id: # (test.t1)
select * from t1;
a
1
drop table t1;
FLUSH LOGS;
FLUSH LOGS;
End of 5.0 tests

View File

@@ -4,12 +4,6 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
SET @old_binlog_format= @@global.binlog_format;
SET BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
SELECT @@GLOBAL.BINLOG_FORMAT, @@SESSION.BINLOG_FORMAT;
@@GLOBAL.BINLOG_FORMAT @@SESSION.BINLOG_FORMAT
MIXED MIXED
**** On Master ****
CREATE TABLE t1 (a INT, b LONG);
INSERT INTO t1 VALUES (1,1), (2,2);
@@ -73,4 +67,3 @@ slave-bin.000001 # Table_map 1 # table_id: # (test.t1)
slave-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F
slave-bin.000001 # Query 1 # COMMIT
DROP TABLE IF EXISTS t1;
SET @@global.binlog_format= @old_binlog_format;

View File

@@ -0,0 +1,160 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set @old_slave_exec_mode= @@global.slave_exec_mode;
set @@global.slave_exec_mode= IDEMPOTENT;
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
select * from ti1 order by b /* must be (1),(2),(3) */;
b
1
2
3
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
a b
1 1
2 2
set @save_binlog_format= @@session.binlog_format;
set @@session.binlog_format= row;
delete from ti1 where b=1;
select * from ti1 order by b /* must be (2),(3) */;
b
2
3
select * from ti1 order by b /* must stays as were on master (1),(2),(3) */;
b
1
2
3
delete from ti1 where b=3;
insert into ti2 set a=3, b=3;
select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */;
a b
1 1
2 2
set global slave_exec_mode='IDEMPOTENT';
set global slave_exec_mode='STRICT';
set global slave_exec_mode='IDEMPOTENT,STRICT';
ERROR HY000: Ambiguous slave modes combination.
select @@global.slave_exec_mode /* must be STRICT */;
@@global.slave_exec_mode
STRICT
*** foreign keys errors as above now forces to stop
set foreign_key_checks=0;
drop table ti2, ti1;
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
select * from ti1 order by b /* must be (1),(2),(3) */;
b
1
2
3
*** conspire future problem
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
a b
1 1
2 2
delete from ti1 where b=1 /* offending delete event */;
select * from ti1 order by b /* must be (2),(3) */;
b
2
3
*** slave must stop (Trying to delete a referenced foreing key)
Last_SQL_Error
1451
select * from ti1 order by b /* must be (1),(2),(3) - not deleted */;
b
1
2
3
set foreign_key_checks= 0;
delete from ti2 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
*** conspire the following insert failure
*** conspire future problem
delete from ti1 where b=3;
insert into ti2 set a=3, b=3 /* offending write event */;
*** slave must stop (Trying to insert an invalid foreign key)
Last_SQL_Error
1452
select * from ti2 order by b /* must be (2,2) */;
a b
2 2
set foreign_key_checks= 0;
insert into ti1 set b=3;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
select * from ti2 order by b /* must be (2,2),(3,3) */;
a b
2 2
3 3
*** other errors
*** conspiring query
insert into ti1 set b=1;
insert into ti1 set b=1 /* offending write event */;
*** slave must stop (Trying to insert a dupliacte key)
Last_SQL_Error
1062
set foreign_key_checks= 0;
delete from ti1 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT);
INSERT INTO t1 VALUES (-1),(-2),(-3);
INSERT INTO t2 VALUES (-1),(-2),(-3);
DELETE FROM t1 WHERE a = -2;
DELETE FROM t2 WHERE a = -2;
DELETE FROM t1 WHERE a = -2;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
DELETE FROM t2 WHERE a = -2;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
UPDATE t1 SET a = 1 WHERE a = -1;
UPDATE t2 SET a = 1 WHERE a = -1;
UPDATE t1 SET a = 1 WHERE a = -1;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
set global slave_exec_mode='STRICT';
UPDATE t2 SET a = 1 WHERE a = -1;
*** slave must stop (Key was not found)
Last_SQL_Error
1032
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
SET @@global.slave_exec_mode= @old_slave_exec_mode;
drop table t1,t2,ti2,ti1;
set @@global.slave_exec_mode= @old_slave_exec_mode;
*** end of tests

View File

@@ -4,8 +4,6 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set @old_global_binlog_format = @@global.binlog_format;
set @@global.binlog_format = row;
CREATE SCHEMA IF NOT EXISTS mysqlslap;
USE mysqlslap;
select @@global.binlog_format;
@@ -59,4 +57,3 @@ a
1
drop table t1;
End of 5.0 tests
set @@global.binlog_format = @old_global_binlog_format;

View File

@@ -0,0 +1,110 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
==== Initialize ====
**** On Master ****
CREATE TABLE t1 (a INT);
CREATE TABLE logtbl (sect INT, test INT, count INT);
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
==== Simple test ====
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,1,@a);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
a
1
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,2,@a);
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 3
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sect test count
1 1 183
1 2 3
==== Stored procedure ====
**** On Master ****
CREATE PROCEDURE calc_and_log(sect INT, test INT) BEGIN
DECLARE cnt INT;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test,cnt);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test+1,cnt);
END $$
CALL calc_and_log(2,1);
a
1
a
7
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.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a system function whose value may differ on slave.
CREATE PROCEDURE just_log(sect INT, test INT, found_rows INT) BEGIN
INSERT INTO logtbl VALUES (sect,test,found_rows);
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @found_rows;
CALL just_log(2,3,@found_rows);
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 183
2 3 183
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
sect test count
2 1 3
2 2 183
2 3 183
==== Stored functions ====
**** On Master ****
CREATE FUNCTION log_rows(sect INT, test INT, found_rows INT)
RETURNS INT
BEGIN
INSERT INTO logtbl VALUES(sect,test,found_rows);
RETURN found_rows;
END $$
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
a
7
SELECT FOUND_ROWS() INTO @found_rows;
SELECT log_rows(3,1,@found_rows), log_rows(3,2,@found_rows);
log_rows(3,1,@found_rows) log_rows(3,2,@found_rows)
183 183
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
sect test count
3 1 183
3 2 183
**** On Slave ****
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
sect test count
3 1 183
3 2 183
==== Cleanup ====
**** On Master ****
DROP TABLE t1, logtbl;
DROP PROCEDURE just_log;
DROP PROCEDURE calc_and_log;
DROP FUNCTION log_rows;
**** Resetting master and slave ****
include/stop_slave.inc
RESET SLAVE;
RESET MASTER;
include/start_slave.inc

View File

@@ -4,8 +4,6 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set @old_global_binlog_format = @@global.binlog_format;
set @@global.binlog_format = statement;
CREATE SCHEMA IF NOT EXISTS mysqlslap;
USE mysqlslap;
select @@global.binlog_format;
@@ -71,70 +69,3 @@ drop table t1;
FLUSH LOGS;
FLUSH LOGS;
End of 5.0 tests
set @@global.binlog_format = mixed;
CREATE SCHEMA IF NOT EXISTS mysqlslap;
USE mysqlslap;
select @@global.binlog_format;
@@global.binlog_format
MIXED
CREATE TABLE t1 (id INT primary key auto_increment, name VARCHAR(64));
FLUSH TABLE t1;
SELECT COUNT(*) FROM t1;
COUNT(*)
5000
use mysqlslap;
SELECT COUNT(*) FROM t1;
COUNT(*)
5000
truncate table t1;
insert delayed into t1 values(10, "my name");
insert delayed into t1 values(10, "is Bond"), (20, "James Bond");
flush table t1;
select * from t1;
id name
10 my name
20 James Bond
select * from t1;
id name
10 my name
20 James Bond
delete from t1 where id!=10;
insert delayed into t1 values(20, "is Bond"), (10, "James Bond");
flush table t1;
select * from t1;
id name
10 my name
20 is Bond
select * from t1;
id name
10 my name
20 is Bond
USE test;
DROP SCHEMA mysqlslap;
use test;
FLUSH LOGS;
FLUSH LOGS;
CREATE TABLE t1(a int, UNIQUE(a));
INSERT DELAYED IGNORE INTO t1 VALUES(1);
INSERT DELAYED IGNORE INTO t1 VALUES(1);
flush table t1;
show binlog events in 'master-bin.000002' LIMIT 2,2;
Log_name Pos Event_type Server_id End_log_pos Info
x x x x x use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
x x x x x use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
select * from t1;
a
1
On slave
show binlog events in 'slave-bin.000002' LIMIT 2,2;
Log_name Pos Event_type Server_id End_log_pos Info
x x x x x use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
x x x x x use `test`; INSERT DELAYED IGNORE INTO t1 VALUES(1)
select * from t1;
a
1
drop table t1;
FLUSH LOGS;
FLUSH LOGS;
End of 5.0 tests
set @@global.binlog_format = @old_global_binlog_format;

View File

@@ -10,7 +10,7 @@ CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, PRIMARY KEY(a));
INSERT INTO test.t1 VALUES(1,'test');
UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=1;
Warnings:
Note 1592 Statement may not be safe to log in statement format.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a system function whose value may differ on slave.
create procedure test.p1()
begin
INSERT INTO test.t1 VALUES(2,'test');
@@ -18,7 +18,7 @@ UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2;
end|
CALL test.p1();
Warnings:
Note 1592 Statement may not be safe to log in statement format.
Note 1592 Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT. Reason: Statement uses a system function whose value may differ on slave.
SELECT * FROM test.t1 ORDER BY blob_column;
a blob_column
1 abase

View File

@@ -6,7 +6,6 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
call mtr.add_suppression("Deadlock found");
**** On Master ****
SET SESSION BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
**** On Slave ****

View File

@@ -4,7 +4,6 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
set binlog_format=row;
drop table if exists t1;
"*** Test 1) Test UDFs via loadable libraries ***
"Running on the master"
@@ -156,163 +155,3 @@ affected rows: 0
"Running on the master"
DROP TABLE t1;
affected rows: 0
set binlog_format=statement;
drop table if exists t1;
"*** Test 1) Test UDFs via loadable libraries ***
"Running on the master"
CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
affected rows: 0
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
affected rows: 0
CREATE FUNCTION myfunc_nonexist RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
ERROR HY000: Can't find symbol 'myfunc_nonexist' in library
SELECT * FROM mysql.func ORDER BY name;
name ret dl type
myfunc_double 1 UDF_LIB function
myfunc_int 2 UDF_LIB function
affected rows: 2
"Running on the slave"
SELECT * FROM mysql.func ORDER BY name;
name ret dl type
myfunc_double 1 UDF_LIB function
myfunc_int 2 UDF_LIB function
affected rows: 2
"Running on the master"
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
affected rows: 0
INSERT INTO t1 VALUES(myfunc_int(100), myfunc_double(50.00));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(10), myfunc_double(5.00));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(200), myfunc_double(25.00));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
INSERT INTO t1 VALUES(myfunc_int(1), myfunc_double(500.00));
Warnings:
Note 1592 Statement may not be safe to log in statement format.
affected rows: 1
SELECT * FROM t1 ORDER BY sum;
sum price
1 48.5
10 48.75
100 48.6
200 49
affected rows: 4
"Running on the slave"
SELECT * FROM t1 ORDER BY sum;
sum price
1 48.5
10 48.75
100 48.6
200 49
affected rows: 4
SELECT myfunc_int(25);
myfunc_int(25)
25
affected rows: 1
SELECT myfunc_double(75.00);
myfunc_double(75.00)
50.00
affected rows: 1
"Running on the master"
DROP FUNCTION myfunc_double;
affected rows: 0
DROP FUNCTION myfunc_int;
affected rows: 0
SELECT * FROM mysql.func ORDER BY name;
name ret dl type
affected rows: 0
"Running on the slave"
SELECT * FROM mysql.func ORDER BY name;
name ret dl type
affected rows: 0
"Running on the master"
DROP TABLE t1;
affected rows: 0
"*** Test 2) Test UDFs with SQL body ***
"Running on the master"
CREATE FUNCTION myfuncsql_int(i INT) RETURNS INTEGER DETERMINISTIC RETURN i;
affected rows: 0
CREATE FUNCTION myfuncsql_double(d DOUBLE) RETURNS INTEGER DETERMINISTIC RETURN d * 2.00;
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%' ORDER BY name;
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 2.00
test myfuncsql_int FUNCTION i INT RETURN i
affected rows: 2
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%' ORDER BY name;
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 2.00
test myfuncsql_int FUNCTION i INT RETURN i
affected rows: 2
"Running on the master"
CREATE TABLE t1(sum INT, price FLOAT(24)) ENGINE=MyISAM;
affected rows: 0
INSERT INTO t1 VALUES(myfuncsql_int(100), myfuncsql_double(50.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(10), myfuncsql_double(5.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(200), myfuncsql_double(25.00));
affected rows: 1
INSERT INTO t1 VALUES(myfuncsql_int(1), myfuncsql_double(500.00));
affected rows: 1
SELECT * FROM t1 ORDER BY sum;
sum price
1 1000
10 10
100 100
200 50
affected rows: 4
"Running on the slave"
SELECT * FROM t1 ORDER BY sum;
sum price
1 1000
10 10
100 100
200 50
affected rows: 4
"Running on the master"
ALTER FUNCTION myfuncsql_int COMMENT "This was altered.";
affected rows: 0
ALTER FUNCTION myfuncsql_double COMMENT "This was altered.";
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%' ORDER BY name;
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 2.00 This was altered.
test myfuncsql_int FUNCTION i INT RETURN i This was altered.
affected rows: 2
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%' ORDER BY name;
db name type param_list body comment
test myfuncsql_double FUNCTION d DOUBLE RETURN d * 2.00 This was altered.
test myfuncsql_int FUNCTION i INT RETURN i This was altered.
affected rows: 2
SELECT myfuncsql_int(25);
myfuncsql_int(25)
25
affected rows: 1
SELECT myfuncsql_double(75.00);
myfuncsql_double(75.00)
150
affected rows: 1
"Running on the master"
DROP FUNCTION myfuncsql_double;
affected rows: 0
DROP FUNCTION myfuncsql_int;
affected rows: 0
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%' ORDER BY name;
db name type param_list body comment
affected rows: 0
"Running on the slave"
SELECT db, name, type, param_list, body, comment FROM mysql.proc WHERE db = 'test' AND name LIKE 'myfuncsql%' ORDER BY name;
db name type param_list body comment
affected rows: 0
"Running on the master"
DROP TABLE t1;
affected rows: 0

View File

@@ -1,3 +1,4 @@
source include/have_binlog_format_mixed_or_row.inc;
source include/master-slave.inc;
CREATE DATABASE track;

View File

@@ -1,11 +1,9 @@
##################################################################
# Author: Giuseppe #
# Date: 2006-12-20 #
# Purpose: To test that event effects are replicated #
# in both row based and statement based format #
# Purpose: To test that event effects are replicated. #
##################################################################
--source include/not_embedded.inc
--source include/master-slave.inc
SET @old_event_scheduler = @@global.event_scheduler;
@@ -13,14 +11,6 @@ set global event_scheduler=1;
let $engine_type= MyISAM;
set binlog_format=row;
# Embedded server doesn't support binlogging
--source include/rpl_events.inc
set binlog_format=statement;
# Embedded server doesn't support binlogging
--source include/rpl_events.inc
#

View File

@@ -1,16 +1,9 @@
#############################################################
# Purpose: To test having extra columns on the master WL#3915
#############################################################
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
-- source include/have_innodb.inc
let $engine_type = 'InnoDB';
set binlog_format=row;
-- source extra/rpl_tests/rpl_extraMaster_Col.test
set binlog_format=statement;
-- source extra/rpl_tests/rpl_extraMaster_Col.test
set binlog_format=mixed;
-- source extra/rpl_tests/rpl_extraMaster_Col.test
--source extra/rpl_tests/rpl_extraMaster_Col.test

View File

@@ -1,15 +1,8 @@
#############################################################
# Purpose: To test having extra columns on the master WL#3915
#############################################################
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
let $engine_type = 'MyISAM';
set binlog_format=row;
-- source extra/rpl_tests/rpl_extraMaster_Col.test
set binlog_format=statement;
-- source extra/rpl_tests/rpl_extraMaster_Col.test
set binlog_format=mixed;
-- source extra/rpl_tests/rpl_extraMaster_Col.test
--source extra/rpl_tests/rpl_extraMaster_Col.test

View File

@@ -1 +0,0 @@
--slave-exec-mode=IDEMPOTENT

View File

@@ -2,17 +2,11 @@
# work the same way under statement based as under row based.
source include/master-slave.inc;
connection master;
source include/have_innodb.inc;
connection slave;
source include/have_innodb.inc;
# Add suppression for expected warning(s) in slaves error log
call mtr.add_suppression("Slave: Can\'t find record in \'t1\' Error_code: 1032");
call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452");
SET @old_slave_exec_mode= @@global.slave_exec_mode;
connection master;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT);
@@ -20,6 +14,9 @@ INSERT INTO t1 VALUES (-1),(-2),(-3);
INSERT INTO t2 VALUES (-1),(-2),(-3);
sync_slave_with_master;
SET @old_slave_exec_mode= @@global.slave_exec_mode;
SET @@global.slave_exec_mode= IDEMPOTENT;
# A delete for a row that does not exist, the statement is
# deliberately written to be idempotent for statement-based
# replication as well. We test this towards both a table with a
@@ -57,6 +54,7 @@ disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
# BUG#19958: RBR idempotency issue for UPDATE and DELETE
# Statement-based and row-based replication have different behaviour
@@ -88,316 +86,4 @@ connection master;
DROP TABLE t1, t2;
sync_slave_with_master;
# bug#31609 Not all RBR slave errors reported as errors
# bug#31552 Replication breaks when deleting rows from out-of-sync table
# without PK
#
# Idempotent applying is not default any longer.
# The default for slave-exec-mode option and server
# variable slave_exec_mode is 'STRICT'.
# When 'STRICT' mode is set, the slave SQL thread will stop whenever
# the row to change is not found. In 'IDEMPOTENT' mode, the SQL thread
# will continue running and apply the row - replace if it's Write_rows event -
# or skip to the next event.
# the previous part of the tests was with IDEMPOTENT slave's mode.
#
# Other than above idempotent errors dealing with foreign keys constraint
#
select @@global.slave_exec_mode /* must be IDEMPOTENT */;
connection master;
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
sync_slave_with_master;
#connection slave;
select * from ti1 order by b /* must be (1),(2),(3) */;
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
connection master;
# from now on checking rbr specific idempotent errors
set @save_binlog_format= @@session.binlog_format;
set @@session.binlog_format= row;
delete from ti1 where b=1;
select * from ti1 order by b /* must be (2),(3) */;
# slave must catch up (expect some warnings in error.log)
sync_slave_with_master;
#connection slave;
select * from ti1 order by b /* must stays as were on master (1),(2),(3) */;
delete from ti1 where b=3;
connection master;
insert into ti2 set a=3, b=3;
# slave must catch up (expect some warnings in error.log)
sync_slave_with_master;
#connection slave;
select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */;
#
# Checking the new global sys variable
#
connection slave;
set global slave_exec_mode='IDEMPOTENT';
set global slave_exec_mode='STRICT';
# checking mutual exclusion for the options
--error ER_SLAVE_AMBIGOUS_EXEC_MODE
set global slave_exec_mode='IDEMPOTENT,STRICT';
select @@global.slave_exec_mode /* must be STRICT */;
#
# Checking stops.
# In the following sections strict slave sql thread is going to
# stop when faces an idempotent error. In order to proceed
# the mode is temporarily switched to indempotent.
#
#
--echo *** foreign keys errors as above now forces to stop
#
connection master;
set foreign_key_checks=0;
drop table ti2, ti1;
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
sync_slave_with_master;
#connection slave;
select * from ti1 order by b /* must be (1),(2),(3) */;
--echo *** conspire future problem
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
connection master;
delete from ti1 where b=1 /* offending delete event */;
select * from ti1 order by b /* must be (2),(3) */;
# foreign key: row is referenced
--echo *** slave must stop (Trying to delete a referenced foreing key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
select * from ti1 order by b /* must be (1),(2),(3) - not deleted */;
set foreign_key_checks= 0;
delete from ti2 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
sync_slave_with_master;
#connection slave;
--echo *** conspire the following insert failure
# foreign key: no referenced row
--echo *** conspire future problem
delete from ti1 where b=3;
connection master;
insert into ti2 set a=3, b=3 /* offending write event */;
--echo *** slave must stop (Trying to insert an invalid foreign key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
select * from ti2 order by b /* must be (2,2) */;
set foreign_key_checks= 0;
insert into ti1 set b=3;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
sync_slave_with_master;
select * from ti2 order by b /* must be (2,2),(3,3) */;
#
--echo *** other errors
#
# dup key insert
#connection slave;
--echo *** conspiring query
insert into ti1 set b=1;
connection master;
insert into ti1 set b=1 /* offending write event */;
--echo *** slave must stop (Trying to insert a dupliacte key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set foreign_key_checks= 0;
delete from ti1 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
# key not found
connection master;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT);
INSERT INTO t1 VALUES (-1),(-2),(-3);
INSERT INTO t2 VALUES (-1),(-2),(-3);
sync_slave_with_master;
#connection slave;
DELETE FROM t1 WHERE a = -2;
DELETE FROM t2 WHERE a = -2;
connection master;
DELETE FROM t1 WHERE a = -2;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
DELETE FROM t2 WHERE a = -2;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
UPDATE t1 SET a = 1 WHERE a = -1;
UPDATE t2 SET a = 1 WHERE a = -1;
connection master;
UPDATE t1 SET a = 1 WHERE a = -1;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
UPDATE t2 SET a = 1 WHERE a = -1;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
SET @@global.slave_exec_mode= @old_slave_exec_mode;
# cleanup for bug#31609 tests
connection master;
set @@session.binlog_format= @save_binlog_format;
drop table t1,t2,ti2,ti1;
--source include/master-slave-end.inc
--echo *** end of tests

View File

@@ -1,16 +1,15 @@
source include/master-slave.inc;
source include/have_binlog_format_mixed.inc;
# It is not possible to replicate FOUND_ROWS() using statement-based
# replication, but there is a workaround that stores the result of
# FOUND_ROWS() into a user variable and then replicates this instead.
#
# The purpose of this test case is to test that the workaround works
# properly even when inside stored programs (i.e., stored routines and
# triggers).
# The purpose of this test case is to test that the workaround
# function properly even when inside stored programs (i.e., stored
# routines and triggers).
--echo ==== 0. Setting it all up ====
SET BINLOG_FORMAT=STATEMENT;
--echo ==== Initialize ====
--echo **** On Master ****
connection master;
@@ -25,106 +24,10 @@ INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
--echo #### 1. Using statement mode ####
--echo ==== 1.1. Simple test ====
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
# Instead of
# INSERT INTO logtbl VALUES(1, 1, FOUND_ROWS());
# we write
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,1,@a);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
# Instead of
# INSERT INTO logtbl VALUES(1, 2, FOUND_ROWS());
# we write
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,2,@a);
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
--echo **** On Slave ****
sync_slave_with_master;
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
--echo ==== 1.2. Stored procedure ====
# Here we do both the calculation and the logging. We also do it twice
# to make sure that there are no limitations on how many times it can
# be used.
--echo ==== Checking a procedure ====
--echo **** On Master ****
connection master;
--delimiter $$
CREATE PROCEDURE calc_and_log(sect INT, test INT) BEGIN
DECLARE cnt INT;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test,cnt);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test+1,cnt);
END $$
--delimiter ;
CALL calc_and_log(2,1);
--delimiter $$
CREATE PROCEDURE just_log(sect INT, test INT, found_rows INT) BEGIN
INSERT INTO logtbl VALUES (sect,test,found_rows);
END $$
--delimiter ;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO @found_rows;
CALL just_log(2,3,@found_rows);
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
--echo **** On Slave ****
sync_slave_with_master;
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
--echo ==== 1.3. Stored functions ====
--echo **** On Master ****
connection master;
--delimiter $$
CREATE FUNCTION log_rows(sect INT, test INT, found_rows INT)
RETURNS INT
BEGIN
INSERT INTO logtbl VALUES(sect,test,found_rows);
RETURN found_rows;
END $$
--delimiter ;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO @found_rows;
SELECT log_rows(3,1,@found_rows), log_rows(3,2,@found_rows);
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
--echo **** On Slave ****
sync_slave_with_master;
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
--echo ==== 1.9. Cleanup ====
--echo **** On Master ****
connection master;
DELETE FROM logtbl;
DROP PROCEDURE just_log;
DROP PROCEDURE calc_and_log;
DROP FUNCTION log_rows;
sync_slave_with_master;
source include/reset_master_and_slave.inc;
--echo #### 2. Using mixed mode ####
--echo ==== 2.1. Checking a procedure ====
--echo **** On Master ****
connection master;
SET BINLOG_FORMAT=MIXED;
# We will now check some stuff that will not work in statement-based
# replication, but which should cause the binary log to switch to
@@ -139,7 +42,6 @@ sync_slave_with_master;
--echo **** On Master 1 ****
connection master1;
SET BINLOG_FORMAT=MIXED;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
CALL just_log(1,1);
@@ -167,7 +69,7 @@ SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
sync_slave_with_master;
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
--echo ==== 2.1. Checking a stored function ====
--echo ==== Checking a stored function ====
--echo **** On Master ****
connection master;
--delimiter $$

View File

@@ -0,0 +1,5 @@
--source include/have_binlog_format_mixed.inc
--source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
--source extra/rpl_tests/rpl_insert_delayed.test

View File

@@ -1,15 +1,9 @@
-- source include/have_binlog_format_mixed_or_statement.inc
-- source include/have_binlog_format_mixed.inc
-- source include/not_ndb_default.inc
-- source include/master-slave.inc
# Test that the slave temporarily switches to ROW when seeing binrow
# events when it is in STATEMENT or MIXED mode
SET @old_binlog_format= @@global.binlog_format;
SET BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
SELECT @@GLOBAL.BINLOG_FORMAT, @@SESSION.BINLOG_FORMAT;
# Test that the slave temporarily switches to ROW when seeing row
# events when it is in MIXED mode
--echo **** On Master ****
CREATE TABLE t1 (a INT, b LONG);
@@ -35,7 +29,6 @@ SHOW BINLOG EVENTS;
connection master;
DROP TABLE IF EXISTS t1;
SET @@global.binlog_format= @old_binlog_format;
# Let's compare. Note: If they match test will pass, if they do not match
# the test will show that the diff statement failed and not reject file

View File

@@ -0,0 +1,325 @@
# Testing various forms of idempotency for replication. This file is
# for tests that should only be executed in row mode.
source include/have_binlog_format_row.inc;
source include/master-slave.inc;
connection master;
source include/have_innodb.inc;
connection slave;
source include/have_innodb.inc;
# bug#31609 Not all RBR slave errors reported as errors
# bug#31552 Replication breaks when deleting rows from out-of-sync table
# without PK
# The default for slave-exec-mode option and server
# variable slave_exec_mode is 'STRICT'.
# When 'STRICT' mode is set, the slave SQL thread will stop whenever
# the row to change is not found. In 'IDEMPOTENT' mode, the SQL thread
# will continue running and apply the row - replace if it's Write_rows event -
# or skip to the next event.
# the previous part of the tests was with IDEMPOTENT slave's mode.
#
# Other than above idempotent errors dealing with foreign keys constraint
#
connection slave;
set @old_slave_exec_mode= @@global.slave_exec_mode;
set @@global.slave_exec_mode= IDEMPOTENT;
connection master;
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
sync_slave_with_master;
#connection slave;
select * from ti1 order by b /* must be (1),(2),(3) */;
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
connection master;
# from now on checking rbr specific idempotent errors
set @save_binlog_format= @@session.binlog_format;
set @@session.binlog_format= row;
delete from ti1 where b=1;
select * from ti1 order by b /* must be (2),(3) */;
# slave must catch up (expect some warnings in error.log)
sync_slave_with_master;
#connection slave;
select * from ti1 order by b /* must stays as were on master (1),(2),(3) */;
delete from ti1 where b=3;
connection master;
insert into ti2 set a=3, b=3;
# slave must catch up (expect some warnings in error.log)
sync_slave_with_master;
#connection slave;
select * from ti2 order by b /* must be (1,1),(2,2) - not inserted */;
#
# Checking the new global sys variable
#
connection slave;
set global slave_exec_mode='IDEMPOTENT';
set global slave_exec_mode='STRICT';
# checking mutual exclusion for the options
--error ER_SLAVE_AMBIGOUS_EXEC_MODE
set global slave_exec_mode='IDEMPOTENT,STRICT';
select @@global.slave_exec_mode /* must be STRICT */;
#
# Checking stops.
# In the following sections strict slave sql thread is going to
# stop when faces an idempotent error. In order to proceed
# the mode is temporarily switched to indempotent.
#
#
--echo *** foreign keys errors as above now forces to stop
#
connection master;
set foreign_key_checks=0;
drop table ti2, ti1;
create table ti1 (b int primary key) engine = innodb;
create table ti2 (a int primary key, b int, foreign key (b) references ti1(b))
engine = innodb;
set foreign_key_checks=1 /* ensure the check */;
insert into ti1 values (1),(2),(3);
insert into ti2 set a=2, b=2;
sync_slave_with_master;
#connection slave;
select * from ti1 order by b /* must be (1),(2),(3) */;
--echo *** conspire future problem
insert into ti2 set a=1, b=1;
select * from ti2 order by b /* must be (1,1) (2,2) */;
connection master;
delete from ti1 where b=1 /* offending delete event */;
select * from ti1 order by b /* must be (2),(3) */;
# foreign key: row is referenced
--echo *** slave must stop (Trying to delete a referenced foreing key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
select * from ti1 order by b /* must be (1),(2),(3) - not deleted */;
set foreign_key_checks= 0;
delete from ti2 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
sync_slave_with_master;
#connection slave;
--echo *** conspire the following insert failure
# foreign key: no referenced row
--echo *** conspire future problem
delete from ti1 where b=3;
connection master;
insert into ti2 set a=3, b=3 /* offending write event */;
--echo *** slave must stop (Trying to insert an invalid foreign key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
select * from ti2 order by b /* must be (2,2) */;
set foreign_key_checks= 0;
insert into ti1 set b=3;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
sync_slave_with_master;
select * from ti2 order by b /* must be (2,2),(3,3) */;
#
--echo *** other errors
#
# dup key insert
#connection slave;
--echo *** conspiring query
insert into ti1 set b=1;
connection master;
insert into ti1 set b=1 /* offending write event */;
--echo *** slave must stop (Trying to insert a dupliacte key)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set foreign_key_checks= 0;
delete from ti1 where b=1;
set foreign_key_checks= 1;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
# key not found
connection master;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT);
INSERT INTO t1 VALUES (-1),(-2),(-3);
INSERT INTO t2 VALUES (-1),(-2),(-3);
sync_slave_with_master;
#connection slave;
DELETE FROM t1 WHERE a = -2;
DELETE FROM t2 WHERE a = -2;
connection master;
DELETE FROM t1 WHERE a = -2;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
DELETE FROM t2 WHERE a = -2;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
UPDATE t1 SET a = 1 WHERE a = -1;
UPDATE t2 SET a = 1 WHERE a = -1;
connection master;
UPDATE t1 SET a = 1 WHERE a = -1;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
set global slave_exec_mode='STRICT';
connection master;
UPDATE t2 SET a = 1 WHERE a = -1;
--echo *** slave must stop (Key was not found)
connection slave;
source include/wait_for_slave_sql_to_stop.inc;
let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1);
disable_query_log;
eval SELECT "$last_error" AS Last_SQL_Error;
enable_query_log;
set global slave_exec_mode='IDEMPOTENT';
start slave sql_thread;
connection master;
sync_slave_with_master;
#connection slave;
SET @@global.slave_exec_mode= @old_slave_exec_mode;
# cleanup for bug#31609 tests
connection master;
drop table t1,t2,ti2,ti1;
sync_slave_with_master;
set @@global.slave_exec_mode= @old_slave_exec_mode;
--source include/master-slave-end.inc
--echo *** end of tests

View File

@@ -2,13 +2,4 @@
--source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
connection master;
set @old_global_binlog_format = @@global.binlog_format;
let $binlog_format_statement=0;
set @@global.binlog_format = row;
--source extra/rpl_tests/rpl_insert_delayed.test
connection master;
set @@global.binlog_format = @old_global_binlog_format;

View File

@@ -1,3 +1,9 @@
# Every statement in this test is either executing under ROW or
# STATEMENT format, which requires the slave thread to be able to apply
# both statement and row events. Hence, we only need to execute this
# test for MIXED mode.
source include/have_binlog_format_mixed.inc;
source include/master-slave.inc;
source include/have_innodb.inc;

View File

@@ -0,0 +1,121 @@
source include/have_binlog_format_statement.inc;
source include/master-slave.inc;
# It is not possible to replicate FOUND_ROWS() using statement-based
# replication, but there is a workaround that stores the result of
# FOUND_ROWS() into a user variable and then replicates this instead.
#
# The purpose of this test case is to test that the workaround works
# properly even when inside stored programs (i.e., stored routines and
# triggers).
--echo ==== Initialize ====
--echo **** On Master ****
connection master;
CREATE TABLE t1 (a INT);
CREATE TABLE logtbl (sect INT, test INT, count INT);
INSERT INTO t1 VALUES (1),(2),(3);
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
INSERT INTO t1 SELECT 2*a+3 FROM t1;
--echo ==== Simple test ====
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
# Instead of
# INSERT INTO logtbl VALUES(1, 1, FOUND_ROWS());
# we write
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,1,@a);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
# Instead of
# INSERT INTO logtbl VALUES(1, 2, FOUND_ROWS());
# we write
SELECT FOUND_ROWS() INTO @a;
INSERT INTO logtbl VALUES(1,2,@a);
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
--echo **** On Slave ****
sync_slave_with_master;
SELECT * FROM logtbl WHERE sect = 1 ORDER BY sect,test;
--echo ==== Stored procedure ====
# Here we do both the calculation and the logging. We also do it twice
# to make sure that there are no limitations on how many times it can
# be used.
--echo **** On Master ****
connection master;
--delimiter $$
CREATE PROCEDURE calc_and_log(sect INT, test INT) BEGIN
DECLARE cnt INT;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a < 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test,cnt);
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO cnt;
INSERT INTO logtbl VALUES(sect,test+1,cnt);
END $$
--delimiter ;
CALL calc_and_log(2,1);
--delimiter $$
CREATE PROCEDURE just_log(sect INT, test INT, found_rows INT) BEGIN
INSERT INTO logtbl VALUES (sect,test,found_rows);
END $$
--delimiter ;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO @found_rows;
CALL just_log(2,3,@found_rows);
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
--echo **** On Slave ****
sync_slave_with_master;
SELECT * FROM logtbl WHERE sect = 2 ORDER BY sect,test;
--echo ==== Stored functions ====
--echo **** On Master ****
connection master;
--delimiter $$
CREATE FUNCTION log_rows(sect INT, test INT, found_rows INT)
RETURNS INT
BEGIN
INSERT INTO logtbl VALUES(sect,test,found_rows);
RETURN found_rows;
END $$
--delimiter ;
SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE a > 5 ORDER BY a LIMIT 1;
SELECT FOUND_ROWS() INTO @found_rows;
SELECT log_rows(3,1,@found_rows), log_rows(3,2,@found_rows);
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
--echo **** On Slave ****
sync_slave_with_master;
SELECT * FROM logtbl WHERE sect = 3 ORDER BY sect,test;
--echo ==== Cleanup ====
--echo **** On Master ****
connection master;
DROP TABLE t1, logtbl;
DROP PROCEDURE just_log;
DROP PROCEDURE calc_and_log;
DROP FUNCTION log_rows;
sync_slave_with_master;
source include/reset_master_and_slave.inc;

View File

@@ -1,20 +1,5 @@
# we run first in statement-based then in mixed binlogging
--source include/have_binlog_format_mixed_or_statement.inc
--source include/have_binlog_format_statement.inc
--source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
connection master;
set @old_global_binlog_format = @@global.binlog_format;
let $binlog_format_statement=1;
set @@global.binlog_format = statement;
--source extra/rpl_tests/rpl_insert_delayed.test
let $binlog_format_statement=0;
set @@global.binlog_format = mixed;
--source extra/rpl_tests/rpl_insert_delayed.test
connection master;
set @@global.binlog_format = @old_global_binlog_format;

View File

@@ -1,17 +1,25 @@
#
# rpl_switch_stm_row_mixed tests covers
#
# - switching explicitly between STATEMENT, ROW, and MIXED binlog format
# showing when it is possible and when not.
# - switching from MIXED to RBR implicitly listing all use cases,
# e.g a query invokes UUID(), thereafter to serve as the definition
# of MIXED binlog format
# - Master is switching explicitly between STATEMENT, ROW, and MIXED
# binlog format showing when it is possible and when not.
# - Master switching from MIXED to RBR implicitly listing all use
# cases, e.g a query invokes UUID(), thereafter to serve as the
# definition of MIXED binlog format
# - correctness of execution
-- source include/not_ndb_default.inc
-- source include/master-slave.inc
# Since this test generates row-based events in the binary log, the
# slave SQL thread cannot be in STATEMENT mode to execute this test,
# so we only execute it for MIXED and ROW as default value of
# BINLOG_FORMAT.
connection slave;
-- source include/have_binlog_format_mixed_or_row.inc
connection master;
--disable_warnings
drop database if exists mysqltest1;

View File

@@ -1,10 +1,10 @@
source include/have_binlog_format_row.inc;
source include/master-slave.inc;
call mtr.add_suppression("Deadlock found");
--echo **** On Master ****
connection master;
SET SESSION BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
--echo **** On Slave ****

View File

@@ -5,18 +5,7 @@
# statement based format. This tests work completed in WL#3629. #
###################################################################
--source include/not_embedded.inc
--source include/master-slave.inc
let $engine_type= MyISAM;
set binlog_format=row;
# Embedded server doesn't support binlogging
--source include/rpl_udf.inc
set binlog_format=statement;
# Embedded server doesn't support binlogging
--source include/rpl_udf.inc

View File

@@ -0,0 +1,8 @@
[row]
binlog-format=row
[stmt]
binlog-format=statement
[mix]
binlog-format=mixed

View File

@@ -0,0 +1,130 @@
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
==== Initialize ====
[on slave]
SET @old_binlog_format= @@global.binlog_format;
INSTALL PLUGIN example SONAME 'ha_example.so';
[on master]
SET @old_binlog_format= @@global.binlog_format;
INSTALL PLUGIN example SONAME 'ha_example.so';
CREATE TABLE t (a VARCHAR(100)) ENGINE = MYISAM;
CREATE TABLE t_self_logging (a VARCHAR(100)) ENGINE = NDB;
CREATE TABLE t_row (a VARCHAR(100)) ENGINE = INNODB;
CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE;
CREATE TABLE t_slave_stmt (a VARCHAR(100)) ENGINE = MYISAM;
CREATE DATABASE other;
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
[on slave]
DROP TABLE t_slave_stmt;
CREATE TABLE t_slave_stmt (a INT) ENGINE = EXAMPLE;
[on master]
BINLOG '
1gRVSg8BAAAAZgAAAGoAAAABAAQANS4xLjM2LWRlYnVnLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADWBFVKEzgNAAgAEgAEBAQEEgAAUwAEGggAAAAICAgC
';
==== Test ====
---- binlog_format=row ----
* Modify tables of more than one engine, one of which is self-logging
CREATE TRIGGER trig_1 AFTER INSERT ON t_self_logging FOR EACH ROW BEGIN INSERT INTO t VALUES (1); END;
INSERT INTO t_self_logging VALUES (1);
ERROR HY000: Cannot execute statement: binlogging impossible since more than one engine is involved and at least one engine is self-logging.
DROP trigger trig_1;
* Modify both row-only and stmt-only table
CREATE TRIGGER trig_2 AFTER INSERT ON t_stmt FOR EACH ROW BEGIN INSERT INTO t_row VALUES(1); END;
INSERT INTO t_stmt VALUES (1);
ERROR HY000: Cannot execute statement: binlogging impossible since both row-incapable engines and statement-incapable engines are involved.
DROP TRIGGER trig_2;
* Stmt-only table and binlog_format=row
INSERT INTO t_stmt VALUES (1);
ERROR HY000: Cannot execute statement: binlogging impossible since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-logging.
* Row injection and stmt-only table: in slave sql thread
INSERT INTO t_slave_stmt VALUES (1);
[on slave]
--source include/wait_for_slave_sql_error_and_skip.inc
Last_SQL_Error = Error 'Cannot execute row injection: binlogging impossible since at least one table uses a storage engine limited to statement-logging.' on opening tables
set global sql_slave_skip_counter=1;
include/start_slave.inc
* Row injection and stmt-only table: use BINLOG statement
BINLOG '
1gRVShMBAAAALwAAAEABAAAAABcAAAAAAAAABHRlc3QABnRfc3RtdAABDwJkAAE=
1gRVShcBAAAAIAAAAGABAAAQABcAAAAAAAEAAf/+ATE=
';
ERROR HY000: Cannot execute row injection: binlogging impossible since at least one table uses a storage engine limited to statement-logging.
---- binlog_format=mixed ----
[on slave]
include/stop_slave.inc
SET @@global.binlog_format = MIXED;
include/start_slave.inc
[on master]
SET @@global.binlog_format = MIXED;
SET @@session.binlog_format = MIXED;
* Unsafe statement and stmt-only engine
INSERT INTO t_stmt VALUES (UUID());
Warnings:
Note 1641 Unsafe statement binlogged as statement since storage engine is limited to statement-logging. Reason: Statement uses a system function whose value may differ on slave.
---- binlog_format=statement ----
[on slave]
include/stop_slave.inc
SET @@global.binlog_format = STATEMENT;
include/start_slave.inc
[on master]
SET @@global.binlog_format = STATEMENT;
SET @@session.binlog_format = STATEMENT;
* Row-only engine and binlog_format=statement: innodb-specific message
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.
* Row-only engine and binlog_format=statement: generic message
SET @@session.debug= '+d,no_innodb_binlog_errors';
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.
* 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
BINLOG '
cNpVShMBAAAAKgAAADYBAAAAABcAAAAAAAAABHRlc3QAAXQAAQ8CZAAB
cNpVShcBAAAAIAAAAFYBAAAQABcAAAAAAAEAAf/+ATE=
';
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
INSERT INTO t VALUES (UUID());
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.
* 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 ----
SET @@global.binlog_format = MIXED;
SET @@session.binlog_format = MIXED;
* Row injection and binlog_format=statement: in slave sql thread
INSERT INTO t VALUES (UUID());
[on slave]
--source include/wait_for_slave_sql_error_and_skip.inc
Last_SQL_Error = Error 'Cannot execute row injection: binlogging impossible since BINLOG_FORMAT = STATEMENT.' on opening tables
set global sql_slave_skip_counter=1;
include/start_slave.inc
[on master]
==== Clean up ====
DROP TABLE t, t_self_logging, t_row, t_stmt, t_slave_stmt;
DROP DATABASE other;
SET @@global.binlog_format = @old_binlog_format;
SET @@session.binlog_format = @old_binlog_format;
UNINSTALL PLUGIN example;
[on slave]
SET @@global.binlog_format = @old_binlog_format;
SET @@session.binlog_format = @old_binlog_format;
UNINSTALL PLUGIN example;

View File

@@ -102,3 +102,4 @@ Last_IO_Errno #
Last_IO_Error #
Last_SQL_Errno 0
Last_SQL_Error
DROP TABLE t1;

View File

@@ -8,6 +8,9 @@
# test and to have control over the tests.
##############################################################
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/master-slave.inc
-- connection slave

View File

@@ -8,6 +8,9 @@
# test and to have control over the tests.
##############################################################
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/master-slave.inc
-- connection slave

View File

@@ -1,4 +1,7 @@
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc

View File

@@ -0,0 +1 @@
--innodb $EXAMPLE_PLUGIN_OPT --binlog-ignore-db=other

View File

@@ -0,0 +1 @@
--innodb $EXAMPLE_PLUGIN_OPT

View File

@@ -0,0 +1,225 @@
# ==== Purpose ====
#
# Verify that errors or warnings are issued for all error conditions
# related to deciding the binlog format of a statement. The possible
# errors are listed in a comment above decide_logging_format() in
# sql_base.cc.
#
# ==== Method ====
#
# Each error condition is executed; we verify that there is an error.
#
# ==== Related bugs ====
#
# BUG#39934: Slave stops for engine that only support row-based logging
# BUG#42829: binlogging enabled for all schemas regardless of binlog-db-db / binlog-ignore-db
#
# ==== Related test cases ====
#
# binlog.binlog_unsafe verifies more thoroughly that a warning is
# given for the case when an unsafe statement is executed and
# binlog_format = STATEMENT.
# Need debug so that 'SET @@session.debug' works.
--source include/have_debug.inc
# Need example plugin because it is the only statement-only engine.
--source include/have_example_plugin.inc
# The test changes binlog_format, so there is no reason to run it
# under more than one binlog format.
--source include/have_binlog_format_row.inc
--source include/have_ndb.inc
--source include/have_innodb.inc
--source include/ndb_master-slave.inc
--echo ==== Initialize ====
--echo [on slave]
--connection slave
SET @old_binlog_format= @@global.binlog_format;
INSTALL PLUGIN example SONAME 'ha_example.so';
--echo [on master]
--connection master
SET @old_binlog_format= @@global.binlog_format;
INSTALL PLUGIN example SONAME 'ha_example.so';
CREATE TABLE t (a VARCHAR(100)) ENGINE = MYISAM;
CREATE TABLE t_self_logging (a VARCHAR(100)) ENGINE = NDB;
CREATE TABLE t_row (a VARCHAR(100)) ENGINE = INNODB;
CREATE TABLE t_stmt (a VARCHAR(100)) ENGINE = EXAMPLE;
CREATE TABLE t_slave_stmt (a VARCHAR(100)) ENGINE = MYISAM;
CREATE DATABASE other;
# This makes the innodb table row-only
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
--echo [on slave]
--sync_slave_with_master
DROP TABLE t_slave_stmt;
CREATE TABLE t_slave_stmt (a INT) ENGINE = EXAMPLE;
--echo [on 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 ---- binlog_format=row ----
--echo * Modify tables of more than one engine, one of which is self-logging
--eval CREATE TRIGGER trig_1 AFTER INSERT ON t_self_logging FOR EACH ROW BEGIN INSERT INTO t VALUES (1); END
--error ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE
INSERT INTO t_self_logging VALUES (1);
DROP trigger trig_1;
--echo * Modify both row-only and stmt-only table
--eval CREATE TRIGGER trig_2 AFTER INSERT ON t_stmt FOR EACH ROW BEGIN INSERT INTO t_row VALUES(1); END
--error ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE
INSERT INTO t_stmt VALUES (1);
DROP TRIGGER trig_2;
--echo * Stmt-only table and binlog_format=row
--error ER_BINLOG_ROW_MODE_AND_STMT_ENGINE
INSERT INTO t_stmt VALUES (1);
--echo * Row injection and stmt-only table: in slave sql thread
INSERT INTO t_slave_stmt VALUES (1);
--echo [on slave]
--connection slave
# 1642 = ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE
--let $slave_sql_errno= 1642
--let $show_sql_error= 1
--source include/wait_for_slave_sql_error_and_skip.inc
--echo * Row injection and stmt-only table: use BINLOG statement
# This is a Table_map_event and a Write_rows_event. Together, they are
# equivalent to 'INSERT INTO t_stmt VALUES (1)'
--error ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE
BINLOG '
1gRVShMBAAAALwAAAEABAAAAABcAAAAAAAAABHRlc3QABnRfc3RtdAABDwJkAAE=
1gRVShcBAAAAIAAAAGABAAAQABcAAAAAAAEAAf/+ATE=
';
--echo ---- binlog_format=mixed ----
--echo [on slave]
--sync_slave_with_master
--source include/stop_slave.inc
SET @@global.binlog_format = MIXED;
--source include/start_slave.inc
--echo [on master]
--connection master
SET @@global.binlog_format = MIXED;
SET @@session.binlog_format = MIXED;
--echo * Unsafe statement and stmt-only engine
# This will give a warning.
INSERT INTO t_stmt VALUES (UUID());
--echo ---- binlog_format=statement ----
--echo [on slave]
--sync_slave_with_master
--source include/stop_slave.inc
SET @@global.binlog_format = STATEMENT;
--source include/start_slave.inc
--echo [on master]
--connection master
SET @@global.binlog_format = STATEMENT;
SET @@session.binlog_format = STATEMENT;
--echo * Row-only engine and binlog_format=statement: innodb-specific message
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
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
SET @@session.debug= '+d,no_innodb_binlog_errors';
--error ER_BINLOG_STMT_MODE_AND_ROW_ENGINE
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
# This is a Table_map_event and a Write_rows_event. Together, they are
# equivalent to 'INSERT INTO t VALUES (1)'.
--error ER_BINLOG_ROW_INJECTION_AND_STMT_MODE
BINLOG '
cNpVShMBAAAAKgAAADYBAAAAABcAAAAAAAAABHRlc3QAAXQAAQ8CZAAB
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
# This will give a warning.
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 ----
SET @@global.binlog_format = MIXED;
SET @@session.binlog_format = MIXED;
--echo * Row injection and binlog_format=statement: in slave sql thread
INSERT INTO t VALUES (UUID());
--echo [on slave]
--connection slave
# 1644 = ER_BINLOG_ROW_INJECTION_AND_STMT_MODE
--let $slave_sql_errno= 1644
--let $show_sql_error= 1
--source include/wait_for_slave_sql_error_and_skip.inc
--echo [on master]
--connection master
--echo ==== Clean up ====
DROP TABLE t, t_self_logging, t_row, t_stmt, t_slave_stmt;
DROP DATABASE other;
SET @@global.binlog_format = @old_binlog_format;
SET @@session.binlog_format = @old_binlog_format;
UNINSTALL PLUGIN example;
--echo [on slave]
--sync_slave_with_master
SET @@global.binlog_format = @old_binlog_format;
SET @@session.binlog_format = @old_binlog_format;
UNINSTALL PLUGIN example;

View File

@@ -1,4 +1,7 @@
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc
#

View File

@@ -3,6 +3,11 @@
# Using wrapper to share test #
# code between engine tests #
#################################
#
# Since the master generates row-based events, the slave may not be in
# STATEMENT mode to accept the events.
#
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/have_ndb.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDBCLUSTER;

View File

@@ -1,4 +1,7 @@
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc
# set up circular replication

View File

@@ -1,4 +1,7 @@
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc
connection master;
@@ -78,3 +81,7 @@ SELECT * FROM t1 ORDER BY a;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # 35 # 36 #
query_vertical SHOW SLAVE STATUS;
connection master;
DROP TABLE t1;
sync_slave_with_master;

View File

@@ -4,6 +4,10 @@
# Different engines #
# By JBM 2004-02-15 #
#####################################
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/have_ndb.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDB;

View File

@@ -1,5 +1,8 @@
--source include/have_ucs2.inc
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc
#

View File

@@ -3,6 +3,9 @@
# Share test code between engine tests #
#########################################
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDB;
-- source extra/rpl_tests/rpl_delete_no_where.test

View File

@@ -6,6 +6,9 @@
##########################################################
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc
--disable_warnings

View File

@@ -6,6 +6,9 @@
##########################################################
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc
--disable_warnings

View File

@@ -7,6 +7,9 @@
# reduce test case code #
###################################
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDB;
-- source extra/rpl_tests/rpl_row_func003.test

View File

@@ -2,6 +2,9 @@
-- source include/have_ndb.inc
-- source include/have_innodb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
create table t1 (a int, unique(a)) engine=ndbcluster;

View File

@@ -2,6 +2,9 @@
# Wrapper for rpl_insert_ignore.test#
#####################################
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDB;
let $engine_type2=myisam;

View File

@@ -23,6 +23,9 @@
source include/have_ndb.inc;
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
source include/have_binlog_format_mixed_or_row.inc;
source include/ndb_master-slave.inc;
source include/have_innodb.inc;

View File

@@ -3,6 +3,9 @@
# to reuse test code between engine runs #
############################################################
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDB;
-- source extra/rpl_tests/rpl_multi_update3.test

View File

@@ -7,6 +7,9 @@
##########################################################
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
--source include/ndb_master-slave.inc
--disable_warnings

View File

@@ -2,6 +2,9 @@
# By JBM 2005-02-15 Wrapped to allow reuse of test code#
########################################################
--source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
--source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDB;
-- source extra/rpl_tests/rpl_row_001.test

View File

@@ -5,6 +5,9 @@
# For different engines #
#################################
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDBCLUSTER;
-- source extra/rpl_tests/rpl_row_sp003.test

View File

@@ -5,6 +5,9 @@
# For different engines #
#################################
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDBCLUSTER;
-- source extra/rpl_tests/rpl_row_sp006.test

View File

@@ -8,6 +8,9 @@
# Includes
-- source include/have_ndb.inc
# Since the master generates row-based events, the slave must be in
# ROW or MIXED mode to accept the events.
-- source include/have_binlog_format_mixed_or_row.inc
-- source include/ndb_master-slave.inc
let $engine_type=NDB;
-- source extra/rpl_tests/rpl_trig004.test