1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

merge mysql-5.1-rep+3 --> mysql-5.1-rep+2-delivery1

This commit is contained in:
Alfranio Correia
2009-12-17 21:43:35 +00:00
288 changed files with 52852 additions and 11629 deletions

View File

@ -0,0 +1,400 @@
# ==== 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

View File

@ -0,0 +1,423 @@
########################################################################################
# This test verifies if the binlog is not corrupted when the cache buffer is not
# big enough to accommodate the changes and is divided in five steps:
#
# 1 - Single Statements:
# 1.1 - Single statement on transactional table.
# 1.2 - Single statement on non-transactional table.
# 1.3 - Single statement on both transactional and non-transactional tables.
# In both 1.2 and 1.3, an incident event is logged to notify the user that the
# master and slave are diverging.
#
# 2 - Transactions ended by an implicit commit.
#
# 3 - Transactions ended by a COMMIT.
#
# 4 - Transactions ended by a ROLLBACK.
#
# 5 - Transactions with a failing statement that updates a non-transactional
# table. In this case, a failure means that the statement does not get into
# the cache and an incident event is logged to notify the user that the master
# and slave are diverging.
#
########################################################################################
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;
CREATE TABLE t3(a INT PRIMARY KEY, data VARCHAR(30000)) ENGINE=Innodb;
let $data = `select concat('"', repeat('a',2000), '"')`;
--echo ########################################################################################
--echo # 1 - SINGLE STATEMENT
--echo ########################################################################################
connection master;
--echo *** Single statement on transactional table ***
--disable_query_log
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
eval INSERT INTO t1 (a, data) VALUES (1,
CONCAT($data, $data, $data, $data, $data));
--enable_query_log
--echo *** Single statement on non-transactional table ***
--disable_query_log
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
eval INSERT INTO t2 (a, data) VALUES (2,
CONCAT($data, $data, $data, $data, $data, $data));
--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
eval INSERT INTO t1 (a, data) VALUES (3, $data);
eval INSERT INTO t1 (a, data) VALUES (4, $data);
eval INSERT INTO t1 (a, data) VALUES (5, $data);
eval INSERT INTO t2 (a, data) VALUES (3, $data);
eval INSERT INTO t2 (a, data) VALUES (4, $data);
eval INSERT INTO t2 (a, data) VALUES (5, $data);
--enable_query_log
--echo *** Single statement on both transactional and non-transactional 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),
t1.data = CONCAT($data, $data, $data, $data);
--enable_query_log
connection slave;
--source include/wait_for_slave_sql_to_stop.inc
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;
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;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
BEGIN;
--disable_query_log
--eval INSERT INTO t1 (a, data) VALUES (1, $data);
--eval INSERT INTO t1 (a, data) VALUES (2, $data);
--eval INSERT INTO t1 (a, data) VALUES (3, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--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);
--eval INSERT INTO t1 (a, data) VALUES (7, 's');
--eval INSERT INTO t2 (a, data) VALUES (8, 's');
--eval INSERT INTO t1 (a, data) VALUES (9, 's');
--enable_query_log
--disable_query_log
ALTER TABLE t3 ADD COLUMN d int;
--enable_query_log
--disable_query_log
--eval INSERT INTO t2 (a, data) VALUES (10, $data);
--eval INSERT INTO t2 (a, data) VALUES (11, $data);
--eval INSERT INTO t2 (a, data) VALUES (12, $data);
--eval INSERT INTO t2 (a, data) VALUES (13, $data);
--enable_query_log
BEGIN;
--disable_query_log
--eval INSERT INTO t1 (a, data) VALUES (14, $data);
--eval INSERT INTO t1 (a, data) VALUES (15, $data);
--eval INSERT INTO t1 (a, data) VALUES (16, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (17, $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, 's');
--eval INSERT INTO t2 (a, data) VALUES (20, 's');
--eval INSERT INTO t1 (a, data) VALUES (21, 's');
--enable_query_log
if (`SELECT @@binlog_format = 'STATEMENT'`)
{
--disable_query_log
CREATE TABLE t4 SELECT * FROM t1;
--enable_query_log
}
if (`SELECT @@binlog_format = 'ROW' || @@binlog_format = 'MIXED'`)
{
--disable_query_log
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
CREATE TABLE t4 SELECT * FROM t1;
--enable_query_log
}
--disable_query_log
--eval INSERT INTO t2 (a, data) VALUES (15, $data);
--enable_query_log
BEGIN;
--disable_query_log
--eval INSERT INTO t1 (a, data) VALUES (22, $data);
--eval INSERT INTO t1 (a, data) VALUES (23, $data);
--eval INSERT INTO t1 (a, data) VALUES (24, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (25, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (26, $data);
--eval INSERT INTO t1 (a, data) VALUES (27, 's');
--eval INSERT INTO t2 (a, data) VALUES (28, 's');
--eval INSERT INTO t1 (a, data) VALUES (29, 's');
--enable_query_log
--disable_query_log
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
--echo ########################################################################################
--echo # 3 - BEGIN - COMMIT
--echo ########################################################################################
connection master;
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
BEGIN;
--disable_query_log
--eval INSERT INTO t1 (a, data) VALUES (1, $data);
--eval INSERT INTO t1 (a, data) VALUES (2, $data);
--eval INSERT INTO t1 (a, data) VALUES (3, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--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);
--eval INSERT INTO t1 (a, data) VALUES (7, 's');
--eval INSERT INTO t2 (a, data) VALUES (8, 's');
--eval INSERT INTO t1 (a, data) VALUES (9, 's');
--enable_query_log
COMMIT;
let $diff_statement= SELECT * FROM t1;
--source include/diff_master_slave.inc
--echo ########################################################################################
--echo # 4 - BEGIN - ROLLBACK
--echo ########################################################################################
connection master;
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
BEGIN;
--disable_query_log
--eval INSERT INTO t1 (a, data) VALUES (1, $data);
--eval INSERT INTO t1 (a, data) VALUES (2, $data);
--eval INSERT INTO t1 (a, data) VALUES (3, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--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);
--eval INSERT INTO t1 (a, data) VALUES (7, 's');
--eval INSERT INTO t2 (a, data) VALUES (8, 's');
--eval INSERT INTO t1 (a, data) VALUES (9, 's');
--enable_query_log
ROLLBACK;
let $diff_statement= SELECT * FROM t1;
--source include/diff_master_slave.inc
--echo ########################################################################################
--echo # 5 - PROCEDURE
--echo ########################################################################################
connection master;
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
DELIMITER //;
CREATE PROCEDURE p1(pd VARCHAR(30000))
BEGIN
INSERT INTO t1 (a, data) VALUES (1, pd);
INSERT INTO t1 (a, data) VALUES (2, pd);
INSERT INTO t1 (a, data) VALUES (3, pd);
INSERT INTO t1 (a, data) VALUES (4, pd);
INSERT INTO t1 (a, data) VALUES (5, 's');
END//
DELIMITER ;//
TRUNCATE TABLE t1;
--disable_query_log
eval CALL p1($data);
--enable_query_log
TRUNCATE TABLE t1;
BEGIN;
--disable_query_log
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
eval CALL p1($data);
--enable_query_log
COMMIT;
TRUNCATE TABLE t1;
BEGIN;
--disable_query_log
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
eval CALL p1($data);
--enable_query_log
ROLLBACK;
let $diff_statement= SELECT * FROM t1;
--source include/diff_master_slave.inc
--echo ########################################################################################
--echo # 6 - XID
--echo ########################################################################################
connection master;
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
BEGIN;
--disable_query_log
--eval INSERT INTO t1 (a, data) VALUES (1, $data);
--eval INSERT INTO t1 (a, data) VALUES (2, $data);
--eval INSERT INTO t1 (a, data) VALUES (3, $data);
--error ER_TRANS_CACHE_FULL, ER_ERROR_ON_WRITE
--eval INSERT INTO t1 (a, data) VALUES (4, $data);
SAVEPOINT sv;
--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);
--eval INSERT INTO t1 (a, data) VALUES (7, 's');
--eval INSERT INTO t2 (a, data) VALUES (8, 's');
--eval INSERT INTO t1 (a, data) VALUES (9, 's');
--enable_query_log
ROLLBACK TO sv;
COMMIT;
let $diff_statement= SELECT * FROM t1;
--source include/diff_master_slave.inc
--echo ########################################################################################
--echo # 7 - NON-TRANS TABLE
--echo ########################################################################################
connection master;
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
TRUNCATE TABLE t3;
BEGIN;
--disable_query_log
--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);
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);
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');
--eval INSERT INTO t1 (a, data) VALUES (11, 's');
--enable_query_log
COMMIT;
BEGIN;
--disable_query_log
--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 (19, $data);
--enable_query_log
COMMIT;
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 ########################################################################################
connection master;
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;
sync_slave_with_master;

