Commit b9f2a573 authored by Alexander Nozdrin's avatar Alexander Nozdrin
Browse files

Auto-merge from mysql-next-mr.

parents 46400e13 60700c95
......@@ -392,6 +392,7 @@ client/rpl_record_old.h
client/rpl_tblmap.h
client/rpl_tblmap.cc
client/rpl_utility.h
client/rpl_utility.cc
client/select_test
client/sql_string.cpp
client/ssl_test
......@@ -1143,6 +1144,7 @@ libmysqld/rpl_handler.cc
libmysqld/rpl_injector.cc
libmysqld/rpl_record.cc
libmysqld/rpl_record_old.cc
libmysqld/rpl_utility.cc
libmysqld/scheduler.cc
libmysqld/set_var.cc
libmysqld/simple-test
......
......@@ -104,9 +104,10 @@ DEFS = -DMYSQL_CLIENT_NO_THREADS \
-DMYSQL_DATADIR="\"$(localstatedir)\""
sql_src=log_event.h mysql_priv.h rpl_constants.h \
rpl_utility.h rpl_tblmap.h rpl_tblmap.cc \
rpl_tblmap.h rpl_tblmap.cc \
log_event.cc my_decimal.h my_decimal.cc \
log_event_old.h log_event_old.cc \
rpl_utility.h rpl_utility.cc \
rpl_record_old.h rpl_record_old.cc
strings_src=decimal.c dtoa.c
......
......@@ -2140,4 +2140,4 @@ int main(int argc, char** argv)
#include "my_decimal.cc"
#include "log_event.cc"
#include "log_event_old.cc"
#include "rpl_utility.cc"
......@@ -117,6 +117,12 @@ enum enum_server_command
thread */
#define REFRESH_MASTER 128 /* Remove all bin logs in the index
and truncate the index */
#define REFRESH_ERROR_LOG 256 /* Rotate only the erorr log */
#define REFRESH_ENGINE_LOG 512 /* Flush all storage engine logs */
#define REFRESH_BINARY_LOG 1024 /* Flush the binary log */
#define REFRESH_RELAY_LOG 2048 /* Flush the relay log */
#define REFRESH_GENERAL_LOG 4096 /* Flush the general log */
#define REFRESH_SLOW_LOG 8192 /* Flush the slow query log */
/* The following can't be set with mysql_refresh() */
#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
......
......@@ -56,7 +56,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
item_geofunc.cc item_subselect.cc item_row.cc\
item_xmlfunc.cc \
key.cc lock.cc log.cc sql_state.c \
log_event.cc rpl_record.cc \
log_event.cc rpl_record.cc rpl_utility.cc \
log_event_old.cc rpl_record_old.cc \
protocol.cc net_serv.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \
......
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
################################################################################
# Let
# - B be begin, C commit and R rollback.
# - T a statement that accesses and changes only transactional tables, i.e.
# T-tables
# - N a statement that accesses and changes only non-transactional tables,
# i.e, N-tables.
# - M be a mixed statement, i.e. a statement that updates both T- and
# N-tables.
# - M* be a mixed statement that fails while updating either a T
# or N-table.
# - N* be a statement that fails while updating a N-table.
#
# In this test case, when changes are logged as rows either in the RBR or MIXED
# modes, we check if a M* statement that happens early in a transaction is
# written to the binary log outside the boundaries of the transaction and
# wrapped up in a BEGIN/ROLLBACK. This is done to keep the slave consistent with
# the master as the rollback will keep the changes on N-tables and undo them on
# T-tables. In particular, we expect the following behavior:
#
# 1. B M* T C would generate in the binlog B M* R B T C.
# 2. B M M* C would generate in the binlog B M M* C.
# 3. B M* M* T C would generate in the binlog B M* R B M* R B T C.
#
# SBR is not considered in this test because a failing statement is written to
# the binary along with the error code such that a slave executes and rolls it
# back, thus undoing the effects on T-tables.
#
# Note that, in the first case, we are not preserving history from the master as
# we are introducing a rollback that never happened. However, this seems to be
# more acceptable than making the slave diverge. In the second case, the slave
# will diverge as the changes on T-tables that originated from the M statement
# are rolled back on the master but not on the slave. Unfortunately, we cannot
# simply roll the transaction back as this would undo any uncommitted changes
# on T-tables.
#
# We check two more cases. First, INSERT...SELECT* which produces the following
# results:
#
# 1. B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
# the binlog the following entries: "Nothing".
# 2. B INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates in
# the binlog the following entries: B INSERT M...SELECT* R.
#
# Finally, we also check if any N statement that happens early in a transaction
# (i.e. before any T or M statement) is written to the binary log outside the
# boundaries of the transaction. In particular, we expect the following
# behavior:
#
# 1. B N N T C would generate in the binlog B N C B N C B T C.
# 2. B N N T R would generate in the binlog B N C B N C B T R.
# 3. B N* N* T C would generate in the binlog B N R B N R B T C.
# 4. B N* N* T R would generate in the binlog B N R B N R B T R.
# 5. B N N T N T C would generate in the binlog B N C B N C B T N T C.
# 6. B N N T N T R would generate in the binlog the B N C B N C B T N T R.
#
# Such issues do not happen in SBR. In RBR and MBR, a full-fledged fix will be
# pushed after the WL#2687.
#
# Please, remove this test case after pushing WL#2687.
################################################################################
--echo ###################################################################################
--echo # CONFIGURATION
--echo ###################################################################################
CREATE TABLE nt_1 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
CREATE TABLE nt_2 (a text, b int PRIMARY KEY) ENGINE = MyISAM;
CREATE TABLE tt_1 (a text, b int PRIMARY KEY) ENGINE = Innodb;
CREATE TABLE tt_2 (a text, b int PRIMARY KEY) ENGINE = Innodb;
DELIMITER |;
CREATE TRIGGER tr_i_tt_1_to_nt_1 BEFORE INSERT ON tt_1 FOR EACH ROW
BEGIN
INSERT INTO nt_1 VALUES (NEW.a, NEW.b);
END|
CREATE TRIGGER tr_i_nt_2_to_tt_2 BEFORE INSERT ON nt_2 FOR EACH ROW
BEGIN
INSERT INTO tt_2 VALUES (NEW.a, NEW.b);
END|
DELIMITER ;|
--echo ###################################################################################
--echo # CHECK HISTORY IN BINLOG
--echo ###################################################################################
--echo
--echo
--echo
--echo *** "B M* T C" with error in M* generates in the binlog the "B M* R B T C" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
INSERT INTO nt_1 VALUES ("new text 1", 1);
BEGIN;
--error ER_DUP_ENTRY
INSERT INTO tt_1 VALUES (USER(), 2), (USER(), 1);
INSERT INTO tt_2 VALUES ("new text 3", 3);
COMMIT;
--source include/show_binlog_events.inc
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
INSERT INTO tt_2 VALUES ("new text 4", 4);
BEGIN;
--error ER_DUP_ENTRY
INSERT INTO nt_2 VALUES (USER(), 5), (USER(), 4);
INSERT INTO tt_2 VALUES ("new text 6", 6);
COMMIT;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B M M* T C" with error in M* generates in the binlog the "B M M* T C" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
INSERT INTO nt_1 VALUES ("new text 10", 10);
BEGIN;
INSERT INTO tt_1 VALUES ("new text 7", 7), ("new text 8", 8);
--error ER_DUP_ENTRY
INSERT INTO tt_1 VALUES (USER(), 9), (USER(), 10);
INSERT INTO tt_2 VALUES ("new text 11", 11);
COMMIT;
--source include/show_binlog_events.inc
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
INSERT INTO tt_2 VALUES ("new text 15", 15);
BEGIN;
INSERT INTO nt_2 VALUES ("new text 12", 12), ("new text 13", 13);
--error ER_DUP_ENTRY
INSERT INTO nt_2 VALUES (USER(), 14), (USER(), 15);
INSERT INTO tt_2 VALUES ("new text 16", 16);
COMMIT;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B M* M* T C" with error in M* generates in the binlog the "B M* R B M* R B T C" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
INSERT INTO nt_1 VALUES ("new text 18", 18);
INSERT INTO nt_1 VALUES ("new text 20", 20);
BEGIN;
--error ER_DUP_ENTRY
INSERT INTO tt_1 VALUES (USER(), 17), (USER(), 18);
--error ER_DUP_ENTRY
INSERT INTO tt_1 VALUES (USER(), 19), (USER(), 20);
INSERT INTO tt_2 VALUES ("new text 21", 21);
COMMIT;
--source include/show_binlog_events.inc
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
INSERT INTO tt_2 VALUES ("new text 23", 23);
INSERT INTO tt_2 VALUES ("new text 25", 25);
BEGIN;
--error ER_DUP_ENTRY
INSERT INTO nt_2 VALUES (USER(), 22), (USER(), 23);
--error ER_DUP_ENTRY
INSERT INTO nt_2 VALUES (USER(), 24), (USER(), 25);
INSERT INTO tt_2 VALUES ("new text 26", 26);
COMMIT;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B T INSERT M...SELECT* C" with an error in INSERT M...SELECT* generates
--echo *** in the binlog the following entries: "Nothing".
--echo *** There is a bug in that will be fixed after WL#2687. Please, check BUG#47175 for further details.
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
TRUNCATE TABLE nt_2;
TRUNCATE TABLE tt_2;
INSERT INTO tt_2 VALUES ("new text 7", 7);
BEGIN;
INSERT INTO tt_2 VALUES ("new text 27", 27);
--error ER_DUP_ENTRY
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
INSERT INTO tt_2 VALUES ("new text 28", 28);
ROLLBACK;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B INSERT M..SELECT* C" with an error in INSERT M...SELECT* generates
--echo *** in the binlog the following entries: "B INSERT M..SELECT* R".
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
TRUNCATE TABLE nt_2;
TRUNCATE TABLE tt_2;
INSERT INTO tt_2 VALUES ("new text 7", 7);
BEGIN;
--error ER_DUP_ENTRY
INSERT INTO nt_2(a, b) SELECT USER(), b FROM nt_1;
COMMIT;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B N N T C" generates in the binlog the "B N C B N C B T C" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
TRUNCATE TABLE nt_1;
TRUNCATE TABLE tt_2;
BEGIN;
INSERT INTO nt_1 VALUES (USER(), 1);
INSERT INTO nt_1 VALUES (USER(), 2);
INSERT INTO tt_2 VALUES (USER(), 3);
COMMIT;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B N N T R" generates in the binlog the "B N C B N C B T R" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
BEGIN;
INSERT INTO nt_1 VALUES (USER(), 4);
INSERT INTO nt_1 VALUES (USER(), 5);
INSERT INTO tt_2 VALUES (USER(), 6);
ROLLBACK;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B N* N* T C" with error in N* generates in the binlog the "B N R B N R B T C" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
BEGIN;
--error ER_DUP_ENTRY
INSERT INTO nt_1 VALUES (USER(), 7), (USER(), 1);
--error ER_DUP_ENTRY
INSERT INTO nt_1 VALUES (USER(), 8), (USER(), 1);
INSERT INTO tt_2 VALUES (USER(), 9);
COMMIT;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B N* N* T R" with error in N* generates in the binlog the "B N R B N R B T R" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
BEGIN;
--error ER_DUP_ENTRY
INSERT INTO nt_1 VALUES (USER(), 10), (USER(), 1);
--error ER_DUP_ENTRY
INSERT INTO nt_1 VALUES (USER(), 11), (USER(), 1);
INSERT INTO tt_2 VALUES (USER(), 12);
ROLLBACK;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B N N T N T C" generates in the binlog the "B N C B N C B T N T C" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
BEGIN;
INSERT INTO nt_1 VALUES (USER(), 13);
INSERT INTO nt_1 VALUES (USER(), 14);
INSERT INTO tt_2 VALUES (USER(), 15);
INSERT INTO nt_1 VALUES (USER(), 16);
INSERT INTO tt_2 VALUES (USER(), 17);
COMMIT;
--source include/show_binlog_events.inc
--echo
--echo
--echo
--echo *** "B N N T N T R" generates in the binlog the "B N C B N C B T N T R" entries
--echo
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
BEGIN;
INSERT INTO nt_1 VALUES (USER(), 18);
INSERT INTO nt_1 VALUES (USER(), 19);
INSERT INTO tt_2 VALUES (USER(), 20);
INSERT INTO nt_1 VALUES (USER(), 21);
INSERT INTO tt_2 VALUES (USER(), 22);
ROLLBACK;
--source include/show_binlog_events.inc
--echo ###################################################################################
--echo # CLEAN
--echo ###################################################################################
DROP TABLE tt_1;
DROP TABLE tt_2;
DROP TABLE nt_1;
DROP TABLE nt_2;
......@@ -6,6 +6,8 @@
-- source include/have_blackhole.inc
-- source include/have_log_bin.inc
CALL mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
# The server need to be started in $MYSQLTEST_VARDIR since it
# uses ../../std_data/
-- source include/uses_vardir.inc
......
......@@ -8,6 +8,7 @@
-- source include/have_log_bin.inc
-- source include/have_innodb.inc
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
--disable_warnings
drop table if exists t1, t2;
......@@ -323,23 +324,24 @@ let $MYSQLD_DATADIR= `select @@datadir`;
# and does not make slave to stop)
if (`select @@binlog_format = 'ROW'`)
{
--exec $MYSQL_BINLOG --start-position=525 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
--echo This does not matter in ROW mode as the rolled back changes do not contain transactional changes as these
--echo were previously flushed upon committing/rolling back each statement.
}
if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`)
{
--exec $MYSQL_BINLOG --start-position=556 $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
}
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
is not null;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
eval select
@a like "%#%error_code=0%ROLLBACK\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR
@a like "%#%error_code=0%ROLLBACK\\r\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%",
@a not like "%#%error_code=%error_code=%";
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
eval select
(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
is not null;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
eval select
@a like "%#%error_code=0%ROLLBACK\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%" OR
@a like "%#%error_code=0%ROLLBACK\\r\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%",
@a not like "%#%error_code=%error_code=%";
}
drop table t1, t2;
#
......
# Helper file to perform one insert of a value into a table with
# different types on master and slave. The file will insert the
# result into the type_conversions table *on the slave* to get a
# summary of failing and succeeding tests.
# Input:
# $source_type Type on the master
# $target_type Type on the slave
# $source_value Value on the master (inserted into the table)
# $target_value Value on the slave (expected value in the table
# on the slave)
# $can_convert True if conversion shall work, false if it
# shall generate an error
connection master;
disable_warnings;
DROP TABLE IF EXISTS t1;
enable_warnings;
eval CREATE TABLE t1 (a $source_type);
sync_slave_with_master;
eval ALTER TABLE t1 MODIFY a $target_type;
connection master;
eval INSERT INTO t1 VALUES($source_value);
if ($can_convert) {
sync_slave_with_master;
eval SELECT a = $target_value into @compare FROM t1;
eval INSERT INTO type_conversions SET
Source = "$source_type",
Target = "$target_type",
Flags = @@slave_type_conversions,
On_Master = $source_value,
Expected = $target_value,
Compare = @compare;
UPDATE type_conversions
SET On_Slave = (SELECT a FROM t1)
WHERE TestNo = LAST_INSERT_ID();
}
if (!$can_convert) {
connection slave;
wait_for_slave_to_stop;
let $error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
eval INSERT INTO type_conversions SET
Source = "$source_type",
Target = "$target_type",
Flags = @@slave_type_conversions,
On_Master = $source_value,
Error = "$error";
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
}
# ==== Purpose ====
#
# Creates a stored routine, stored function, trigger, view, or
# prepared statement (commonly referred to as "recursive construct")
# that invokes a given unsafe statement.
#
# Then, it invokes the created recursive construct several times:
#
# - With SQL_LOG_BIN = 1 and binlog_format = STATEMENT, to verify
# that it gives a warning.
#
# - With SQL_LOG_BIN = 0 and binlog_format = STATEMENT, to verify that
# there is no warning and nothing is logged.
#
# - With SQL_LOG_BIN = 1 and binlog_format = MIXED, to verify that it
# writes row events to the binlog.
#
# - In some cases, the recursive construct can be invoked so that it
# has no side-effects but returns a value that may be
# nondeterministic. An example is a function that returns UUID().
# The function does not have side effects but its a return value
# that may differ on slave. Such statements are invoked so that
# the return value is discarded (e.g., SELECT func()), with
# SQL_LOG_BIN = 1 and binlog_format = STATEMENT. In this case, no
# warning should be given and nothing should be written to the
# binlog.
#
# This is an auxiliary file particularly targeted to being used by the
# test binlog_unsafe. In this context, the purpose is to check how
# warnings for unsafe statements are propagated in recursive
# constructs.
#
# The statement to invoke ("input") is described using mtr variables,
# and the resulting recursive construct ("output") is stored in mtr
# variables in a similar fashion. To create several levels of nested
# recursive constructs, source this file once, then copy the values of
# appropriate output variables to the input variables, and then source
# this file again.
#
#
# ==== Usage ====
#
# See binlog_unsafe for an example of how to use this file.
#
# let $CRC_ARG_level= <level>;
# let $CRC_ARG_type= <type>;
# let $CRC_ARG_stmt_sidef= <stmt>;
# let $CRC_ARG_value= <stmt>;
# let $CRC_ARG_sel_retval= <stmt>;
# let $CRC_ARG_sel_sidef= <stmt>;
# let $CRC_ARG_desc= <desc>;
# source extra/rpl_tests/create_recursive_construct.inc;
# let $my_stmt_sidef= $CRC_RET_stmt_sidef;
# let $my_value= $CRC_RET_value;
# let $my_sel_sidef= $CRC_RET_sel_sidef;
# let $my_sel_retval= $CRC_RET_sel_retval;
# let $my_drop= $CRC_RET_drop;
# let $my_is_toplevel= $CRC_RET_top_is_toplevel;
# let $my_desc= $CRC_RET_desc;
#
# $CRC_ARG_* are used as input parameters (arguments) to this file:
#
# $CRC_ARG_level is the recursion depth: 1 for the innermost
# statement created, 2 for a statement that invokes a statement on
# level 1, etc.
#
# $CRC_ARG_type is an integer from 0 to 6, indicating what type of
# statement shall be created:
# 0 - Create a stored function where the return value depends on
# the value of the given statement.
# 1 - Create a stored function that invokes the given statement as
# a side-effect but may not return a value that depends on it.
# 2 - Create a stored routine that invokes the given statement.
# 3 - Create a trigger (on table trigger_table_$CRC_ARG_level) that
# invokes the given statement.
# 4 - Create a view that returns a value that depends on the value
# of the given statement.
# 5 - Create a view that invokes the given statement but may return
# a value that does not depend on it.
# 6 - Create a prepared statement that invokes the given statement.
#
# $CRC_ARG_stmt_sidef is the statement to invoke. It should be a
# statement that can be invoked on its own (not sub-statement),
# which causes something unsafe to be written to the binlog.
#
# $CRC_ARG_value is a sub-statement holding the value of the given
# statement. Can be empty if the given statement does not have a
# value. Typically, this is non-empty if the given statement is a
# function call or user variable, but not if it is a stored routine
# call, INSERT, SELECT, etc (because none of them has a value).
# $CRC_ARG_value is used only when $CRC_ARG_type=6.
#
# $CRC_ARG_sel_sidef is a SELECT sub-statement that invokes the
# statement as a side-effect, but returns a result set that may not
# depend on the statement. Can be empty if the statement cannot
# produce a result set from a SELECT. $CRC_ARG_sel_sidef is used
# only if $CRC_ARG_type=2
#
# $CRC_ARG_sel_retval is a SELECT sub-statement that does not have
# side-effects, but returns a result set that depends on the unsafe
# statement. Can be empty if the statement cannot be invoked from a
# SELECT. $CRC_ARG_sel_retval is used only if $CRC_ARG_type=3.
#
# $CRC_ARG_desc is a human-readable description of the statement to
# invoke.
#
# $CRC_RET_* are used as output parameters (return values) of this
# file:
#
# $CRC_RET_stmt_sidef is a statement invoking the resulting recursive
# construct.
#
# $CRC_RET_value is a sub-statement invoking the resulting recursive
# construct and returning the value of the recursive construct.
# This is the empty string if the resulting recursive construct does
# not have a value. In particular, this is non-empty only if
# $CRC_ARG_value=7.
#
# $CRC_RET_sel_sidef is a SELECT sub-statement that invokes the
# resulting recursive construct as a side-effect but where the
# result set may not depend on the recursive construct. This is the
# empty string if the recursive construct cannot be invoked from a
# SELECT. In particular, this is non-empty only if $CRC_ARG_value=6
# or $CRC_ARG_value=2.
#
# $CRC_RET_sel_retval is a SELECT sub-statement that does not have
# side-effects, but returns a result set depending on the unsafe
# statement. This is the empty string if the recursive construct
# cannot produce a result set from a SELECT. In particular, this is
# non-empty only if $CRC_ARG_value=7 or $CRC_ARG_value=3.
#
# $CRC_RET_drop is a statement that drops the created object. I.e.,
# it is one of 'DROP FUNCTION <func>', 'DROP PROCEDURE <proc>', etc.
#
# $CRC_RET_top_is_toplevel is 0 normally, or 1 if the resulting
# recursive construct can only be called from a top-level statement.
# In particular, this is 1 only when $CRC_ARG_value=1, because
# prepared statements cannot be invoked from other recursive
# constructs.
#
# $CRC_RET_desc is a text string that describes the invokation of
# the recursive construct in a human-readable fashion.
#
# Assumptions
#
# Before sourcing this file with $CRC_ARG_level=X, you need to
# create three tables: tX, taX and trigger_table_X. These are used
# as auxiliary tables.
#--echo debug: >>>>ENTER create_recursive_construct
#--echo debug: level=$CRC_ARG_level
#--echo debug: type=$CRC_ARG_type
#--echo debug: stmt_sidef=$CRC_ARG_stmt_sidef
#--echo debug: value=$CRC_ARG_value
#--echo debug: sel_retval=$CRC_ARG_sel_retval
#--echo debug: sel_sidef=$CRC_ARG_sel_sidef
--let $CRC_RET_stmt_sidef=
--let $CRC_RET_value=
--let $CRC_RET_sel_retval=
--let $CRC_RET_sel_sidef=
--let $CRC_RET_drop=
--let $CRC_RET_is_toplevel= 1
--let $CRC_RET_desc=
--let $CRC_name=
--let $CRC_create=
######## func_retval ########
if (`SELECT $CRC_ARG_type = 0 AND '$CRC_ARG_value' != ''`) {
# It will be safe to call this function and discard the return
# value, but it will be unsafe to use return value (e.g., in
# INSERT...SELECT).
--let $CRC_name= func_retval_$CRC_ARG_level
--let $CRC_create= CREATE FUNCTION $CRC_name() RETURNS VARCHAR(100) BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); RETURN $CRC_ARG_value; END
--let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_level VALUES ($CRC_name())
--let $CRC_RET_value= $CRC_name()
--let $CRC_RET_sel_sidef=
--let $CRC_RET_sel_retval= SELECT $CRC_name()
--let $CRC_RET_drop= DROP FUNCTION $CRC_name
--let $CRC_RET_is_toplevel= 0
--let $CRC_RET_desc= function $CRC_name returning value from $CRC_ARG_desc
}
######## func_sidef ########
if (`SELECT $CRC_ARG_type = 1`) {
# It will be unsafe to call func even if you discard return value.
--let $CRC_name= func_sidef_$CRC_ARG_level
--let $CRC_create= CREATE FUNCTION $CRC_name() RETURNS VARCHAR(100) BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); $CRC_ARG_stmt_sidef; RETURN 0; END
--let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_level SELECT $CRC_name()
--let $CRC_RET_value=
--let $CRC_RET_sel_retval=
--let $CRC_RET_sel_sidef= SELECT $CRC_name()
--let $CRC_RET_drop= DROP FUNCTION $CRC_name
--let $CRC_RET_is_toplevel= 0
--let $CRC_RET_desc= function $CRC_name invoking $CRC_ARG_desc
}
######## proc ########
if (`SELECT $CRC_ARG_type = 2`) {
# It will be unsafe to call this procedure.
--let $CRC_name= proc_$CRC_ARG_level
--let $CRC_create= CREATE PROCEDURE $CRC_name() BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); $CRC_ARG_stmt_sidef; END
--let $CRC_RET_stmt_sidef= CALL $CRC_name()
--let $CRC_RET_value=
--let $CRC_RET_sel_retval=
--let $CRC_RET_sel_sidef=
--let $CRC_RET_drop= DROP PROCEDURE $CRC_name
--let $CRC_RET_is_toplevel= 0
--let $CRC_RET_desc= procedure $CRC_name invoking $CRC_ARG_desc
}
######## trig ########
if (`SELECT $CRC_ARG_type = 3`) {
# It will be unsafe to invoke this trigger.
--let $CRC_name= trig_$CRC_ARG_level
--let $CRC_create= CREATE TRIGGER $CRC_name BEFORE INSERT ON trigger_table_$CRC_ARG_level FOR EACH ROW BEGIN INSERT INTO ta$CRC_ARG_level VALUES (47); $CRC_ARG_stmt_sidef; END
--let $CRC_RET_stmt_sidef= INSERT INTO trigger_table_$CRC_ARG_level VALUES (1)
--let $CRC_RET_value=
--let $CRC_RET_sel_retval=
--let $CRC_RET_sel_sidef=
--let $CRC_RET_drop= DROP TRIGGER $CRC_name
--let $CRC_RET_is_toplevel= 0
--let $CRC_RET_desc= trigger $CRC_name invoking $CRC_ARG_desc
}
######## view_retval ########
if (`SELECT $CRC_ARG_type = 4 AND '$CRC_ARG_sel_retval' != ''`) {
# It will be safe to select from this view if you discard the result
# set, but unsafe to use result set (e.g., in INSERT..SELECT).
--let $CRC_name= view_retval_$CRC_ARG_level
--let $CRC_create= CREATE VIEW $CRC_name AS $CRC_ARG_sel_retval
--let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_LEVEL SELECT * FROM $CRC_name
--let $CRC_RET_value=
--let $CRC_RET_sel_retval= SELECT * FROM $CRC_name
--let $CRC_RET_sel_sidef=
--let $CRC_RET_drop= DROP VIEW $CRC_name
--let $CRC_RET_is_toplevel= 0
--let $CRC_RET_desc= view $CRC_name returning value from $CRC_ARG_desc
}
######## view_sidef ########
if (`SELECT $CRC_ARG_type = 5 AND '$CRC_ARG_sel_sidef' != ''`) {
# It will be unsafe to select from this view, even if you discard
# the return value.
--let $CRC_name= view_sidef_$CRC_ARG_level
--let $CRC_create= CREATE VIEW $CRC_name AS $CRC_ARG_sel_sidef
--let $CRC_RET_stmt_sidef= INSERT INTO t$CRC_ARG_level SELECT * FROM $CRC_name
--let $CRC_RET_value=
--let $CRC_RET_sel_retval=
--let $CRC_RET_sel_sidef= SELECT * FROM $CRC_name
--let $CRC_RET_drop= DROP VIEW $CRC_name
--let $CRC_RET_is_toplevel= 0
--let $CRC_RET_desc= view $CRC_name invoking $CRC_ARG_desc
}
######## prep ########
if (`SELECT $CRC_ARG_type = 6`) {
# It will be unsafe to execute this prepared statement
--let $CRC_name= prep_$CRC_ARG_level
--let $CRC_create= PREPARE $CRC_name FROM "$CRC_ARG_stmt_sidef"
--let $CRC_RET_stmt_sidef= EXECUTE $CRC_name
--let $CRC_RET_value=
--let $CRC_RET_sel_retval=
--let $CRC_RET_sel_sidef=
--let $CRC_RET_drop= DROP PREPARE $CRC_name
--let $CRC_RET_is_toplevel= 1
--let $CRC_RET_desc= prepared statement $CRC_name invoking $CRC_ARG_desc
}
######## no recursive construct: just return the given statement ########
if (`SELECT $CRC_ARG_type = 7`) {
# CRC_ARG_type=7 is a special case. We just set $CRC_RET_x =
# $CRC_ARG_x. This way, the $CRC_ARG_stmt gets executed directly
# (below). In binlog_unsafe.test, it is used to invoke the unsafe
# statement created in the outermost loop directly, without
# enclosing it in a recursive construct.
--let $CRC_RET_stmt_sidef= $CRC_ARG_stmt_sidef
--let $CRC_RET_value= $CRC_ARG_value
--let $CRC_RET_sel_retval= $CRC_ARG_sel_retval
--let $CRC_RET_sel_sidef= $CRC_ARG_sel_sidef
--let $CRC_RET_drop=
--let $CRC_RET_is_toplevel= 1
--let $CRC_RET_desc= $CRC_ARG_desc
}
######## execute! ########
if (`SELECT '$CRC_RET_stmt_sidef' != ''`) {
--echo
--echo Invoking $CRC_RET_desc.
if (`SELECT '$CRC_create' != ''`) {
--eval $CRC_create
}
--echo * binlog_format = STATEMENT: expect $CRC_ARG_expected_number_of_warnings warnings.
--eval $CRC_RET_stmt_sidef
--let $n_warnings= `SHOW COUNT(*) WARNINGS`
if (`SELECT '$n_warnings' != '$CRC_ARG_expected_number_of_warnings'`) {
--echo ******** Failure! Expected $CRC_ARG_expected_number_of_warnings warnings, got $n_warnings warnings. ********
SHOW WARNINGS;
SHOW BINLOG EVENTS;
--die Wrong number of warnings.
}
# These queries are run without query log, to make result file more
# readable. Debug info is only printed if something abnormal
# happens.
--disable_query_log
--echo * SQL_LOG_BIN = 0: expect nothing logged and no warning.
SET SQL_LOG_BIN = 0;
RESET MASTER;
--eval $CRC_RET_stmt_sidef
--let $n_warnings= `SHOW COUNT(*) WARNINGS`
if (`SELECT '$n_warnings' != '0'`) {
--echo ******** Failure! Expected 0 warnings, got $n_warnings warnings. ********
SHOW WARNINGS;
SHOW BINLOG EVENTS;
--die Wrong number of warnings.
}
--let $binlog_event= query_get_value(SHOW BINLOG EVENTS, Event_type, 2)
if (`SELECT '$binlog_event' != 'No such row'`) {
--enable_query_log
--echo ******** Failure! Something was written to the binlog despite SQL_LOG_BIN=0 ********
SHOW BINLOG EVENTS;
--die Binlog not empty
}
SET SQL_LOG_BIN = 1;
--echo * binlog_format = MIXED: expect row events in binlog and no warning.
SET binlog_format = MIXED;
RESET MASTER;
--eval $CRC_RET_stmt_sidef
--let $n_warnings= `SHOW COUNT(*) WARNINGS`
if (`SELECT '$n_warnings' != '0'`) {
--echo ******** Failure! Expected 0 warnings, got $n_warnings warnings. ********
SHOW WARNINGS;
SHOW BINLOG EVENTS;
--die Warnings printed
}
# The first event is format_description, the second is
# Query_event('BEGIN'), and the third should be our Table_map.
--let $event_type= query_get_value(SHOW BINLOG EVENTS, Event_type, 3)
if (`SELECT '$event_type' != 'Table_map'`) {
--enable_query_log
--echo ******** Failure! Event number 3 was a '$event_type', not a 'Table_map'. ********
# Currently, there is a bug causing some statements to be logged
# partially in statement format. Hence, we don't fail here, we
# just print the events (masking out nondeterministic components
# of the output) and continue. When binloggging works perfectly,
# we should instead execute:
#--enable_query_log
#SHOW BINLOG EVENTS;
#--die Wrong events in binlog.
# Here, we should really source
# include/show_binlog_events.inc. But due to BUG#41913, that
# doesn't work, and we have to inline the entire file here. Sigh
# :-(
--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR 107 <binlog_start>
--replace_column 2 # 4 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ /block_len=[0-9]+/block_len=#/
--eval SHOW BINLOG EVENTS FROM 107
--disable_query_log
}
SET binlog_format = STATEMENT;
--enable_query_log
}
# Invoke created object, discarding the return value. This should not
# give any warning.
if (`SELECT '$CRC_RET_sel_retval' != ''`) {
--echo * Invoke statement so that return value is dicarded: expect no warning.
--disable_result_log
--eval $CRC_RET_sel_retval
--enable_result_log
# Currently, due to a bug, we do get warnings here, so we don't
# fail. When the bug is fixed, we should execute the following.
#--let $n_warnings= `SHOW COUNT(*) WARNINGS`
#if (`SELECT '$n_warnings' != '0'`) {
# --enable_query_log
# --echo Failure! Expected 0 warnings, got $n_warnings warnings.
# SHOW WARNINGS;
# SHOW BINLOG EVENTS;
# --die Wrong number of warnings.
#}
}
#--echo debug: <<<<EXIT create_recursive_construct
#--echo debug: stmt_sidef=$CRC_RET_stmt_sidef
#--echo debug: value=$CRC_RET_value
#--echo debug: sel_retval=$CRC_RET_sel_retval
#--echo debug: sel_sidef=$CRC_RET_sel_sidef
#--echo debug: drop=$CRC_RET_drop
#--echo debug: is_toplevel=$CRC_RET_is_toplevel
#--echo debug: desc=$CRC_RET_desc
......@@ -22,13 +22,7 @@
#
########################################################################################
########################################################################################
# Configuring the environment
########################################################################################
--source include/have_innodb.inc
--source include/master-slave.inc
--source include/not_embedded.inc
--source include/not_windows.inc
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
CREATE TABLE t1(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
CREATE TABLE t2(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=MyIsam;
......@@ -50,30 +44,18 @@ eval INSERT INTO t1 (a, data) VALUES (1,
--enable_query_log
--echo *** Single statement on non-transactional table ***
--echo *** After WL#2687 the difference between STATEMENT/MIXED and ROW will not exist. ***
--disable_query_log
--disable_warnings
if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`)
{
eval INSERT INTO t2 (a, data) VALUES (2,
CONCAT($data, $data, $data, $data, $data, $data));
--echo Got one of the listed errors
}
if (`SELECT @@binlog_format = 'ROW'`)
{
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
eval INSERT INTO t2 (a, data) VALUES (2,
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
eval INSERT INTO t2 (a, data) VALUES (2,
CONCAT($data, $data, $data, $data, $data, $data));
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE SQL_THREAD;
--source include/wait_for_slave_sql_to_start.inc
}
--enable_warnings
--enable_query_log
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE SQL_THREAD;
--source include/wait_for_slave_sql_to_start.inc
connection master;
--disable_query_log
......@@ -86,7 +68,6 @@ eval INSERT INTO t2 (a, data) VALUES (5, $data);
--enable_query_log
--echo *** Single statement on both transactional and non-transactional tables. ***
--echo *** After WL#2687 we will be able to change the order of the tables. ***
--disable_query_log
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
eval UPDATE t2, t1 SET t2.data = CONCAT($data, $data, $data, $data),
......@@ -95,13 +76,25 @@ eval UPDATE t2, t1 SET t2.data = CONCAT($data, $data, $data, $data),
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
if (`SELECT @@binlog_format = 'STATEMENT'`)
{
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
}
if (`SELECT @@binlog_format = 'ROW' || @@binlog_format = 'MIXED'`)
{
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 2;
}
START SLAVE SQL_THREAD;
--source include/wait_for_slave_sql_to_start.inc
connection master;
#--echo ########################################################################################
#--echo # 2 - BEGIN - IMPLICIT COMMIT by DDL
#--echo ########################################################################################
let $diff_statement= SELECT * FROM t1;
--source include/diff_master_slave.inc
--echo ########################################################################################
--echo # 2 - BEGIN - IMPLICIT COMMIT by DDL
--echo ########################################################################################
connection master;
TRUNCATE TABLE t1;
......@@ -149,14 +142,13 @@ BEGIN;
--eval INSERT INTO t1 (a, data) VALUES (21, 's');
--enable_query_log
if (`SELECT @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`)
if (`SELECT @@binlog_format = 'STATEMENT'`)
{
--disable_query_log
CREATE TABLE t4 SELECT * FROM t1;
--enable_query_log
--echo Got one of the listed errors
}
if (`SELECT @@binlog_format = 'ROW'`)
if (`SELECT @@binlog_format = 'ROW' || @@binlog_format = 'MIXED'`)
{
--disable_query_log
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
......@@ -186,6 +178,17 @@ BEGIN;
CREATE TABLE t5 (a int);
--enable_query_log
if (`SELECT @@binlog_format = 'ROW' || @@binlog_format = 'MIXED'` )
{
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE SQL_THREAD;
--source include/wait_for_slave_sql_to_start.inc
connection master;
}
let $diff_statement= SELECT * FROM t1;
--source include/diff_master_slave.inc
......@@ -341,16 +344,30 @@ BEGIN;
--eval INSERT INTO t1 (a, data) VALUES (1, $data);
--eval INSERT INTO t1 (a, data) VALUES (2, $data);
--eval INSERT INTO t2 (a, data) VALUES (3, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (4, $data);
if (`SELECT @@binlog_format = 'STATEMENT'`)
{
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (4, $data);
}
if (`SELECT @@binlog_format = 'ROW' || @@binlog_format = 'MIXED'`)
{
--eval INSERT INTO t1 (a, data) VALUES (4, $data);
}
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (5, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (6, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (7, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval UPDATE t2 SET data= CONCAT($data, $data);
if (`SELECT @@binlog_format = 'STATEMENT'`)
{
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval UPDATE t2 SET data= CONCAT($data, $data);
}
if (`SELECT @@binlog_format = 'ROW' || @@binlog_format = 'MIXED'`)
{
--eval UPDATE t2 SET data= CONCAT($data, $data);
}
--eval INSERT INTO t1 (a, data) VALUES (8, 's');
--eval INSERT INTO t1 (a, data) VALUES (9, 's');
--eval INSERT INTO t2 (a, data) VALUES (10, 's');
......@@ -363,19 +380,38 @@ BEGIN;
--eval INSERT INTO t1 (a, data) VALUES (15, $data);
--eval INSERT INTO t1 (a, data) VALUES (16, $data);
--eval INSERT INTO t2 (a, data) VALUES (17, $data);
if (`SELECT @@binlog_format = 'STATEMENT'`)
{
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (18, $data);
}
if (`SELECT @@binlog_format = 'ROW' || @@binlog_format = 'MIXED'`)
{
--eval INSERT INTO t1 (a, data) VALUES (18, $data);
}
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (18, $data);
--eval INSERT INTO t1 (a, data) VALUES (19, $data);
--enable_query_log
COMMIT;
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
if (`SELECT @@binlog_format = 'STATEMENT'`)
{
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE SQL_THREAD;
--source include/wait_for_slave_sql_to_start.inc
connection master;
}
let $diff_statement= SELECT * FROM t1;
--source include/diff_master_slave.inc
--echo ########################################################################################
--echo # CLEAN
--echo ########################################################################################
--disable_warnings
connection master;
DROP TABLE t1;
DROP TABLE t2;
......@@ -384,12 +420,4 @@ DROP TABLE IF EXISTS t4;
DROP TABLE IF EXISTS t5;
DROP TABLE IF EXISTS t6;
DROP PROCEDURE p1;
connection slave;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE IF EXISTS t4;
DROP TABLE IF EXISTS t5;
DROP TABLE IF EXISTS t6;
DROP PROCEDURE p1;
--enable_warnings
sync_slave_with_master;
......@@ -36,6 +36,9 @@ sync_slave_with_master;
STOP SLAVE;
RESET SLAVE;
SET @saved_slave_type_conversions = @@slave_type_conversions;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = 'ALL_NON_LOSSY';
eval CREATE TABLE t1 (a INT, b INT PRIMARY KEY, c CHAR(20),
d FLOAT DEFAULT '2.00',
e CHAR(4) DEFAULT 'TEST')
......@@ -62,6 +65,8 @@ SELECT * FROM t1 ORDER BY a;
sync_slave_with_master;
SELECT * FROM t1 ORDER BY a;
SET GLOBAL SLAVE_TYPE_CONVERSIONS = @saved_slave_type_conversions;
--echo *** Drop t1 ***
connection master;
DROP TABLE t1;
......@@ -97,9 +102,8 @@ SELECT * FROM t2 ORDER BY a;
connection slave;
START SLAVE;
source include/wait_for_slave_sql_to_stop.inc;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
STOP SLAVE;
RESET SLAVE;
SELECT * FROM t2 ORDER BY a;
......@@ -146,13 +150,12 @@ set @b1 = concat(@b1,@b1);
INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TESTING');
--echo ********************************************
--echo *** Expect slave to fail with Error 1522 ***
--echo *** Expect slave to fail with Error 1677 ***
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
......@@ -191,13 +194,12 @@ INSERT INTO t4 () VALUES(100.22,2,'Kyle, TEX'),(200.26,1,'JOE AUSTIN'),
(30000.22,4,'QA TESTING');
--echo ********************************************
--echo *** Expect slave to fail with Error 1522 ***
--echo *** Expect slave to fail with Error 1677 ***
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
......@@ -236,13 +238,12 @@ INSERT INTO t5 () VALUES(1,'Kyle',200.23,1,'b1b1',23.00098),
(2,'JOE',300.01,0,'b2b2',1.0000009);
--echo ********************************************
--echo *** Expect slave to fail with Error 1522 ***
--echo *** Expect slave to fail with Error 1677 ***
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
......@@ -282,13 +283,12 @@ INSERT INTO t6 () VALUES(1,'Kyle',200.23,1),
(2,'JOE',300.01,0);
--echo ********************************************
--echo *** Expect slave to fail with Error 1522 ***
--echo *** Expect slave to fail with Error 1677 ***
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=3;
#START SLAVE;
......@@ -491,13 +491,12 @@ set @b1 = concat(@b1,@b1);
INSERT INTO t10 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
--echo ********************************************
--echo *** Expect slave to fail with Error 1522 ***
--echo *** Expect slave to fail with Error 1677 ***
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
......@@ -515,7 +514,7 @@ sync_slave_with_master;
--echo *** Create t11 on slave ***
STOP SLAVE;
RESET SLAVE;
eval CREATE TABLE t11 (a INT KEY, b BLOB, f TEXT,
eval CREATE TABLE t11 (a INT KEY, b BLOB, f INT,
c CHAR(5) DEFAULT 'test', e INT DEFAULT '1')ENGINE=$engine_type;
--echo *** Create t11 on Master ***
......@@ -535,13 +534,12 @@ set @b1 = concat(@b1,@b1);
INSERT INTO t11 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
--echo ********************************************
--echo *** Expect slave to fail with Error 1522 ***
--echo *** Expect slave to fail with Error 1677 ***
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
......@@ -811,9 +809,8 @@ ALTER TABLE t15 ADD COLUMN c6 INT AFTER c5;
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
START SLAVE;
......@@ -918,13 +915,12 @@ connection master;
INSERT INTO t17 () VALUES(9223372036854775807,2,'Kyle, TEX');
--echo ********************************************
--echo *** Expect slave to fail with Error 1522 ***
--echo *** Expect slave to fail with Error 1677 ***
--echo ********************************************
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 4 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 #
--query_vertical SHOW SLAVE STATUS
--let $errno= query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1)
--echo Slave failed with Error $errno
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
START SLAVE;
......
......@@ -20,19 +20,15 @@ rename table t1 to t5, t2 to t1;
# first don't write it to the binlog, to test the NO_WRITE_TO_BINLOG keyword.
flush no_write_to_binlog tables;
# Check that it's not in the binlog.
--replace_result $SERVER_VERSION SERVER_VERSION
--replace_column 2 # 5 #
--replace_regex /table_id: [0-9]+/table_id: #/
eval SHOW BINLOG EVENTS FROM $rename_event_pos ;
let $binlog_start= $rename_event_pos;
source include/show_binlog_events.inc;
# Check that the master is not confused.
select * from t3;
# This FLUSH should go into the binlog to not confuse the slave.
flush tables;
# Check that it's in the binlog.
--replace_result $SERVER_VERSION SERVER_VERSION
--replace_column 2 # 5 #
--replace_regex /table_id: [0-9]+/table_id: #/
eval SHOW BINLOG EVENTS FROM $rename_event_pos ;
let $binlog_start= $rename_event_pos;
source include/show_binlog_events.inc;
sync_slave_with_master;
# Check that the slave is not confused.
......
......@@ -47,7 +47,6 @@ 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;
--echo must sync w/o a problem (could not with the buggy code)
......
################################################################################
# In this test case, we verify if some DDL statements implicitly commit a
# transaction and are written directly to the binary log without going
# through either the Statement- or Transactional-Cache.
#
# As any statement that goes through a cache is written to the binary log
# wrapped in a BEGIN...COMMIT, we proceed as follows:
#
# - create a transaction and insert some values into a transactional table.
# - execute a DDL statement that is supposed to implicitly commit the previous
# transaction.
# - Check in the binary log for a COMMIT mark which is supposed to be written
# before the DDL statement.
# - Check in the binary log if the DDL is not wrapped by a BEGIN..COMMIT.
#
# For further details, please, read WL#2687 and WL#5072.
################################################################################
--echo #########################################################################
--echo # CONFIGURATION
--echo #########################################################################
connection master;
eval CREATE TABLE tt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = $engine;
eval CREATE TABLE tt_2 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = $engine;
eval CREATE TABLE nt_1 (ddl_case INT, PRIMARY KEY(ddl_case)) ENGINE = MyIsam;
INSERT INTO tt_1(ddl_case) VALUES(0);
INSERT INTO tt_2(ddl_case) VALUES(0);
--echo #########################################################################
--echo # CHECK IMPLICT COMMIT
--echo #########################################################################
SET AUTOCOMMIT= 0;
let $ddl_cases= 41;
while (`SELECT $ddl_cases >= 1`)
{
--echo -b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b-
let $in_temporary= "no";
let $ok= "yes";
#
# In SBR and MIXED modes, the commit event is usually the third event in the
# binary log:
#
# 1: BEGIN
# 2: INSERT
# 3: COMMIT
# 4: DDL EVENT which triggered the previous commmit.
#
if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`)
{
let $commit_event_row_number= 3;
}
#
# In RBR mode, the commit event is usually the fourth event in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: ROW EVENT
# 4: COMMIT
# 5: DDL EVENT which triggered the previous commmit.
#
if (`select @@binlog_format = 'ROW'`)
{
let $commit_event_row_number= 4;
}
#
# In NDB (RBR and MIXED modes), the commit event is usually the seventh event
# in the binary log:
#
# 1: COMMAND
# 2: BEGIN
# 3: TABLE MAP EVENT
# 4: TABLE MAP EVENT (ndb_apply_status)
# 5: ROW EVENT
# 6: ROW EVENT
# 7: COMMIT
#
if (`select '$engine' = 'NDB'`)
{
let $commit_event_row_number= 7;
}
let $first_binlog_position= query_get_value("SHOW MASTER STATUS", Position, 1);
--enable_query_log
eval INSERT INTO tt_1(ddl_case) VALUES ($ddl_cases);
if (`SELECT $ddl_cases = 41`)
{
let $cmd= LOAD INDEX INTO CACHE nt_1 IGNORE LEAVES;
if (`SELECT '$engine' = 'NDB'`)
{
# This seems to be related to epochs.
# We need to check this against an updated version or avoid it.
let $ok= "no";
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 40`)
{
let $cmd= LOAD INDEX INTO CACHE tt_1, tt_2 IGNORE LEAVES;
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 39`)
{
let $cmd= ANALYZE TABLE nt_1;
}
if (`SELECT $ddl_cases = 38`)
{
let $cmd= CHECK TABLE nt_1;
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 37`)
{
let $cmd= OPTIMIZE TABLE nt_1;
}
if (`SELECT $ddl_cases = 36`)
{
let $cmd= REPAIR TABLE nt_1;
}
if (`SELECT $ddl_cases = 35`)
{
let $cmd= LOCK TABLES tt_1 WRITE;
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 34`)
{
let $cmd= UNLOCK TABLES;
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 33`)
{
let $cmd= CREATE USER 'user'@'localhost';
}
if (`SELECT $ddl_cases = 32`)
{
let $cmd= GRANT ALL ON *.* TO 'user'@'localhost';
}
if (`SELECT $ddl_cases = 31`)
{
let $cmd= SET PASSWORD FOR 'user'@'localhost' = PASSWORD('newpass');
#
# In NDB (RBR mode), the commit event is the eleventh event
# in the binary log:
#
# 1: DDL EVENT which triggered the previous commmit.
# 2: BEGIN
# 3: TABLE MAP EVENT
# 4: ROW EVENT
# 5: COMMIT
# 6: BEGIN
# 7: TABLE MAP EVENT
# 8: TABLE MAP EVENT (ndb_apply_status)
# 9: ROW EVENT
# 10: ROW EVENT
# 11: COMMIT
#
if (`SELECT '$engine' = 'NDB' && @@binlog_format = 'ROW'`)
{
let $commit_event_row_number= 11;
}
#
# In NDB (MIXED mode), the commit event is the eighth event
# in the binary log:
#
# 1: DDL EVENT which triggered the previous commmit.
# 2: COMMIT
# 3: BEGIN
# 4: TABLE MAP EVENT
# 5: TABLE MAP EVENT (ndb_apply_status)
# 6: ROW EVENT
# 7: ROW EVENT
# 8: COMMIT
#
if (`SELECT '$engine' = 'NDB' && @@binlog_format != 'ROW'`)
{
let $commit_event_row_number= 7;
}
}
if (`SELECT $ddl_cases = 30`)
{
let $cmd= REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'user'@'localhost';
}
if (`SELECT $ddl_cases = 29`)
{
let $cmd= RENAME USER 'user'@'localhost' TO 'user_new'@'localhost';
}
if (`SELECT $ddl_cases = 28`)
{
let $cmd= DROP USER 'user_new'@'localhost';
}
if (`SELECT $ddl_cases = 27`)
{
let $cmd= CREATE EVENT evt ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR DO SELECT * FROM tt_1;
}
if (`SELECT $ddl_cases = 26`)
{
let $cmd= ALTER EVENT evt COMMENT 'evt';
}
if (`SELECT $ddl_cases = 25`)
{
let $cmd= DROP EVENT evt;
}
if (`SELECT $ddl_cases = 24`)
{
let $cmd= CREATE TRIGGER tr AFTER INSERT ON tt_1 FOR EACH ROW UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case;
}
if (`SELECT $ddl_cases = 23`)
{
let $cmd= DROP TRIGGER tr;
#
# In RBR mode, due to the trigger the tt_2 is also updated:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT
# 4: ROW EVENT
# 5: COMMIT
# 6: DDL EVENT which triggered the previous commmit.
#
if (`select @@binlog_format = 'ROW' && '$engine' != 'NDB'`)
{
let $commit_event_row_number= 5;
}
}
if (`SELECT $ddl_cases = 22`)
{
let $cmd= CREATE FUNCTION fc () RETURNS VARCHAR(64) RETURN "fc";
}
if (`SELECT $ddl_cases = 21`)
{
let $cmd= ALTER FUNCTION fc COMMENT 'fc';
}
if (`SELECT $ddl_cases = 20`)
{
let $cmd= DROP FUNCTION fc;
}
if (`SELECT $ddl_cases = 19`)
{
let $cmd= CREATE PROCEDURE pc () UPDATE tt_2 SET ddl_case = ddl_case WHERE ddl_case= NEW.ddl_case;
}
if (`SELECT $ddl_cases = 18`)
{
let $cmd= ALTER PROCEDURE pc COMMENT 'pc';
}
if (`SELECT $ddl_cases = 17`)
{
let $cmd= DROP PROCEDURE pc;
}
if (`SELECT $ddl_cases = 16`)
{
let $cmd= CREATE VIEW v AS SELECT * FROM tt_1;
}
if (`SELECT $ddl_cases = 15`)
{
let $cmd= ALTER VIEW v AS SELECT * FROM tt_1;
}
if (`SELECT $ddl_cases = 14`)
{
let $cmd= DROP VIEW v;
}
if (`SELECT $ddl_cases = 13`)
{
let $cmd= CREATE INDEX ix ON tt_1(ddl_case);
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
# 7: DDL EVENT which triggered the previous commmit.
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 12`)
{
let $cmd= DROP INDEX ix ON tt_1;
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
# 7: DDL EVENT which triggered the previous commmit.
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 11`)
{
let $cmd= CREATE TEMPORARY TABLE tt_xx (a int);
let $in_temporary= "yes";
# In SBR and MIXED modes, the DDL statement is written to the binary log but
# does not commit the current transaction.
#
# 1: BEGIN
# 2: INSERT
# 3: CREATE TEMPORARY
#
# In RBR the transaction is not committed either and the statement is not
# written to the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: ROW EVENT
#
if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`)
{
let $commit_event_row_number= 4;
}
#
# In NDB (RBR mode), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB' && @@binlog_format = 'ROW'` )
{
let $commit_event_row_number= 6;
}
#
# In NDB (MIXED mode), the commit event is the nineth event
# in the binary log:
#
# 1: BEGIN
# 2: DDL EVENT which triggered the previous commmit.
# 3: COMMIT
# 4: BEGIN
# 5: TABLE MAP EVENT
# 6: TABLE MAP EVENT (ndb_apply_status)
# 7: ROW EVENT
# 8: ROW EVENT
# 9: COMMIT
#
if (`SELECT '$engine' = 'NDB' && @@binlog_format != 'ROW'` )
{
let $commit_event_row_number= 9;
}
}
if (`SELECT $ddl_cases = 10`)
{
let $cmd= ALTER TABLE tt_xx ADD COLUMN (b int);
#
# In MIXED mode, the changes are logged as rows and we have what follows:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: ROW EVENT
# 4: COMMIT
# 5: DDL EVENT which triggered the previous commmit.
#
if (`select @@binlog_format = 'MIXED'`)
{
let $commit_event_row_number= 4;
}
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 9`)
{
let $cmd= ALTER TABLE tt_xx RENAME new_tt_xx;
#
# In MIXED mode, the changes are logged as rows and we have what follows:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: ROW EVENT
# 4: COMMIT
# 5: DDL EVENT which triggered the previous commmit.
#
if (`select @@binlog_format = 'MIXED'`)
{
let $commit_event_row_number= 4;
}
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 8`)
{
let $cmd= DROP TEMPORARY TABLE IF EXISTS new_tt_xx;
let $in_temporary= "yes";
#
# In SBR and MIXED modes, the DDL statement is written to the binary log
# but does not commit the current transaction:
#
# 1: BEGIN
# 2: INSERT
# 3: DROP TEMPORARY
#
# In RBR the transaction is not committed either and the statement is not
# written to the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: ROW EVENT
#
if (`select @@binlog_format = 'STATEMENT'`)
{
let $commit_event_row_number= 4;
}
# In MIXED mode, the changes are logged as rows and we have what follows:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: ROW EVENT
# 4: DROP TEMPORARY table IF EXISTS
#
if (`select @@binlog_format = 'MIXED'`)
{
let $commit_event_row_number= 5;
}
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
#
# In NDB (MIXED mode), the commit event is the nineth event
# in the binary log:
#
# 1: BEGIN
# 2: DDL EVENT which triggered the previous commmit.
# 3: COMMIT
# 4: BEGIN
# 5: TABLE MAP EVENT
# 6: TABLE MAP EVENT (ndb_apply_status)
# 7: ROW EVENT
# 8: ROW EVENT
# 9: COMMIT
#
if (`SELECT '$engine' = 'NDB' && @@binlog_format != 'ROW'` )
{
let $commit_event_row_number= 9;
}
}
if (`SELECT $ddl_cases = 7`)
{
let $cmd= CREATE TABLE tt_xx (a int);
}
if (`SELECT $ddl_cases = 6`)
{
let $cmd= ALTER TABLE tt_xx ADD COLUMN (b int);
}
if (`SELECT $ddl_cases = 5`)
{
let $cmd= RENAME TABLE tt_xx TO new_tt_xx;
}
if (`SELECT $ddl_cases = 4`)
{
let $cmd= TRUNCATE TABLE new_tt_xx;
}
if (`SELECT $ddl_cases = 3`)
{
let $cmd= DROP TABLE IF EXISTS tt_xx, new_tt_xx;
}
if (`SELECT $ddl_cases = 2`)
{
let $cmd= CREATE DATABASE db;
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
# 7: DDL EVENT which triggered the previous commmit.
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
if (`SELECT $ddl_cases = 1`)
{
let $cmd= DROP DATABASE IF EXISTS db;
#
# In NDB (RBR and MIXED modes), the commit event is the sixth event
# in the binary log:
#
# 1: BEGIN
# 2: TABLE MAP EVENT
# 3: TABLE MAP EVENT (ndb_apply_status)
# 4: ROW EVENT
# 5: ROW EVENT
# 6: COMMIT
# 7: DDL EVENT which triggered the previous commmit.
#
if (`SELECT '$engine' = 'NDB'`)
{
let $commit_event_row_number= 6;
}
}
--eval $cmd
--disable_query_log
#
# When a temporary table is either created or dropped, there is no implicit
# commit. The flag in_temporary is used to avoid aborting the test in such
# cases. Thus we force the commit.
#
if (`SELECT $in_temporary = "yes"`)
{
--eval COMMIT
}
let $event_commit= query_get_value("SHOW BINLOG EVENTS FROM $first_binlog_position", Info, $commit_event_row_number);
if (`SELECT SUBSTRING("$event_commit",1,6) != "COMMIT"`)
{
if (`SELECT $ok = "yes"`)
{
--echo it *does not* commit the current transaction.
--echo $cmd
--echo $event_commit
SHOW BINLOG EVENTS;
exit;
}
}
--echo -e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e-
let $binlog_start= $first_binlog_position;
--echo -b-b-b-b-b-b-b-b-b-b-b- >> << -b-b-b-b-b-b-b-b-b-b-b-
--source include/show_binlog_events.inc
--echo -e-e-e-e-e-e-e-e-e-e-e- >> << -e-e-e-e-e-e-e-e-e-e-e-
--echo
dec $ddl_cases;
}
SET AUTOCOMMIT= 1;
--echo ###################################################################################
--echo # CHECK CONSISTENCY
--echo ###################################################################################
--sync_slave_with_master
--let $diff_table_1= master:test.tt_1
--let $diff_table_2= slave:test.tt_1
--source include/diff_tables.inc
--echo ###################################################################################
--echo # CLEAN
--echo ###################################################################################
connection master;
DROP TABLE tt_1;
DROP TABLE tt_2;
DROP TABLE nt_1;
sync_slave_with_master;
# File for specialities regarding replication from or to InnoDB
# tables.
source include/master-slave.inc;
source include/have_innodb.inc;
#
# Bug#11401: Load data infile 'REPLACE INTO' fails on slave.
#
......@@ -76,7 +70,7 @@ sync_slave_with_master;
connection slave;
# We want to verify that the following transactions are written to the
# binlog, despite the transaction is rolled back. (The should be
# binlog, despite the transaction is rolled back. (They should be
# written to the binlog since they contain non-transactional DROP
# TEMPORARY TABLE). To see that, we use the auxiliary table t1, which
# is transactional (InnoDB) on master and MyISAM on slave. t1 should
......@@ -84,6 +78,10 @@ connection slave;
# the transaction to be logged. Since t1 is non-transactional on
# slave, the change will not be rolled back, so the inserted rows will
# stay in t1 and we can verify that the transaction was replicated.
#
# Note, however, that the previous explanation is not true for ROW and
# MIXED modes as rollback on a transactional table is not written to
# the binary log.
ALTER TABLE mysqltest1.t1 ENGINE = MyISAM;
SHOW CREATE TABLE mysqltest1.t1;
......
......@@ -38,18 +38,19 @@ connection master;
truncate table t1;
# first scenario: duplicate on first row
insert delayed into t1 values(10, "my name");
if ($binlog_format_statement)
flush table t1;
if (`SELECT @@global.binlog_format = 'STATEMENT'`)
{
# statement below will be converted to non-delayed INSERT and so
# will stop at first error, guaranteeing replication.
--error ER_DUP_ENTRY
insert delayed into t1 values(10, "is Bond"), (20, "James Bond");
}
if (!$binlog_format_statement)
if (`SELECT @@global.binlog_format != 'STATEMENT'`)
{
insert delayed into t1 values(10, "is Bond"), (20, "James Bond");
}
flush table t1; # to wait for INSERT DELAYED to be done
flush table t1;
select * from t1;
sync_slave_with_master;
# when bug existed in statement-based binlogging, t1 on slave had
......@@ -59,7 +60,7 @@ select * from t1;
# second scenario: duplicate on second row
connection master;
delete from t1 where id!=10;
if ($binlog_format_statement)
if (`SELECT @@global.binlog_format = 'STATEMENT'`)
{
# statement below will be converted to non-delayed INSERT and so
# will be binlogged with its ER_DUP_ENTRY error code, guaranteeing
......@@ -67,7 +68,7 @@ if ($binlog_format_statement)
--error ER_DUP_ENTRY
insert delayed into t1 values(20, "is Bond"), (10, "James Bond");
}
if (!$binlog_format_statement)
if (`SELECT @@global.binlog_format != 'STATEMENT'`)
{
insert delayed into t1 values(20, "is Bond"), (10, "James Bond");
}
......@@ -108,6 +109,7 @@ if (`SELECT @@global.binlog_format != 'ROW'`)
{
#must show two INSERT DELAYED
--replace_column 1 x 2 x 3 x 4 x 5 x
--replace_regex /table_id: [0-9]+/table_id: #/
show binlog events in 'master-bin.000002' LIMIT 2,2;
}
select * from t1;
......@@ -118,6 +120,7 @@ if (`SELECT @@global.binlog_format != 'ROW'`)
{
#must show two INSERT DELAYED
--replace_column 1 x 2 x 3 x 4 x 5 x
--replace_regex /table_id: [0-9]+/table_id: #/
show binlog events in 'slave-bin.000002' LIMIT 2,2;
}
select * from t1;
......
......@@ -9,6 +9,8 @@
# column and index but without primary key.
##############################################################
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
--echo #
--echo # Setup
--echo #
......@@ -188,7 +190,9 @@ drop trigger t1_bi;
# Check that nested call doesn't affect outer context.
select last_insert_id();
--disable_warnings
select bug15728_insert();
--enable_warnings
select last_insert_id();
insert into t1 (last_id) values (bug15728());
# This should be exactly one greater than in the previous call.
......@@ -441,7 +445,9 @@ delimiter ;|
INSERT INTO t1 VALUES (NULL, -1);
CALL p1();
--disable_warnings
SELECT f1();
--enable_warnings
INSERT INTO t1 VALUES (NULL, f2()), (NULL, LAST_INSERT_ID()),
(NULL, LAST_INSERT_ID()), (NULL, f2()), (NULL, f2());
INSERT INTO t1 VALUES (NULL, f2());
......@@ -510,7 +516,9 @@ insert into t2 (id) values(1),(2),(3);
delete from t2;
set sql_log_bin=1;
#inside SELECT, then inside INSERT
--disable_warnings
select insid();
--enable_warnings
set sql_log_bin=0;
insert into t2 (id) values(5),(6),(7);
delete from t2 where id>=5;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment