polardbxengine/mysql-test/extra/rpl_tests/rpl_split_statements_debug....

577 lines
18 KiB
Plaintext

# ==== Purpose ====
#
# This is part of rpl_split_statements.test which covers DROP DATABASE
# statement and one scenario for DROP TABLES statement.
#
# ==============================================================================
#
# DROP TABLES: See detailed description of its behavior in
# rpl_split_statements.test file.
#
# This file contains coverage for the following scenario:
#
# We drop group of 4 tables, where 2 tables are in SE which
# do not support atomic DDL and 2 in SE which support it and
# then fail. This triggers code path in DROP TABLE implementation
# which differs from case when there is no failure.
# This is done for both GTID_MODE='AUTOMATIC' and GTID_MODE='UUID:NUMBER'
# to see difference in splitting/combining. Notice that with GTID
# assigned even such failed DROP TABLE will consume GTID.
#
# ==============================================================================
#
# DROP DATABASE: this statement will first drop all non-temporary
# tables in the database, then stored routines and events in it,
# and then try to remove database from the data-dictionary.
# If there is an error during one of the latter steps, then the
# removal of events, stored routines and tables in SEs supporting
# atomic DDL will be rolled back. Removal of tables in SEs which
# don't support atomic DDL can't be rolled back and will be logged
# as a group of DROP TABLE IF EXISTS statements, with one DROP
# statement per table.
#
# If GTID_NEXT='UUID:NUMBER', the statement will not be logged and
# the gtid will not be added to GTID_EXECUTED, if the statement
# fails. This is regardless of whether it would result in multiple
# DROP statements or just one.
#
# This test verifies that all DROP DATABASE works, for all values of
# GTID_MODE/GTID_NEXT, and both on a client connection and in a slave
# connection.
#
# === Implementation ===
#
# We try five different error scenarios:
#
# 3.1. Database exists and is empty.
# 3.2. Database exists and contains one InnoDB table
# (no side-effects of failure).
# 3.3. Database exists and contains one InnoDB and one MyISAM table,
# so we get single DROP TABLE statement in the binary log.
# 3.4. Database exists and contains one InnoDB and two MyISAM tables,
# so we get two DROP TABLE statements in the binary log.
# 3.5. Database has not been created, but the directory exists.
# 3.6. Database has not created and the directory does not exist.
#
# We run these six scenarios in three ways:
#
# - On master with GTID_MODE='AUTOMATIC'
# - On master with GTID_MODE!='AUTOMATIC' ('ANONYMOUS'/'UUID:NUMBER',
# depending on GTID_MODE).
# - On slave.
#
# We also run scenario with successful drop of database which contains one
# InnoDB and one MyISAM table. In AUTOMATIC/ANONYMOUS mode such statement
# is split into DROP TABLE IF EXISTS for MyISAM table and DROP DATABASE
# statement. With GTID assigned it is logged as single DROP DATABASE
# statement.
#
# This last scenario and scenario 3.6 also provide coverage for changes to
# DROP DATABASE binary logging which were implemented as part of WL#7743
# "New data dictionary: changes to DDL-related parts of SE API".
#
# We use DBUG_EXECUTE_IF to simulate errors during DROP DATABASE.
--source include/have_debug.inc
# It suffices to test one binlog_format.
--source include/have_binlog_format_statement.inc
--let $rpl_gtid_utils= 1
--source include/master-slave.inc
CALL mtr.add_suppression('Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.');
if ($gtid_mode_on)
{
CALL mtr.add_suppression('Cannot execute statement because it needs to be written to the binary log as multiple statements');
CALL mtr.add_suppression('DROP DATABASE failed; some tables may have been dropped but the database directory remains.');
}
--connection slave
CALL mtr.add_suppression("Error dropping database");
CALL mtr.add_suppression("Can't drop database '.*'; database doesn't exist");
CALL mtr.add_suppression("Slave SQL for channel '': ... The slave coordinator and worker threads are stopped, possibly leaving data in inconsistent state. .* Error_code: MY-001756");
CALL mtr.add_suppression("Slave SQL for channel '': .* Error_code: MY-001105");
--connection master
--let $gtid_step_gtid_mode_agnostic= 1
--echo ==== Case 2: DROP TABLES ====
--echo ==== Case 2D: Failing DROP TABLES for base tables with and without atomic DDL support ====
CREATE TABLE base_1_n (a INT) ENGINE = MyISAM;
CREATE TABLE base_2_n (a INT) ENGINE = MyISAM;
CREATE TABLE base_3_a (a INT) ENGINE = InnoDB;
CREATE TABLE base_4_a (pk INT PRIMARY KEY) ENGINE = InnoDB;
--source include/rpl_sync.inc
--echo ---- GTID_MODE=AUTOMATIC ----
--source include/gtid_step_reset.inc
SET SESSION DEBUG='+d,rm_table_no_locks_abort_after_atomic_tables';
--error ER_UNKNOWN_ERROR
DROP TABLES base_1_n, base_2_n, base_3_a, base_4_a;
SET SESSION DEBUG='-d,rm_table_no_locks_abort_after_atomic_tables';
--echo # In AUTOMATIC mode the above statement should be split into
--echo # two statements for each of MyISAM tables.
--echo # There should be no statement for dropping base_3_a or
--echo # base_4_a as their removal is rolled back.
--let $gtid_step_count= 2.
--source include/gtid_step_assert.inc
--echo # base_3_a and base_4_a should still be there on master
SHOW CREATE TABLE base_3_a;
SHOW CREATE TABLE base_4_a;
--source include/rpl_sync.inc
--connection slave
--echo # base_3_a and base_4_a should still be there on slave
SHOW CREATE TABLE base_3_a;
SHOW CREATE TABLE base_4_a;
--connection master
CREATE TABLE base_1_n (a INT) ENGINE = MyISAM;
CREATE TABLE base_2_n (a INT) ENGINE = MyISAM;
--source include/rpl_sync.inc
--echo ---- GTID_NEXT=non-automatic ----
--source include/gtid_step_reset.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
SET SESSION DEBUG='+d,rm_table_no_locks_abort_after_atomic_tables';
--error ER_UNKNOWN_ERROR
DROP TABLES base_1_n, base_2_n, base_3_a, base_4_a;
SET SESSION DEBUG='-d,rm_table_no_locks_abort_after_atomic_tables';
SET GTID_NEXT= 'AUTOMATIC';
if ($gtid_mode_on)
{
--echo # With GTID assigned the above statement should not be split.
--let $gtid_step_count= 1
--source include/gtid_step_assert.inc
}
if (!$gtid_mode_on)
{
--echo # Without GTID assigned the above statement should be split into
--echo # two as in AUTOMATIC mode.
--let $gtid_step_count= 2
--source include/gtid_step_assert.inc
}
--echo # base_3_a and base_4_a should still be there on master
SHOW CREATE TABLE base_3_a;
SHOW CREATE TABLE base_4_a;
--source include/rpl_sync.inc
--connection slave
--echo # base_3_a and base_4_a should still be there on slave
SHOW CREATE TABLE base_3_a;
SHOW CREATE TABLE base_4_a;
--connection master
--echo ---- Clean up ----
DROP TABLE base_4_a, base_3_a;
--source include/rpl_sync.inc
--echo ==== Case 3: DROP DATABASE ====
--echo ---- Initialize ----
--echo # db1, db2, db3: no tables.
CREATE DATABASE db1;
CREATE DATABASE db2;
CREATE DATABASE db3;
--source include/rpl_sync.inc
--echo # db4, db5, db6: one table.
CREATE DATABASE db4;
CREATE DATABASE db5;
CREATE DATABASE db6;
CREATE TABLE db4.t1 (a INT);
CREATE TABLE db5.t1 (a INT);
CREATE TABLE db6.t1 (a INT);
--source include/rpl_sync.inc
--echo # db7, db8, db9: one MyISAM and one InnoDB table.
CREATE DATABASE db7;
CREATE DATABASE db8;
CREATE DATABASE db9;
CREATE TABLE db7.t1 (a INT) ENGINE=InnoDB;
CREATE TABLE db8.t1 (a INT) ENGINE=InnoDB;
CREATE TABLE db9.t1 (a INT) ENGINE=InnoDB;
CREATE TABLE db7.t2 (a INT) ENGINE=MyISAM;
CREATE TABLE db8.t2 (a INT) ENGINE=MyISAM;
CREATE TABLE db9.t2 (a INT) ENGINE=MyISAM;
--source include/rpl_sync.inc
--echo # db10, db11, db12: two MyISAM and one InnoDB table.
CREATE DATABASE db10;
CREATE DATABASE db11;
CREATE DATABASE db12;
CREATE TABLE db10.t1 (a INT) ENGINE=MyISAM;
CREATE TABLE db11.t1 (a INT) ENGINE=MyISAM;
CREATE TABLE db12.t1 (a INT) ENGINE=MyISAM;
CREATE TABLE db10.t2 (a INT) ENGINE=MyISAM;
CREATE TABLE db11.t2 (a INT) ENGINE=MyISAM;
CREATE TABLE db12.t2 (a INT) ENGINE=MyISAM;
CREATE TABLE db10.t3 (a INT) ENGINE=InnoDB;
CREATE TABLE db11.t3 (a INT) ENGINE=InnoDB;
CREATE TABLE db12.t3 (a INT) ENGINE=InnoDB;
--source include/rpl_sync.inc
--echo # db13, db14: not a database, but the directory and the entry exist.
--mkdir $server_1_datadir/db13
--mkdir $server_1_datadir/db14
--write_file $server_1_datadir/db13/file.txt
EOF
--write_file $server_1_datadir/db14/file.txt
EOF
--echo # db15 is not a database, but the empty directory exists on master.
--mkdir $server_1_datadir/db15
--source include/rpl_sync.inc
--echo # db19, db20: one MyISAM and one InnoDB table (successfull case).
CREATE DATABASE db19;
CREATE DATABASE db20;
CREATE TABLE db19.t1 (a INT) ENGINE=InnoDB;
CREATE TABLE db20.t1 (a INT) ENGINE=InnoDB;
CREATE TABLE db19.t2 (a INT) ENGINE=MyISAM;
CREATE TABLE db20.t2 (a INT) ENGINE=MyISAM;
--source include/rpl_sync.inc
--echo ---- DROP DATABASE is split on master; GTID_NEXT=AUTOMATIC ----
--echo # db1: no table.
--source include/save_binlog_position.inc
SET GTID_NEXT = 'AUTOMATIC';
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db1;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
--echo # db4: one InnoDB table.
--source include/save_binlog_position.inc
SET GTID_NEXT = 'AUTOMATIC';
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db4;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
--echo # db7: one MyISAM and one InnoDB table.
--source include/save_binlog_position.inc
SET GTID_NEXT = 'AUTOMATIC';
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db7;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
if ($gtid_mode_on)
{
--let $event_sequence= Gtid # !Q(DROP TABLE.*)
}
if (!$gtid_mode_on)
{
--let $event_sequence= Anonymous_Gtid # !Q(DROP TABLE.*)
}
--source include/assert_binlog_events.inc
--echo # db10: two MyISAM and one InnoDB table.
--source include/save_binlog_position.inc
SET GTID_NEXT = 'AUTOMATIC';
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db10;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
if ($gtid_mode_on)
{
--let $event_sequence= Gtid # !Q(DROP TABLE.*) # Gtid # !Q(DROP TABLE.*)
}
if (!$gtid_mode_on)
{
--let $event_sequence= Anonymous_Gtid # !Q(DROP TABLE.*) # Anonymous_Gtid # !Q(DROP TABLE.*)
}
--source include/assert_binlog_events.inc
--echo # db13: not a database, but directory exists.
--source include/save_binlog_position.inc
SET GTID_NEXT = 'AUTOMATIC';
--replace_result \\ /
--error ER_SCHEMA_DIR_UNKNOWN
DROP DATABASE db13;
--let $event_sequence= ()
--source include/assert_binlog_events.inc
--echo # db16: not a database.
--source include/save_binlog_position.inc
SET GTID_NEXT = 'AUTOMATIC';
--replace_result \\ /
--error ER_DB_DROP_EXISTS
DROP DATABASE db16;
--let $event_sequence= ()
--source include/assert_binlog_events.inc
--echo # db19: Successfull DROP DATABASE for one MyISAM and one InnoDB table.
--source include/save_binlog_position.inc
SET GTID_NEXT = 'AUTOMATIC';
DROP DATABASE db19;
if ($gtid_mode_on)
{
--let $event_sequence= Gtid # !Q(DROP TABLE.*) # Gtid # !Q(DROP DATABASE.*)
}
if (!$gtid_mode_on)
{
--let $event_sequence= Anonymous_Gtid # !Q(DROP TABLE.*) # Anonymous_Gtid # !Q(DROP DATABASE.*)
}
--source include/assert_binlog_events.inc
--echo ---- DROP DATABASE is split on master; GTID_NEXT=non-automatic ----
--echo # db2: no table.
--source include/save_binlog_position.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
if (!$gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db2;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
}
if ($gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db2;
--replace_result $server_1_uuid MASTER_UUID \\ /
SHOW WARNINGS;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
}
SET GTID_NEXT = 'AUTOMATIC';
--echo # db5: one InnoDB table.
--source include/save_binlog_position.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
if (!$gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db5;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
}
if ($gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db5;
--replace_result $server_1_uuid MASTER_UUID \\ /
SHOW WARNINGS;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
}
SET GTID_NEXT = 'AUTOMATIC';
--echo # db8: one MyISAM and one InnoDB table.
--source include/save_binlog_position.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
if (!$gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db8;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= Anonymous_Gtid # !Q(DROP TABLE.*)
--source include/assert_binlog_events.inc
}
if ($gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db8;
--replace_result $server_1_uuid MASTER_UUID \\ /
SHOW WARNINGS;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
}
SET GTID_NEXT = 'AUTOMATIC';
--echo # db11: two MyISAM and one InnoDB tables.
--source include/save_binlog_position.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
if (!$gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db11;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= Anonymous_Gtid # !Q(DROP TABLE.*) # Anonymous_Gtid # !Q(DROP TABLE.*)
--source include/assert_binlog_events.inc
}
if ($gtid_mode_on)
{
SET DEBUG= '+d, rm_db_fail_after_dropping_tables';
--error ER_UNKNOWN_ERROR
DROP DATABASE db11;
--replace_result $server_1_uuid MASTER_UUID \\ /
SHOW WARNINGS;
SET DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $event_sequence= ()
--source include/assert_binlog_events.inc
}
SET GTID_NEXT = 'AUTOMATIC';
--echo # db14: not a database, but directory exists.
--source include/save_binlog_position.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
--replace_result \\ /
--error ER_SCHEMA_DIR_UNKNOWN
DROP DATABASE db14;
--let $event_sequence= ()
--source include/assert_binlog_events.inc
SET GTID_NEXT = 'AUTOMATIC';
--echo # db17: not a database.
--source include/save_binlog_position.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
--error ER_DB_DROP_EXISTS
DROP DATABASE db17;
--let $event_sequence= ()
--source include/assert_binlog_events.inc
SET GTID_NEXT = 'AUTOMATIC';
--echo # db20: Successfull DROP DATABASE for one MyISAM and one InnoDB table.
--echo # No splitting if GTID is assigned.
--source include/save_binlog_position.inc
--source include/set_gtid_next_gtid_mode_agnostic.inc
DROP DATABASE db20;
if ($gtid_mode_on)
{
--let $event_sequence= Gtid # !Q(DROP DATABASE.*)
}
if (!$gtid_mode_on)
{
--let $event_sequence= Anonymous_Gtid # !Q(DROP TABLE.*) # Anonymous_Gtid # !Q(DROP DATABASE.*)
}
--source include/assert_binlog_events.inc
SET GTID_NEXT = 'AUTOMATIC';
--source include/rpl_sync.inc
--echo ---- DROP DATABASE is split on slave ----
SET GTID_NEXT = 'AUTOMATIC';
--let $slave_sql_errno= convert_error(ER_UNKNOWN_ERROR)
--connection slave
SET GLOBAL DEBUG= '+d, rm_db_fail_after_dropping_tables';
--let $rpl_connection_name= master
--source include/rpl_connection.inc
--echo # db3: no table.
DROP DATABASE db3;
--source include/sync_slave_io_with_master.inc
--source include/wait_for_slave_sql_error.inc
--source include/rpl_skip_to_end_of_relay_log.inc
--let $rpl_connection_name= master
--source include/rpl_connection.inc
--echo # db6: one InnoDB table.
DROP DATABASE db6;
--source include/sync_slave_io_with_master.inc
--source include/wait_for_slave_sql_error.inc
--source include/rpl_skip_to_end_of_relay_log.inc
--let $rpl_connection_name= master
--source include/rpl_connection.inc
--echo # db9: one MyISAM and one InnoDB table.
DROP DATABASE db9;
--source include/sync_slave_io_with_master.inc
--source include/wait_for_slave_sql_error.inc
--source include/rpl_skip_to_end_of_relay_log.inc
--let $rpl_connection_name= master
--source include/rpl_connection.inc
--echo # db12: two MyISAM and one InnoDB table.
DROP DATABASE db12;
--source include/sync_slave_io_with_master.inc
--source include/wait_for_slave_sql_error.inc
--source include/rpl_skip_to_end_of_relay_log.inc
--connection slave
SET GLOBAL DEBUG= '-d, rm_db_fail_after_dropping_tables';
--let $rpl_connection_name= master
--source include/rpl_connection.inc
--echo # db15: not a database, but an empty directory exists.
--replace_result \\ /
--error ER_SCHEMA_DIR_UNKNOWN
DROP DATABASE db15;
--echo ---- Clean up ----
--remove_file $server_1_datadir/db13/file.txt
--remove_file $server_1_datadir/db14/file.txt
--rmdir $server_1_datadir/db13
--rmdir $server_1_datadir/db14
--rmdir $server_1_datadir/db15
DROP DATABASE db1;
DROP DATABASE db2;
DROP DATABASE IF EXISTS db3;
DROP DATABASE db4;
DROP DATABASE db5;
DROP DATABASE IF EXISTS db6;
DROP DATABASE db7;
DROP DATABASE db8;
DROP DATABASE IF EXISTS db9;
DROP DATABASE db10;
DROP DATABASE db11;
DROP DATABASE IF EXISTS db12;
--source include/rpl_sync.inc
--source include/rpl_end.inc