View File

@ -102,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;
@ -155,9 +154,8 @@ INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TEST
--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;
@ -200,9 +198,8 @@ INSERT INTO t4 () VALUES(100.22,2,'Kyle, TEX'),(200.26,1,'JOE AUSTIN'),
--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;
@ -245,9 +242,8 @@ INSERT INTO t5 () VALUES(1,'Kyle',200.23,1,'b1b1',23.00098),
--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;
@ -291,9 +287,8 @@ INSERT INTO t6 () VALUES(1,'Kyle',200.23,1),
--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;
@ -500,9 +495,8 @@ INSERT INTO t10 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
--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;
@ -544,9 +538,8 @@ INSERT INTO t11 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA');
--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;
@ -816,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;
@ -927,9 +919,8 @@ INSERT INTO t17 () VALUES(9223372036854775807,2,'Kyle, TEX');
--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;

View File

@ -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.

View File

@ -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)

View File

@ -0,0 +1,656 @@
################################################################################
# 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;

View File

@ -0,0 +1,123 @@
#
# Bug#11401: Load data infile 'REPLACE INTO' fails on slave.
#
connection master;
CREATE TABLE t4 (
id INT(5) unsigned NOT NULL auto_increment,
name varchar(15) NOT NULL default '',
number varchar(35) NOT NULL default 'default',
PRIMARY KEY (id),
UNIQUE KEY unique_rec (name,number)
) ENGINE=InnoDB;
--disable_warnings
LOAD DATA
INFILE '../../std_data/loaddata_pair.dat'
REPLACE INTO TABLE t4
(name,number);
--enable_warnings
SELECT * FROM t4;
sync_slave_with_master;
SELECT * FROM t4;
connection master;
--disable_warnings
LOAD DATA
INFILE '../../std_data/loaddata_pair.dat'
REPLACE INTO TABLE t4
(name,number);
--enable_warnings
SELECT * FROM t4;
sync_slave_with_master;
SELECT * FROM t4;
connection master;
--disable_query_log
DROP TABLE t4;
--enable_query_log
sync_slave_with_master;
connection master;
# End of 4.1 tests
#
# Bug #26418: Slave out of sync after CREATE/DROP TEMPORARY TABLE + ROLLBACK
# on master
#
#Note Matthias: to be merged to rpl_ddl.test
--source include/not_ndb_default.inc
FLUSH LOGS;
sync_slave_with_master;
FLUSH LOGS;
connection master;
let $engine_type= "InnoDB";
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1;
--enable_warnings
CREATE DATABASE mysqltest1;
CREATE TEMPORARY TABLE mysqltest1.tmp (f1 BIGINT);
eval CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE=$engine_type;
SET AUTOCOMMIT = 0;
sync_slave_with_master;
--echo -------- switch to slave --------
connection slave;
# We want to verify that the following transactions are written to the
# 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
# be transactional on master so that the insert into t1 does not cause
# 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;
--echo -------- switch to master --------
connection master;
INSERT INTO mysqltest1.t1 SET f1= 1;
DROP TEMPORARY TABLE mysqltest1.tmp;
ROLLBACK;
--error ER_NO_SUCH_TABLE
SHOW CREATE TABLE mysqltest1.tmp;
# Must return no rows here
SELECT COUNT(*) FROM mysqltest1.t1;
INSERT INTO mysqltest1.t1 SET f1= 2;
CREATE TEMPORARY TABLE mysqltest1.tmp2(a INT);
ROLLBACK;
SHOW CREATE TABLE mysqltest1.tmp2;
# Must return no rows here
SELECT COUNT(*) FROM mysqltest1.t1;
sync_slave_with_master;
--echo -------- switch to slave --------
connection slave;
--error ER_NO_SUCH_TABLE
SHOW CREATE TABLE mysqltest1.tmp;
--error ER_NO_SUCH_TABLE
SHOW CREATE TABLE mysqltest1.tmp2;
# t1 has two rows here: the transaction not rolled back since t1 uses MyISAM
SELECT COUNT(*) FROM mysqltest1.t1;
FLUSH LOGS;
--echo -------- switch to master --------
connection master;
FLUSH LOGS;
DROP DATABASE mysqltest1;
-- source include/master-slave-end.inc
--echo End of 5.1 tests

