mirror of
https://github.com/MariaDB/server.git
synced 2025-12-12 08:01:43 +03:00
breaks
When a "CREATE TEMPORARY TABLE SELECT * FROM" was executed the OPTION_KEEP_LOG was
not set into the thd->variables.option_bits. For that reason, if the transaction
had updated only transactional engines and was rolled back at the end (.e.g due to
a deadlock) the changes were not written to the binary log, including the creation
of the temporary table.
To fix the problem, we have set the OPTION_KEEP_LOG into the
thd->variables.option_bits when a "CREATE TEMPORARY TABLE
SELECT * FROM" is executed.
229 lines
8.7 KiB
Plaintext
229 lines
8.7 KiB
Plaintext
################################################################################
|
|
# BUG#51894 Replication failure with SBR on DROP TEMPORARY TABLE inside a
|
|
# transaction
|
|
# BUG#52616 Temp table prevents switch binlog format from STATEMENT to ROW
|
|
#
|
|
# This test verifies what follows:
|
|
#
|
|
# 1 - If the following statements are classified as unsafe:
|
|
# 1.1 - INSERT INTO t_myisam SELECT * FROM t_myisam_temp
|
|
# 1.2 - INSERT INTO t_myisam_temp SELECT * FROM t_myisam
|
|
#
|
|
# 2 - If the following statements are classified as safe:
|
|
# 1.7 - INSERT INTO t_innodb SELECT * FROM t_myisam_temp
|
|
# 1.8 - INSERT INTO t_myisam_temp SELECT * FROM t_innodb
|
|
#
|
|
# 3 - If we can switch from statement to row format.
|
|
#
|
|
# 4 - If statements that can manipulate a temporary table and do not cause an
|
|
# implicit commit are kept in the boundaries of an on-going transaction. For
|
|
# instance:
|
|
# 4.1 - CREATE TEMPORARY TABLE
|
|
# 4.2 - CREATE TEMPORARY TABLE LIKE
|
|
# 4.3 - CREATE TEMPORARY TABLE SELECT * FROM
|
|
# 4.4 - INSERT/UPDATE/DELETE (Note that only inserts are verified)
|
|
# 4.5 - INSERT INTO t_myisam SELECT * FROM t_myisam_temp
|
|
# 4.6 - INSERT INTO t_myisam_temp SELECT * FROM t_myisam
|
|
# 4.7 - INSERT INTO t_innodb SELECT * FROM t_myisam_temp
|
|
# 4.8 - INSERT INTO t_myisam_temp SELECT * FROM t_innodb
|
|
#
|
|
# 5 - If transactions that have a DROP TEMPORARY are always written to the
|
|
# binary log regardless of the mode and the outcome: commit or rollback.
|
|
#
|
|
# 6 - In particular, if the current statement logging format is set to row
|
|
# the CREATE TEMPORARY is not logged and the DROP TEMPORARY is extended with
|
|
# the IF EXISTS clause.
|
|
#
|
|
# 7 - It verifies if the CONNECTION_ID along with a non-transactional
|
|
# table is written outside the transaction boundaries and is not classified
|
|
# as unsafe. See BUG#53075.
|
|
#
|
|
# 8 - It verifies if OPTION_KEEP_LOG is set and thus forcing to write the
|
|
# trx-cache to the binary log when an rollback is issued and only trx-tables
|
|
# were updated. See BUG#53421.
|
|
################################################################################
|
|
|
|
source include/master-slave.inc;
|
|
source include/have_binlog_format_statement.inc;
|
|
source include/have_innodb.inc;
|
|
|
|
CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
|
|
|
|
--echo ########################################################################
|
|
--echo # VERIFY ITEMS 1 and 2
|
|
--echo ########################################################################
|
|
|
|
--echo #
|
|
--echo # Create temporary tables to verify when statements involving temporary
|
|
--echo # tables are classified as safe or unsafe by printing out the warning
|
|
--echo # messages.
|
|
--echo #
|
|
connection master;
|
|
CREATE TABLE t_myisam(id int) engine= MyIsam;
|
|
INSERT INTO t_myisam VALUES(1);
|
|
CREATE TABLE t_innodb(id int) engine= Innodb;
|
|
INSERT INTO t_innodb VALUES(1);
|
|
CREATE TEMPORARY TABLE t_myisam_temp(id int) engine= MyIsam;
|
|
INSERT INTO t_myisam_temp VALUES(1);
|
|
CREATE TEMPORARY TABLE t_innodb_temp(id int) engine= Innodb;
|
|
INSERT INTO t_innodb_temp VALUES(1);
|
|
|
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
|
BEGIN;
|
|
INSERT INTO t_myisam SELECT * FROM t_myisam_temp;
|
|
INSERT INTO t_innodb SELECT * FROM t_myisam_temp;
|
|
INSERT INTO t_innodb SELECT * FROM t_innodb_temp;
|
|
ROLLBACK;
|
|
|
|
BEGIN;
|
|
INSERT INTO t_myisam SELECT * FROM t_innodb_temp;
|
|
INSERT INTO t_innodb SELECT * FROM t_myisam_temp;
|
|
INSERT INTO t_innodb SELECT * FROM t_innodb_temp;
|
|
ROLLBACK;
|
|
|
|
--echo ########################################################################
|
|
--echo # VERIFY ITEM 3
|
|
--echo ########################################################################
|
|
|
|
--echo #
|
|
--echo # When there is a temporary table we can switch between the mixed and
|
|
--echo # row formats. However, we cannot switch to the statement format.
|
|
--echo #
|
|
SET BINLOG_FORMAT=MIXED;
|
|
SET BINLOG_FORMAT=ROW;
|
|
SET BINLOG_FORMAT=MIXED;
|
|
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
|
|
--echo #
|
|
--echo # When there is a temporary table we can switch between the mixed and
|
|
--echo # row formats. However, we cannot swith to the statement format.
|
|
--echo #
|
|
SET BINLOG_FORMAT=MIXED;
|
|
DROP TABLE t_myisam_temp, t_innodb_temp, t_myisam, t_innodb;
|
|
source include/show_binlog_events.inc;
|
|
|
|
--echo ########################################################################
|
|
--echo # VERIFY ITEMS 4 and 5
|
|
--echo ########################################################################
|
|
|
|
--echo #
|
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
|
BEGIN;
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
INSERT INTO tmp1 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp1;
|
|
DROP TEMPORARY TABLE tmp2;
|
|
DROP TEMPORARY TABLE tmp3;
|
|
COMMIT;
|
|
source include/show_binlog_events.inc;
|
|
|
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
|
BEGIN;
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
INSERT INTO tmp1 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp1;
|
|
DROP TEMPORARY TABLE tmp2;
|
|
DROP TEMPORARY TABLE tmp3;
|
|
ROLLBACK;
|
|
source include/show_binlog_events.inc;
|
|
|
|
--echo ########################################################################
|
|
--echo # VERIFY ITEM 6
|
|
--echo ########################################################################
|
|
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
SET BINLOG_FORMAT=ROW;
|
|
DROP TEMPORARY TABLE tmp1;
|
|
BEGIN;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp2;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp3;
|
|
COMMIT;
|
|
source include/show_binlog_events.inc;
|
|
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
CREATE TEMPORARY TABLE tmp2 LIKE tmp1;
|
|
CREATE TEMPORARY TABLE tmp3 engine= MyIsam SELECT * FROM tmp1;
|
|
SET BINLOG_FORMAT=ROW;
|
|
DROP TEMPORARY TABLE tmp1;
|
|
BEGIN;
|
|
INSERT INTO tmp2 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp2;
|
|
INSERT INTO tmp3 VALUES(1);
|
|
DROP TEMPORARY TABLE tmp3;
|
|
ROLLBACK;
|
|
source include/show_binlog_events.inc;
|
|
|
|
--echo ########################################################################
|
|
--echo # VERIFY ITEM 7
|
|
--echo ########################################################################
|
|
|
|
SET BINLOG_FORMAT=STATEMENT;
|
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
|
|
|
CREATE TEMPORARY TABLE tmp1(id int) engine= MyIsam;
|
|
CREATE TABLE t_myisam (f1 BIGINT) ENGINE = MyISAM;
|
|
CREATE TABLE t_innodb (f1 BIGINT) ENGINE = Innodb;
|
|
|
|
BEGIN;
|
|
INSERT INTO t_myisam VALUES(CONNECTION_ID());
|
|
INSERT INTO tmp1 VALUES(1);
|
|
INSERT INTO t_myisam VALUES(1);
|
|
INSERT INTO t_innodb VALUES(1);
|
|
INSERT INTO t_myisam VALUES(CONNECTION_ID());
|
|
INSERT INTO t_innodb VALUES(1);
|
|
COMMIT;
|
|
source include/show_binlog_events.inc;
|
|
|
|
--echo ########################################################################
|
|
--echo # VERIFY ITEM 8
|
|
--echo ########################################################################
|
|
#
|
|
# Before the patch for BUG#53421, nothing were written to the binary log on
|
|
# behalf of the transaction presented below:
|
|
#
|
|
SET BINLOG_FORMAT=MIXED;
|
|
let $binlog_start= query_get_value("SHOW MASTER STATUS", Position, 1);
|
|
BEGIN;
|
|
CREATE TEMPORARY TABLE tmp2 SELECT * FROM t_innodb;
|
|
INSERT INTO t_innodb VALUES(1);
|
|
INSERT INTO t_innodb VALUES(1);
|
|
ROLLBACK;
|
|
source include/show_binlog_events.inc;
|
|
|
|
--echo ###################################################################################
|
|
--echo # CHECK CONSISTENCY
|
|
--echo ###################################################################################
|
|
sync_slave_with_master;
|
|
connection master;
|
|
|
|
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql
|
|
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
|
|
--diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql
|
|
|
|
--echo ###################################################################################
|
|
--echo # CLEAN UP
|
|
--echo ###################################################################################
|
|
connection master;
|
|
|
|
DROP TABLE t_myisam;
|
|
DROP TABLE t_innodb;
|
|
|
|
sync_slave_with_master;
|