View File

@ -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;

View File

@ -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 #
@ -187,7 +189,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.
@ -440,7 +444,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());
@ -509,7 +515,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;

View File

@ -55,7 +55,9 @@ INSERT INTO t1 VALUES (2, 2);
INSERT INTO t1 VALUES (3, 3);
INSERT INTO t1 VALUES (4, 4);
--disable_warnings
INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
--enable_warnings
SELECT * FROM t1 ORDER BY a;

View File

@ -1,6 +1,3 @@
# Requires statement logging
-- source include/have_binlog_format_mixed_or_statement.inc
# See if replication of a "LOAD DATA in an autoincrement column"
# Honours autoincrement values
# i.e. if the master and slave have the same sequence
@ -71,7 +68,7 @@ set global sql_slave_skip_counter=1;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
--query_vertical show slave status;
# Trigger error again to test CHANGE MASTER
@ -93,7 +90,7 @@ stop slave;
change master to master_user='test';
change master to master_user='root';
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
--query_vertical show slave status;
# Trigger error again to test RESET SLAVE
@ -115,7 +112,7 @@ connection slave;
stop slave;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
--replace_column 1 # 8 # 9 # 16 # 22 # 23 # 33 #
--query_vertical show slave status;
# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE

View File

@ -43,7 +43,7 @@ show binlog events from 107 limit 1;
show binlog events from 107 limit 2;
--replace_column 2 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events from 107 limit 2,1;
show binlog events from 107 limit 1,4;
flush logs;
# We need an extra update before doing save_master_pos.
@ -104,7 +104,7 @@ show binlog events in 'slave-bin.000001' from 4;
--replace_column 2 # 5 #
--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
show binlog events in 'slave-bin.000002' from 4;
source include/show_slave_status.inc;
source include/show_slave_status2.inc;
# Need to recode the following

View File

@ -0,0 +1,554 @@
################################################################################
# This is an auxiliary file used by rpl_mixing_engines.test, and that it
# executes SQL statements according to a format string, as specified in
# rpl_mixing_engines.test. In addition, it accepts the special format
# strings 'configure' and 'clean', used before and after everything else.
################################################################################
if (`SELECT HEX(@commands) = HEX('configure')`)
{
connection master;
SET SQL_LOG_BIN=0;
eval CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval SET SQL_LOG_BIN=1;
connection slave;
SET SQL_LOG_BIN=0;
eval CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM;
eval CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
eval CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type;
SET SQL_LOG_BIN=1;
connection master;
INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1);
INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1);
INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1);
INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1);
INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1);
INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1);
INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1);
INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1);
INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1);
INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1);
INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1);
INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1);
DELIMITER |;
CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
END|
CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER)
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
END|
CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
RETURN "fc_i_tt_5_suc";
END|
CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64)
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id;
INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id);
INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1);
RETURN "fc_i_nt_5_suc";
END|
CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
END|
CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
END|
CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id;
INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
END|
CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW
BEGIN
DECLARE in_stmt_id INTEGER;
SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id;
SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id;
INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id);
INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1);
END|
DELIMITER ;|
let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1);
let $trans_id= 7;
let $tb_id= 1;
let $stmt_id= 1;
let $commands= '';
SET @commands= '';
}
if (`SELECT HEX(@commands) = HEX('clean')`)
{
connection master;
DROP TABLE tt_1;
DROP TABLE tt_2;
DROP TABLE tt_3;
DROP TABLE tt_4;
DROP TABLE tt_5;
DROP TABLE tt_6;
DROP TABLE nt_1;
DROP TABLE nt_2;
DROP TABLE nt_3;
DROP TABLE nt_4;
DROP TABLE nt_5;
DROP TABLE nt_6;
DROP PROCEDURE pc_i_tt_5_suc;
DROP PROCEDURE pc_i_nt_5_suc;
DROP FUNCTION fc_i_tt_5_suc;
DROP FUNCTION fc_i_nt_5_suc;
sync_slave_with_master;
SET @commands= '';
}
while (`SELECT HEX(@commands) != HEX('')`)
{
--disable_query_log
SET @command= SUBSTRING_INDEX(@commands, ' ', 1);
let $command= `SELECT @command`;
--eval SET @check_commands= '$commands'
if (`SELECT HEX(@check_commands) = HEX('''')`)
{
let $commands= `SELECT @commands`;
}
--echo -b-b-b-b-b-b-b-b-b-b-b- >> $command << -b-b-b-b-b-b-b-b-b-b-b-
let $pos_command= query_get_value("SHOW MASTER STATUS", Position, 1);
--enable_query_log
if (`SELECT HEX(@command) = HEX('B')`)
{
eval BEGIN;
}
if (`SELECT HEX(@command) = HEX('T')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('T-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('T-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval SELECT fc_i_tt_5_suc ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('T-proc')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval CALL pc_i_tt_5_suc ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('eT')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from tt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('Te')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from tt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('Te-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from tt_5`;
let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('Te-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from tt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO tt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id));
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('N')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('N-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('N-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval SELECT fc_i_nt_5_suc ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('N-proc')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval CALL pc_i_nt_5_suc ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('eN')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from nt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('Ne')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from nt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('Ne-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from nt_5`;
let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('Ne-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from nt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO nt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id));
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('tN')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1;
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('tNe')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from nt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM tt_1;
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('nT')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1;
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('nTe')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from tt_1`;
let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM nt_1;
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('NT')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval UPDATE nt_3, tt_3 SET nt_3.info= "new text $trans_id --> $stmt_id", tt_3.info= "new text $trans_id --> $stmt_id" where nt_3.trans_id = tt_3.trans_id and tt_3.trans_id = 1;
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('NT-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('NT-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_tt_5_suc($trans_id, $stmt_id));
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('NeT-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from nt_4`;
let $old_stmt_id= `SELECT max(stmt_id) from nt_4 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('NeT-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from nt_5`;
let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id));
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('TN')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval UPDATE tt_4, nt_4 SET tt_4.info= "new text $trans_id --> $stmt_id", nt_4.info= "new text $trans_id --> $stmt_id" where nt_4.trans_id = tt_4.trans_id and tt_4.trans_id = 1;
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('TN-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('TN-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_nt_5_suc($trans_id, $stmt_id));
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('TeN-trig')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from tt_3`;
let $old_stmt_id= `SELECT max(stmt_id) from tt_3 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id);
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('TeN-func')`)
{
#--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id)
let $old_trans_id= `SELECT max(trans_id) from tt_5`;
let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`;
--error ER_DUP_ENTRY, ER_DUP_KEY
eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id));
inc $stmt_id;
}
if (`SELECT HEX(@command) = HEX('CS-T->T')`)
{
--eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('CS-N->N')`)
{
--eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('CS-T->N')`)
{
--eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('CS-N->T')`)
{
--eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('CSe-T->T')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('CSe-N->N')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('CSe-T->N')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('CSe-N->T')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('CT')`)
{
--eval CREATE TEMPORARY TABLE tt_xx_$tb_id (a int) engine=$engine_type;
}
if (`SELECT HEX(@command) = HEX('IS-T<-N')`)
{
--eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('ISe-T<-N')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('IS-N<-T')`)
{
--eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('ISe-N<-T')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('IS-T<-T')`)
{
--eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('ISe-T<-T')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1;
}
if (`SELECT HEX(@command) = HEX('IS-N<-N')`)
{
--eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('ISe-N<-N')`)
{
--error ER_DUP_ENTRY, ER_DUP_KEY
--eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1;
}
if (`SELECT HEX(@command) = HEX('trunc-CS-T')`)
{
eval TRUNCATE TABLE tt_xx_$tb_id;
}
if (`SELECT HEX(@command) = HEX('trunc-CS-N')`)
{
eval TRUNCATE TABLE nt_xx_$tb_id;
}
if (`SELECT HEX(@command) = HEX('trunc-CT')`)
{
eval TRUNCATE TABLE tt_xx_$tb_id;
}
if (`SELECT HEX(@command) = HEX('drop-CS')`)
{
--disable_warnings
eval DROP TABLE IF EXISTS tt_xx_$tb_id, nt_xx_$tb_id;
inc $tb_id;
--enable_warnings
}
if (`SELECT HEX(@command) = HEX('drop-CT')`)
{
--disable_warnings
eval DROP TEMPORARY TABLE IF EXISTS tt_xx_$tb_id;
inc $tb_id;
--enable_warnings
}
if (`SELECT HEX(@command) = HEX('C')`)
{
--error 0, ER_GET_ERRMSG
eval COMMIT;
}
if (`SELECT HEX(@command) = HEX('R')`)
{
--error 0, ER_GET_ERRMSG
eval ROLLBACK;
}
if (`SELECT HEX(@command) = HEX('S1')`)
{
eval SAVEPOINT s1;
}
if (`SELECT HEX(@command) = HEX('R1')`)
{
eval ROLLBACK TO s1;
}
--disable_query_log
SET @commands= LTRIM(SUBSTRING(@commands, LENGTH(@command) + 1));
inc $stmt_id;
let $binlog_start= $pos_command;
--source include/show_binlog_events.inc
--echo -e-e-e-e-e-e-e-e-e-e-e- >> $command << -e-e-e-e-e-e-e-e-e-e-e-
if (`SELECT HEX(@commands) = HEX('')`)
{
let $binlog_start= $pos_trans_command;
--echo -b-b-b-b-b-b-b-b-b-b-b- >> $commands << -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- >> $commands << -e-e-e-e-e-e-e-e-e-e-e-
--echo
let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1);
let $stmt_id= 1;
inc $trans_id;
let $commands= '';
}
}

File diff suppressed because it is too large Load Diff

View File

@ -141,7 +141,9 @@ let $run= 5;
while ($run)
{
START TRANSACTION;
--disable_warnings
--eval CALL tpcb.trans($rpl_format);
--enable_warnings
eval SET @my_errno= $mysql_errno;
let $run_good= `SELECT @my_errno = 0`;
let $run_bad= `SELECT @my_errno <> 0`;
@ -190,7 +192,9 @@ let $run= 5;
while ($run)
{
START TRANSACTION;
--disable_warnings
--eval CALL tpcb.trans($rpl_format);
--enable_warnings
eval SET @my_errno= $mysql_errno;
let $run_good= `SELECT @my_errno = 0`;
let $run_bad= `SELECT @my_errno <> 0`;
@ -240,7 +244,9 @@ let $run= 5;
while ($run)
{
START TRANSACTION;
--disable_warnings
--eval CALL tpcb.trans($rpl_format);
--enable_warnings
eval SET @my_errno= $mysql_errno;
let $run_good= `SELECT @my_errno = 0`;
let $run_bad= `SELECT @my_errno <> 0`;

View File

@ -23,7 +23,7 @@ let $binary_log_limit_row= 3;
-- echo [MASTER] ********* SOW BINLOG EVENTS ... LIMIT offset,rows *********
let $binary_log_file= ;
let $binary_log_limit_row= 3;
let $binary_log_limit_row= 4;
let $binary_log_limit_offset= 1;
-- source include/show_binlog_events.inc
@ -49,7 +49,7 @@ let $binary_log_limit_row= 3;
-- echo [SLAVE] ********* SOW BINLOG EVENTS ... LIMIT offset,rows *********
let $binary_log_file= ;
let $binary_log_limit_row= 3;
let $binary_log_limit_row= 4;
let $binary_log_limit_offset= 1;
-- source include/show_binlog_events.inc

View File

@ -0,0 +1,125 @@
#
# Bug#6148 ()
#
# Let the master do lots of insertions
connection master;
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
connection slave;
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
connection master;
create table t1(n int);
sync_slave_with_master;
stop slave;
--source include/wait_for_slave_to_stop.inc
connection master;
let $1=5000;
disable_query_log;
while ($1)
{
eval insert into t1 values($1);
dec $1;
}
enable_query_log;
save_master_pos;
connection slave;
start slave;
let $wait_condition= SELECT COUNT(*) > 0 FROM t1;
source include/wait_condition.inc;
stop slave io_thread;
start slave io_thread;
source include/wait_for_slave_to_start.inc;
sync_with_master;
connection master;
drop table t1;
sync_slave_with_master;
#
# Bug#38205 Row-based Replication (RBR) causes inconsistencies...
# Bug#319 if while a non-transactional slave is replicating a transaction...
#
# Verifying that STOP SLAVE does not interrupt excution of a group
# execution of events if the group can not roll back.
# Killing the sql thread continues to provide a "hard" stop (the
# part II, moved to the bugs suite as it's hard to make it
# deterministic with KILL).
#
#
# Part I. The being stopped sql thread finishes first the current group of
# events if the group contains an event on a non-transaction table.
connection master;
create table t1i(n int primary key) engine=innodb;
create table t2m(n int primary key) engine=myisam;
begin;
insert into t1i values (1);
insert into t1i values (2);
insert into t1i values (3);
commit;
sync_slave_with_master;
connection slave;
begin;
insert into t1i values (5);
connection master;
let $pos0_master= query_get_value(SHOW MASTER STATUS, Position, 1);
begin;
insert into t1i values (4);
insert into t2m values (1); # non-ta update to process
insert into t1i values (5); # to block at. to be played with stopped
commit;
connection slave;
# slave sql thread must be locked out by the conn `slave' explicit lock
let $pos0_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);
--disable_query_log
eval select $pos0_master - $pos0_slave as zero;
--enable_query_log
connection slave1;
let $count= 1;
let $table= t2m;
source include/wait_until_rows_count.inc;
send stop slave;
connection slave;
rollback; # release the sql thread
connection slave1;
reap;
source include/wait_for_slave_to_stop.inc;
let $sql_status= query_get_value(SHOW SLAVE STATUS, Slave_SQL_Running, 1);
--echo *** sql thread is *not* running: $sql_status ***
connection master;
let $pos1_master= query_get_value(SHOW MASTER STATUS, Position, 1);
connection slave;
let $pos1_slave= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1);
--echo *** the prove: the stopped slave has finished the current transaction ***
--disable_query_log
select count(*) as five from t1i;
eval select $pos1_master - $pos1_slave as zero;
eval select $pos1_slave > $pos0_slave as one;
--enable_query_log
source include/start_slave.inc;
# clean-up
connection master;
drop table t1i, t2m;
sync_slave_with_master;
# End of tests

View File

@ -3,7 +3,7 @@
-- source include/have_binlog_format_statement.inc
-- source include/master-slave.inc
CALL mtr.add_suppression("Statement may not be safe to log in statement format.");
CALL mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
# Load some data into t1
create table t1 (word char(20) not null);

View File

@ -0,0 +1,147 @@
# Proving that stopping in the middle of applying a group of events
# does not have immediate effect if a non-transaction table has been changed.
# The slave sql thread has to try to finish applying first.
# The tests rely on simulation of the killed status.
# The matter of testing correlates to some of `rpl_start_stop_slave' that does
# not require `have_debug'.
connection master;
call mtr.add_suppression("Unsafe statement binlogged in statement format since BINLOG_FORMAT = STATEMENT");
create table tm (a int auto_increment primary key) engine=myisam;
create table ti (a int auto_increment primary key) engine=innodb;
sync_slave_with_master;
set @@global.debug="+d,stop_slave_middle_group";
connection master;
begin;
insert into ti set a=null;
insert into tm set a=null; # to simulate killed status on the slave
commit;
connection slave;
# slave will catch the killed status but won't shut down immediately
# only after the whole group has done (commit)
source include/wait_for_slave_sql_to_stop.inc;
# checking: no error and the group is finished
let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
let $read = query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1);
let $exec = query_get_value("SHOW SLAVE STATUS", Exec_Master_Log_Pos, 1);
--disable_query_log
eval SELECT $read = $exec into @check;
--enable_query_log
eval SELECT "NO$error" AS Last_SQL_Error, @check as `true`;
select count(*) as one from tm;
select count(*) as one from ti;
set @@global.debug="-d";
#
# bug#45940 issues around rli->last_event_start_time
# Testing of slave stopped after it had waited (in vain) for
# the group be finished.
# It could not be finished because of simulation of failure to
# receive the terminal part
# The test relay on simulation of the incomplete group in the relay log
# Two cases are verified: a mixed transacton and a mixed multi-table update.
#
# The mixed transacton.
#
source include/start_slave.inc;
connection master;
truncate table tm; # cleanup of former tests
truncate table ti;
#connection slave;
sync_slave_with_master;
set @@global.debug="+d,stop_slave_middle_group";
set @@global.debug="+d,incomplete_group_in_relay_log";
connection master;
begin;
insert into ti set a=null;
insert into tm set a=null;
commit;
connection slave;
# slave will catch the killed status, won't shut down immediately
# but does it eventually having the whole group unfinished (not committed)
source include/wait_for_slave_sql_to_stop.inc;
# checking: the error and group unfinished
let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
let $read = query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1);
let $exec = query_get_value("SHOW SLAVE STATUS", Exec_Master_Log_Pos, 1);
--disable_query_log
eval SELECT $read - $exec > 0 into @check;
--enable_query_log
eval SELECT "$error" AS Last_SQL_Error, @check as `true`;
select count(*) as one from tm;
select count(*) as zero from ti;
set @@global.debug="-d";
#
# The mixed multi-table update
#
stop slave;
truncate table tm;
source include/start_slave.inc;
connection master;
#connection slave;
sync_slave_with_master;
set @@global.debug="+d,stop_slave_middle_group";
set @@global.debug="+d,incomplete_group_in_relay_log";
connection master;
update tm as t1, ti as t2 set t1.a=t1.a * 2, t2.a=t2.a * 2;
connection slave;
# slave will catch the killed status, won't shut down immediately
# but does it eventually having the whole group unfinished (not committed)
#
source include/wait_for_slave_sql_to_stop.inc;
# checking: the error and group unfinished
let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1);
let $read = query_get_value("SHOW SLAVE STATUS", Read_Master_Log_Pos, 1);
let $exec = query_get_value("SHOW SLAVE STATUS", Exec_Master_Log_Pos, 1);
--disable_query_log
eval SELECT $read - $exec > 0 into @check;
--enable_query_log
eval SELECT "$error" AS Last_SQL_Error, @check as `true`;
select max(a) as two from tm;
select max(a) as one from ti;
set @@global.debug="-d";
#
# clean-up
#
connection master;
drop table tm, ti;
connection slave; # slave SQL thread is stopped
source include/stop_slave.inc;
drop table tm, ti;